[compiler-rt] r201565 - [asan] Stack overflow detection.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Tue Feb 18 03:49:52 PST 2014


Author: eugenis
Date: Tue Feb 18 05:49:52 2014
New Revision: 201565

URL: http://llvm.org/viewvc/llvm-project?rev=201565&view=rev
Log:
[asan] Stack overflow detection.

Report segmentation faults near or below stack bottom as stack-overflow
(not stack-buffer-overflow!).

Added:
    compiler-rt/trunk/test/asan/TestCases/stack-buffer-overflow.cc
      - copied, changed from r201512, compiler-rt/trunk/test/asan/TestCases/stack-overflow.cc
    compiler-rt/trunk/test/asan/TestCases/stack-overflow.cc   (with props)
Modified:
    compiler-rt/trunk/lib/asan/asan_report.cc

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=201565&r1=201564&r2=201565&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_report.cc Tue Feb 18 05:49:52 2014
@@ -568,19 +568,42 @@ class ScopedInErrorReport {
   }
 };
 
+static bool IsStackOverflow(uptr addr, uptr sp) {
+  uptr stack_frame_bottom = sp;
+#ifdef __x86_64__
+  stack_frame_bottom -= 128; // x86_64 stack redzone
+#else
+  // call stores return value 1 word below SP.
+  stack_frame_bottom -= sizeof(uptr);
+#endif
+  // Access below sp (+ redzone on x86_64) is probably something else (like
+  // stack of another thread).
+  if (addr < stack_frame_bottom)
+    return false;
+
+  AsanThread *t = GetCurrentThread();
+  // Anything below stack_bottom, but not too far away is a stack overflow.
+  // Bottom 4k may be a guard page. Treat it as stack-overflow as well.
+  return addr < t->stack_bottom() + GetPageSizeCached() &&
+         addr > t->stack_bottom() - 0xFFFF;
+}
+
 void ReportSIGSEGV(uptr pc, uptr sp, uptr bp, void *context, uptr addr) {
   ScopedInErrorReport in_report;
   Decorator d;
   Printf("%s", d.Warning());
-  Report("ERROR: AddressSanitizer: SEGV on unknown address %p"
-             " (pc %p sp %p bp %p T%d)\n",
-             (void*)addr, (void*)pc, (void*)sp, (void*)bp,
-             GetCurrentTidOrInvalid());
+  bool stack_overflow = IsStackOverflow(addr, sp);
+  Report(
+      "ERROR: AddressSanitizer: %s %p"
+      " (pc %p sp %p bp %p T%d)\n",
+      stack_overflow ? "stack-overflow on address" : "SEGV on unknown address",
+      (void *)addr, (void *)pc, (void *)sp, (void *)bp,
+      GetCurrentTidOrInvalid());
   Printf("%s", d.EndWarning());
   GET_STACK_TRACE_SIGNAL(pc, bp, context);
   stack.Print();
   Printf("AddressSanitizer can not provide additional info.\n");
-  ReportErrorSummary("SEGV", &stack);
+  ReportErrorSummary(stack_overflow ? "stack-overflow" : "SEGV", &stack);
 }
 
 void ReportDoubleFree(uptr addr, StackTrace *free_stack) {

Copied: compiler-rt/trunk/test/asan/TestCases/stack-buffer-overflow.cc (from r201512, compiler-rt/trunk/test/asan/TestCases/stack-overflow.cc)
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/stack-buffer-overflow.cc?p2=compiler-rt/trunk/test/asan/TestCases/stack-buffer-overflow.cc&p1=compiler-rt/trunk/test/asan/TestCases/stack-overflow.cc&r1=201512&r2=201565&rev=201565&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/stack-overflow.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/stack-buffer-overflow.cc Tue Feb 18 05:49:52 2014
@@ -9,8 +9,8 @@ int main(int argc, char **argv) {
   memset(x, 0, 10);
   int res = x[argc * 10];  // BOOOM
   // CHECK: {{READ of size 1 at 0x.* thread T0}}
-  // CHECK: {{    #0 0x.* in main .*stack-overflow.cc:}}[[@LINE-2]]
+  // CHECK: {{    #0 0x.* in main .*stack-buffer-overflow.cc:}}[[@LINE-2]]
   // CHECK: {{Address 0x.* is located in stack of thread T0 at offset}}
-  // CHECK-NEXT: in{{.*}}main{{.*}}stack-overflow.cc
+  // CHECK-NEXT: in{{.*}}main{{.*}}stack-buffer-overflow.cc
   return res;
 }

Added: compiler-rt/trunk/test/asan/TestCases/stack-overflow.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/stack-overflow.cc?rev=201565&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/stack-overflow.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/stack-overflow.cc Tue Feb 18 05:49:52 2014
@@ -0,0 +1,47 @@
+// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS=use_sigaltstack=1 not %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O1 %s -o %t && ASAN_OPTIONS=use_sigaltstack=1 not %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O2 %s -o %t && ASAN_OPTIONS=use_sigaltstack=1 not %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 %s -o %t && ASAN_OPTIONS=use_sigaltstack=1 not %t 2>&1 | FileCheck %s
+
+// RUN: %clangxx_asan -O0 %s -DTHREAD -o %t && ASAN_OPTIONS=use_sigaltstack=1 not %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O1 %s -DTHREAD -o %t && ASAN_OPTIONS=use_sigaltstack=1 not %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O2 %s -DTHREAD -o %t && ASAN_OPTIONS=use_sigaltstack=1 not %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 %s -DTHREAD -o %t && ASAN_OPTIONS=use_sigaltstack=1 not %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+const int BS = 1024;
+volatile char x;
+
+void large_frame_func(char *p, int level) {
+  char buf[BS];
+  if (p)
+    assert(p - buf >= BS);
+  buf[rand() % BS] = 1;
+  buf[rand() % BS] = 2;
+  x = buf[rand() % BS];
+  volatile int y = 1;
+  if (y)
+    large_frame_func(buf, level + 1);
+  // CHECK: {{stack-overflow on address 0x.* \(pc 0x.* sp 0x.* bp 0x.* T.*\)}}
+  // Frame 0 may be anywhere (in rand(), for example).
+  // CHECK: {{    #1 0x.* in large_frame_func.*stack-overflow.cc:}}[[@LINE-3]]
+}
+
+void *ThreadFn(void* unused) {
+  large_frame_func(0, 0);
+  return 0;
+}
+
+int main(int argc, char **argv) {
+#ifdef THREAD
+  pthread_t t;
+  pthread_create(&t, 0, ThreadFn, 0);
+  pthread_join(t, 0);
+#else
+  large_frame_func(0, 0);
+#endif
+  return 0;
+}

Propchange: compiler-rt/trunk/test/asan/TestCases/stack-overflow.cc
------------------------------------------------------------------------------
    svn:eol-style = LF





More information about the llvm-commits mailing list