13cab2bb3Spatrick //===-- asan_interface_test.cpp -------------------------------------------===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file is a part of AddressSanitizer, an address sanity checker.
103cab2bb3Spatrick //
113cab2bb3Spatrick //===----------------------------------------------------------------------===//
123cab2bb3Spatrick #include "asan_test_utils.h"
133cab2bb3Spatrick #include "sanitizer_common/sanitizer_internal_defs.h"
143cab2bb3Spatrick #include <sanitizer/allocator_interface.h>
153cab2bb3Spatrick #include <sanitizer/asan_interface.h>
163cab2bb3Spatrick #include <vector>
173cab2bb3Spatrick
TEST(AddressSanitizerInterface,GetEstimatedAllocatedSize)183cab2bb3Spatrick TEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) {
193cab2bb3Spatrick EXPECT_EQ(0U, __sanitizer_get_estimated_allocated_size(0));
203cab2bb3Spatrick const size_t sizes[] = { 1, 30, 1<<30 };
213cab2bb3Spatrick for (size_t i = 0; i < 3; i++) {
223cab2bb3Spatrick EXPECT_EQ(sizes[i], __sanitizer_get_estimated_allocated_size(sizes[i]));
233cab2bb3Spatrick }
243cab2bb3Spatrick }
253cab2bb3Spatrick
263cab2bb3Spatrick static const char* kGetAllocatedSizeErrorMsg =
273cab2bb3Spatrick "attempting to call __sanitizer_get_allocated_size";
283cab2bb3Spatrick
TEST(AddressSanitizerInterface,GetAllocatedSizeAndOwnershipTest)293cab2bb3Spatrick TEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) {
303cab2bb3Spatrick const size_t kArraySize = 100;
313cab2bb3Spatrick char *array = Ident((char*)malloc(kArraySize));
323cab2bb3Spatrick int *int_ptr = Ident(new int);
333cab2bb3Spatrick
343cab2bb3Spatrick // Allocated memory is owned by allocator. Allocated size should be
353cab2bb3Spatrick // equal to requested size.
363cab2bb3Spatrick EXPECT_EQ(true, __sanitizer_get_ownership(array));
373cab2bb3Spatrick EXPECT_EQ(kArraySize, __sanitizer_get_allocated_size(array));
383cab2bb3Spatrick EXPECT_EQ(true, __sanitizer_get_ownership(int_ptr));
393cab2bb3Spatrick EXPECT_EQ(sizeof(int), __sanitizer_get_allocated_size(int_ptr));
403cab2bb3Spatrick
413cab2bb3Spatrick // We cannot call GetAllocatedSize from the memory we didn't map,
423cab2bb3Spatrick // and from the interior pointers (not returned by previous malloc).
433cab2bb3Spatrick void *wild_addr = (void*)0x1;
443cab2bb3Spatrick EXPECT_FALSE(__sanitizer_get_ownership(wild_addr));
453cab2bb3Spatrick EXPECT_DEATH(__sanitizer_get_allocated_size(wild_addr),
463cab2bb3Spatrick kGetAllocatedSizeErrorMsg);
473cab2bb3Spatrick EXPECT_FALSE(__sanitizer_get_ownership(array + kArraySize / 2));
483cab2bb3Spatrick EXPECT_DEATH(__sanitizer_get_allocated_size(array + kArraySize / 2),
493cab2bb3Spatrick kGetAllocatedSizeErrorMsg);
503cab2bb3Spatrick
513cab2bb3Spatrick // NULL is not owned, but is a valid argument for
523cab2bb3Spatrick // __sanitizer_get_allocated_size().
533cab2bb3Spatrick EXPECT_FALSE(__sanitizer_get_ownership(NULL));
543cab2bb3Spatrick EXPECT_EQ(0U, __sanitizer_get_allocated_size(NULL));
553cab2bb3Spatrick
563cab2bb3Spatrick // When memory is freed, it's not owned, and call to GetAllocatedSize
573cab2bb3Spatrick // is forbidden.
583cab2bb3Spatrick free(array);
593cab2bb3Spatrick EXPECT_FALSE(__sanitizer_get_ownership(array));
603cab2bb3Spatrick EXPECT_DEATH(__sanitizer_get_allocated_size(array),
613cab2bb3Spatrick kGetAllocatedSizeErrorMsg);
623cab2bb3Spatrick delete int_ptr;
633cab2bb3Spatrick
643cab2bb3Spatrick void *zero_alloc = Ident(malloc(0));
653cab2bb3Spatrick if (zero_alloc != 0) {
663cab2bb3Spatrick // If malloc(0) is not null, this pointer is owned and should have valid
673cab2bb3Spatrick // allocated size.
683cab2bb3Spatrick EXPECT_TRUE(__sanitizer_get_ownership(zero_alloc));
693cab2bb3Spatrick // Allocated size is 0 or 1 depending on the allocator used.
703cab2bb3Spatrick EXPECT_LT(__sanitizer_get_allocated_size(zero_alloc), 2U);
713cab2bb3Spatrick }
723cab2bb3Spatrick free(zero_alloc);
733cab2bb3Spatrick }
743cab2bb3Spatrick
TEST(AddressSanitizerInterface,GetCurrentAllocatedBytesTest)753cab2bb3Spatrick TEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) {
763cab2bb3Spatrick size_t before_malloc, after_malloc, after_free;
773cab2bb3Spatrick char *array;
783cab2bb3Spatrick const size_t kMallocSize = 100;
793cab2bb3Spatrick before_malloc = __sanitizer_get_current_allocated_bytes();
803cab2bb3Spatrick
813cab2bb3Spatrick array = Ident((char*)malloc(kMallocSize));
823cab2bb3Spatrick after_malloc = __sanitizer_get_current_allocated_bytes();
833cab2bb3Spatrick EXPECT_EQ(before_malloc + kMallocSize, after_malloc);
843cab2bb3Spatrick
853cab2bb3Spatrick free(array);
863cab2bb3Spatrick after_free = __sanitizer_get_current_allocated_bytes();
873cab2bb3Spatrick EXPECT_EQ(before_malloc, after_free);
883cab2bb3Spatrick }
893cab2bb3Spatrick
TEST(AddressSanitizerInterface,GetHeapSizeTest)903cab2bb3Spatrick TEST(AddressSanitizerInterface, GetHeapSizeTest) {
913cab2bb3Spatrick // ASan allocator does not keep huge chunks in free list, but unmaps them.
923cab2bb3Spatrick // The chunk should be greater than the quarantine size,
93*810390e3Srobert // otherwise it will be stuck in quarantine instead of being unmapped.
943cab2bb3Spatrick static const size_t kLargeMallocSize = (1 << 28) + 1; // 256M
953cab2bb3Spatrick free(Ident(malloc(kLargeMallocSize))); // Drain quarantine.
963cab2bb3Spatrick size_t old_heap_size = __sanitizer_get_heap_size();
973cab2bb3Spatrick for (int i = 0; i < 3; i++) {
983cab2bb3Spatrick // fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize);
993cab2bb3Spatrick free(Ident(malloc(kLargeMallocSize)));
1003cab2bb3Spatrick EXPECT_EQ(old_heap_size, __sanitizer_get_heap_size());
1013cab2bb3Spatrick }
1023cab2bb3Spatrick }
1033cab2bb3Spatrick
1043cab2bb3Spatrick #if !defined(__NetBSD__)
1053cab2bb3Spatrick static const size_t kManyThreadsMallocSizes[] = {5, 1UL<<10, 1UL<<14, 357};
1063cab2bb3Spatrick static const size_t kManyThreadsIterations = 250;
1073cab2bb3Spatrick static const size_t kManyThreadsNumThreads =
1083cab2bb3Spatrick (SANITIZER_WORDSIZE == 32) ? 40 : 200;
1093cab2bb3Spatrick
ManyThreadsWithStatsWorker(void * arg)1103cab2bb3Spatrick static void *ManyThreadsWithStatsWorker(void *arg) {
1113cab2bb3Spatrick (void)arg;
1123cab2bb3Spatrick for (size_t iter = 0; iter < kManyThreadsIterations; iter++) {
1133cab2bb3Spatrick for (size_t size_index = 0; size_index < 4; size_index++) {
1143cab2bb3Spatrick free(Ident(malloc(kManyThreadsMallocSizes[size_index])));
1153cab2bb3Spatrick }
1163cab2bb3Spatrick }
1173cab2bb3Spatrick // Just one large allocation.
1183cab2bb3Spatrick free(Ident(malloc(1 << 20)));
1193cab2bb3Spatrick return 0;
1203cab2bb3Spatrick }
1213cab2bb3Spatrick
TEST(AddressSanitizerInterface,ManyThreadsWithStatsStressTest)1223cab2bb3Spatrick TEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {
1233cab2bb3Spatrick size_t before_test, after_test, i;
1243cab2bb3Spatrick pthread_t threads[kManyThreadsNumThreads];
1253cab2bb3Spatrick before_test = __sanitizer_get_current_allocated_bytes();
1263cab2bb3Spatrick for (i = 0; i < kManyThreadsNumThreads; i++) {
1273cab2bb3Spatrick PTHREAD_CREATE(&threads[i], 0,
1283cab2bb3Spatrick (void* (*)(void *x))ManyThreadsWithStatsWorker, (void*)i);
1293cab2bb3Spatrick }
1303cab2bb3Spatrick for (i = 0; i < kManyThreadsNumThreads; i++) {
1313cab2bb3Spatrick PTHREAD_JOIN(threads[i], 0);
1323cab2bb3Spatrick }
1333cab2bb3Spatrick after_test = __sanitizer_get_current_allocated_bytes();
1343cab2bb3Spatrick // ASan stats also reflect memory usage of internal ASan RTL structs,
1353cab2bb3Spatrick // so we can't check for equality here.
1363cab2bb3Spatrick EXPECT_LT(after_test, before_test + (1UL<<20));
1373cab2bb3Spatrick }
1383cab2bb3Spatrick #endif
1393cab2bb3Spatrick
DoDoubleFree()1403cab2bb3Spatrick static void DoDoubleFree() {
1413cab2bb3Spatrick int *x = Ident(new int);
1423cab2bb3Spatrick delete Ident(x);
1433cab2bb3Spatrick delete Ident(x);
1443cab2bb3Spatrick }
1453cab2bb3Spatrick
MyDeathCallback()1463cab2bb3Spatrick static void MyDeathCallback() {
1473cab2bb3Spatrick fprintf(stderr, "MyDeathCallback\n");
1483cab2bb3Spatrick fflush(0); // On Windows, stderr doesn't flush on crash.
1493cab2bb3Spatrick }
1503cab2bb3Spatrick
TEST(AddressSanitizerInterface,DeathCallbackTest)1513cab2bb3Spatrick TEST(AddressSanitizerInterface, DeathCallbackTest) {
1523cab2bb3Spatrick __asan_set_death_callback(MyDeathCallback);
1533cab2bb3Spatrick EXPECT_DEATH(DoDoubleFree(), "MyDeathCallback");
1543cab2bb3Spatrick __asan_set_death_callback(NULL);
1553cab2bb3Spatrick }
1563cab2bb3Spatrick
1573cab2bb3Spatrick #define GOOD_ACCESS(ptr, offset) \
1583cab2bb3Spatrick EXPECT_FALSE(__asan_address_is_poisoned(ptr + offset))
1593cab2bb3Spatrick
1603cab2bb3Spatrick #define BAD_ACCESS(ptr, offset) \
1613cab2bb3Spatrick EXPECT_TRUE(__asan_address_is_poisoned(ptr + offset))
1623cab2bb3Spatrick
1633cab2bb3Spatrick static const char* kUseAfterPoisonErrorMessage = "use-after-poison";
1643cab2bb3Spatrick
TEST(AddressSanitizerInterface,SimplePoisonMemoryRegionTest)1653cab2bb3Spatrick TEST(AddressSanitizerInterface, SimplePoisonMemoryRegionTest) {
1663cab2bb3Spatrick char *array = Ident((char*)malloc(120));
1673cab2bb3Spatrick // poison array[40..80)
1683cab2bb3Spatrick __asan_poison_memory_region(array + 40, 40);
1693cab2bb3Spatrick GOOD_ACCESS(array, 39);
1703cab2bb3Spatrick GOOD_ACCESS(array, 80);
1713cab2bb3Spatrick BAD_ACCESS(array, 40);
1723cab2bb3Spatrick BAD_ACCESS(array, 60);
1733cab2bb3Spatrick BAD_ACCESS(array, 79);
174d89ec533Spatrick EXPECT_DEATH(Ident(array[40]), kUseAfterPoisonErrorMessage);
1753cab2bb3Spatrick __asan_unpoison_memory_region(array + 40, 40);
1763cab2bb3Spatrick // access previously poisoned memory.
1773cab2bb3Spatrick GOOD_ACCESS(array, 40);
1783cab2bb3Spatrick GOOD_ACCESS(array, 79);
1793cab2bb3Spatrick free(array);
1803cab2bb3Spatrick }
1813cab2bb3Spatrick
TEST(AddressSanitizerInterface,OverlappingPoisonMemoryRegionTest)1823cab2bb3Spatrick TEST(AddressSanitizerInterface, OverlappingPoisonMemoryRegionTest) {
1833cab2bb3Spatrick char *array = Ident((char*)malloc(120));
1843cab2bb3Spatrick // Poison [0..40) and [80..120)
1853cab2bb3Spatrick __asan_poison_memory_region(array, 40);
1863cab2bb3Spatrick __asan_poison_memory_region(array + 80, 40);
1873cab2bb3Spatrick BAD_ACCESS(array, 20);
1883cab2bb3Spatrick GOOD_ACCESS(array, 60);
1893cab2bb3Spatrick BAD_ACCESS(array, 100);
1903cab2bb3Spatrick // Poison whole array - [0..120)
1913cab2bb3Spatrick __asan_poison_memory_region(array, 120);
1923cab2bb3Spatrick BAD_ACCESS(array, 60);
1933cab2bb3Spatrick // Unpoison [24..96)
1943cab2bb3Spatrick __asan_unpoison_memory_region(array + 24, 72);
1953cab2bb3Spatrick BAD_ACCESS(array, 23);
1963cab2bb3Spatrick GOOD_ACCESS(array, 24);
1973cab2bb3Spatrick GOOD_ACCESS(array, 60);
1983cab2bb3Spatrick GOOD_ACCESS(array, 95);
1993cab2bb3Spatrick BAD_ACCESS(array, 96);
2003cab2bb3Spatrick free(array);
2013cab2bb3Spatrick }
2023cab2bb3Spatrick
TEST(AddressSanitizerInterface,PushAndPopWithPoisoningTest)2033cab2bb3Spatrick TEST(AddressSanitizerInterface, PushAndPopWithPoisoningTest) {
2043cab2bb3Spatrick // Vector of capacity 20
2053cab2bb3Spatrick char *vec = Ident((char*)malloc(20));
2063cab2bb3Spatrick __asan_poison_memory_region(vec, 20);
2073cab2bb3Spatrick for (size_t i = 0; i < 7; i++) {
2083cab2bb3Spatrick // Simulate push_back.
2093cab2bb3Spatrick __asan_unpoison_memory_region(vec + i, 1);
2103cab2bb3Spatrick GOOD_ACCESS(vec, i);
2113cab2bb3Spatrick BAD_ACCESS(vec, i + 1);
2123cab2bb3Spatrick }
2133cab2bb3Spatrick for (size_t i = 7; i > 0; i--) {
2143cab2bb3Spatrick // Simulate pop_back.
2153cab2bb3Spatrick __asan_poison_memory_region(vec + i - 1, 1);
2163cab2bb3Spatrick BAD_ACCESS(vec, i - 1);
2173cab2bb3Spatrick if (i > 1) GOOD_ACCESS(vec, i - 2);
2183cab2bb3Spatrick }
2193cab2bb3Spatrick free(vec);
2203cab2bb3Spatrick }
2213cab2bb3Spatrick
2223cab2bb3Spatrick #if !defined(ASAN_SHADOW_SCALE) || ASAN_SHADOW_SCALE == 3
2233cab2bb3Spatrick // Make sure that each aligned block of size "2^granularity" doesn't have
2243cab2bb3Spatrick // "true" value before "false" value.
MakeShadowValid(bool * shadow,int length,int granularity)2253cab2bb3Spatrick static void MakeShadowValid(bool *shadow, int length, int granularity) {
2263cab2bb3Spatrick bool can_be_poisoned = true;
2273cab2bb3Spatrick for (int i = length - 1; i >= 0; i--) {
2283cab2bb3Spatrick if (!shadow[i])
2293cab2bb3Spatrick can_be_poisoned = false;
2303cab2bb3Spatrick if (!can_be_poisoned)
2313cab2bb3Spatrick shadow[i] = false;
2323cab2bb3Spatrick if (i % (1 << granularity) == 0) {
2333cab2bb3Spatrick can_be_poisoned = true;
2343cab2bb3Spatrick }
2353cab2bb3Spatrick }
2363cab2bb3Spatrick }
2373cab2bb3Spatrick
TEST(AddressSanitizerInterface,PoisoningStressTest)2383cab2bb3Spatrick TEST(AddressSanitizerInterface, PoisoningStressTest) {
2393cab2bb3Spatrick const size_t kSize = 24;
2403cab2bb3Spatrick bool expected[kSize];
2413cab2bb3Spatrick char *arr = Ident((char*)malloc(kSize));
2423cab2bb3Spatrick for (size_t l1 = 0; l1 < kSize; l1++) {
2433cab2bb3Spatrick for (size_t s1 = 1; l1 + s1 <= kSize; s1++) {
2443cab2bb3Spatrick for (size_t l2 = 0; l2 < kSize; l2++) {
2453cab2bb3Spatrick for (size_t s2 = 1; l2 + s2 <= kSize; s2++) {
2463cab2bb3Spatrick // Poison [l1, l1+s1), [l2, l2+s2) and check result.
2473cab2bb3Spatrick __asan_unpoison_memory_region(arr, kSize);
2483cab2bb3Spatrick __asan_poison_memory_region(arr + l1, s1);
2493cab2bb3Spatrick __asan_poison_memory_region(arr + l2, s2);
2503cab2bb3Spatrick memset(expected, false, kSize);
2513cab2bb3Spatrick memset(expected + l1, true, s1);
2523cab2bb3Spatrick MakeShadowValid(expected, kSize, /*granularity*/ 3);
2533cab2bb3Spatrick memset(expected + l2, true, s2);
2543cab2bb3Spatrick MakeShadowValid(expected, kSize, /*granularity*/ 3);
2553cab2bb3Spatrick for (size_t i = 0; i < kSize; i++) {
2563cab2bb3Spatrick ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
2573cab2bb3Spatrick }
2583cab2bb3Spatrick // Unpoison [l1, l1+s1) and [l2, l2+s2) and check result.
2593cab2bb3Spatrick __asan_poison_memory_region(arr, kSize);
2603cab2bb3Spatrick __asan_unpoison_memory_region(arr + l1, s1);
2613cab2bb3Spatrick __asan_unpoison_memory_region(arr + l2, s2);
2623cab2bb3Spatrick memset(expected, true, kSize);
2633cab2bb3Spatrick memset(expected + l1, false, s1);
2643cab2bb3Spatrick MakeShadowValid(expected, kSize, /*granularity*/ 3);
2653cab2bb3Spatrick memset(expected + l2, false, s2);
2663cab2bb3Spatrick MakeShadowValid(expected, kSize, /*granularity*/ 3);
2673cab2bb3Spatrick for (size_t i = 0; i < kSize; i++) {
2683cab2bb3Spatrick ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
2693cab2bb3Spatrick }
2703cab2bb3Spatrick }
2713cab2bb3Spatrick }
2723cab2bb3Spatrick }
2733cab2bb3Spatrick }
2743cab2bb3Spatrick free(arr);
2753cab2bb3Spatrick }
2763cab2bb3Spatrick #endif // !defined(ASAN_SHADOW_SCALE) || ASAN_SHADOW_SCALE == 3
2773cab2bb3Spatrick
TEST(AddressSanitizerInterface,GlobalRedzones)2783cab2bb3Spatrick TEST(AddressSanitizerInterface, GlobalRedzones) {
2793cab2bb3Spatrick GOOD_ACCESS(glob1, 1 - 1);
2803cab2bb3Spatrick GOOD_ACCESS(glob2, 2 - 1);
2813cab2bb3Spatrick GOOD_ACCESS(glob3, 3 - 1);
2823cab2bb3Spatrick GOOD_ACCESS(glob4, 4 - 1);
2833cab2bb3Spatrick GOOD_ACCESS(glob5, 5 - 1);
2843cab2bb3Spatrick GOOD_ACCESS(glob6, 6 - 1);
2853cab2bb3Spatrick GOOD_ACCESS(glob7, 7 - 1);
2863cab2bb3Spatrick GOOD_ACCESS(glob8, 8 - 1);
2873cab2bb3Spatrick GOOD_ACCESS(glob9, 9 - 1);
2883cab2bb3Spatrick GOOD_ACCESS(glob10, 10 - 1);
2893cab2bb3Spatrick GOOD_ACCESS(glob11, 11 - 1);
2903cab2bb3Spatrick GOOD_ACCESS(glob12, 12 - 1);
2913cab2bb3Spatrick GOOD_ACCESS(glob13, 13 - 1);
2923cab2bb3Spatrick GOOD_ACCESS(glob14, 14 - 1);
2933cab2bb3Spatrick GOOD_ACCESS(glob15, 15 - 1);
2943cab2bb3Spatrick GOOD_ACCESS(glob16, 16 - 1);
2953cab2bb3Spatrick GOOD_ACCESS(glob17, 17 - 1);
2963cab2bb3Spatrick GOOD_ACCESS(glob1000, 1000 - 1);
2973cab2bb3Spatrick GOOD_ACCESS(glob10000, 10000 - 1);
2983cab2bb3Spatrick GOOD_ACCESS(glob100000, 100000 - 1);
2993cab2bb3Spatrick
3003cab2bb3Spatrick BAD_ACCESS(glob1, 1);
3013cab2bb3Spatrick BAD_ACCESS(glob2, 2);
3023cab2bb3Spatrick BAD_ACCESS(glob3, 3);
3033cab2bb3Spatrick BAD_ACCESS(glob4, 4);
3043cab2bb3Spatrick BAD_ACCESS(glob5, 5);
3053cab2bb3Spatrick BAD_ACCESS(glob6, 6);
3063cab2bb3Spatrick BAD_ACCESS(glob7, 7);
3073cab2bb3Spatrick BAD_ACCESS(glob8, 8);
3083cab2bb3Spatrick BAD_ACCESS(glob9, 9);
3093cab2bb3Spatrick BAD_ACCESS(glob10, 10);
3103cab2bb3Spatrick BAD_ACCESS(glob11, 11);
3113cab2bb3Spatrick BAD_ACCESS(glob12, 12);
3123cab2bb3Spatrick BAD_ACCESS(glob13, 13);
3133cab2bb3Spatrick BAD_ACCESS(glob14, 14);
3143cab2bb3Spatrick BAD_ACCESS(glob15, 15);
3153cab2bb3Spatrick BAD_ACCESS(glob16, 16);
3163cab2bb3Spatrick BAD_ACCESS(glob17, 17);
3173cab2bb3Spatrick BAD_ACCESS(glob1000, 1000);
3183cab2bb3Spatrick BAD_ACCESS(glob1000, 1100); // Redzone is at least 101 bytes.
3193cab2bb3Spatrick BAD_ACCESS(glob10000, 10000);
3203cab2bb3Spatrick BAD_ACCESS(glob10000, 11000); // Redzone is at least 1001 bytes.
3213cab2bb3Spatrick BAD_ACCESS(glob100000, 100000);
3223cab2bb3Spatrick BAD_ACCESS(glob100000, 110000); // Redzone is at least 10001 bytes.
3233cab2bb3Spatrick }
3243cab2bb3Spatrick
TEST(AddressSanitizerInterface,PoisonedRegion)3253cab2bb3Spatrick TEST(AddressSanitizerInterface, PoisonedRegion) {
3263cab2bb3Spatrick size_t rz = 16;
3273cab2bb3Spatrick for (size_t size = 1; size <= 64; size++) {
3283cab2bb3Spatrick char *p = new char[size];
3293cab2bb3Spatrick for (size_t beg = 0; beg < size + rz; beg++) {
3303cab2bb3Spatrick for (size_t end = beg; end < size + rz; end++) {
3313cab2bb3Spatrick void *first_poisoned = __asan_region_is_poisoned(p + beg, end - beg);
3323cab2bb3Spatrick if (beg == end) {
3333cab2bb3Spatrick EXPECT_FALSE(first_poisoned);
3343cab2bb3Spatrick } else if (beg < size && end <= size) {
3353cab2bb3Spatrick EXPECT_FALSE(first_poisoned);
3363cab2bb3Spatrick } else if (beg >= size) {
3373cab2bb3Spatrick EXPECT_EQ(p + beg, first_poisoned);
3383cab2bb3Spatrick } else {
3393cab2bb3Spatrick EXPECT_GT(end, size);
3403cab2bb3Spatrick EXPECT_EQ(p + size, first_poisoned);
3413cab2bb3Spatrick }
3423cab2bb3Spatrick }
3433cab2bb3Spatrick }
3443cab2bb3Spatrick delete [] p;
3453cab2bb3Spatrick }
3463cab2bb3Spatrick }
3473cab2bb3Spatrick
3483cab2bb3Spatrick // This is a performance benchmark for manual runs.
3493cab2bb3Spatrick // asan's memset interceptor calls mem_is_zero for the entire shadow region.
3503cab2bb3Spatrick // the profile should look like this:
3513cab2bb3Spatrick // 89.10% [.] __memset_sse2
3523cab2bb3Spatrick // 10.50% [.] __sanitizer::mem_is_zero
3533cab2bb3Spatrick // I.e. mem_is_zero should consume ~ SHADOW_GRANULARITY less CPU cycles
3543cab2bb3Spatrick // than memset itself.
TEST(AddressSanitizerInterface,DISABLED_StressLargeMemset)3553cab2bb3Spatrick TEST(AddressSanitizerInterface, DISABLED_StressLargeMemset) {
3563cab2bb3Spatrick size_t size = 1 << 20;
3573cab2bb3Spatrick char *x = new char[size];
3583cab2bb3Spatrick for (int i = 0; i < 100000; i++)
3593cab2bb3Spatrick Ident(memset)(x, 0, size);
3603cab2bb3Spatrick delete [] x;
3613cab2bb3Spatrick }
3623cab2bb3Spatrick
3633cab2bb3Spatrick // Same here, but we run memset with small sizes.
TEST(AddressSanitizerInterface,DISABLED_StressSmallMemset)3643cab2bb3Spatrick TEST(AddressSanitizerInterface, DISABLED_StressSmallMemset) {
3653cab2bb3Spatrick size_t size = 32;
3663cab2bb3Spatrick char *x = new char[size];
3673cab2bb3Spatrick for (int i = 0; i < 100000000; i++)
3683cab2bb3Spatrick Ident(memset)(x, 0, size);
3693cab2bb3Spatrick delete [] x;
3703cab2bb3Spatrick }
3713cab2bb3Spatrick static const char *kInvalidPoisonMessage = "invalid-poison-memory-range";
3723cab2bb3Spatrick static const char *kInvalidUnpoisonMessage = "invalid-unpoison-memory-range";
3733cab2bb3Spatrick
TEST(AddressSanitizerInterface,DISABLED_InvalidPoisonAndUnpoisonCallsTest)3743cab2bb3Spatrick TEST(AddressSanitizerInterface, DISABLED_InvalidPoisonAndUnpoisonCallsTest) {
3753cab2bb3Spatrick char *array = Ident((char*)malloc(120));
3763cab2bb3Spatrick __asan_unpoison_memory_region(array, 120);
3773cab2bb3Spatrick // Try to unpoison not owned memory
3783cab2bb3Spatrick EXPECT_DEATH(__asan_unpoison_memory_region(array, 121),
3793cab2bb3Spatrick kInvalidUnpoisonMessage);
3803cab2bb3Spatrick EXPECT_DEATH(__asan_unpoison_memory_region(array - 1, 120),
3813cab2bb3Spatrick kInvalidUnpoisonMessage);
3823cab2bb3Spatrick
3833cab2bb3Spatrick __asan_poison_memory_region(array, 120);
3843cab2bb3Spatrick // Try to poison not owned memory.
3853cab2bb3Spatrick EXPECT_DEATH(__asan_poison_memory_region(array, 121), kInvalidPoisonMessage);
3863cab2bb3Spatrick EXPECT_DEATH(__asan_poison_memory_region(array - 1, 120),
3873cab2bb3Spatrick kInvalidPoisonMessage);
3883cab2bb3Spatrick free(array);
3893cab2bb3Spatrick }
3903cab2bb3Spatrick
TEST(AddressSanitizerInterface,GetOwnershipStressTest)3913cab2bb3Spatrick TEST(AddressSanitizerInterface, GetOwnershipStressTest) {
3923cab2bb3Spatrick std::vector<char *> pointers;
3933cab2bb3Spatrick std::vector<size_t> sizes;
3943cab2bb3Spatrick const size_t kNumMallocs = 1 << 9;
3953cab2bb3Spatrick for (size_t i = 0; i < kNumMallocs; i++) {
3963cab2bb3Spatrick size_t size = i * 100 + 1;
3973cab2bb3Spatrick pointers.push_back((char*)malloc(size));
3983cab2bb3Spatrick sizes.push_back(size);
3993cab2bb3Spatrick }
4003cab2bb3Spatrick for (size_t i = 0; i < 4000000; i++) {
4013cab2bb3Spatrick EXPECT_FALSE(__sanitizer_get_ownership(&pointers));
4023cab2bb3Spatrick EXPECT_FALSE(__sanitizer_get_ownership((void*)0x1234));
4033cab2bb3Spatrick size_t idx = i % kNumMallocs;
4043cab2bb3Spatrick EXPECT_TRUE(__sanitizer_get_ownership(pointers[idx]));
4053cab2bb3Spatrick EXPECT_EQ(sizes[idx], __sanitizer_get_allocated_size(pointers[idx]));
4063cab2bb3Spatrick }
4073cab2bb3Spatrick for (size_t i = 0, n = pointers.size(); i < n; i++)
4083cab2bb3Spatrick free(pointers[i]);
4093cab2bb3Spatrick }
4103cab2bb3Spatrick
TEST(AddressSanitizerInterface,HandleNoReturnTest)4113cab2bb3Spatrick TEST(AddressSanitizerInterface, HandleNoReturnTest) {
4123cab2bb3Spatrick char array[40];
4133cab2bb3Spatrick __asan_poison_memory_region(array, sizeof(array));
4143cab2bb3Spatrick BAD_ACCESS(array, 20);
4153cab2bb3Spatrick __asan_handle_no_return();
416*810390e3Srobert // Fake stack does not need to be unpoisoned.
417*810390e3Srobert if (__asan_get_current_fake_stack())
418*810390e3Srobert return;
4193cab2bb3Spatrick // It unpoisons the whole thread stack.
4203cab2bb3Spatrick GOOD_ACCESS(array, 20);
4213cab2bb3Spatrick }
422