From 8c4b9ff9215158a0bc341644013b2bcb3ab23c08 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Tue, 9 Feb 2016 23:46:43 +0000 Subject: [PATCH] [asan] update the scariness score: tweak a few weights and add tests llvm-svn: 260327 --- compiler-rt/lib/asan/asan_report.cc | 20 ++++++++++------- .../TestCases/Linux/scariness_score_test.cc | 22 +++++++++++++++---- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/compiler-rt/lib/asan/asan_report.cc b/compiler-rt/lib/asan/asan_report.cc index f912336c21dc..94fe04e26e57 100644 --- a/compiler-rt/lib/asan/asan_report.cc +++ b/compiler-rt/lib/asan/asan_report.cc @@ -748,7 +748,7 @@ void ReportStackOverflow(const SignalContext &sig) { (void *)sig.addr, (void *)sig.pc, (void *)sig.bp, (void *)sig.sp, GetCurrentTidOrInvalid()); Printf("%s", d.EndWarning()); - ScarinessScore::PrintSimple(15, "stack-overflow"); + ScarinessScore::PrintSimple(10, "stack-overflow"); GET_STACK_TRACE_SIGNAL(sig); stack.Print(); ReportErrorSummary("stack-overflow", &stack); @@ -851,7 +851,7 @@ void ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack) { curr_tid, ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname))); Printf("%s", d.EndWarning()); CHECK_GT(free_stack->size, 0); - ScarinessScore::PrintSimple(10, "bad-free"); + ScarinessScore::PrintSimple(40, "bad-free"); GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp); stack.Print(); DescribeHeapAddress(addr, 1); @@ -1054,6 +1054,10 @@ static void PrintContainerOverflowHint() { "AddressSanitizerContainerOverflow.\n"); } +static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) { + return s[-1] > 127 && s[1] > 127; +} + void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write, uptr access_size, u32 exp, bool fatal) { if (!fatal && SuppressErrorReport(pc)) return; @@ -1100,7 +1104,7 @@ void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write, case kAsanArrayCookieMagic: bug_descr = "heap-buffer-overflow"; bug_type_score = 10; - far_from_bounds = shadow_addr[-1] > 127 && shadow_addr[1] > 127; + far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr); break; case kAsanHeapFreeMagic: bug_descr = "heap-use-after-free"; @@ -1109,7 +1113,7 @@ void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write, case kAsanStackLeftRedzoneMagic: bug_descr = "stack-buffer-underflow"; bug_type_score = 25; - far_from_bounds = shadow_addr[-1] > 127 && shadow_addr[1] > 127; + far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr); break; case kAsanInitializationOrderMagic: bug_descr = "initialization-order-fiasco"; @@ -1120,7 +1124,7 @@ void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write, case kAsanStackPartialRedzoneMagic: bug_descr = "stack-buffer-overflow"; bug_type_score = 25; - far_from_bounds = shadow_addr[-1] > 127 && shadow_addr[1] > 127; + far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr); break; case kAsanStackAfterReturnMagic: bug_descr = "stack-use-after-return"; @@ -1128,7 +1132,7 @@ void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write, break; case kAsanUserPoisonedMemoryMagic: bug_descr = "use-after-poison"; - bug_type_score = 10; + bug_type_score = 20; break; case kAsanContiguousContainerOOBMagic: bug_descr = "container-overflow"; @@ -1141,7 +1145,7 @@ void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write, case kAsanGlobalRedzoneMagic: bug_descr = "global-buffer-overflow"; bug_type_score = 10; - far_from_bounds = shadow_addr[-1] > 127 && shadow_addr[1] > 127; + far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr); break; case kAsanIntraObjectRedzone: bug_descr = "intra-object-overflow"; @@ -1151,7 +1155,7 @@ void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write, case kAsanAllocaRightMagic: bug_descr = "dynamic-stack-buffer-overflow"; bug_type_score = 25; - far_from_bounds = shadow_addr[-1] > 127 && shadow_addr[1] > 127; + far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr); break; } SS.Scare(bug_type_score, bug_descr); diff --git a/compiler-rt/test/asan/TestCases/Linux/scariness_score_test.cc b/compiler-rt/test/asan/TestCases/Linux/scariness_score_test.cc index 65906e8db64e..77d58b70d81d 100644 --- a/compiler-rt/test/asan/TestCases/Linux/scariness_score_test.cc +++ b/compiler-rt/test/asan/TestCases/Linux/scariness_score_test.cc @@ -2,6 +2,8 @@ // RUN: %clangxx_asan -O0 %s -o %t // RUN: export %env_asan_opts=detect_stack_use_after_return=1:handle_abort=1:print_scariness=1 +// Make sure the stack is limited (may not be the default under GNU make) +// RUN: ulimit -s 4096 // RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK1 // RUN: not %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK2 // RUN: not %run %t 3 2>&1 | FileCheck %s --check-prefix=CHECK3 @@ -19,8 +21,7 @@ // RUN: not %run %t 15 2>&1 | FileCheck %s --check-prefix=CHECK15 // RUN: not %run %t 16 2>&1 | FileCheck %s --check-prefix=CHECK16 // RUN: not %run %t 17 2>&1 | FileCheck %s --check-prefix=CHECK17 -// Stack overflow may not trigger under GNU make. -// DISABLED: not %run %t 18 2>&1 | FileCheck %s --check-prefix=CHECK18 +// RUN: not %run %t 18 2>&1 | FileCheck %s --check-prefix=CHECK18 // RUN: not %run %t 19 2>&1 | FileCheck %s --check-prefix=CHECK19 // RUN: not %run %t 20 2>&1 | FileCheck %s --check-prefix=CHECK20 // RUN: not %run %t 21 2>&1 | FileCheck %s --check-prefix=CHECK21 @@ -29,12 +30,16 @@ // RUN: not %run %t 24 2>&1 | FileCheck %s --check-prefix=CHECK24 // RUN: not %run %t 25 2>&1 | FileCheck %s --check-prefix=CHECK25 // RUN: not %run %t 26 2>&1 | FileCheck %s --check-prefix=CHECK26 +// RUN: not %run %t 27 2>&1 | FileCheck %s --check-prefix=CHECK27 // Parts of the test are too platform-specific: // REQUIRES: x86_64-supported-target +// REQUIRES: shell #include #include #include +#include + enum ReadOrWrite { Read = 0, Write = 1 }; struct S32 { @@ -114,6 +119,13 @@ void StackOverflow(int Idx) { StackOverflow(Idx - 1); } +void UseAfterPoison() { + int buf[100]; + __asan_poison_memory_region(buf, sizeof(buf)); + static volatile int sink; + sink = buf[42]; +} + int main(int argc, char **argv) { char arr[100]; static volatile int zero = 0; @@ -148,6 +160,7 @@ int main(int argc, char **argv) { case 24: delete (new int[10]); break; case 25: free((char*)malloc(100) + 10); break; case 26: memcpy(arr, arr+10, 20); break; + case 27: UseAfterPoison(); break; // CHECK1: SCARINESS: 12 (1-byte-read-heap-buffer-overflow) // CHECK2: SCARINESS: 17 (4-byte-read-heap-buffer-overflow) // CHECK3: SCARINESS: 33 (2-byte-write-heap-buffer-overflow) @@ -165,14 +178,15 @@ int main(int argc, char **argv) { // CHECK15: SCARINESS: 31 (1-byte-write-global-buffer-overflow) // CHECK16: SCARINESS: 36 (multi-byte-read-global-buffer-overflow-far-from-bounds) // CHECK17: SCARINESS: 42 (double-free) - // CHECK18: SCARINESS: 15 (stack-overflow) + // CHECK18: SCARINESS: 10 (stack-overflow) // CHECK19: SCARINESS: 10 (null-deref) // CHECK20: SCARINESS: 30 (wild-addr-write) // CHECK21: SCARINESS: 20 (wild-addr-read) // CHECK22: SCARINESS: 10 (signal) // CHECK23: SCARINESS: 60 (wild-jump) // CHECK24: SCARINESS: 10 (alloc-dealloc-mismatch) - // CHECK25: SCARINESS: 10 (bad-free) + // CHECK25: SCARINESS: 40 (bad-free) // CHECK26: SCARINESS: 10 (memcpy-param-overlap) + // CHECK27: SCARINESS: 27 (4-byte-read-use-after-poison) } }