[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