From 522c35eb80f826be430b1b41f07762e31e519cca Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Mon, 4 Aug 2014 12:43:13 +0000 Subject: [PATCH] [asan] introduce __asan_poison_cxx_array_cookie. This is asan-rt part of PR19838 (Left OOB accesses on new[]-allocated arrays with array cookies are not detected). No tests yet. They will follow once I commit the clang part. llvm-svn: 214711 --- compiler-rt/lib/asan/asan_flags.h | 1 + compiler-rt/lib/asan/asan_interface_internal.h | 3 +++ compiler-rt/lib/asan/asan_internal.h | 1 + compiler-rt/lib/asan/asan_poisoning.cc | 7 +++++++ compiler-rt/lib/asan/asan_report.cc | 4 ++++ compiler-rt/lib/asan/asan_rtl.cc | 4 ++++ 6 files changed, 20 insertions(+) diff --git a/compiler-rt/lib/asan/asan_flags.h b/compiler-rt/lib/asan/asan_flags.h index d8cbbae1feea..803b19ff7071 100644 --- a/compiler-rt/lib/asan/asan_flags.h +++ b/compiler-rt/lib/asan/asan_flags.h @@ -57,6 +57,7 @@ struct Flags { bool print_full_thread_history; bool poison_heap; bool poison_partial; + bool poison_array_cookie; bool alloc_dealloc_mismatch; bool new_delete_type_mismatch; bool strict_memcmp; diff --git a/compiler-rt/lib/asan/asan_interface_internal.h b/compiler-rt/lib/asan/asan_interface_internal.h index 7985236d6b00..e7639e107144 100644 --- a/compiler-rt/lib/asan/asan_interface_internal.h +++ b/compiler-rt/lib/asan/asan_interface_internal.h @@ -162,6 +162,9 @@ extern "C" { void* __asan_memset(void *s, int c, uptr n); SANITIZER_INTERFACE_ATTRIBUTE void* __asan_memmove(void* dest, const void* src, uptr n); + + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_poison_cxx_array_cookie(uptr p); } // extern "C" #endif // ASAN_INTERFACE_INTERNAL_H diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h index 38eb6a3f4325..1c18bd865139 100644 --- a/compiler-rt/lib/asan/asan_internal.h +++ b/compiler-rt/lib/asan/asan_internal.h @@ -136,6 +136,7 @@ const int kAsanContiguousContainerOOBMagic = 0xfc; const int kAsanStackUseAfterScopeMagic = 0xf8; const int kAsanGlobalRedzoneMagic = 0xf9; const int kAsanInternalHeapMagic = 0xfe; +const int kAsanArrayCookieMagic = 0xac; static const uptr kCurrentStackFrameMagic = 0x41B58AB3; static const uptr kRetiredStackFrameMagic = 0x45E0360E; diff --git a/compiler-rt/lib/asan/asan_poisoning.cc b/compiler-rt/lib/asan/asan_poisoning.cc index b356e4073e46..6f2c2f7bcf6a 100644 --- a/compiler-rt/lib/asan/asan_poisoning.cc +++ b/compiler-rt/lib/asan/asan_poisoning.cc @@ -227,6 +227,13 @@ void __sanitizer_unaligned_store64(uu64 *p, u64 x) { *p = x; } +extern "C" SANITIZER_INTERFACE_ATTRIBUTE +void __asan_poison_cxx_array_cookie(uptr p) { + if (!flags()->poison_array_cookie) return; + uptr s = MEM_TO_SHADOW(p); + *reinterpret_cast(s) = 0xac; +} + // This is a simplified version of __asan_(un)poison_memory_region, which // assumes that left border of region to be poisoned is properly aligned. static void PoisonAlignedStackMemory(uptr addr, uptr size, bool do_poison) { diff --git a/compiler-rt/lib/asan/asan_report.cc b/compiler-rt/lib/asan/asan_report.cc index 56a648023459..2719c33f3704 100644 --- a/compiler-rt/lib/asan/asan_report.cc +++ b/compiler-rt/lib/asan/asan_report.cc @@ -59,6 +59,7 @@ class Decorator: public __sanitizer::SanitizerCommonDecorator { switch (byte) { case kAsanHeapLeftRedzoneMagic: case kAsanHeapRightRedzoneMagic: + case kAsanArrayCookieMagic: return Red(); case kAsanHeapFreeMagic: return Magenta(); @@ -143,6 +144,8 @@ static void PrintLegend(InternalScopedString *str) { kAsanUserPoisonedMemoryMagic); PrintShadowByte(str, " Container overflow: ", kAsanContiguousContainerOOBMagic); + PrintShadowByte(str, " Array cookie: ", + kAsanArrayCookieMagic); PrintShadowByte(str, " ASan internal: ", kAsanInternalHeapMagic); } @@ -905,6 +908,7 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write, switch (*shadow_addr) { case kAsanHeapLeftRedzoneMagic: case kAsanHeapRightRedzoneMagic: + case kAsanArrayCookieMagic: bug_descr = "heap-buffer-overflow"; break; case kAsanHeapFreeMagic: diff --git a/compiler-rt/lib/asan/asan_rtl.cc b/compiler-rt/lib/asan/asan_rtl.cc index e0f61e9df265..9a268f41d252 100644 --- a/compiler-rt/lib/asan/asan_rtl.cc +++ b/compiler-rt/lib/asan/asan_rtl.cc @@ -191,6 +191,9 @@ static void ParseFlagsFromString(Flags *f, const char *str) { "Poison (or not) the heap memory on [de]allocation. Zero value is useful " "for benchmarking the allocator or instrumentator."); + ParseFlag(str, &f->poison_array_cookie, "poison_array_cookie", + "Poison (or not) the array cookie after operator new[]."); + ParseFlag(str, &f->poison_partial, "poison_partial", "If true, poison partially addressable 8-byte aligned words " "(default=true). This flag affects heap and global buffers, but not " @@ -272,6 +275,7 @@ void InitializeFlags(Flags *f, const char *env) { f->allow_reexec = true; f->print_full_thread_history = true; f->poison_heap = true; + f->poison_array_cookie = true; f->poison_partial = true; // Turn off alloc/dealloc mismatch checker on Mac and Windows for now. // https://code.google.com/p/address-sanitizer/issues/detail?id=131