]>
Commit | Line | Data |
---|---|---|
c6e5f90c A |
1 | #include "darwintest_defaults.h" |
2 | #include <spawn.h> | |
3 | #include <unistd.h> | |
4 | #include <stdlib.h> | |
5 | #include <sys/resource.h> | |
6 | ||
7 | ||
8 | extern char **environ; | |
9 | ||
10 | T_DECL(setrlimit_overflow_segfault, | |
11 | "sigsegv is sent when stack(limit set with setrlimit) is fully used.", | |
12 | T_META_IGNORECRASHES(".*stackoverflow_crash.*"), | |
13 | T_META_CHECK_LEAKS(NO), | |
14 | T_META_ALL_VALID_ARCHS(YES), | |
15 | T_META_ASROOT(YES)) | |
16 | { | |
17 | pid_t child_pid = 0; | |
18 | int rv = 0; | |
19 | ||
20 | struct rlimit lim, save; | |
21 | T_ASSERT_POSIX_SUCCESS(getrlimit(RLIMIT_STACK, &save), NULL); | |
22 | T_ASSERT_POSIX_SUCCESS(getrlimit(RLIMIT_STACK, &lim), NULL); | |
23 | T_LOG("parent: stack limits cur=%llx max=%llx", lim.rlim_cur, lim.rlim_max); | |
24 | lim.rlim_cur = lim.rlim_cur/8; | |
25 | T_ASSERT_POSIX_SUCCESS(setrlimit(RLIMIT_STACK, &lim), NULL); | |
26 | int status = 0; | |
27 | int exit_signal = 0; | |
28 | ||
29 | char *crash_cmd[] = { "./assets/stackoverflow_crash", NULL }; | |
30 | posix_spawn_file_actions_t fact; | |
31 | posix_spawn_file_actions_init(&fact); | |
32 | T_ASSERT_POSIX_SUCCESS(posix_spawn_file_actions_addinherit_np(&fact, STDIN_FILENO), NULL); | |
33 | T_ASSERT_POSIX_SUCCESS(posix_spawn_file_actions_addinherit_np(&fact, STDOUT_FILENO), NULL); | |
34 | T_ASSERT_POSIX_SUCCESS(posix_spawn_file_actions_addinherit_np(&fact, STDERR_FILENO), NULL); | |
35 | T_LOG("spawning %s", crash_cmd[0]); | |
36 | rv = posix_spawn(&child_pid, crash_cmd[0], &fact, NULL, crash_cmd, environ); | |
37 | T_ASSERT_POSIX_SUCCESS(rv, "spawning the stackoverflow program"); | |
38 | ||
39 | T_LOG("parent: waiting for child process with pid %d", child_pid); | |
40 | wait(&status); | |
41 | T_LOG("parent: child process exited. status=%d", WEXITSTATUS(status)); | |
42 | ||
43 | ||
44 | T_ASSERT_POSIX_SUCCESS(setrlimit(RLIMIT_STACK, &save), "Restore original limtis"); | |
45 | posix_spawn_file_actions_destroy(&fact); | |
46 | ||
47 | T_ASSERT_TRUE(WIFSIGNALED(status), "child exit with a signal"); | |
48 | exit_signal = WTERMSIG(status); | |
49 | T_ASSERT_EQ(exit_signal, SIGSEGV, "child should receive SIGSEGV"); | |
50 | ||
51 | return; | |
52 | } |