summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/asan
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/asan')
-rw-r--r--compiler-rt/lib/asan/asan_allocator2.cc3
-rw-r--r--compiler-rt/lib/asan/asan_flags.h6
-rw-r--r--compiler-rt/lib/asan/asan_rtl.cc8
-rw-r--r--compiler-rt/lib/asan/lit_tests/TestCases/max_redzone.cc26
4 files changed, 39 insertions, 4 deletions
diff --git a/compiler-rt/lib/asan/asan_allocator2.cc b/compiler-rt/lib/asan/asan_allocator2.cc
index 6b195dcf988..082cf86d749 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 c828b815abf..a731ab0b544 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 60571fd3178..3dedcc1c163 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 00000000000..dbcedd04484
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sanitizer/asan_interface.h>
+
+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);
+}
OpenPOWER on IntegriCloud