asan_noinst_test.cc revision 866334332ff8c2a1b7f3715224614b6b75a7578c
1bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//===-- asan_noinst_test.cc -----------------------------------------------===// 2bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 3f5256e16dfc425c1d466f6308d4026d529ce9e0bHoward Hinnant// The LLVM Compiler Infrastructure 4bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// This file is distributed under the University of Illinois Open Source 6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// License. See LICENSE.TXT for details. 7bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 8bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//===----------------------------------------------------------------------===// 9bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 10bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// This file is a part of AddressSanitizer, an address sanity checker. 11bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 12bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// This test file should be compiled w/o asan instrumentation. 13bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//===----------------------------------------------------------------------===// 14712522cfd8f61321b4f197ec0de02b0146afb5a5Howard Hinnant 15712522cfd8f61321b4f197ec0de02b0146afb5a5Howard Hinnant#include "asan_allocator.h" 16712522cfd8f61321b4f197ec0de02b0146afb5a5Howard Hinnant#include "asan_internal.h" 17bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include "asan_mapping.h" 18bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include "asan_stack.h" 19bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include "asan_test_utils.h" 20bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include "sanitizer/asan_interface.h" 21bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 2283e2c4d877fe2d7793868b1c6a5d9525a7c4d431Marshall Clow#include <assert.h> 23bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <stdio.h> 24bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <stdlib.h> 25bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <string.h> // for memset() 26bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <algorithm> 27bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <vector> 28bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 29bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// Simple stand-alone pseudorandom number generator. 30bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// Current algorithm is ANSI C linear congruential PRNG. 31bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantstatic inline u32 my_rand(u32* state) { 32bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return (*state = *state * 1103515245 + 12345) >> 16; 33bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 34bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 358226d0b7c5f9e3a4d4a2b94179234085d973841fMarshall Clowstatic u32 global_seed = 0; 368226d0b7c5f9e3a4d4a2b94179234085d973841fMarshall Clow 37bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 38bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard HinnantTEST(AddressSanitizer, InternalSimpleDeathTest) { 39bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant EXPECT_DEATH(exit(1), ""); 408226d0b7c5f9e3a4d4a2b94179234085d973841fMarshall Clow} 41bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 428226d0b7c5f9e3a4d4a2b94179234085d973841fMarshall Clowstatic void MallocStress(size_t n) { 438226d0b7c5f9e3a4d4a2b94179234085d973841fMarshall Clow u32 seed = my_rand(&global_seed); 448226d0b7c5f9e3a4d4a2b94179234085d973841fMarshall Clow __asan::StackTrace stack1; 458226d0b7c5f9e3a4d4a2b94179234085d973841fMarshall Clow stack1.trace[0] = 0xa123; 468226d0b7c5f9e3a4d4a2b94179234085d973841fMarshall Clow stack1.trace[1] = 0xa456; 47bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant stack1.size = 2; 48 49 __asan::StackTrace stack2; 50 stack2.trace[0] = 0xb123; 51 stack2.trace[1] = 0xb456; 52 stack2.size = 2; 53 54 __asan::StackTrace stack3; 55 stack3.trace[0] = 0xc123; 56 stack3.trace[1] = 0xc456; 57 stack3.size = 2; 58 59 std::vector<void *> vec; 60 for (size_t i = 0; i < n; i++) { 61 if ((i % 3) == 0) { 62 if (vec.empty()) continue; 63 size_t idx = my_rand(&seed) % vec.size(); 64 void *ptr = vec[idx]; 65 vec[idx] = vec.back(); 66 vec.pop_back(); 67 __asan::asan_free(ptr, &stack1); 68 } else { 69 size_t size = my_rand(&seed) % 1000 + 1; 70 switch ((my_rand(&seed) % 128)) { 71 case 0: size += 1024; break; 72 case 1: size += 2048; break; 73 case 2: size += 4096; break; 74 } 75 size_t alignment = 1 << (my_rand(&seed) % 10 + 1); 76 char *ptr = (char*)__asan::asan_memalign(alignment, size, &stack2); 77 vec.push_back(ptr); 78 ptr[0] = 0; 79 ptr[size-1] = 0; 80 ptr[size/2] = 0; 81 } 82 } 83 for (size_t i = 0; i < vec.size(); i++) 84 __asan::asan_free(vec[i], &stack3); 85} 86 87 88TEST(AddressSanitizer, NoInstMallocTest) { 89#ifdef __arm__ 90 MallocStress(300000); 91#else 92 MallocStress(1000000); 93#endif 94} 95 96static void PrintShadow(const char *tag, uptr ptr, size_t size) { 97 fprintf(stderr, "%s shadow: %lx size % 3ld: ", tag, (long)ptr, (long)size); 98 uptr prev_shadow = 0; 99 for (sptr i = -32; i < (sptr)size + 32; i++) { 100 uptr shadow = __asan::MemToShadow(ptr + i); 101 if (i == 0 || i == (sptr)size) 102 fprintf(stderr, "."); 103 if (shadow != prev_shadow) { 104 prev_shadow = shadow; 105 fprintf(stderr, "%02x", (int)*(u8*)shadow); 106 } 107 } 108 fprintf(stderr, "\n"); 109} 110 111TEST(AddressSanitizer, DISABLED_InternalPrintShadow) { 112 for (size_t size = 1; size <= 513; size++) { 113 char *ptr = new char[size]; 114 PrintShadow("m", (uptr)ptr, size); 115 delete [] ptr; 116 PrintShadow("f", (uptr)ptr, size); 117 } 118} 119 120static uptr pc_array[] = { 121#if __WORDSIZE == 64 122 0x7effbf756068ULL, 123 0x7effbf75e5abULL, 124 0x7effc0625b7cULL, 125 0x7effc05b8997ULL, 126 0x7effbf990577ULL, 127 0x7effbf990c56ULL, 128 0x7effbf992f3cULL, 129 0x7effbf950c22ULL, 130 0x7effc036dba0ULL, 131 0x7effc03638a3ULL, 132 0x7effc035be4aULL, 133 0x7effc0539c45ULL, 134 0x7effc0539a65ULL, 135 0x7effc03db9b3ULL, 136 0x7effc03db100ULL, 137 0x7effc037c7b8ULL, 138 0x7effc037bfffULL, 139 0x7effc038b777ULL, 140 0x7effc038021cULL, 141 0x7effc037c7d1ULL, 142 0x7effc037bfffULL, 143 0x7effc038b777ULL, 144 0x7effc038021cULL, 145 0x7effc037c7d1ULL, 146 0x7effc037bfffULL, 147 0x7effc038b777ULL, 148 0x7effc038021cULL, 149 0x7effc037c7d1ULL, 150 0x7effc037bfffULL, 151 0x7effc0520d26ULL, 152 0x7effc009ddffULL, 153 0x7effbf90bb50ULL, 154 0x7effbdddfa69ULL, 155 0x7effbdde1fe2ULL, 156 0x7effbdde2424ULL, 157 0x7effbdde27b3ULL, 158 0x7effbddee53bULL, 159 0x7effbdde1988ULL, 160 0x7effbdde0904ULL, 161 0x7effc106ce0dULL, 162 0x7effbcc3fa04ULL, 163 0x7effbcc3f6a4ULL, 164 0x7effbcc3e726ULL, 165 0x7effbcc40852ULL, 166 0x7effb681ec4dULL, 167#endif // __WORDSIZE 168 0xB0B5E768, 169 0x7B682EC1, 170 0x367F9918, 171 0xAE34E13, 172 0xBA0C6C6, 173 0x13250F46, 174 0xA0D6A8AB, 175 0x2B07C1A8, 176 0x6C844F4A, 177 0x2321B53, 178 0x1F3D4F8F, 179 0x3FE2924B, 180 0xB7A2F568, 181 0xBD23950A, 182 0x61020930, 183 0x33E7970C, 184 0x405998A1, 185 0x59F3551D, 186 0x350E3028, 187 0xBC55A28D, 188 0x361F3AED, 189 0xBEAD0F73, 190 0xAEF28479, 191 0x757E971F, 192 0xAEBA450, 193 0x43AD22F5, 194 0x8C2C50C4, 195 0x7AD8A2E1, 196 0x69EE4EE8, 197 0xC08DFF, 198 0x4BA6538, 199 0x3708AB2, 200 0xC24B6475, 201 0x7C8890D7, 202 0x6662495F, 203 0x9B641689, 204 0xD3596B, 205 0xA1049569, 206 0x44CBC16, 207 0x4D39C39F 208}; 209 210void CompressStackTraceTest(size_t n_iter) { 211 u32 seed = my_rand(&global_seed); 212 const size_t kNumPcs = ARRAY_SIZE(pc_array); 213 u32 compressed[2 * kNumPcs]; 214 215 for (size_t iter = 0; iter < n_iter; iter++) { 216 std::random_shuffle(pc_array, pc_array + kNumPcs); 217 __asan::StackTrace stack0, stack1; 218 stack0.CopyFrom(pc_array, kNumPcs); 219 stack0.size = std::max((size_t)1, (size_t)(my_rand(&seed) % stack0.size)); 220 size_t compress_size = 221 std::max((size_t)2, (size_t)my_rand(&seed) % (2 * kNumPcs)); 222 size_t n_frames = 223 __asan::StackTrace::CompressStack(&stack0, compressed, compress_size); 224 Ident(n_frames); 225 assert(n_frames <= stack0.size); 226 __asan::StackTrace::UncompressStack(&stack1, compressed, compress_size); 227 assert(stack1.size == n_frames); 228 for (size_t i = 0; i < stack1.size; i++) { 229 assert(stack0.trace[i] == stack1.trace[i]); 230 } 231 } 232} 233 234TEST(AddressSanitizer, CompressStackTraceTest) { 235 CompressStackTraceTest(10000); 236} 237 238void CompressStackTraceBenchmark(size_t n_iter) { 239 const size_t kNumPcs = ARRAY_SIZE(pc_array); 240 u32 compressed[2 * kNumPcs]; 241 std::random_shuffle(pc_array, pc_array + kNumPcs); 242 243 __asan::StackTrace stack0; 244 stack0.CopyFrom(pc_array, kNumPcs); 245 stack0.size = kNumPcs; 246 for (size_t iter = 0; iter < n_iter; iter++) { 247 size_t compress_size = kNumPcs; 248 size_t n_frames = 249 __asan::StackTrace::CompressStack(&stack0, compressed, compress_size); 250 Ident(n_frames); 251 } 252} 253 254TEST(AddressSanitizer, CompressStackTraceBenchmark) { 255 CompressStackTraceBenchmark(1 << 24); 256} 257 258TEST(AddressSanitizer, QuarantineTest) { 259 __asan::StackTrace stack; 260 stack.trace[0] = 0x890; 261 stack.size = 1; 262 263 const int size = 32; 264 void *p = __asan::asan_malloc(size, &stack); 265 __asan::asan_free(p, &stack); 266 size_t i; 267 size_t max_i = 1 << 30; 268 for (i = 0; i < max_i; i++) { 269 void *p1 = __asan::asan_malloc(size, &stack); 270 __asan::asan_free(p1, &stack); 271 if (p1 == p) break; 272 } 273 // fprintf(stderr, "i=%ld\n", i); 274 EXPECT_GE(i, 100000U); 275 EXPECT_LT(i, max_i); 276} 277 278void *ThreadedQuarantineTestWorker(void *unused) { 279 (void)unused; 280 u32 seed = my_rand(&global_seed); 281 __asan::StackTrace stack; 282 stack.trace[0] = 0x890; 283 stack.size = 1; 284 285 for (size_t i = 0; i < 1000; i++) { 286 void *p = __asan::asan_malloc(1 + (my_rand(&seed) % 4000), &stack); 287 __asan::asan_free(p, &stack); 288 } 289 return NULL; 290} 291 292// Check that the thread local allocators are flushed when threads are 293// destroyed. 294TEST(AddressSanitizer, ThreadedQuarantineTest) { 295 const int n_threads = 3000; 296 size_t mmaped1 = __asan_get_heap_size(); 297 for (int i = 0; i < n_threads; i++) { 298 pthread_t t; 299 pthread_create(&t, NULL, ThreadedQuarantineTestWorker, 0); 300 pthread_join(t, 0); 301 size_t mmaped2 = __asan_get_heap_size(); 302 EXPECT_LT(mmaped2 - mmaped1, 320U * (1 << 20)); 303 } 304} 305 306void *ThreadedOneSizeMallocStress(void *unused) { 307 (void)unused; 308 __asan::StackTrace stack; 309 stack.trace[0] = 0x890; 310 stack.size = 1; 311 const size_t kNumMallocs = 1000; 312 for (int iter = 0; iter < 1000; iter++) { 313 void *p[kNumMallocs]; 314 for (size_t i = 0; i < kNumMallocs; i++) { 315 p[i] = __asan::asan_malloc(32, &stack); 316 } 317 for (size_t i = 0; i < kNumMallocs; i++) { 318 __asan::asan_free(p[i], &stack); 319 } 320 } 321 return NULL; 322} 323 324TEST(AddressSanitizer, ThreadedOneSizeMallocStressTest) { 325 const int kNumThreads = 4; 326 pthread_t t[kNumThreads]; 327 for (int i = 0; i < kNumThreads; i++) { 328 pthread_create(&t[i], 0, ThreadedOneSizeMallocStress, 0); 329 } 330 for (int i = 0; i < kNumThreads; i++) { 331 pthread_join(t[i], 0); 332 } 333} 334 335TEST(AddressSanitizer, MemsetWildAddressTest) { 336 typedef void*(*memset_p)(void*, int, size_t); 337 // Prevent inlining of memset(). 338 volatile memset_p libc_memset = (memset_p)memset; 339 EXPECT_DEATH(libc_memset((void*)(kLowShadowBeg + kPageSize), 0, 100), 340 "unknown-crash.*low shadow"); 341 EXPECT_DEATH(libc_memset((void*)(kShadowGapBeg + kPageSize), 0, 100), 342 "unknown-crash.*shadow gap"); 343 EXPECT_DEATH(libc_memset((void*)(kHighShadowBeg + kPageSize), 0, 100), 344 "unknown-crash.*high shadow"); 345} 346 347TEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) { 348 EXPECT_EQ(1U, __asan_get_estimated_allocated_size(0)); 349 const size_t sizes[] = { 1, 30, 1<<30 }; 350 for (size_t i = 0; i < 3; i++) { 351 EXPECT_EQ(sizes[i], __asan_get_estimated_allocated_size(sizes[i])); 352 } 353} 354 355static const char* kGetAllocatedSizeErrorMsg = 356 "attempting to call __asan_get_allocated_size()"; 357 358TEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) { 359 const size_t kArraySize = 100; 360 char *array = Ident((char*)malloc(kArraySize)); 361 int *int_ptr = Ident(new int); 362 363 // Allocated memory is owned by allocator. Allocated size should be 364 // equal to requested size. 365 EXPECT_EQ(true, __asan_get_ownership(array)); 366 EXPECT_EQ(kArraySize, __asan_get_allocated_size(array)); 367 EXPECT_EQ(true, __asan_get_ownership(int_ptr)); 368 EXPECT_EQ(sizeof(int), __asan_get_allocated_size(int_ptr)); 369 370 // We cannot call GetAllocatedSize from the memory we didn't map, 371 // and from the interior pointers (not returned by previous malloc). 372 void *wild_addr = (void*)0x1; 373 EXPECT_EQ(false, __asan_get_ownership(wild_addr)); 374 EXPECT_DEATH(__asan_get_allocated_size(wild_addr), kGetAllocatedSizeErrorMsg); 375 EXPECT_EQ(false, __asan_get_ownership(array + kArraySize / 2)); 376 EXPECT_DEATH(__asan_get_allocated_size(array + kArraySize / 2), 377 kGetAllocatedSizeErrorMsg); 378 379 // NULL is not owned, but is a valid argument for __asan_get_allocated_size(). 380 EXPECT_EQ(false, __asan_get_ownership(NULL)); 381 EXPECT_EQ(0U, __asan_get_allocated_size(NULL)); 382 383 // When memory is freed, it's not owned, and call to GetAllocatedSize 384 // is forbidden. 385 free(array); 386 EXPECT_EQ(false, __asan_get_ownership(array)); 387 EXPECT_DEATH(__asan_get_allocated_size(array), kGetAllocatedSizeErrorMsg); 388 389 delete int_ptr; 390} 391 392TEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) { 393 size_t before_malloc, after_malloc, after_free; 394 char *array; 395 const size_t kMallocSize = 100; 396 before_malloc = __asan_get_current_allocated_bytes(); 397 398 array = Ident((char*)malloc(kMallocSize)); 399 after_malloc = __asan_get_current_allocated_bytes(); 400 EXPECT_EQ(before_malloc + kMallocSize, after_malloc); 401 402 free(array); 403 after_free = __asan_get_current_allocated_bytes(); 404 EXPECT_EQ(before_malloc, after_free); 405} 406 407static void DoDoubleFree() { 408 int *x = Ident(new int); 409 delete Ident(x); 410 delete Ident(x); 411} 412 413// This test is run in a separate process, so that large malloced 414// chunk won't remain in the free lists after the test. 415// Note: use ASSERT_* instead of EXPECT_* here. 416static void RunGetHeapSizeTestAndDie() { 417 size_t old_heap_size, new_heap_size, heap_growth; 418 // We unlikely have have chunk of this size in free list. 419 static const size_t kLargeMallocSize = 1 << 29; // 512M 420 old_heap_size = __asan_get_heap_size(); 421 fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize); 422 free(Ident(malloc(kLargeMallocSize))); 423 new_heap_size = __asan_get_heap_size(); 424 heap_growth = new_heap_size - old_heap_size; 425 fprintf(stderr, "heap growth after first malloc: %zu\n", heap_growth); 426 ASSERT_GE(heap_growth, kLargeMallocSize); 427 ASSERT_LE(heap_growth, 2 * kLargeMallocSize); 428 429 // Now large chunk should fall into free list, and can be 430 // allocated without increasing heap size. 431 old_heap_size = new_heap_size; 432 free(Ident(malloc(kLargeMallocSize))); 433 heap_growth = __asan_get_heap_size() - old_heap_size; 434 fprintf(stderr, "heap growth after second malloc: %zu\n", heap_growth); 435 ASSERT_LT(heap_growth, kLargeMallocSize); 436 437 // Test passed. Now die with expected double-free. 438 DoDoubleFree(); 439} 440 441TEST(AddressSanitizerInterface, GetHeapSizeTest) { 442 EXPECT_DEATH(RunGetHeapSizeTestAndDie(), "double-free"); 443} 444 445// Note: use ASSERT_* instead of EXPECT_* here. 446static void DoLargeMallocForGetFreeBytesTestAndDie() { 447 size_t old_free_bytes, new_free_bytes; 448 static const size_t kLargeMallocSize = 1 << 29; // 512M 449 // If we malloc and free a large memory chunk, it will not fall 450 // into quarantine and will be available for future requests. 451 old_free_bytes = __asan_get_free_bytes(); 452 fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize); 453 fprintf(stderr, "free bytes before malloc: %zu\n", old_free_bytes); 454 free(Ident(malloc(kLargeMallocSize))); 455 new_free_bytes = __asan_get_free_bytes(); 456 fprintf(stderr, "free bytes after malloc and free: %zu\n", new_free_bytes); 457 ASSERT_GE(new_free_bytes, old_free_bytes + kLargeMallocSize); 458 // Test passed. 459 DoDoubleFree(); 460} 461 462TEST(AddressSanitizerInterface, GetFreeBytesTest) { 463 static const size_t kNumOfChunks = 100; 464 static const size_t kChunkSize = 100; 465 char *chunks[kNumOfChunks]; 466 size_t i; 467 size_t old_free_bytes, new_free_bytes; 468 // Allocate a small chunk. Now allocator probably has a lot of these 469 // chunks to fulfill future requests. So, future requests will decrease 470 // the number of free bytes. 471 chunks[0] = Ident((char*)malloc(kChunkSize)); 472 old_free_bytes = __asan_get_free_bytes(); 473 for (i = 1; i < kNumOfChunks; i++) { 474 chunks[i] = Ident((char*)malloc(kChunkSize)); 475 new_free_bytes = __asan_get_free_bytes(); 476 EXPECT_LT(new_free_bytes, old_free_bytes); 477 old_free_bytes = new_free_bytes; 478 } 479 EXPECT_DEATH(DoLargeMallocForGetFreeBytesTestAndDie(), "double-free"); 480} 481 482static const size_t kManyThreadsMallocSizes[] = {5, 1UL<<10, 1UL<<20, 357}; 483static const size_t kManyThreadsIterations = 250; 484static const size_t kManyThreadsNumThreads = (__WORDSIZE == 32) ? 40 : 200; 485 486void *ManyThreadsWithStatsWorker(void *arg) { 487 (void)arg; 488 for (size_t iter = 0; iter < kManyThreadsIterations; iter++) { 489 for (size_t size_index = 0; size_index < 4; size_index++) { 490 free(Ident(malloc(kManyThreadsMallocSizes[size_index]))); 491 } 492 } 493 return 0; 494} 495 496TEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) { 497 size_t before_test, after_test, i; 498 pthread_t threads[kManyThreadsNumThreads]; 499 before_test = __asan_get_current_allocated_bytes(); 500 for (i = 0; i < kManyThreadsNumThreads; i++) { 501 pthread_create(&threads[i], 0, 502 (void* (*)(void *x))ManyThreadsWithStatsWorker, (void*)i); 503 } 504 for (i = 0; i < kManyThreadsNumThreads; i++) { 505 pthread_join(threads[i], 0); 506 } 507 after_test = __asan_get_current_allocated_bytes(); 508 // ASan stats also reflect memory usage of internal ASan RTL structs, 509 // so we can't check for equality here. 510 EXPECT_LT(after_test, before_test + (1UL<<20)); 511} 512 513TEST(AddressSanitizerInterface, ExitCode) { 514 int original_exit_code = __asan_set_error_exit_code(7); 515 EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(7), ""); 516 EXPECT_EQ(7, __asan_set_error_exit_code(8)); 517 EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(8), ""); 518 EXPECT_EQ(8, __asan_set_error_exit_code(original_exit_code)); 519 EXPECT_EXIT(DoDoubleFree(), 520 ::testing::ExitedWithCode(original_exit_code), ""); 521} 522 523static void MyDeathCallback() { 524 fprintf(stderr, "MyDeathCallback\n"); 525} 526 527TEST(AddressSanitizerInterface, DeathCallbackTest) { 528 __asan_set_death_callback(MyDeathCallback); 529 EXPECT_DEATH(DoDoubleFree(), "MyDeathCallback"); 530 __asan_set_death_callback(NULL); 531} 532 533static const char* kUseAfterPoisonErrorMessage = "use-after-poison"; 534 535#define GOOD_ACCESS(ptr, offset) \ 536 EXPECT_FALSE(__asan::AddressIsPoisoned((uptr)(ptr + offset))) 537 538#define BAD_ACCESS(ptr, offset) \ 539 EXPECT_TRUE(__asan::AddressIsPoisoned((uptr)(ptr + offset))) 540 541TEST(AddressSanitizerInterface, SimplePoisonMemoryRegionTest) { 542 char *array = Ident((char*)malloc(120)); 543 // poison array[40..80) 544 __asan_poison_memory_region(array + 40, 40); 545 GOOD_ACCESS(array, 39); 546 GOOD_ACCESS(array, 80); 547 BAD_ACCESS(array, 40); 548 BAD_ACCESS(array, 60); 549 BAD_ACCESS(array, 79); 550 EXPECT_DEATH(__asan_report_error(0, 0, 0, (uptr)(array + 40), true, 1), 551 kUseAfterPoisonErrorMessage); 552 __asan_unpoison_memory_region(array + 40, 40); 553 // access previously poisoned memory. 554 GOOD_ACCESS(array, 40); 555 GOOD_ACCESS(array, 79); 556 free(array); 557} 558 559TEST(AddressSanitizerInterface, OverlappingPoisonMemoryRegionTest) { 560 char *array = Ident((char*)malloc(120)); 561 // Poison [0..40) and [80..120) 562 __asan_poison_memory_region(array, 40); 563 __asan_poison_memory_region(array + 80, 40); 564 BAD_ACCESS(array, 20); 565 GOOD_ACCESS(array, 60); 566 BAD_ACCESS(array, 100); 567 // Poison whole array - [0..120) 568 __asan_poison_memory_region(array, 120); 569 BAD_ACCESS(array, 60); 570 // Unpoison [24..96) 571 __asan_unpoison_memory_region(array + 24, 72); 572 BAD_ACCESS(array, 23); 573 GOOD_ACCESS(array, 24); 574 GOOD_ACCESS(array, 60); 575 GOOD_ACCESS(array, 95); 576 BAD_ACCESS(array, 96); 577 free(array); 578} 579 580TEST(AddressSanitizerInterface, PushAndPopWithPoisoningTest) { 581 // Vector of capacity 20 582 char *vec = Ident((char*)malloc(20)); 583 __asan_poison_memory_region(vec, 20); 584 for (size_t i = 0; i < 7; i++) { 585 // Simulate push_back. 586 __asan_unpoison_memory_region(vec + i, 1); 587 GOOD_ACCESS(vec, i); 588 BAD_ACCESS(vec, i + 1); 589 } 590 for (size_t i = 7; i > 0; i--) { 591 // Simulate pop_back. 592 __asan_poison_memory_region(vec + i - 1, 1); 593 BAD_ACCESS(vec, i - 1); 594 if (i > 1) GOOD_ACCESS(vec, i - 2); 595 } 596 free(vec); 597} 598 599// Make sure that each aligned block of size "2^granularity" doesn't have 600// "true" value before "false" value. 601static void MakeShadowValid(bool *shadow, int length, int granularity) { 602 bool can_be_poisoned = true; 603 for (int i = length - 1; i >= 0; i--) { 604 if (!shadow[i]) 605 can_be_poisoned = false; 606 if (!can_be_poisoned) 607 shadow[i] = false; 608 if (i % (1 << granularity) == 0) { 609 can_be_poisoned = true; 610 } 611 } 612} 613 614TEST(AddressSanitizerInterface, PoisoningStressTest) { 615 const size_t kSize = 24; 616 bool expected[kSize]; 617 char *arr = Ident((char*)malloc(kSize)); 618 for (size_t l1 = 0; l1 < kSize; l1++) { 619 for (size_t s1 = 1; l1 + s1 <= kSize; s1++) { 620 for (size_t l2 = 0; l2 < kSize; l2++) { 621 for (size_t s2 = 1; l2 + s2 <= kSize; s2++) { 622 // Poison [l1, l1+s1), [l2, l2+s2) and check result. 623 __asan_unpoison_memory_region(arr, kSize); 624 __asan_poison_memory_region(arr + l1, s1); 625 __asan_poison_memory_region(arr + l2, s2); 626 memset(expected, false, kSize); 627 memset(expected + l1, true, s1); 628 MakeShadowValid(expected, kSize, /*granularity*/ 3); 629 memset(expected + l2, true, s2); 630 MakeShadowValid(expected, kSize, /*granularity*/ 3); 631 for (size_t i = 0; i < kSize; i++) { 632 ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i)); 633 } 634 // Unpoison [l1, l1+s1) and [l2, l2+s2) and check result. 635 __asan_poison_memory_region(arr, kSize); 636 __asan_unpoison_memory_region(arr + l1, s1); 637 __asan_unpoison_memory_region(arr + l2, s2); 638 memset(expected, true, kSize); 639 memset(expected + l1, false, s1); 640 MakeShadowValid(expected, kSize, /*granularity*/ 3); 641 memset(expected + l2, false, s2); 642 MakeShadowValid(expected, kSize, /*granularity*/ 3); 643 for (size_t i = 0; i < kSize; i++) { 644 ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i)); 645 } 646 } 647 } 648 } 649 } 650} 651 652static const char *kInvalidPoisonMessage = "invalid-poison-memory-range"; 653static const char *kInvalidUnpoisonMessage = "invalid-unpoison-memory-range"; 654 655TEST(AddressSanitizerInterface, DISABLED_InvalidPoisonAndUnpoisonCallsTest) { 656 char *array = Ident((char*)malloc(120)); 657 __asan_unpoison_memory_region(array, 120); 658 // Try to unpoison not owned memory 659 EXPECT_DEATH(__asan_unpoison_memory_region(array, 121), 660 kInvalidUnpoisonMessage); 661 EXPECT_DEATH(__asan_unpoison_memory_region(array - 1, 120), 662 kInvalidUnpoisonMessage); 663 664 __asan_poison_memory_region(array, 120); 665 // Try to poison not owned memory. 666 EXPECT_DEATH(__asan_poison_memory_region(array, 121), kInvalidPoisonMessage); 667 EXPECT_DEATH(__asan_poison_memory_region(array - 1, 120), 668 kInvalidPoisonMessage); 669 free(array); 670} 671 672static void ErrorReportCallbackOneToZ(const char *report) { 673 int report_len = strlen(report); 674 ASSERT_EQ(6, write(2, "ABCDEF", 6)); 675 ASSERT_EQ(report_len, write(2, report, report_len)); 676 ASSERT_EQ(6, write(2, "ABCDEF", 6)); 677 _exit(1); 678} 679 680TEST(AddressSanitizerInterface, SetErrorReportCallbackTest) { 681 __asan_set_error_report_callback(ErrorReportCallbackOneToZ); 682 EXPECT_DEATH(__asan_report_error(0, 0, 0, 0, true, 1), 683 ASAN_PCRE_DOTALL "ABCDEF.*AddressSanitizer.*WRITE.*ABCDEF"); 684 __asan_set_error_report_callback(NULL); 685} 686 687TEST(AddressSanitizerInterface, GetOwnershipStressTest) { 688 std::vector<char *> pointers; 689 std::vector<size_t> sizes; 690 const size_t kNumMallocs = 691 (__WORDSIZE <= 32 || ASAN_LOW_MEMORY) ? 1 << 10 : 1 << 14; 692 for (size_t i = 0; i < kNumMallocs; i++) { 693 size_t size = i * 100 + 1; 694 pointers.push_back((char*)malloc(size)); 695 sizes.push_back(size); 696 } 697 for (size_t i = 0; i < 4000000; i++) { 698 EXPECT_FALSE(__asan_get_ownership(&pointers)); 699 EXPECT_FALSE(__asan_get_ownership((void*)0x1234)); 700 size_t idx = i % kNumMallocs; 701 EXPECT_TRUE(__asan_get_ownership(pointers[idx])); 702 EXPECT_EQ(sizes[idx], __asan_get_allocated_size(pointers[idx])); 703 } 704 for (size_t i = 0, n = pointers.size(); i < n; i++) 705 free(pointers[i]); 706} 707