summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2012-12-25 09:40:20 +0000
committerKostya Serebryany <kcc@google.com>2012-12-25 09:40:20 +0000
commitf1877cf0a314f407ac535ab1606fdac4f9b05026 (patch)
treece98f4dcaebb021ae5f42d1b74994dcd9a10a3bc /lib
parent81088ebf34c3ef1b8ac3a9789d3896c7b9a93003 (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.cc4
-rw-r--r--lib/asan/tests/asan_noinst_test.cc8
-rw-r--r--lib/asan/tests/asan_test.cc12
-rw-r--r--lib/sanitizer_common/sanitizer_allocator.h4
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;
}