diff options
author | Kostya Serebryany <kcc@google.com> | 2013-04-04 11:17:14 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2013-04-04 11:17:14 +0000 |
commit | 13b07733b1b1a5ac4c51117f08f0b3ae31e87886 (patch) | |
tree | 3d55bd09132f11fcee830cda5361e3d3b998cba8 | |
parent | 24b2169e0797db87426b0d9b3d2cd493f577415f (diff) | |
download | bcm5719-llvm-13b07733b1b1a5ac4c51117f08f0b3ae31e87886.tar.gz bcm5719-llvm-13b07733b1b1a5ac4c51117f08f0b3ae31e87886.zip |
[asan] fill first 4K of malloc-ed memory with garbage, implement flags max_malloc_fill_size and malloc_fill_byte
llvm-svn: 178757
-rw-r--r-- | compiler-rt/lib/asan/asan_allocator2.cc | 27 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_flags.h | 6 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_rtl.cc | 4 | ||||
-rw-r--r-- | compiler-rt/lib/asan/lit_tests/malloc_fill.cc | 22 | ||||
-rw-r--r-- | compiler-rt/lib/asan/lit_tests/use-after-poison.cc | 1 |
5 files changed, 45 insertions, 15 deletions
diff --git a/compiler-rt/lib/asan/asan_allocator2.cc b/compiler-rt/lib/asan/asan_allocator2.cc index 08a576091e4..46cc78d7ae6 100644 --- a/compiler-rt/lib/asan/asan_allocator2.cc +++ b/compiler-rt/lib/asan/asan_allocator2.cc @@ -298,9 +298,10 @@ void InitializeAllocator() { } static void *Allocate(uptr size, uptr alignment, StackTrace *stack, - AllocType alloc_type) { + AllocType alloc_type, bool can_fill) { if (!asan_inited) __asan_init(); + Flags &fl = *flags(); CHECK(stack); const uptr min_alignment = SHADOW_GRANULARITY; if (alignment < min_alignment) @@ -384,7 +385,7 @@ static void *Allocate(uptr size, uptr alignment, StackTrace *stack, meta[1] = chunk_beg; } - if (flags()->use_stack_depot) { + if (fl.use_stack_depot) { m->alloc_context_id = StackDepotPut(stack->trace, stack->size); } else { m->alloc_context_id = 0; @@ -396,7 +397,7 @@ static void *Allocate(uptr size, uptr alignment, StackTrace *stack, if (size_rounded_down_to_granularity) PoisonShadow(user_beg, size_rounded_down_to_granularity, 0); // Deal with the end of the region if size is not aligned to granularity. - if (size != size_rounded_down_to_granularity && flags()->poison_heap) { + if (size != size_rounded_down_to_granularity && fl.poison_heap) { u8 *shadow = (u8*)MemToShadow(user_beg + size_rounded_down_to_granularity); *shadow = size & (SHADOW_GRANULARITY - 1); } @@ -411,6 +412,10 @@ static void *Allocate(uptr size, uptr alignment, StackTrace *stack, thread_stats.malloc_large++; void *res = reinterpret_cast<void *>(user_beg); + if (can_fill && fl.max_malloc_fill_size) { + uptr fill_size = Min(size, (uptr)fl.max_malloc_fill_size); + REAL(memset)(res, fl.malloc_fill_byte, fill_size); + } ASAN_MALLOC_HOOK(res, size); return res; } @@ -485,7 +490,7 @@ static void *Reallocate(void *old_ptr, uptr new_size, StackTrace *stack) { CHECK(m->chunk_state == CHUNK_ALLOCATED); uptr old_size = m->UsedSize(); uptr memcpy_size = Min(new_size, old_size); - void *new_ptr = Allocate(new_size, 8, stack, FROM_MALLOC); + void *new_ptr = Allocate(new_size, 8, stack, FROM_MALLOC, true); if (new_ptr) { CHECK_NE(REAL(memcpy), (void*)0); REAL(memcpy)(new_ptr, old_ptr, memcpy_size); @@ -590,7 +595,7 @@ void PrintInternalAllocatorStats() { SANITIZER_INTERFACE_ATTRIBUTE void *asan_memalign(uptr alignment, uptr size, StackTrace *stack, AllocType alloc_type) { - return Allocate(size, alignment, stack, alloc_type); + return Allocate(size, alignment, stack, alloc_type, true); } SANITIZER_INTERFACE_ATTRIBUTE @@ -600,12 +605,12 @@ void asan_free(void *ptr, StackTrace *stack, AllocType alloc_type) { SANITIZER_INTERFACE_ATTRIBUTE void *asan_malloc(uptr size, StackTrace *stack) { - return Allocate(size, 8, stack, FROM_MALLOC); + return Allocate(size, 8, stack, FROM_MALLOC, true); } void *asan_calloc(uptr nmemb, uptr size, StackTrace *stack) { if (CallocShouldReturnNullDueToOverflow(size, nmemb)) return 0; - void *ptr = Allocate(nmemb * size, 8, stack, FROM_MALLOC); + void *ptr = Allocate(nmemb * size, 8, stack, FROM_MALLOC, false); // If the memory comes from the secondary allocator no need to clear it // as it comes directly from mmap. if (ptr && allocator.FromPrimary(ptr)) @@ -615,7 +620,7 @@ void *asan_calloc(uptr nmemb, uptr size, StackTrace *stack) { void *asan_realloc(void *p, uptr size, StackTrace *stack) { if (p == 0) - return Allocate(size, 8, stack, FROM_MALLOC); + return Allocate(size, 8, stack, FROM_MALLOC, true); if (size == 0) { Deallocate(p, stack, FROM_MALLOC); return 0; @@ -624,7 +629,7 @@ void *asan_realloc(void *p, uptr size, StackTrace *stack) { } void *asan_valloc(uptr size, StackTrace *stack) { - return Allocate(size, GetPageSizeCached(), stack, FROM_MALLOC); + return Allocate(size, GetPageSizeCached(), stack, FROM_MALLOC, true); } void *asan_pvalloc(uptr size, StackTrace *stack) { @@ -634,12 +639,12 @@ void *asan_pvalloc(uptr size, StackTrace *stack) { // pvalloc(0) should allocate one page. size = PageSize; } - return Allocate(size, PageSize, stack, FROM_MALLOC); + return Allocate(size, PageSize, stack, FROM_MALLOC, true); } int asan_posix_memalign(void **memptr, uptr alignment, uptr size, StackTrace *stack) { - void *ptr = Allocate(size, alignment, stack, FROM_MALLOC); + void *ptr = Allocate(size, alignment, stack, FROM_MALLOC, true); CHECK(IsAligned((uptr)ptr, alignment)); *memptr = ptr; return 0; diff --git a/compiler-rt/lib/asan/asan_flags.h b/compiler-rt/lib/asan/asan_flags.h index 377354a440d..0969ae23767 100644 --- a/compiler-rt/lib/asan/asan_flags.h +++ b/compiler-rt/lib/asan/asan_flags.h @@ -58,9 +58,9 @@ struct Flags { bool mac_ignore_invalid_free; // ASan allocator flag. See asan_allocator.cc. bool use_fake_stack; - // ASan allocator flag. Sets the maximal size of allocation request - // that would return memory filled with zero bytes. - int max_malloc_fill_size; + // ASan allocator flag. max_malloc_fill_size is the maximal amount of bytes + // that will be filled with malloc_fill_byte on malloc. + int max_malloc_fill_size, malloc_fill_byte; // Override exit status if something was reported. int exitcode; // If set, user may manually mark memory regions as poisoned or unpoisoned. diff --git a/compiler-rt/lib/asan/asan_rtl.cc b/compiler-rt/lib/asan/asan_rtl.cc index 496dfd12252..07c2551d672 100644 --- a/compiler-rt/lib/asan/asan_rtl.cc +++ b/compiler-rt/lib/asan/asan_rtl.cc @@ -106,6 +106,7 @@ static void ParseFlagsFromString(Flags *f, const char *str) { ParseFlag(str, &f->mac_ignore_invalid_free, "mac_ignore_invalid_free"); ParseFlag(str, &f->use_fake_stack, "use_fake_stack"); ParseFlag(str, &f->max_malloc_fill_size, "max_malloc_fill_size"); + ParseFlag(str, &f->malloc_fill_byte, "malloc_fill_byte"); ParseFlag(str, &f->exitcode, "exitcode"); ParseFlag(str, &f->allow_user_poisoning, "allow_user_poisoning"); ParseFlag(str, &f->sleep_before_dying, "sleep_before_dying"); @@ -147,7 +148,8 @@ void InitializeFlags(Flags *f, const char *env) { f->replace_intrin = true; f->mac_ignore_invalid_free = false; f->use_fake_stack = true; - f->max_malloc_fill_size = 0; + f->max_malloc_fill_size = 0x1000; // By default, fill only the first 4K. + f->malloc_fill_byte = 0xbe; f->exitcode = ASAN_DEFAULT_FAILURE_EXITCODE; f->allow_user_poisoning = true; f->sleep_before_dying = 0; diff --git a/compiler-rt/lib/asan/lit_tests/malloc_fill.cc b/compiler-rt/lib/asan/lit_tests/malloc_fill.cc new file mode 100644 index 00000000000..c23516b3329 --- /dev/null +++ b/compiler-rt/lib/asan/lit_tests/malloc_fill.cc @@ -0,0 +1,22 @@ +// Check that we fill malloc-ed memory correctly. +// RUN: %clangxx_asan -m64 %s -o %t +// RUN: %t | FileCheck %s +// RUN: ASAN_OPTIONS=max_malloc_fill_size=10:malloc_fill_byte=8 %t | FileCheck %s --check-prefix=CHECK-10-8 +// RUN: ASAN_OPTIONS=max_malloc_fill_size=20:malloc_fill_byte=171 %t | FileCheck %s --check-prefix=CHECK-20-ab + +#include <stdio.h> +int main(int argc, char **argv) { + // With asan allocator this makes sure we get memory from mmap. + static const int kSize = 1 << 25; + unsigned char *x = new unsigned char[kSize]; + printf("-"); + for (int i = 0; i <= 32; i++) { + printf("%02x", x[i]); + } + printf("-\n"); + delete [] x; +} + +// CHECK: -bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe- +// CHECK-10-8: -080808080808080808080000000000000000000000000000000000000000000000- +// CHECK-20-ab: -abababababababababababababababababababab00000000000000000000000000- diff --git a/compiler-rt/lib/asan/lit_tests/use-after-poison.cc b/compiler-rt/lib/asan/lit_tests/use-after-poison.cc index 634eb80bafa..d8734290024 100644 --- a/compiler-rt/lib/asan/lit_tests/use-after-poison.cc +++ b/compiler-rt/lib/asan/lit_tests/use-after-poison.cc @@ -10,6 +10,7 @@ extern "C" void __asan_poison_memory_region(void *, size_t); int main(int argc, char **argv) { char *x = new char[16]; + x[10] = 0; __asan_poison_memory_region(x, 16); int res = x[argc * 10]; // BOOOM // CHECK: ERROR: AddressSanitizer: use-after-poison |