[compiler-rt] r192581 - [ASan] Don't die with internal ASan error on large buffer overflows

Alexey Samsonov samsonov at google.com
Mon Oct 14 04:13:55 PDT 2013


Author: samsonov
Date: Mon Oct 14 06:13:54 2013
New Revision: 192581

URL: http://llvm.org/viewvc/llvm-project?rev=192581&view=rev
Log:
[ASan] Don't die with internal ASan error on large buffer overflows

Summary:
Out-of-bound access may touch not-yet allocated or already freed
and recycled from quarantine chunks. We should treat this situation as
a "free-range memory access" and avoid printing any data about that
irrelevant chunk (which may be inconsistent).

This should fix https://code.google.com/p/address-sanitizer/issues/detail?id=183

Reviewers: kcc

Reviewed By: kcc

CC: timurrrr, llvm-commits

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

Added:
    compiler-rt/trunk/lib/asan/lit_tests/TestCases/heap-overflow-large.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_allocator.h
    compiler-rt/trunk/lib/asan/asan_allocator2.cc
    compiler-rt/trunk/lib/asan/asan_report.cc
    compiler-rt/trunk/lib/asan/lit_tests/TestCases/null_deref.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=192581&r1=192580&r2=192581&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator.h (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator.h Mon Oct 14 06:13:54 2013
@@ -35,10 +35,11 @@ void InitializeAllocator();
 class AsanChunkView {
  public:
   explicit AsanChunkView(AsanChunk *chunk) : chunk_(chunk) {}
-  bool IsValid() { return chunk_ != 0; }
-  uptr Beg();       // first byte of user memory.
-  uptr End();       // last byte of user memory.
-  uptr UsedSize();  // size requested by the user.
+  bool IsValid();   // Checks if AsanChunkView points to a valid allocated
+                    // or quarantined chunk.
+  uptr Beg();       // First byte of user memory.
+  uptr End();       // Last byte of user memory.
+  uptr UsedSize();  // Size requested by the user.
   uptr AllocTid();
   uptr FreeTid();
   void GetAllocStack(StackTrace *stack);

Modified: compiler-rt/trunk/lib/asan/asan_allocator2.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator2.cc?rev=192581&r1=192580&r2=192581&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator2.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator2.cc Mon Oct 14 06:13:54 2013
@@ -218,6 +218,9 @@ struct AsanChunk: ChunkBase {
   }
 };
 
+bool AsanChunkView::IsValid() {
+  return chunk_ != 0 && chunk_->chunk_state != CHUNK_AVAILABLE;
+}
 uptr AsanChunkView::Beg() { return chunk_->Beg(); }
 uptr AsanChunkView::End() { return Beg() + UsedSize(); }
 uptr AsanChunkView::UsedSize() { return chunk_->UsedSize(); }
@@ -228,9 +231,8 @@ static void GetStackTraceFromId(u32 id,
   CHECK(id);
   uptr size = 0;
   const uptr *trace = StackDepotGet(id, &size);
-  CHECK_LT(size, kStackTraceMax);
-  internal_memcpy(stack->trace, trace, sizeof(uptr) * size);
-  stack->size = size;
+  CHECK(trace);
+  stack->CopyFrom(trace, size);
 }
 
 void AsanChunkView::GetAllocStack(StackTrace *stack) {

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=192581&r1=192580&r2=192581&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_report.cc Mon Oct 14 06:13:54 2013
@@ -414,7 +414,11 @@ static void DescribeAccessToHeapChunk(As
 
 void DescribeHeapAddress(uptr addr, uptr access_size) {
   AsanChunkView chunk = FindHeapChunkByAddress(addr);
-  if (!chunk.IsValid()) return;
+  if (!chunk.IsValid()) {
+    Printf("AddressSanitizer can not describe address in more detail "
+           "(wild memory access suspected).\n");
+    return;
+  }
   DescribeAccessToHeapChunk(chunk, addr, access_size);
   CHECK(chunk.AllocTid() != kInvalidTid);
   asanThreadRegistry().CheckLocked();
@@ -564,9 +568,9 @@ void ReportSIGSEGV(uptr pc, uptr sp, upt
              (void*)addr, (void*)pc, (void*)sp, (void*)bp,
              GetCurrentTidOrInvalid());
   Printf("%s", d.EndWarning());
-  Printf("AddressSanitizer can not provide additional info.\n");
   GET_STACK_TRACE_FATAL(pc, bp);
   PrintStack(&stack);
+  Printf("AddressSanitizer can not provide additional info.\n");
   ReportSummary("SEGV", &stack);
 }
 

Added: compiler-rt/trunk/lib/asan/lit_tests/TestCases/heap-overflow-large.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/TestCases/heap-overflow-large.cc?rev=192581&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/lit_tests/TestCases/heap-overflow-large.cc (added)
+++ compiler-rt/trunk/lib/asan/lit_tests/TestCases/heap-overflow-large.cc Mon Oct 14 06:13:54 2013
@@ -0,0 +1,23 @@
+// Regression test for
+// https://code.google.com/p/address-sanitizer/issues/detail?id=183
+
+// RUN: %clangxx_asan -O2 %s -o %t
+// RUN: not %t 12 2>&1 | FileCheck %s
+// RUN: not %t 100 2>&1 | FileCheck %s
+// RUN: not %t 10000 2>&1 | FileCheck %s
+
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char *argv[]) {
+  int *x = new int[5];
+  memset(x, 0, sizeof(x[0]) * 5);
+  int index = atoi(argv[1]);
+  int res = x[index];
+  // CHECK: AddressSanitizer: {{(heap-buffer-overflow|SEGV)}}
+  // CHECK: #0 0x{{.*}} in main {{.*}}heap-overflow-large.cc:[[@LINE-2]]
+  // CHECK: AddressSanitizer can not {{(provide additional info|describe address in more detail \(wild memory access suspected\))}}
+  // CHECK: SUMMARY: AddressSanitizer: {{(heap-buffer-overflow|SEGV)}}
+  delete[] x;
+  return res;
+}

Modified: compiler-rt/trunk/lib/asan/lit_tests/TestCases/null_deref.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/TestCases/null_deref.cc?rev=192581&r1=192580&r2=192581&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/lit_tests/TestCases/null_deref.cc (original)
+++ compiler-rt/trunk/lib/asan/lit_tests/TestCases/null_deref.cc Mon Oct 14 06:13:54 2013
@@ -11,7 +11,6 @@ __attribute__((noinline))
 static void NullDeref(int *ptr) {
   // CHECK: ERROR: AddressSanitizer: SEGV on unknown address
   // CHECK:   {{0x0*00028 .*pc 0x.*}}
-  // CHECK: {{AddressSanitizer can not provide additional info.}}
   ptr[10]++;  // BOOM
   // atos on Mac cannot extract the symbol name correctly.
   // CHECK-Linux: {{    #0 0x.* in NullDeref.*null_deref.cc:}}[[@LINE-2]]
@@ -20,4 +19,5 @@ static void NullDeref(int *ptr) {
 int main() {
   NullDeref((int*)0);
   // CHECK: {{    #1 0x.* in main.*null_deref.cc:}}[[@LINE-1]]
+  // CHECK: {{AddressSanitizer can not provide additional info.}}
 }





More information about the llvm-commits mailing list