From 219719a2da4309ba26b46b949c74e960f9032bc0 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Thu, 9 Jan 2014 14:41:03 +0000 Subject: [PATCH] [asan] Implement max_redzone runtime flag. llvm-svn: 198873 --- compiler-rt/lib/asan/asan_allocator2.cc | 3 ++- compiler-rt/lib/asan/asan_flags.h | 6 +++-- compiler-rt/lib/asan/asan_rtl.cc | 8 +++++- .../asan/lit_tests/TestCases/max_redzone.cc | 26 +++++++++++++++++++ 4 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 compiler-rt/lib/asan/lit_tests/TestCases/max_redzone.cc diff --git a/compiler-rt/lib/asan/asan_allocator2.cc b/compiler-rt/lib/asan/asan_allocator2.cc index 6b195dcf9884..082cf86d7497 100644 --- a/compiler-rt/lib/asan/asan_allocator2.cc +++ b/compiler-rt/lib/asan/asan_allocator2.cc @@ -133,7 +133,8 @@ static uptr ComputeRZLog(uptr user_requested_size) { user_requested_size <= (1 << 14) - 256 ? 4 : user_requested_size <= (1 << 15) - 512 ? 5 : user_requested_size <= (1 << 16) - 1024 ? 6 : 7; - return Max(rz_log, RZSize2Log(flags()->redzone)); + return Min(Max(rz_log, RZSize2Log(flags()->redzone)), + RZSize2Log(flags()->max_redzone)); } // The memory chunk allocated from the underlying allocator looks like this: diff --git a/compiler-rt/lib/asan/asan_flags.h b/compiler-rt/lib/asan/asan_flags.h index c828b815abf0..a731ab0b5442 100644 --- a/compiler-rt/lib/asan/asan_flags.h +++ b/compiler-rt/lib/asan/asan_flags.h @@ -32,9 +32,11 @@ struct Flags { // Lower value may reduce memory usage but increase the chance of // false negatives. int quarantine_size; - // Size (in bytes) of redzones around heap objects. - // Requirement: redzone >= 32, is a power of two. + // Minimal size (in bytes) of redzones around heap objects. + // Requirement: redzone >= 16, is a power of two. int redzone; + // Maximal size (in bytes) of redzones around heap objects. + int max_redzone; // If set, prints some debugging information and does additional checks. bool debug; // Controls the way to handle globals (0 - don't detect buffer overflow diff --git a/compiler-rt/lib/asan/asan_rtl.cc b/compiler-rt/lib/asan/asan_rtl.cc index 60571fd31783..3dedcc1c163c 100644 --- a/compiler-rt/lib/asan/asan_rtl.cc +++ b/compiler-rt/lib/asan/asan_rtl.cc @@ -96,8 +96,12 @@ static void ParseFlagsFromString(Flags *f, const char *str) { ParseFlag(str, &f->quarantine_size, "quarantine_size"); ParseFlag(str, &f->redzone, "redzone"); + ParseFlag(str, &f->max_redzone, "max_redzone"); CHECK_GE(f->redzone, 16); + CHECK_GE(f->max_redzone, f->redzone); + CHECK_LE(f->max_redzone, 2048); CHECK(IsPowerOfTwo(f->redzone)); + CHECK(IsPowerOfTwo(f->max_redzone)); ParseFlag(str, &f->debug, "debug"); ParseFlag(str, &f->report_globals, "report_globals"); @@ -145,6 +149,7 @@ void InitializeFlags(Flags *f, const char *env) { internal_memset(f, 0, sizeof(*f)); f->quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 26 : 1UL << 28; f->redzone = 16; + f->max_redzone = 2048; f->debug = false; f->report_globals = 1; f->check_initialization_order = false; @@ -376,7 +381,8 @@ static void PrintAddressSpaceLayout() { (void*)MEM_TO_SHADOW(kMidShadowEnd)); } Printf("\n"); - Printf("red_zone=%zu\n", (uptr)flags()->redzone); + Printf("redzone=%zu\n", (uptr)flags()->redzone); + Printf("max_redzone=%zu\n", (uptr)flags()->max_redzone); Printf("quarantine_size=%zuM\n", (uptr)flags()->quarantine_size >> 20); Printf("malloc_context_size=%zu\n", (uptr)common_flags()->malloc_context_size); diff --git a/compiler-rt/lib/asan/lit_tests/TestCases/max_redzone.cc b/compiler-rt/lib/asan/lit_tests/TestCases/max_redzone.cc new file mode 100644 index 000000000000..dbcedd044847 --- /dev/null +++ b/compiler-rt/lib/asan/lit_tests/TestCases/max_redzone.cc @@ -0,0 +1,26 @@ +// Test max_redzone runtime option. + +// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS=max_redzone=16 %t 0 2>&1 +// RUN: %clangxx_asan -O0 %s -o %t && %t 1 2>&1 +// RUN: %clangxx_asan -O3 %s -o %t && ASAN_OPTIONS=max_redzone=16 %t 0 2>&1 +// RUN: %clangxx_asan -O3 %s -o %t && %t 1 2>&1 + +#include +#include +#include +#include + +int main(int argc, char **argv) { + if (argc < 2) + return 1; + bool large_redzone = atoi(argv[1]); + size_t before = __asan_get_heap_size(); + void *pp[10000]; + for (int i = 0; i < 10000; ++i) + pp[i] = malloc(4096 - 64); + size_t after = __asan_get_heap_size(); + for (int i = 0; i < 10000; ++i) + free(pp[i]); + size_t diff = after - before; + return !(large_redzone ? diff > 46000000 : diff < 46000000); +}