[compiler-rt] r196778 - [lsan] Make LSan ignore memory poisoned by ASan.

Sergey Matveev earthdok at google.com
Mon Dec 9 05:12:11 PST 2013


Author: smatveev
Date: Mon Dec  9 07:12:10 2013
New Revision: 196778

URL: http://llvm.org/viewvc/llvm-project?rev=196778&view=rev
Log:
[lsan] Make LSan ignore memory poisoned by ASan.

Summary:
No more (potenital) false negatives due to red zones or fake stack
frames.

Reviewers: kcc, samsonov

Reviewed By: samsonov

CC: llvm-commits, samsonov

Differential Revision: http://llvm-reviews.chandlerc.com/D2359

Added:
    compiler-rt/trunk/lib/lsan/lit_tests/TestCases/use_poisoned_asan.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_poisoning.cc
    compiler-rt/trunk/lib/lsan/lit_tests/AsanConfig/lit.cfg
    compiler-rt/trunk/lib/lsan/lsan.cc
    compiler-rt/trunk/lib/lsan/lsan_common.cc
    compiler-rt/trunk/lib/lsan/lsan_common.h

Modified: compiler-rt/trunk/lib/asan/asan_poisoning.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_poisoning.cc?rev=196778&r1=196777&r2=196778&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_poisoning.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_poisoning.cc Mon Dec  9 07:12:10 2013
@@ -292,3 +292,11 @@ void __sanitizer_annotate_contiguous_con
     *(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(uptr));
+}
+}
+

Modified: compiler-rt/trunk/lib/lsan/lit_tests/AsanConfig/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lit_tests/AsanConfig/lit.cfg?rev=196778&r1=196777&r2=196778&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lit_tests/AsanConfig/lit.cfg (original)
+++ compiler-rt/trunk/lib/lsan/lit_tests/AsanConfig/lit.cfg Mon Dec  9 07:12:10 2013
@@ -17,6 +17,8 @@ if not os.path.exists(lsan_lit_cfg):
   lit_config.fatal("Can't find common LSan lit config at: %r" % lsan_lit_cfg)
 lit_config.load_config(config, lsan_lit_cfg)
 
+config.available_features.add('asan')
+
 config.name = 'LeakSanitizer-AddressSanitizer'
 
 clang_lsan_cxxflags = config.clang_cxxflags + " -fsanitize=address "

Added: compiler-rt/trunk/lib/lsan/lit_tests/TestCases/use_poisoned_asan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lit_tests/TestCases/use_poisoned_asan.cc?rev=196778&view=auto
==============================================================================
--- compiler-rt/trunk/lib/lsan/lit_tests/TestCases/use_poisoned_asan.cc (added)
+++ compiler-rt/trunk/lib/lsan/lit_tests/TestCases/use_poisoned_asan.cc Mon Dec  9 07:12:10 2013
@@ -0,0 +1,25 @@
+// ASan-poisoned memory should be ignored if use_poisoned is false.
+// REQUIRES: asan
+// 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:

Modified: compiler-rt/trunk/lib/lsan/lsan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan.cc?rev=196778&r1=196777&r2=196778&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan.cc Mon Dec  9 07:12:10 2013
@@ -35,6 +35,11 @@ static void InitializeCommonFlags() {
   ParseCommonFlagsFromString(cf, GetEnv("LSAN_OPTIONS"));
 }
 
+///// Interface to the common LSan module. /////
+bool WordIsPoisoned(uptr addr) {
+  return false;
+}
+
 }  // namespace __lsan
 
 using namespace __lsan;  // NOLINT

Modified: compiler-rt/trunk/lib/lsan/lsan_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.cc?rev=196778&r1=196777&r2=196778&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_common.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan_common.cc Mon Dec  9 07:12:10 2013
@@ -47,6 +47,7 @@ static void InitializeFlags() {
   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 @@ static void InitializeFlags() {
     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 @@ void ScanRangeForPointers(uptr begin, up
     // 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,

Modified: compiler-rt/trunk/lib/lsan/lsan_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.h?rev=196778&r1=196777&r2=196778&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_common.h (original)
+++ compiler-rt/trunk/lib/lsan/lsan_common.h Mon Dec  9 07:12:10 2013
@@ -66,6 +66,8 @@ struct Flags {
 
   // 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 @@ void GetAllocatorGlobalRange(uptr *begin
 // 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();





More information about the llvm-commits mailing list