From 7b664299f08243e1cfb44e834c5b8e748b07cf52 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Tue, 19 Nov 2013 08:40:07 +0000 Subject: [asan] new shadow poison magic for contiguous-container-buffer-overflow, addressed Alexey Samsonov's comments for r195011 llvm-svn: 195117 --- .../include/sanitizer/common_interface_defs.h | 6 ++-- compiler-rt/lib/asan/asan_internal.h | 1 + compiler-rt/lib/asan/asan_poisoning.cc | 33 ++++++++++++---------- compiler-rt/lib/asan/asan_report.cc | 32 ++++++++++++--------- .../TestCases/contiguous_container_crash.cc | 16 +++++++++++ .../lib/sanitizer_common/sanitizer_internal_defs.h | 6 ++-- 6 files changed, 62 insertions(+), 32 deletions(-) create mode 100644 compiler-rt/lib/asan/lit_tests/TestCases/contiguous_container_crash.cc (limited to 'compiler-rt') diff --git a/compiler-rt/include/sanitizer/common_interface_defs.h b/compiler-rt/include/sanitizer/common_interface_defs.h index 4cc2aeae23c..ce6b994a9dd 100644 --- a/compiler-rt/include/sanitizer/common_interface_defs.h +++ b/compiler-rt/include/sanitizer/common_interface_defs.h @@ -71,8 +71,10 @@ extern "C" { // Use with caution and don't use for anything other than vector-like classes. // // For AddressSanitizer, 'beg' should be 8-aligned. - void __sanitizer_annotate_contiguous_container(void *beg, void *end, - void *old_mid, void *new_mid); + void __sanitizer_annotate_contiguous_container(const void *beg, + const void *end, + const void *old_mid, + const void *new_mid); #ifdef __cplusplus } // extern "C" diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h index 70e55ea0afe..4f8f8e83c77 100644 --- a/compiler-rt/lib/asan/asan_internal.h +++ b/compiler-rt/lib/asan/asan_internal.h @@ -136,6 +136,7 @@ const int kAsanStackPartialRedzoneMagic = 0xf4; const int kAsanStackAfterReturnMagic = 0xf5; const int kAsanInitializationOrderMagic = 0xf6; const int kAsanUserPoisonedMemoryMagic = 0xf7; +const int kAsanContiguousContainerOOBMagic = 0xfc; const int kAsanStackUseAfterScopeMagic = 0xf8; const int kAsanGlobalRedzoneMagic = 0xf9; const int kAsanInternalHeapMagic = 0xfe; diff --git a/compiler-rt/lib/asan/asan_poisoning.cc b/compiler-rt/lib/asan/asan_poisoning.cc index 280aaeb909a..9887fe19349 100644 --- a/compiler-rt/lib/asan/asan_poisoning.cc +++ b/compiler-rt/lib/asan/asan_poisoning.cc @@ -256,44 +256,47 @@ void __asan_unpoison_stack_memory(uptr addr, uptr size) { PoisonAlignedStackMemory(addr, size, false); } -void __sanitizer_annotate_contiguous_container(void *beg_p, void *end_p, - void *old_mid_p, - void *new_mid_p) { +void __sanitizer_annotate_contiguous_container(const void *beg_p, + const void *end_p, + const void *old_mid_p, + const void *new_mid_p) { + if (common_flags()->verbosity >= 2) + Printf("contiguous_container: %p %p %p %p\n", beg_p, end_p, old_mid_p, + new_mid_p); uptr beg = reinterpret_cast(beg_p); uptr end= reinterpret_cast(end_p); uptr old_mid = reinterpret_cast(old_mid_p); uptr new_mid = reinterpret_cast(new_mid_p); uptr granularity = SHADOW_GRANULARITY; - CHECK(beg <= end && beg <= old_mid && beg <= new_mid && old_mid <= end && - new_mid <= end && IsAligned(beg, granularity)); + CHECK(beg <= old_mid && beg <= new_mid && old_mid <= end && new_mid <= end && + IsAligned(beg, granularity)); CHECK_LE(end - beg, FIRST_32_SECOND_64(1UL << 30, 1UL << 34)); // Sanity check. uptr a = RoundDownTo(Min(old_mid, new_mid), granularity); uptr c = RoundUpTo(Max(old_mid, new_mid), granularity); - uptr b = new_mid; - uptr b1 = RoundDownTo(b, granularity); - uptr b2 = RoundUpTo(b, granularity); - uptr d = old_mid; - uptr d1 = RoundDownTo(d, granularity); - uptr d2 = RoundUpTo(d, granularity); + uptr d1 = RoundDownTo(old_mid, granularity); + uptr d2 = RoundUpTo(old_mid, granularity); // Currently we should be in this state: // [a, d1) is good, [d2, c) is bad, [d1, d2) is partially good. // Make a quick sanity check that we are indeed in this state. if (d1 != d2) - CHECK_EQ(*(u8*)MemToShadow(d1), d - d1); + CHECK_EQ(*(u8*)MemToShadow(d1), old_mid - d1); if (a + granularity <= d1) CHECK_EQ(*(u8*)MemToShadow(a), 0); if (d2 + granularity <= c && c <= end) - CHECK_EQ(*(u8 *)MemToShadow(c - granularity), kAsanUserPoisonedMemoryMagic); + CHECK_EQ(*(u8 *)MemToShadow(c - granularity), + kAsanContiguousContainerOOBMagic); + uptr b1 = RoundDownTo(new_mid, granularity); + uptr b2 = RoundUpTo(new_mid, granularity); // New state: // [a, b1) is good, [b2, c) is bad, [b1, b2) is partially good. // FIXME: we may want to have a separate poison magic value. PoisonShadow(a, b1 - a, 0); - PoisonShadow(b2, c - b2, kAsanUserPoisonedMemoryMagic); + PoisonShadow(b2, c - b2, kAsanContiguousContainerOOBMagic); if (b1 != b2) { CHECK_EQ(b2 - b1, granularity); - *(u8*)MemToShadow(b1) = static_cast(b - b1); + *(u8*)MemToShadow(b1) = static_cast(new_mid - b1); } } diff --git a/compiler-rt/lib/asan/asan_report.cc b/compiler-rt/lib/asan/asan_report.cc index ed4e433c7a5..cff94e2d140 100644 --- a/compiler-rt/lib/asan/asan_report.cc +++ b/compiler-rt/lib/asan/asan_report.cc @@ -74,6 +74,7 @@ class Decorator: private __sanitizer::AnsiColorDecorator { case kAsanInitializationOrderMagic: return Cyan(); case kAsanUserPoisonedMemoryMagic: + case kAsanContiguousContainerOOBMagic: return Blue(); case kAsanStackUseAfterScopeMagic: return Magenta(); @@ -120,19 +121,21 @@ static void PrintLegend() { for (u8 i = 1; i < SHADOW_GRANULARITY; i++) PrintShadowByte("", i, " "); Printf("\n"); - PrintShadowByte(" Heap left redzone: ", kAsanHeapLeftRedzoneMagic); - PrintShadowByte(" Heap right redzone: ", kAsanHeapRightRedzoneMagic); - PrintShadowByte(" Freed heap region: ", kAsanHeapFreeMagic); - PrintShadowByte(" Stack left redzone: ", kAsanStackLeftRedzoneMagic); - PrintShadowByte(" Stack mid redzone: ", kAsanStackMidRedzoneMagic); - PrintShadowByte(" Stack right redzone: ", kAsanStackRightRedzoneMagic); - PrintShadowByte(" Stack partial redzone: ", kAsanStackPartialRedzoneMagic); - PrintShadowByte(" Stack after return: ", kAsanStackAfterReturnMagic); - PrintShadowByte(" Stack use after scope: ", kAsanStackUseAfterScopeMagic); - PrintShadowByte(" Global redzone: ", kAsanGlobalRedzoneMagic); - PrintShadowByte(" Global init order: ", kAsanInitializationOrderMagic); - PrintShadowByte(" Poisoned by user: ", kAsanUserPoisonedMemoryMagic); - PrintShadowByte(" ASan internal: ", kAsanInternalHeapMagic); + PrintShadowByte(" Heap left redzone: ", kAsanHeapLeftRedzoneMagic); + PrintShadowByte(" Heap right redzone: ", kAsanHeapRightRedzoneMagic); + PrintShadowByte(" Freed heap region: ", kAsanHeapFreeMagic); + PrintShadowByte(" Stack left redzone: ", kAsanStackLeftRedzoneMagic); + PrintShadowByte(" Stack mid redzone: ", kAsanStackMidRedzoneMagic); + PrintShadowByte(" Stack right redzone: ", kAsanStackRightRedzoneMagic); + PrintShadowByte(" Stack partial redzone: ", kAsanStackPartialRedzoneMagic); + PrintShadowByte(" Stack after return: ", kAsanStackAfterReturnMagic); + PrintShadowByte(" Stack use after scope: ", kAsanStackUseAfterScopeMagic); + PrintShadowByte(" Global redzone: ", kAsanGlobalRedzoneMagic); + PrintShadowByte(" Global init order: ", kAsanInitializationOrderMagic); + PrintShadowByte(" Poisoned by user: ", kAsanUserPoisonedMemoryMagic); + PrintShadowByte(" Contiguous container OOB:", + kAsanContiguousContainerOOBMagic); + PrintShadowByte(" ASan internal: ", kAsanInternalHeapMagic); } static void PrintShadowMemoryForAddress(uptr addr) { @@ -745,6 +748,9 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp, case kAsanUserPoisonedMemoryMagic: bug_descr = "use-after-poison"; break; + case kAsanContiguousContainerOOBMagic: + bug_descr = "contiguous-container-buffer-overflow"; + break; case kAsanStackUseAfterScopeMagic: bug_descr = "stack-use-after-scope"; break; diff --git a/compiler-rt/lib/asan/lit_tests/TestCases/contiguous_container_crash.cc b/compiler-rt/lib/asan/lit_tests/TestCases/contiguous_container_crash.cc new file mode 100644 index 00000000000..92cf54b1b70 --- /dev/null +++ b/compiler-rt/lib/asan/lit_tests/TestCases/contiguous_container_crash.cc @@ -0,0 +1,16 @@ +// RUN: %clangxx_asan -O %s -o %t && not %t 2>&1 | FileCheck %s +// Test crash due to __sanitizer_annotate_contiguous_container. + +extern "C" { +void __sanitizer_annotate_contiguous_container(const void *beg, const void *end, + const void *old_mid, + const void *new_mid); +} // extern "C" + +int main(int argc, char **argv) { + long t[100]; + __sanitizer_annotate_contiguous_container(&t[0], &t[0] + 100, &t[0] + 100, + &t[0] + 50); + return t[60 * argc]; // Touches the poisoned memory. +} +// CHECK: AddressSanitizer: contiguous-container-buffer-overflow diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h index daa724be06f..765c328d660 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h @@ -114,8 +114,10 @@ extern "C" { SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump(); SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov(void *pc); SANITIZER_INTERFACE_ATTRIBUTE - void __sanitizer_annotate_contiguous_container(void *beg, void *end, - void *old_mid, void *new_mid); + void __sanitizer_annotate_contiguous_container(const void *beg, + const void *end, + const void *old_mid, + const void *new_mid); } // extern "C" -- cgit v1.2.1