]>
git.saurik.com Git - apple/xnu.git/blob - tools/tests/xnu_quick_test/helpers/data_exec.c
15 #define ALT_STK_SIZE (MINSIGSTKSZ + pagesize)
18 typedef unsigned int psint_t
;
21 typedef unsigned long long psint_t
;
26 #define msg(...) do { if (verbose) printf(__VA_ARGS__); } while (0);
29 * Test whether the architecture allows execution from the stack and heap data areas. What's
30 * allowed varies by architecture due to backwards compatibility. We also run a separate test
31 * where we turn on PROT_EXEC explicitly which should always allow execution to take place.
33 * The "expected" array tells us what the result of each test should be based on the architecture.
34 * The code assumes the test numbers in the macros below are consecutive starting from 0.
38 #define HEAP_PROT_EXEC 1
40 #define STACK_PROT_EXEC 3
43 #define FAIL -1 /* can't use 0 since setjmp uses that */
47 SUCCEED
, /* execute from heap */
48 SUCCEED
, /* exeucte from heap with PROT_EXEC */
49 FAIL
, /* execute from stack */
50 SUCCEED
, /* exeucte from stack with PROT_EXEC */
52 FAIL
, /* execute from heap */
53 SUCCEED
, /* exeucte from heap with PROT_EXEC */
54 FAIL
, /* execute from stack */
55 SUCCEED
, /* exeucte from stack with PROT_EXEC */
58 FAIL
, /* execute from heap */
59 SUCCEED
, /* exeucte from heap with PROT_EXEC */
60 FAIL
, /* execute from stack */
61 SUCCEED
, /* exeucte from stack with PROT_EXEC */
66 main(int argc
, char *argv
[])
70 char buf
[func_len
+ 4];
76 struct sigaction sigact
;
82 while ((c
= getopt(argc
, argv
, "v")) != -1) {
90 fprintf(stderr
, "usage: data_exec [-v]\n");
95 pagesize
= getpagesize();
97 sigstk
.ss_sp
= malloc(ALT_STK_SIZE
);
98 sigstk
.ss_size
= ALT_STK_SIZE
;
101 if (sigaltstack(&sigstk
, NULL
) < 0) {
102 perror("sigaltstack");
106 sigact
.sa_handler
= catch_segv
;
107 sigact
.sa_flags
= SA_ONSTACK
;
108 sigemptyset(&sigact
.sa_mask
);
110 if (sigaction(SIGSEGV
, &sigact
, NULL
) == -1) {
111 perror("sigaction SIGSEGV");
115 if (sigaction(SIGBUS
, &sigact
, NULL
) == -1) {
116 perror("sigaction SIGBUS");
124 if ((result
= setjmp(resume
)) != 0) {
125 if (result
!= expected
[test
]) {
126 printf("%s: test %d failed, expected %d, got %d\n", cmd_name
, test
, expected
[test
], result
);
136 msg("attempting to execute from malloc'ed area..\n");
138 func
= (void *)malloc(func_len
);
140 func
= (void *)((char *)func
+ ((psint_t
)test_func
& 0x3));
142 bcopy(test_func
, func
, func_len
);
145 msg("execution suceeded, result is %d\n\n", result
);
146 longjmp(resume
, SUCCEED
);
149 msg("attempting to execute from malloc'ed area with PROT_EXEC..\n");
151 func
= (void *)malloc(func_len
);
153 func
= (void *)((char *)func
+ ((psint_t
)test_func
& 0x3));
154 bcopy(test_func
, func
, func_len
);
156 base
= (psint_t
)func
& ~(pagesize
- 1);
157 len
= func_len
+ (psint_t
)func
- base
;
159 if(mprotect((void *)base
, len
, PROT_READ
|PROT_WRITE
|PROT_EXEC
) == -1) {
160 perror("mprotect of stack");
165 msg("execution suceeded, result is %d\n\n", result
);
166 longjmp(resume
, SUCCEED
);
169 msg("attempting to execute from stack...\n");
171 func
= (void *)(buf
+ ((psint_t
)test_func
& 0x3));
172 bcopy(test_func
, func
, func_len
);
175 msg("stack execution suceeded, result from stack exec is %d\n\n", result
);
176 longjmp(resume
, SUCCEED
);
178 case STACK_PROT_EXEC
:
179 msg("attempting to execute from stack with PROT_EXEC...\n");
181 func
= (void *)(buf
+ ((psint_t
)test_func
& 0x3));
182 bcopy(test_func
, func
, func_len
);
184 base
= (psint_t
)func
& ~(pagesize
- 1);
185 len
= func_len
+ (psint_t
)func
- base
;
187 if(mprotect((void *)base
, len
, PROT_READ
|PROT_WRITE
|PROT_EXEC
) == -1) {
188 perror("mprotect of stack");
193 msg("stack execution suceeded, result from stack exec is %d\n", result
);
194 longjmp(resume
, SUCCEED
);
197 msg("All tests passed.\n");
212 msg("got sig %d\n\n", sig
);
213 longjmp(resume
, FAIL
);