[compiler-rt] r202389 - [asan] *experimental* implementation of invalid-pointer-pair detector (finds when two unrelated pointers are compared or subtracted). This implementation has both false positives and false negatives and is not tuned for performance. A bug report for a proper implementation will follow.

Kostya Serebryany kcc at google.com
Thu Feb 27 04:45:36 PST 2014


Author: kcc
Date: Thu Feb 27 06:45:36 2014
New Revision: 202389

URL: http://llvm.org/viewvc/llvm-project?rev=202389&view=rev
Log:
[asan] *experimental* implementation of invalid-pointer-pair detector (finds when two unrelated pointers are compared or subtracted). This implementation has both false positives and false negatives and is not tuned for performance. A bug report for a proper implementation will follow.

Modified:
    compiler-rt/trunk/lib/asan/asan_allocator.h
    compiler-rt/trunk/lib/asan/asan_flags.h
    compiler-rt/trunk/lib/asan/asan_report.cc
    compiler-rt/trunk/lib/asan/asan_rtl.cc

Modified: compiler-rt/trunk/lib/asan/asan_allocator.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.h?rev=202389&r1=202388&r2=202389&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator.h (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator.h Thu Feb 27 06:45:36 2014
@@ -43,6 +43,7 @@ class AsanChunkView {
   uptr UsedSize();  // Size requested by the user.
   uptr AllocTid();
   uptr FreeTid();
+  bool Eq(const AsanChunkView &c) const { return chunk_ == c.chunk_; }
   void GetAllocStack(StackTrace *stack);
   void GetFreeStack(StackTrace *stack);
   bool AddrIsInside(uptr addr, uptr access_size, sptr *offset) {

Modified: compiler-rt/trunk/lib/asan/asan_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_flags.h?rev=202389&r1=202388&r2=202389&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_flags.h (original)
+++ compiler-rt/trunk/lib/asan/asan_flags.h Thu Feb 27 06:45:36 2014
@@ -114,6 +114,10 @@ struct Flags {
   // them to original values when the first instrumented module is loaded into
   // the process. This is mainly intended to be used on Android.
   bool start_deactivated;
+  // If non-zero, try to detect operations like <, <=, >, >= and - on invalid
+  // pointer pairs (e.g. when pointers belong to different objects).
+  // The bigger the value the harder we try.
+  int detect_invalid_pointer_pairs;
 };
 
 extern Flags asan_flags_dont_use_directly;

Modified: compiler-rt/trunk/lib/asan/asan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.cc?rev=202389&r1=202388&r2=202389&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_report.cc Thu Feb 27 06:45:36 2014
@@ -716,6 +716,34 @@ void ReportBadParamsToAnnotateContiguous
   ReportErrorSummary("bad-__sanitizer_annotate_contiguous_container", stack);
 }
 
+// ----------------------- CheckForInvalidPointerPair ----------- {{{1
+static NOINLINE void
+ReportInvalidPointerPair(uptr pc, uptr bp, uptr sp, uptr a1, uptr a2) {
+  ScopedInErrorReport in_report;
+  Decorator d;
+  Printf("%s", d.Warning());
+  Report("ERROR: AddressSanitizer: invalid-pointer-pair: %p %p\n", a1, a2);
+  Printf("%s", d.EndWarning());
+  GET_STACK_TRACE_FATAL(pc, bp);
+  stack.Print();
+  DescribeAddress(a1, 1);
+  DescribeAddress(a2, 1);
+  ReportErrorSummary("invalid-pointer-pair", &stack);
+}
+
+static INLINE void CheckForInvalidPointerPair(void *p1, void *p2) {
+  if (!flags()->detect_invalid_pointer_pairs) return;
+  uptr a1 = reinterpret_cast<uptr>(p1);
+  uptr a2 = reinterpret_cast<uptr>(p2);
+  AsanChunkView chunk1 = FindHeapChunkByAddress(a1);
+  AsanChunkView chunk2 = FindHeapChunkByAddress(a2);
+  bool valid1 = chunk1.IsValid();
+  bool valid2 = chunk2.IsValid();
+  if ((valid1 != valid2) || (valid1 && valid2 && !chunk1.Eq(chunk2))) {
+    GET_CALLER_PC_BP_SP;                                              \
+    return ReportInvalidPointerPair(pc, bp, sp, a1, a2);
+  }
+}
 // ----------------------- Mac-specific reports ----------------- {{{1
 
 void WarnMacFreeUnallocated(
@@ -844,6 +872,17 @@ void __asan_describe_address(uptr addr)
   DescribeAddress(addr, 1);
 }
 
+extern "C" {
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_ptr_sub(void *a, void *b) {
+  CheckForInvalidPointerPair(a, b);
+}
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_ptr_cmp(void *a, void *b) {
+  CheckForInvalidPointerPair(a, b);
+}
+}  // extern "C"
+
 #if !SANITIZER_SUPPORTS_WEAK_HOOKS
 // Provide default implementation of __asan_on_error that does nothing
 // and may be overriden by user.

Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=202389&r1=202388&r2=202389&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Thu Feb 27 06:45:36 2014
@@ -137,6 +137,8 @@ static void ParseFlagsFromString(Flags *
   ParseFlag(str, &f->strict_memcmp, "strict_memcmp");
   ParseFlag(str, &f->strict_init_order, "strict_init_order");
   ParseFlag(str, &f->start_deactivated, "start_deactivated");
+  ParseFlag(str, &f->detect_invalid_pointer_pairs,
+            "detect_invalid_pointer_pairs");
 }
 
 void InitializeFlags(Flags *f, const char *env) {
@@ -182,6 +184,7 @@ void InitializeFlags(Flags *f, const cha
   f->strict_memcmp = true;
   f->strict_init_order = false;
   f->start_deactivated = false;
+  f->detect_invalid_pointer_pairs = 0;
 
   // Override from compile definition.
   ParseFlagsFromString(f, MaybeUseAsanDefaultOptionsCompileDefiniton());





More information about the llvm-commits mailing list