]>
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);