[PATCH] [lsan] Make LSan ignore memory poisoned by ASan.
Sergey Matveev
earthdok at google.com
Sat Dec 7 12:56:00 PST 2013
Hi kcc,
No more (potenital) false negatives due to red zones or fake stack
frames.
http://llvm-reviews.chandlerc.com/D2359
Files:
lib/asan/asan_poisoning.cc
lib/lsan/lit_tests/AsanConfig/lit.cfg
lib/lsan/lit_tests/LsanConfig/lit.cfg
lib/lsan/lit_tests/TestCases/AsanOnly/use_poisoned.cc
lib/lsan/lsan.cc
lib/lsan/lsan_common.cc
lib/lsan/lsan_common.h
Index: lib/asan/asan_poisoning.cc
===================================================================
--- lib/asan/asan_poisoning.cc
+++ lib/asan/asan_poisoning.cc
@@ -292,3 +292,11 @@
*(u8*)MemToShadow(b1) = static_cast<u8>(new_mid - b1);
}
}
+
+// --- Implementation of LSan-specific functions --- {{{1
+namespace __lsan {
+bool WordIsPoisoned(uptr addr) {
+ return __asan_region_is_poisoned(addr, sizeof(void *)); // NOLINT
+}
+}
+
Index: lib/lsan/lit_tests/AsanConfig/lit.cfg
===================================================================
--- lib/lsan/lit_tests/AsanConfig/lit.cfg
+++ lib/lsan/lit_tests/AsanConfig/lit.cfg
@@ -17,6 +17,8 @@
lit_config.fatal("Can't find common LSan lit config at: %r" % lsan_lit_cfg)
lit_config.load_config(config, lsan_lit_cfg)
+config.tool = 'asan'
+
config.name = 'LeakSanitizer-AddressSanitizer'
clang_lsan_cxxflags = config.clang_cxxflags + " -fsanitize=address "
Index: lib/lsan/lit_tests/LsanConfig/lit.cfg
===================================================================
--- lib/lsan/lit_tests/LsanConfig/lit.cfg
+++ lib/lsan/lit_tests/LsanConfig/lit.cfg
@@ -17,6 +17,8 @@
lit_config.fatal("Can't find common LSan lit config at: %r" % lsan_lit_cfg)
lit_config.load_config(config, lsan_lit_cfg)
+config.tool = 'standalone'
+
config.name = 'LeakSanitizer-Standalone'
clang_lsan_cxxflags = config.clang_cxxflags + " -fsanitize=leak "
Index: lib/lsan/lit_tests/TestCases/AsanOnly/use_poisoned.cc
===================================================================
--- /dev/null
+++ lib/lsan/lit_tests/TestCases/AsanOnly/use_poisoned.cc
@@ -0,0 +1,24 @@
+// Test for the use_poisoned flag.
+// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0"
+// RUN: %clangxx_lsan %s -o %t
+// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_poisoned=0" not %t 2>&1 | FileCheck %s
+// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_poisoned=1" %t 2>&1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sanitizer/asan_interface.h>
+#include <assert.h>
+
+void **p;
+
+int main() {
+ p = new void *;
+ *p = malloc(1337);
+ fprintf(stderr, "Test alloc: %p.\n", *p);
+ __asan_poison_memory_region(p, sizeof(*p));
+ return 0;
+}
+// CHECK: Test alloc: [[ADDR:.*]].
+// CHECK: Directly leaked 1337 byte object at [[ADDR]]
+// CHECK: LeakSanitizer: detected memory leaks
+// CHECK: SUMMARY: AddressSanitizer:
Index: lib/lsan/lsan.cc
===================================================================
--- lib/lsan/lsan.cc
+++ lib/lsan/lsan.cc
@@ -35,6 +35,11 @@
ParseCommonFlagsFromString(cf, GetEnv("LSAN_OPTIONS"));
}
+///// Interface to the common LSan module. /////
+bool WordIsPoisoned(uptr addr) {
+ return false;
+}
+
} // namespace __lsan
using namespace __lsan; // NOLINT
Index: lib/lsan/lsan_common.cc
===================================================================
--- lib/lsan/lsan_common.cc
+++ lib/lsan/lsan_common.cc
@@ -47,6 +47,7 @@
f->use_stacks = true;
f->use_tls = true;
f->use_unaligned = false;
+ f->use_poisoned = false;
f->verbosity = 0;
f->log_pointers = false;
f->log_threads = false;
@@ -58,6 +59,7 @@
ParseFlag(options, &f->use_stacks, "use_stacks");
ParseFlag(options, &f->use_tls, "use_tls");
ParseFlag(options, &f->use_unaligned, "use_unaligned");
+ ParseFlag(options, &f->use_poisoned, "use_poisoned");
ParseFlag(options, &f->report_objects, "report_objects");
ParseFlag(options, &f->resolution, "resolution");
CHECK_GE(&f->resolution, 0);
@@ -148,6 +150,17 @@
// Reachable beats ignored beats leaked.
if (m.tag() == kReachable) continue;
if (m.tag() == kIgnored && tag != kReachable) continue;
+
+ // Do this check relatively late so we can log only the interesting cases.
+ if (!flags()->use_poisoned && WordIsPoisoned(pp)) {
+ if (flags()->log_pointers)
+ Report(
+ "%p is poisoned: ignoring %p pointing into chunk %p-%p of size "
+ "%zu.\n",
+ pp, p, chunk, chunk + m.requested_size(), m.requested_size());
+ continue;
+ }
+
m.set_tag(tag);
if (flags()->log_pointers)
Report("%p: found %p pointing into chunk %p-%p of size %zu.\n", pp, p,
Index: lib/lsan/lsan_common.h
===================================================================
--- lib/lsan/lsan_common.h
+++ lib/lsan/lsan_common.h
@@ -66,6 +66,8 @@
// Consider unaligned pointers valid.
bool use_unaligned;
+ // Consider pointers found in poisoned memory to be valid.
+ bool use_poisoned;
// User-visible verbosity.
int verbosity;
@@ -129,6 +131,8 @@
// Wrappers for allocator's ForceLock()/ForceUnlock().
void LockAllocator();
void UnlockAllocator();
+// Returns true if [addr, addr + sizeof(void *)) is poisoned.
+bool WordIsPoisoned(uptr addr);
// Wrappers for ThreadRegistry access.
void LockThreadRegistry();
void UnlockThreadRegistry();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2359.1.patch
Type: text/x-patch
Size: 4876 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131207/afd28d11/attachment.bin>
More information about the llvm-commits
mailing list