18c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko//===-- asan_test_mac.cc --------------------------------------------------===// 28c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// 38c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// The LLVM Compiler Infrastructure 48c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// 58c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// This file is distributed under the University of Illinois Open Source 68c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// License. See LICENSE.TXT for details. 78c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// 88c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko//===----------------------------------------------------------------------===// 98c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// 108c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// This file is a part of AddressSanitizer, an address sanity checker. 118c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// 128c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko//===----------------------------------------------------------------------===// 138c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 148c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko#include "asan_test_utils.h" 158c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 168c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko#include "asan_mac_test.h" 178c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 188c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko#include <malloc/malloc.h> 198c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko#include <AvailabilityMacros.h> // For MAC_OS_X_VERSION_* 208c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko#include <CoreFoundation/CFString.h> 218c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 228c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, CFAllocatorDefaultDoubleFree) { 238c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH( 248c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko CFAllocatorDefaultDoubleFree(NULL), 258c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko "attempting double-free"); 268c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 278c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 288c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenkovoid CFAllocator_DoubleFreeOnPthread() { 298c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko pthread_t child; 308c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko PTHREAD_CREATE(&child, NULL, CFAllocatorDefaultDoubleFree, NULL); 318c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko PTHREAD_JOIN(child, NULL); // Shouldn't be reached. 328c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 338c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 348c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, CFAllocatorDefaultDoubleFree_ChildPhread) { 358c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH(CFAllocator_DoubleFreeOnPthread(), "attempting double-free"); 368c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 378c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 388c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenkonamespace { 398c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 408c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenkovoid *GLOB; 418c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 428c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenkovoid *CFAllocatorAllocateToGlob(void *unused) { 438c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko GLOB = CFAllocatorAllocate(NULL, 100, /*hint*/0); 448c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko return NULL; 458c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 468c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 478c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenkovoid *CFAllocatorDeallocateFromGlob(void *unused) { 488c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko char *p = (char*)GLOB; 498c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko p[100] = 'A'; // ASan should report an error here. 508c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko CFAllocatorDeallocate(NULL, GLOB); 518c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko return NULL; 528c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 538c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 548c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenkovoid CFAllocator_PassMemoryToAnotherThread() { 558c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko pthread_t th1, th2; 568c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko PTHREAD_CREATE(&th1, NULL, CFAllocatorAllocateToGlob, NULL); 578c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko PTHREAD_JOIN(th1, NULL); 588c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko PTHREAD_CREATE(&th2, NULL, CFAllocatorDeallocateFromGlob, NULL); 598c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko PTHREAD_JOIN(th2, NULL); 608c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 618c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 628c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, CFAllocator_PassMemoryToAnotherThread) { 638c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH(CFAllocator_PassMemoryToAnotherThread(), 648c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko "heap-buffer-overflow"); 658c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 668c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 678c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} // namespace 688c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 698c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// TODO(glider): figure out whether we still need these tests. Is it correct 708c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// to intercept the non-default CFAllocators? 718c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, DISABLED_CFAllocatorSystemDefaultDoubleFree) { 728c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH( 738c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko CFAllocatorSystemDefaultDoubleFree(), 748c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko "attempting double-free"); 758c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 768c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 778c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// We're intercepting malloc, so kCFAllocatorMalloc is routed to ASan. 788c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, CFAllocatorMallocDoubleFree) { 798c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH(CFAllocatorMallocDoubleFree(), "attempting double-free"); 808c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 818c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 828c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, DISABLED_CFAllocatorMallocZoneDoubleFree) { 838c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH(CFAllocatorMallocZoneDoubleFree(), "attempting double-free"); 848c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 858c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 868c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// For libdispatch tests below we check that ASan got to the shadow byte 878c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// legend, i.e. managed to print the thread stacks (this almost certainly 888c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// means that the libdispatch task creation has been intercepted correctly). 898c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, GCDDispatchAsync) { 908c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // Make sure the whole ASan report is printed, i.e. that we don't die 918c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // on a CHECK. 928c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH(TestGCDDispatchAsync(), "Shadow byte legend"); 938c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 948c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 958c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, GCDDispatchSync) { 968c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // Make sure the whole ASan report is printed, i.e. that we don't die 978c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // on a CHECK. 988c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH(TestGCDDispatchSync(), "Shadow byte legend"); 998c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 1008c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 1018c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 1028c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, GCDReuseWqthreadsAsync) { 1038c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // Make sure the whole ASan report is printed, i.e. that we don't die 1048c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // on a CHECK. 1058c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH(TestGCDReuseWqthreadsAsync(), "Shadow byte legend"); 1068c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 1078c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 1088c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, GCDReuseWqthreadsSync) { 1098c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // Make sure the whole ASan report is printed, i.e. that we don't die 1108c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // on a CHECK. 1118c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH(TestGCDReuseWqthreadsSync(), "Shadow byte legend"); 1128c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 1138c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 1148c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, GCDDispatchAfter) { 1158c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // Make sure the whole ASan report is printed, i.e. that we don't die 1168c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // on a CHECK. 1178c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH(TestGCDDispatchAfter(), "Shadow byte legend"); 1188c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 1198c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 1208c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, GCDSourceEvent) { 1218c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // Make sure the whole ASan report is printed, i.e. that we don't die 1228c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // on a CHECK. 1238c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH(TestGCDSourceEvent(), "Shadow byte legend"); 1248c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 1258c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 1268c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, GCDSourceCancel) { 1278c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // Make sure the whole ASan report is printed, i.e. that we don't die 1288c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // on a CHECK. 1298c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH(TestGCDSourceCancel(), "Shadow byte legend"); 1308c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 1318c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 1328c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, GCDGroupAsync) { 1338c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // Make sure the whole ASan report is printed, i.e. that we don't die 1348c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // on a CHECK. 1358c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH(TestGCDGroupAsync(), "Shadow byte legend"); 1368c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 1378c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 1388c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenkovoid *MallocIntrospectionLockWorker(void *_) { 1398c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko const int kNumPointers = 100; 1408c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko int i; 1418c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko void *pointers[kNumPointers]; 1428c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko for (i = 0; i < kNumPointers; i++) { 1438c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko pointers[i] = malloc(i + 1); 1448c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko } 1458c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko for (i = 0; i < kNumPointers; i++) { 1468c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko free(pointers[i]); 1478c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko } 1488c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 1498c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko return NULL; 1508c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 1518c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 1528c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenkovoid *MallocIntrospectionLockForker(void *_) { 1538c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko pid_t result = fork(); 1548c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko if (result == -1) { 1558c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko perror("fork"); 1568c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko } 1578c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko assert(result != -1); 1588c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko if (result == 0) { 1598c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // Call malloc in the child process to make sure we won't deadlock. 1608c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko void *ptr = malloc(42); 1618c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko free(ptr); 1628c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko exit(0); 1638c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko } else { 1648c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // Return in the parent process. 1658c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko return NULL; 1668c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko } 1678c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 1688c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 1698c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, MallocIntrospectionLock) { 1708c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // Incorrect implementation of force_lock and force_unlock in our malloc zone 1718c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // will cause forked processes to deadlock. 1728c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // TODO(glider): need to detect that none of the child processes deadlocked. 1738c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko const int kNumWorkers = 5, kNumIterations = 100; 1748c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko int i, iter; 1758c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko for (iter = 0; iter < kNumIterations; iter++) { 1768c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko pthread_t workers[kNumWorkers], forker; 1778c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko for (i = 0; i < kNumWorkers; i++) { 1788c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko PTHREAD_CREATE(&workers[i], 0, MallocIntrospectionLockWorker, 0); 1798c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko } 1808c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko PTHREAD_CREATE(&forker, 0, MallocIntrospectionLockForker, 0); 1818c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko for (i = 0; i < kNumWorkers; i++) { 1828c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko PTHREAD_JOIN(workers[i], 0); 1838c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko } 1848c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko PTHREAD_JOIN(forker, 0); 1858c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko } 1868c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 1878c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 1888c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenkovoid *TSDAllocWorker(void *test_key) { 1898c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko if (test_key) { 1908c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko void *mem = malloc(10); 1918c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko pthread_setspecific(*(pthread_key_t*)test_key, mem); 1928c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko } 1938c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko return NULL; 1948c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 1958c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 1968c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, DISABLED_TSDWorkqueueTest) { 1978c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko pthread_t th; 1988c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko pthread_key_t test_key; 1998c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko pthread_key_create(&test_key, CallFreeOnWorkqueue); 2008c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko PTHREAD_CREATE(&th, NULL, TSDAllocWorker, &test_key); 2018c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko PTHREAD_JOIN(th, NULL); 2028c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko pthread_key_delete(test_key); 2038c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 2048c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 2058c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// Test that CFStringCreateCopy does not copy constant strings. 2068c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, CFStringCreateCopy) { 2078c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko CFStringRef str = CFSTR("Hello world!\n"); 2088c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko CFStringRef str2 = CFStringCreateCopy(0, str); 2098c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_EQ(str, str2); 2108c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 2118c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 2128c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, NSObjectOOB) { 2138c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // Make sure that our allocators are used for NSObjects. 2148c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_DEATH(TestOOBNSObjects(), "heap-buffer-overflow"); 2158c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 2168c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 2178c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// Make sure that correct pointer is passed to free() when deallocating a 2188c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// NSURL object. 2198c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// See http://code.google.com/p/address-sanitizer/issues/detail?id=70. 2208c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, NSURLDeallocation) { 2218c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko TestNSURLDeallocation(); 2228c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 2238c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 2248c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko// See http://code.google.com/p/address-sanitizer/issues/detail?id=109. 2258c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander PotapenkoTEST(AddressSanitizerMac, Mstats) { 2268c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko malloc_statistics_t stats1, stats2; 2278c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko malloc_zone_statistics(/*all zones*/NULL, &stats1); 2288c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko const size_t kMallocSize = 100000; 2298c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko void *alloc = Ident(malloc(kMallocSize)); 2308c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko malloc_zone_statistics(/*all zones*/NULL, &stats2); 2318c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_GT(stats2.blocks_in_use, stats1.blocks_in_use); 2328c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko EXPECT_GE(stats2.size_in_use - stats1.size_in_use, kMallocSize); 2338c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko free(alloc); 2348c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko // Even the default OSX allocator may not change the stats after free(). 2358c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko} 2368c745fc58d8aca66db1170b1cdbbc0a7743c20a0Alexander Potapenko 237