summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2013-10-16 13:49:01 +0000
committerKostya Serebryany <kcc@google.com>2013-10-16 13:49:01 +0000
commitcca8e781e5353cba810a0ec3a814ddde2c4934e7 (patch)
tree5b61ac26e76c2f3b075453914e832360458e8e1e
parent166d6aac8aeafe0d915b7233ba9e6714fcfa2aae (diff)
downloadcompiler-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.cc2
-rw-r--r--lib/asan/asan_flags.h3
-rw-r--r--lib/asan/asan_poisoning.h3
-rw-r--r--lib/asan/asan_rtl.cc2
-rw-r--r--lib/asan/lit_tests/TestCases/poison_partial.cc19
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