]>
git.saurik.com Git - apple/libpthread.git/blob - tests/stack_aslr.c
5 #include <dispatch/dispatch.h>
8 #include <darwintest.h>
10 #define T_LOG_VERBOSE(...)
13 #define STACK_LOCATIONS 16
15 #define STACK_LOCATIONS 8
19 thread_routine(void *loc
)
22 *(uintptr_t*)loc
= (uintptr_t)&foo
;
27 pointer_compare(const void *ap
, const void *bp
)
29 uintptr_t a
= *(const uintptr_t*)ap
;
30 uintptr_t b
= *(const uintptr_t*)bp
;
31 return a
> b
? 1 : a
< b
? -1 : 0;
35 test_stack_aslr(bool workqueue_thread
)
37 const int attempts
= 128;
38 int attempt_round
= 0;
40 uintptr_t *addr_array
= mmap(NULL
, sizeof(uintptr_t) * attempts
,
41 PROT_READ
|PROT_WRITE
, MAP_SHARED
|MAP_ANON
, -1, 0);
42 T_QUIET
; T_ASSERT_NOTNULL(addr_array
, NULL
);
45 bzero(addr_array
, sizeof(uintptr_t) * attempts
);
47 for (int i
= 0; i
< attempts
; i
++) {
49 T_QUIET
; T_ASSERT_POSIX_SUCCESS(pid
, "[%d] fork()", i
);
52 pid
= waitpid(pid
, NULL
, 0);
53 T_QUIET
; T_ASSERT_POSIX_SUCCESS(pid
, "[%d] waitpid()", i
);
54 } else if (workqueue_thread
) { // child
55 dispatch_async(dispatch_get_global_queue(0,0), ^{
57 addr_array
[i
] = (uintptr_t)&foo
;
60 while (true) sleep(1);
63 int ret
= pthread_create(&th
, NULL
, thread_routine
, &addr_array
[i
]);
65 ret
= pthread_join(th
, NULL
);
71 qsort(addr_array
, attempts
, sizeof(uintptr_t), pointer_compare
);
73 T_LOG("Stack address range: %p - %p (+%lx)", (void*)addr_array
[0], (void*)addr_array
[attempts
-1],
74 addr_array
[attempts
-1] - addr_array
[0]);
76 int unique_values
= 0;
77 T_LOG_VERBOSE("[%p]", (void*)addr_array
[0]);
78 for (int i
= 1; i
< attempts
; i
++) {
79 T_LOG_VERBOSE("[%p]", (void*)addr_array
[i
]);
80 if (addr_array
[i
-1] != addr_array
[i
]) {
85 if (attempt_round
< 3) T_MAYFAIL
;
86 T_EXPECT_GE(unique_values
, STACK_LOCATIONS
, "Should have more than %d unique stack locations", STACK_LOCATIONS
);
87 if (attempt_round
++ < 3 && unique_values
< STACK_LOCATIONS
) goto again
;
90 T_DECL(pthread_stack_aslr
, "Confirm that stacks are ASLRed", T_META_CHECK_LEAKS(NO
),
91 T_META_ALL_VALID_ARCHS(YES
))
93 test_stack_aslr(false);
96 T_DECL(wq_stack_aslr
, "Confirm that workqueue stacks are ASLRed", T_META_CHECK_LEAKS(NO
),
97 T_META_ALL_VALID_ARCHS(YES
))
99 test_stack_aslr(true);