Home | History | Annotate | Download | only in tests
      1 //===-- asan_interface_test.cc --------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is a part of AddressSanitizer, an address sanity checker.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 #include "asan_test_utils.h"
     14 #include <sanitizer/allocator_interface.h>
     15 #include <sanitizer/asan_interface.h>
     16 
     17 TEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) {
     18   EXPECT_EQ(0U, __sanitizer_get_estimated_allocated_size(0));
     19   const size_t sizes[] = { 1, 30, 1<<30 };
     20   for (size_t i = 0; i < 3; i++) {
     21     EXPECT_EQ(sizes[i], __sanitizer_get_estimated_allocated_size(sizes[i]));
     22   }
     23 }
     24 
     25 static const char* kGetAllocatedSizeErrorMsg =
     26   "attempting to call __sanitizer_get_allocated_size";
     27 
     28 TEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) {
     29   const size_t kArraySize = 100;
     30   char *array = Ident((char*)malloc(kArraySize));
     31   int *int_ptr = Ident(new int);
     32 
     33   // Allocated memory is owned by allocator. Allocated size should be
     34   // equal to requested size.
     35   EXPECT_EQ(true, __sanitizer_get_ownership(array));
     36   EXPECT_EQ(kArraySize, __sanitizer_get_allocated_size(array));
     37   EXPECT_EQ(true, __sanitizer_get_ownership(int_ptr));
     38   EXPECT_EQ(sizeof(int), __sanitizer_get_allocated_size(int_ptr));
     39 
     40   // We cannot call GetAllocatedSize from the memory we didn't map,
     41   // and from the interior pointers (not returned by previous malloc).
     42   void *wild_addr = (void*)0x1;
     43   EXPECT_FALSE(__sanitizer_get_ownership(wild_addr));
     44   EXPECT_DEATH(__sanitizer_get_allocated_size(wild_addr),
     45                kGetAllocatedSizeErrorMsg);
     46   EXPECT_FALSE(__sanitizer_get_ownership(array + kArraySize / 2));
     47   EXPECT_DEATH(__sanitizer_get_allocated_size(array + kArraySize / 2),
     48                kGetAllocatedSizeErrorMsg);
     49 
     50   // NULL is not owned, but is a valid argument for
     51   // __sanitizer_get_allocated_size().
     52   EXPECT_FALSE(__sanitizer_get_ownership(NULL));
     53   EXPECT_EQ(0U, __sanitizer_get_allocated_size(NULL));
     54 
     55   // When memory is freed, it's not owned, and call to GetAllocatedSize
     56   // is forbidden.
     57   free(array);
     58   EXPECT_FALSE(__sanitizer_get_ownership(array));
     59   EXPECT_DEATH(__sanitizer_get_allocated_size(array),
     60                kGetAllocatedSizeErrorMsg);
     61   delete int_ptr;
     62 
     63   void *zero_alloc = Ident(malloc(0));
     64   if (zero_alloc != 0) {
     65     // If malloc(0) is not null, this pointer is owned and should have valid
     66     // allocated size.
     67     EXPECT_TRUE(__sanitizer_get_ownership(zero_alloc));
     68     // Allocated size is 0 or 1 depending on the allocator used.
     69     EXPECT_LT(__sanitizer_get_allocated_size(zero_alloc), 2U);
     70   }
     71   free(zero_alloc);
     72 }
     73 
     74 TEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) {
     75   size_t before_malloc, after_malloc, after_free;
     76   char *array;
     77   const size_t kMallocSize = 100;
     78   before_malloc = __sanitizer_get_current_allocated_bytes();
     79 
     80   array = Ident((char*)malloc(kMallocSize));
     81   after_malloc = __sanitizer_get_current_allocated_bytes();
     82   EXPECT_EQ(before_malloc + kMallocSize, after_malloc);
     83 
     84   free(array);
     85   after_free = __sanitizer_get_current_allocated_bytes();
     86   EXPECT_EQ(before_malloc, after_free);
     87 }
     88 
     89 TEST(AddressSanitizerInterface, GetHeapSizeTest) {
     90   // asan_allocator2 does not keep huge chunks in free list, but unmaps them.
     91   // The chunk should be greater than the quarantine size,
     92   // otherwise it will be stuck in quarantine instead of being unmaped.
     93   static const size_t kLargeMallocSize = (1 << 28) + 1;  // 256M
     94   free(Ident(malloc(kLargeMallocSize)));  // Drain quarantine.
     95   size_t old_heap_size = __sanitizer_get_heap_size();
     96   for (int i = 0; i < 3; i++) {
     97     // fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize);
     98     free(Ident(malloc(kLargeMallocSize)));
     99     EXPECT_EQ(old_heap_size, __sanitizer_get_heap_size());
    100   }
    101 }
    102 
    103 static const size_t kManyThreadsMallocSizes[] = {5, 1UL<<10, 1UL<<14, 357};
    104 static const size_t kManyThreadsIterations = 250;
    105 static const size_t kManyThreadsNumThreads =
    106   (SANITIZER_WORDSIZE == 32) ? 40 : 200;
    107 
    108 static void *ManyThreadsWithStatsWorker(void *arg) {
    109   (void)arg;
    110   for (size_t iter = 0; iter < kManyThreadsIterations; iter++) {
    111     for (size_t size_index = 0; size_index < 4; size_index++) {
    112       free(Ident(malloc(kManyThreadsMallocSizes[size_index])));
    113     }
    114   }
    115   // Just one large allocation.
    116   free(Ident(malloc(1 << 20)));
    117   return 0;
    118 }
    119 
    120 TEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {
    121   size_t before_test, after_test, i;
    122   pthread_t threads[kManyThreadsNumThreads];
    123   before_test = __sanitizer_get_current_allocated_bytes();
    124   for (i = 0; i < kManyThreadsNumThreads; i++) {
    125     PTHREAD_CREATE(&threads[i], 0,
    126                    (void* (*)(void *x))ManyThreadsWithStatsWorker, (void*)i);
    127   }
    128   for (i = 0; i < kManyThreadsNumThreads; i++) {
    129     PTHREAD_JOIN(threads[i], 0);
    130   }
    131   after_test = __sanitizer_get_current_allocated_bytes();
    132   // ASan stats also reflect memory usage of internal ASan RTL structs,
    133   // so we can't check for equality here.
    134   EXPECT_LT(after_test, before_test + (1UL<<20));
    135 }
    136 
    137 static void DoDoubleFree() {
    138   int *x = Ident(new int);
    139   delete Ident(x);
    140   delete Ident(x);
    141 }
    142 
    143 TEST(AddressSanitizerInterface, ExitCode) {
    144   int original_exit_code = __asan_set_error_exit_code(7);
    145   EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(7), "");
    146   EXPECT_EQ(7, __asan_set_error_exit_code(8));
    147   EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(8), "");
    148   EXPECT_EQ(8, __asan_set_error_exit_code(original_exit_code));
    149   EXPECT_EXIT(DoDoubleFree(),
    150               ::testing::ExitedWithCode(original_exit_code), "");
    151 }
    152 
    153 static void MyDeathCallback() {
    154   fprintf(stderr, "MyDeathCallback\n");
    155   fflush(0);  // On Windows, stderr doesn't flush on crash.
    156 }
    157 
    158 TEST(AddressSanitizerInterface, DeathCallbackTest) {
    159   __asan_set_death_callback(MyDeathCallback);
    160   EXPECT_DEATH(DoDoubleFree(), "MyDeathCallback");
    161   __asan_set_death_callback(NULL);
    162 }
    163 
    164 static const char* kUseAfterPoisonErrorMessage = "use-after-poison";
    165 
    166 #define GOOD_ACCESS(ptr, offset)  \
    167     EXPECT_FALSE(__asan_address_is_poisoned(ptr + offset))
    168 
    169 #define BAD_ACCESS(ptr, offset) \
    170     EXPECT_TRUE(__asan_address_is_poisoned(ptr + offset))
    171 
    172 TEST(AddressSanitizerInterface, SimplePoisonMemoryRegionTest) {
    173   char *array = Ident((char*)malloc(120));
    174   // poison array[40..80)
    175   __asan_poison_memory_region(array + 40, 40);
    176   GOOD_ACCESS(array, 39);
    177   GOOD_ACCESS(array, 80);
    178   BAD_ACCESS(array, 40);
    179   BAD_ACCESS(array, 60);
    180   BAD_ACCESS(array, 79);
    181   char value;
    182   EXPECT_DEATH(value = Ident(array[40]), kUseAfterPoisonErrorMessage);
    183   __asan_unpoison_memory_region(array + 40, 40);
    184   // access previously poisoned memory.
    185   GOOD_ACCESS(array, 40);
    186   GOOD_ACCESS(array, 79);
    187   free(array);
    188 }
    189 
    190 TEST(AddressSanitizerInterface, OverlappingPoisonMemoryRegionTest) {
    191   char *array = Ident((char*)malloc(120));
    192   // Poison [0..40) and [80..120)
    193   __asan_poison_memory_region(array, 40);
    194   __asan_poison_memory_region(array + 80, 40);
    195   BAD_ACCESS(array, 20);
    196   GOOD_ACCESS(array, 60);
    197   BAD_ACCESS(array, 100);
    198   // Poison whole array - [0..120)
    199   __asan_poison_memory_region(array, 120);
    200   BAD_ACCESS(array, 60);
    201   // Unpoison [24..96)
    202   __asan_unpoison_memory_region(array + 24, 72);
    203   BAD_ACCESS(array, 23);
    204   GOOD_ACCESS(array, 24);
    205   GOOD_ACCESS(array, 60);
    206   GOOD_ACCESS(array, 95);
    207   BAD_ACCESS(array, 96);
    208   free(array);
    209 }
    210 
    211 TEST(AddressSanitizerInterface, PushAndPopWithPoisoningTest) {
    212   // Vector of capacity 20
    213   char *vec = Ident((char*)malloc(20));
    214   __asan_poison_memory_region(vec, 20);
    215   for (size_t i = 0; i < 7; i++) {
    216     // Simulate push_back.
    217     __asan_unpoison_memory_region(vec + i, 1);
    218     GOOD_ACCESS(vec, i);
    219     BAD_ACCESS(vec, i + 1);
    220   }
    221   for (size_t i = 7; i > 0; i--) {
    222     // Simulate pop_back.
    223     __asan_poison_memory_region(vec + i - 1, 1);
    224     BAD_ACCESS(vec, i - 1);
    225     if (i > 1) GOOD_ACCESS(vec, i - 2);
    226   }
    227   free(vec);
    228 }
    229 
    230 // Make sure that each aligned block of size "2^granularity" doesn't have
    231 // "true" value before "false" value.
    232 static void MakeShadowValid(bool *shadow, int length, int granularity) {
    233   bool can_be_poisoned = true;
    234   for (int i = length - 1; i >= 0; i--) {
    235     if (!shadow[i])
    236       can_be_poisoned = false;
    237     if (!can_be_poisoned)
    238       shadow[i] = false;
    239     if (i % (1 << granularity) == 0) {
    240       can_be_poisoned = true;
    241     }
    242   }
    243 }
    244 
    245 TEST(AddressSanitizerInterface, PoisoningStressTest) {
    246   const size_t kSize = 24;
    247   bool expected[kSize];
    248   char *arr = Ident((char*)malloc(kSize));
    249   for (size_t l1 = 0; l1 < kSize; l1++) {
    250     for (size_t s1 = 1; l1 + s1 <= kSize; s1++) {
    251       for (size_t l2 = 0; l2 < kSize; l2++) {
    252         for (size_t s2 = 1; l2 + s2 <= kSize; s2++) {
    253           // Poison [l1, l1+s1), [l2, l2+s2) and check result.
    254           __asan_unpoison_memory_region(arr, kSize);
    255           __asan_poison_memory_region(arr + l1, s1);
    256           __asan_poison_memory_region(arr + l2, s2);
    257           memset(expected, false, kSize);
    258           memset(expected + l1, true, s1);
    259           MakeShadowValid(expected, kSize, /*granularity*/ 3);
    260           memset(expected + l2, true, s2);
    261           MakeShadowValid(expected, kSize, /*granularity*/ 3);
    262           for (size_t i = 0; i < kSize; i++) {
    263             ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
    264           }
    265           // Unpoison [l1, l1+s1) and [l2, l2+s2) and check result.
    266           __asan_poison_memory_region(arr, kSize);
    267           __asan_unpoison_memory_region(arr + l1, s1);
    268           __asan_unpoison_memory_region(arr + l2, s2);
    269           memset(expected, true, kSize);
    270           memset(expected + l1, false, s1);
    271           MakeShadowValid(expected, kSize, /*granularity*/ 3);
    272           memset(expected + l2, false, s2);
    273           MakeShadowValid(expected, kSize, /*granularity*/ 3);
    274           for (size_t i = 0; i < kSize; i++) {
    275             ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
    276           }
    277         }
    278       }
    279     }
    280   }
    281   free(arr);
    282 }
    283 
    284 TEST(AddressSanitizerInterface, GlobalRedzones) {
    285   GOOD_ACCESS(glob1, 1 - 1);
    286   GOOD_ACCESS(glob2, 2 - 1);
    287   GOOD_ACCESS(glob3, 3 - 1);
    288   GOOD_ACCESS(glob4, 4 - 1);
    289   GOOD_ACCESS(glob5, 5 - 1);
    290   GOOD_ACCESS(glob6, 6 - 1);
    291   GOOD_ACCESS(glob7, 7 - 1);
    292   GOOD_ACCESS(glob8, 8 - 1);
    293   GOOD_ACCESS(glob9, 9 - 1);
    294   GOOD_ACCESS(glob10, 10 - 1);
    295   GOOD_ACCESS(glob11, 11 - 1);
    296   GOOD_ACCESS(glob12, 12 - 1);
    297   GOOD_ACCESS(glob13, 13 - 1);
    298   GOOD_ACCESS(glob14, 14 - 1);
    299   GOOD_ACCESS(glob15, 15 - 1);
    300   GOOD_ACCESS(glob16, 16 - 1);
    301   GOOD_ACCESS(glob17, 17 - 1);
    302   GOOD_ACCESS(glob1000, 1000 - 1);
    303   GOOD_ACCESS(glob10000, 10000 - 1);
    304   GOOD_ACCESS(glob100000, 100000 - 1);
    305 
    306   BAD_ACCESS(glob1, 1);
    307   BAD_ACCESS(glob2, 2);
    308   BAD_ACCESS(glob3, 3);
    309   BAD_ACCESS(glob4, 4);
    310   BAD_ACCESS(glob5, 5);
    311   BAD_ACCESS(glob6, 6);
    312   BAD_ACCESS(glob7, 7);
    313   BAD_ACCESS(glob8, 8);
    314   BAD_ACCESS(glob9, 9);
    315   BAD_ACCESS(glob10, 10);
    316   BAD_ACCESS(glob11, 11);
    317   BAD_ACCESS(glob12, 12);
    318   BAD_ACCESS(glob13, 13);
    319   BAD_ACCESS(glob14, 14);
    320   BAD_ACCESS(glob15, 15);
    321   BAD_ACCESS(glob16, 16);
    322   BAD_ACCESS(glob17, 17);
    323   BAD_ACCESS(glob1000, 1000);
    324   BAD_ACCESS(glob1000, 1100);  // Redzone is at least 101 bytes.
    325   BAD_ACCESS(glob10000, 10000);
    326   BAD_ACCESS(glob10000, 11000);  // Redzone is at least 1001 bytes.
    327   BAD_ACCESS(glob100000, 100000);
    328   BAD_ACCESS(glob100000, 110000);  // Redzone is at least 10001 bytes.
    329 }
    330 
    331 TEST(AddressSanitizerInterface, PoisonedRegion) {
    332   size_t rz = 16;
    333   for (size_t size = 1; size <= 64; size++) {
    334     char *p = new char[size];
    335     for (size_t beg = 0; beg < size + rz; beg++) {
    336       for (size_t end = beg; end < size + rz; end++) {
    337         void *first_poisoned = __asan_region_is_poisoned(p + beg, end - beg);
    338         if (beg == end) {
    339           EXPECT_FALSE(first_poisoned);
    340         } else if (beg < size && end <= size) {
    341           EXPECT_FALSE(first_poisoned);
    342         } else if (beg >= size) {
    343           EXPECT_EQ(p + beg, first_poisoned);
    344         } else {
    345           EXPECT_GT(end, size);
    346           EXPECT_EQ(p + size, first_poisoned);
    347         }
    348       }
    349     }
    350     delete [] p;
    351   }
    352 }
    353 
    354 // This is a performance benchmark for manual runs.
    355 // asan's memset interceptor calls mem_is_zero for the entire shadow region.
    356 // the profile should look like this:
    357 //     89.10%   [.] __memset_sse2
    358 //     10.50%   [.] __sanitizer::mem_is_zero
    359 // I.e. mem_is_zero should consume ~ SHADOW_GRANULARITY less CPU cycles
    360 // than memset itself.
    361 TEST(AddressSanitizerInterface, DISABLED_StressLargeMemset) {
    362   size_t size = 1 << 20;
    363   char *x = new char[size];
    364   for (int i = 0; i < 100000; i++)
    365     Ident(memset)(x, 0, size);
    366   delete [] x;
    367 }
    368 
    369 // Same here, but we run memset with small sizes.
    370 TEST(AddressSanitizerInterface, DISABLED_StressSmallMemset) {
    371   size_t size = 32;
    372   char *x = new char[size];
    373   for (int i = 0; i < 100000000; i++)
    374     Ident(memset)(x, 0, size);
    375   delete [] x;
    376 }
    377 static const char *kInvalidPoisonMessage = "invalid-poison-memory-range";
    378 static const char *kInvalidUnpoisonMessage = "invalid-unpoison-memory-range";
    379 
    380 TEST(AddressSanitizerInterface, DISABLED_InvalidPoisonAndUnpoisonCallsTest) {
    381   char *array = Ident((char*)malloc(120));
    382   __asan_unpoison_memory_region(array, 120);
    383   // Try to unpoison not owned memory
    384   EXPECT_DEATH(__asan_unpoison_memory_region(array, 121),
    385                kInvalidUnpoisonMessage);
    386   EXPECT_DEATH(__asan_unpoison_memory_region(array - 1, 120),
    387                kInvalidUnpoisonMessage);
    388 
    389   __asan_poison_memory_region(array, 120);
    390   // Try to poison not owned memory.
    391   EXPECT_DEATH(__asan_poison_memory_region(array, 121), kInvalidPoisonMessage);
    392   EXPECT_DEATH(__asan_poison_memory_region(array - 1, 120),
    393                kInvalidPoisonMessage);
    394   free(array);
    395 }
    396 
    397 #if !defined(_WIN32)  // FIXME: This should really be a lit test.
    398 static void ErrorReportCallbackOneToZ(const char *report) {
    399   int report_len = strlen(report);
    400   ASSERT_EQ(6, write(2, "ABCDEF", 6));
    401   ASSERT_EQ(report_len, write(2, report, report_len));
    402   ASSERT_EQ(6, write(2, "ABCDEF", 6));
    403   _exit(1);
    404 }
    405 
    406 TEST(AddressSanitizerInterface, SetErrorReportCallbackTest) {
    407   __asan_set_error_report_callback(ErrorReportCallbackOneToZ);
    408   EXPECT_DEATH(__asan_report_error(0, 0, 0, 0, true, 1),
    409                ASAN_PCRE_DOTALL "ABCDEF.*AddressSanitizer.*WRITE.*ABCDEF");
    410   __asan_set_error_report_callback(NULL);
    411 }
    412 #endif
    413 
    414 TEST(AddressSanitizerInterface, GetOwnershipStressTest) {
    415   std::vector<char *> pointers;
    416   std::vector<size_t> sizes;
    417   const size_t kNumMallocs = 1 << 9;
    418   for (size_t i = 0; i < kNumMallocs; i++) {
    419     size_t size = i * 100 + 1;
    420     pointers.push_back((char*)malloc(size));
    421     sizes.push_back(size);
    422   }
    423   for (size_t i = 0; i < 4000000; i++) {
    424     EXPECT_FALSE(__sanitizer_get_ownership(&pointers));
    425     EXPECT_FALSE(__sanitizer_get_ownership((void*)0x1234));
    426     size_t idx = i % kNumMallocs;
    427     EXPECT_TRUE(__sanitizer_get_ownership(pointers[idx]));
    428     EXPECT_EQ(sizes[idx], __sanitizer_get_allocated_size(pointers[idx]));
    429   }
    430   for (size_t i = 0, n = pointers.size(); i < n; i++)
    431     free(pointers[i]);
    432 }
    433 
    434