diff options
author | Kostya Serebryany <kcc@google.com> | 2012-12-25 09:40:20 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2012-12-25 09:40:20 +0000 |
commit | f1877cf0a314f407ac535ab1606fdac4f9b05026 (patch) | |
tree | ce98f4dcaebb021ae5f42d1b74994dcd9a10a3bc /lib | |
parent | 81088ebf34c3ef1b8ac3a9789d3896c7b9a93003 (diff) |
[asan] add a test for right OOB with special large sizes. Fix this test in asan_allocator2. More test tweaking for allocator2
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@171058 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/asan/asan_allocator2.cc | 4 | ||||
-rw-r--r-- | lib/asan/tests/asan_noinst_test.cc | 8 | ||||
-rw-r--r-- | lib/asan/tests/asan_test.cc | 12 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_allocator.h | 4 |
4 files changed, 25 insertions, 3 deletions
diff --git a/lib/asan/asan_allocator2.cc b/lib/asan/asan_allocator2.cc index 36eb78cde..2a0a5172e 100644 --- a/lib/asan/asan_allocator2.cc +++ b/lib/asan/asan_allocator2.cc @@ -294,6 +294,10 @@ static void *Allocate(uptr size, uptr alignment, StackTrace *stack, uptr needed_size = rounded_size + rz_size; if (alignment > rz_size) needed_size += alignment; + // If we are allocating from the secondary allocator, there will be no + // automatic right redzone, so add the right redzone manually. + if (!PrimaryAllocator::CanAllocate(needed_size, alignment)) + needed_size += rz_size; CHECK(IsAligned(needed_size, rz_size)); if (size > kMaxAllowedMallocSize || needed_size > kMaxAllowedMallocSize) { Report("WARNING: AddressSanitizer failed to allocate %p bytes\n", diff --git a/lib/asan/tests/asan_noinst_test.cc b/lib/asan/tests/asan_noinst_test.cc index 018e559c3..44e1d9f1b 100644 --- a/lib/asan/tests/asan_noinst_test.cc +++ b/lib/asan/tests/asan_noinst_test.cc @@ -452,7 +452,7 @@ TEST(AddressSanitizerInterface, GetHeapSizeTest) { // asan_allocator2 does not keep huge chunks in free list, but unmaps them. // The chunk should be greater than the quarantine size, // otherwise it will be stuck in quarantine instead of being unmaped. - static const size_t kLargeMallocSize = 1 << 28; // 256M + static const size_t kLargeMallocSize = 1 << 29; // 512M uptr old_heap_size = __asan_get_heap_size(); for (int i = 0; i < 3; i++) { // fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize); @@ -484,6 +484,7 @@ static void DoLargeMallocForGetFreeBytesTestAndDie() { } TEST(AddressSanitizerInterface, GetFreeBytesTest) { +#if ASAN_ALLOCATOR_VERSION == 1 // Allocate a small chunk. Now allocator probably has a lot of these // chunks to fulfill future requests. So, future requests will decrease // the number of free bytes. Do this only on systems where there @@ -505,6 +506,7 @@ TEST(AddressSanitizerInterface, GetFreeBytesTest) { for (i = 0; i < kNumOfChunks; i++) free(chunks[i]); } +#endif EXPECT_DEATH(DoLargeMallocForGetFreeBytesTestAndDie(), "double-free"); } @@ -719,8 +721,12 @@ TEST(AddressSanitizerInterface, SetErrorReportCallbackTest) { TEST(AddressSanitizerInterface, GetOwnershipStressTest) { std::vector<char *> pointers; std::vector<size_t> sizes; +#if ASAN_ALLOCATOR_VERSION == 1 const size_t kNumMallocs = (SANITIZER_WORDSIZE <= 32 || ASAN_LOW_MEMORY) ? 1 << 10 : 1 << 14; +#elif ASAN_ALLOCATOR_VERSION == 2 // too slow with asan_allocator2. :( + const size_t kNumMallocs = 1 << 9; +#endif for (size_t i = 0; i < kNumMallocs; i++) { size_t size = i * 100 + 1; pointers.push_back((char*)malloc(size)); diff --git a/lib/asan/tests/asan_test.cc b/lib/asan/tests/asan_test.cc index 1d2b3ac27..80edeeafa 100644 --- a/lib/asan/tests/asan_test.cc +++ b/lib/asan/tests/asan_test.cc @@ -307,6 +307,18 @@ TEST(AddressSanitizer, OOBRightTest) { } } +#if ASAN_ALLOCATOR_VERSION == 2 // Broken with the asan_allocator1 +TEST(AddressSanitizer, LargeOOBRightTest) { + size_t large_power_of_two = 1 << 19; + for (size_t i = 16; i <= 256; i *= 2) { + size_t size = large_power_of_two - i; + char *p = Ident(new char[size]); + EXPECT_DEATH(p[size] = 0, "is located 0 bytes to the right"); + delete [] p; + } +} +#endif // ASAN_ALLOCATOR_VERSION == 2 + TEST(AddressSanitizer, UAF_char) { const char *uaf_string = "AddressSanitizer:.*heap-use-after-free"; EXPECT_DEATH(uaf_test<U1>(1, 0), uaf_string); diff --git a/lib/sanitizer_common/sanitizer_allocator.h b/lib/sanitizer_common/sanitizer_allocator.h index 33d5a6999..abd684e41 100644 --- a/lib/sanitizer_common/sanitizer_allocator.h +++ b/lib/sanitizer_common/sanitizer_allocator.h @@ -228,7 +228,7 @@ class SizeClassAllocator64 { UnmapOrDie(reinterpret_cast<void *>(beg), size); } - bool CanAllocate(uptr size, uptr alignment) { + static bool CanAllocate(uptr size, uptr alignment) { return size <= SizeClassMap::kMaxSize && alignment <= SizeClassMap::kMaxSize; } @@ -465,7 +465,7 @@ class SizeClassAllocator32 { UnmapOrDie(reinterpret_cast<void *>(beg), size); } - bool CanAllocate(uptr size, uptr alignment) { + static bool CanAllocate(uptr size, uptr alignment) { return size <= SizeClassMap::kMaxSize && alignment <= SizeClassMap::kMaxSize; } |