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