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