diff options
author | Kostya Serebryany <kcc@google.com> | 2013-10-16 13:49:01 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2013-10-16 13:49:01 +0000 |
commit | cca8e781e5353cba810a0ec3a814ddde2c4934e7 (patch) | |
tree | 5b61ac26e76c2f3b075453914e832360458e8e1e | |
parent | 166d6aac8aeafe0d915b7233ba9e6714fcfa2aae (diff) | |
download | compiler-rt-cca8e781e5353cba810a0ec3a814ddde2c4934e7.tar.gz compiler-rt-cca8e781e5353cba810a0ec3a814ddde2c4934e7.tar.bz2 compiler-rt-cca8e781e5353cba810a0ec3a814ddde2c4934e7.tar.xz |
[asan] introduce run-time flag 'poison_partial'
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@192793 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/asan/asan_allocator2.cc | 2 | ||||
-rw-r--r-- | lib/asan/asan_flags.h | 3 | ||||
-rw-r--r-- | lib/asan/asan_poisoning.h | 3 | ||||
-rw-r--r-- | lib/asan/asan_rtl.cc | 2 | ||||
-rw-r--r-- | lib/asan/lit_tests/TestCases/poison_partial.cc | 19 |
5 files changed, 27 insertions, 2 deletions
diff --git a/lib/asan/asan_allocator2.cc b/lib/asan/asan_allocator2.cc index 09ec1376..4fd9d5a6 100644 --- a/lib/asan/asan_allocator2.cc +++ b/lib/asan/asan_allocator2.cc @@ -408,7 +408,7 @@ static void *Allocate(uptr size, uptr alignment, StackTrace *stack, // Deal with the end of the region if size is not aligned to granularity. 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); + *shadow = fl.poison_partial ? (size & (SHADOW_GRANULARITY - 1)) : 0; } AsanStats &thread_stats = GetCurrentThreadStats(); diff --git a/lib/asan/asan_flags.h b/lib/asan/asan_flags.h index 93f7346c..735628d7 100644 --- a/lib/asan/asan_flags.h +++ b/lib/asan/asan_flags.h @@ -96,6 +96,9 @@ struct Flags { // Poison (or not) the heap memory on [de]allocation. Zero value is useful // for benchmarking the allocator or instrumentator. bool poison_heap; + // If true, poison partially addressable 8-byte aligned words (default=true). + // This flag affects heap and global buffers, but not stack buffers. + bool poison_partial; // Report errors on malloc/delete, new/free, new/delete[], etc. bool alloc_dealloc_mismatch; // Use stack depot instead of storing stacks in the redzones. diff --git a/lib/asan/asan_poisoning.h b/lib/asan/asan_poisoning.h index bb886dd7..fbac2119 100644 --- a/lib/asan/asan_poisoning.h +++ b/lib/asan/asan_poisoning.h @@ -43,6 +43,7 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size, ALWAYS_INLINE void FastPoisonShadowPartialRightRedzone( uptr aligned_addr, uptr size, uptr redzone_size, u8 value) { DCHECK(flags()->poison_heap); + bool poison_partial = flags()->poison_partial; u8 *shadow = (u8*)MEM_TO_SHADOW(aligned_addr); for (uptr i = 0; i < redzone_size; i += SHADOW_GRANULARITY, shadow++) { if (i + SHADOW_GRANULARITY <= size) { @@ -51,7 +52,7 @@ ALWAYS_INLINE void FastPoisonShadowPartialRightRedzone( *shadow = (SHADOW_GRANULARITY == 128) ? 0xff : value; // unaddressable } else { // first size-i bytes are addressable - *shadow = static_cast<u8>(size - i); + *shadow = poison_partial ? static_cast<u8>(size - i) : 0; } } } diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc index b34a386b..1c207f16 100644 --- a/lib/asan/asan_rtl.cc +++ b/lib/asan/asan_rtl.cc @@ -124,6 +124,7 @@ static void ParseFlagsFromString(Flags *f, const char *str) { ParseFlag(str, &f->allow_reexec, "allow_reexec"); ParseFlag(str, &f->print_full_thread_history, "print_full_thread_history"); ParseFlag(str, &f->poison_heap, "poison_heap"); + ParseFlag(str, &f->poison_partial, "poison_partial"); ParseFlag(str, &f->alloc_dealloc_mismatch, "alloc_dealloc_mismatch"); ParseFlag(str, &f->use_stack_depot, "use_stack_depot"); ParseFlag(str, &f->strict_memcmp, "strict_memcmp"); @@ -172,6 +173,7 @@ void InitializeFlags(Flags *f, const char *env) { f->allow_reexec = true; f->print_full_thread_history = true; f->poison_heap = true; + f->poison_partial = true; // Turn off alloc/dealloc mismatch checker on Mac and Windows for now. // TODO(glider,timurrrr): Fix known issues and enable this back. f->alloc_dealloc_mismatch = (SANITIZER_MAC == 0) && (SANITIZER_WINDOWS == 0); diff --git a/lib/asan/lit_tests/TestCases/poison_partial.cc b/lib/asan/lit_tests/TestCases/poison_partial.cc new file mode 100644 index 00000000..f7c48bf5 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/poison_partial.cc @@ -0,0 +1,19 @@ +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %t 2>&1 | FileCheck %s +// RUN: not %t heap 2>&1 | FileCheck %s +// RUN: ASAN_OPTIONS=poison_partial=0 %t +// RUN: ASAN_OPTIONS=poison_partial=0 %t heap +#include <string.h> +char g[21]; +char *x; + +int main(int argc, char **argv) { + if (argc >= 2) + x = new char[21]; + else + x = &g[0]; + memset(x, 0, 21); + int *y = (int*)x; + return y[5]; +} +// CHECK: 0 bytes to the right |