]>
Commit | Line | Data |
---|---|---|
1 | #include <stdlib.h> | |
2 | #include <unistd.h> | |
3 | #include <signal.h> | |
4 | #include <setjmp.h> | |
5 | ||
6 | #include <darwintest.h> | |
7 | ||
8 | static char *heap; | |
9 | static volatile int pass; | |
10 | static sigjmp_buf jbuf; | |
11 | ||
12 | static void __dead2 | |
13 | action(int signo, struct __siginfo *info, void *uap __attribute__((unused))) | |
14 | { | |
15 | if (info) { | |
16 | pass = (signo == SIGBUS && info->si_addr == heap); | |
17 | } | |
18 | siglongjmp(jbuf, 0); | |
19 | } | |
20 | ||
21 | T_DECL(nxheap, "Non-executable heap", T_META_CHECK_LEAKS(NO)) | |
22 | { | |
23 | struct sigaction sa = { | |
24 | .__sigaction_u.__sa_sigaction = action, | |
25 | .sa_flags = SA_SIGINFO, | |
26 | }; | |
27 | ||
28 | T_ASSERT_POSIX_ZERO(sigaction(SIGBUS, &sa, NULL), NULL); | |
29 | ||
30 | if (sigsetjmp(jbuf, 0)) { | |
31 | T_PASS("SIGBUS"); | |
32 | T_END; | |
33 | } | |
34 | ||
35 | T_QUIET; T_ASSERT_NOTNULL((heap = malloc(1)), NULL); | |
36 | ||
37 | *heap = (char)0xc3; // retq | |
38 | ((void (*)(void))heap)(); // call *%eax | |
39 | ||
40 | T_FAIL("SIGBUS"); | |
41 | } |