diff options
Diffstat (limited to 'lib/asan/asan_poisoning.cc')
-rw-r--r-- | lib/asan/asan_poisoning.cc | 63 |
1 files changed, 53 insertions, 10 deletions
diff --git a/lib/asan/asan_poisoning.cc b/lib/asan/asan_poisoning.cc index 772b5e64b0277..280aaeb909a36 100644 --- a/lib/asan/asan_poisoning.cc +++ b/lib/asan/asan_poisoning.cc @@ -14,6 +14,7 @@ #include "asan_poisoning.h" #include "sanitizer_common/sanitizer_libc.h" +#include "sanitizer_common/sanitizer_flags.h" namespace __asan { @@ -68,7 +69,7 @@ void __asan_poison_memory_region(void const volatile *addr, uptr size) { if (!flags()->allow_user_poisoning || size == 0) return; uptr beg_addr = (uptr)addr; uptr end_addr = beg_addr + size; - if (flags()->verbosity >= 1) { + if (common_flags()->verbosity >= 1) { Printf("Trying to poison memory region [%p, %p)\n", (void*)beg_addr, (void*)end_addr); } @@ -110,7 +111,7 @@ void __asan_unpoison_memory_region(void const volatile *addr, uptr size) { if (!flags()->allow_user_poisoning || size == 0) return; uptr beg_addr = (uptr)addr; uptr end_addr = beg_addr + size; - if (flags()->verbosity >= 1) { + if (common_flags()->verbosity >= 1) { Printf("Trying to unpoison memory region [%p, %p)\n", (void*)beg_addr, (void*)end_addr); } @@ -183,37 +184,37 @@ uptr __asan_region_is_poisoned(uptr beg, uptr size) { extern "C" SANITIZER_INTERFACE_ATTRIBUTE -u16 __sanitizer_unaligned_load16(const u16 *p) { +u16 __sanitizer_unaligned_load16(const uu16 *p) { CHECK_SMALL_REGION(p, sizeof(*p), false); return *p; } extern "C" SANITIZER_INTERFACE_ATTRIBUTE -u32 __sanitizer_unaligned_load32(const u32 *p) { +u32 __sanitizer_unaligned_load32(const uu32 *p) { CHECK_SMALL_REGION(p, sizeof(*p), false); return *p; } extern "C" SANITIZER_INTERFACE_ATTRIBUTE -u64 __sanitizer_unaligned_load64(const u64 *p) { +u64 __sanitizer_unaligned_load64(const uu64 *p) { CHECK_SMALL_REGION(p, sizeof(*p), false); return *p; } extern "C" SANITIZER_INTERFACE_ATTRIBUTE -void __sanitizer_unaligned_store16(u16 *p, u16 x) { +void __sanitizer_unaligned_store16(uu16 *p, u16 x) { CHECK_SMALL_REGION(p, sizeof(*p), true); *p = x; } extern "C" SANITIZER_INTERFACE_ATTRIBUTE -void __sanitizer_unaligned_store32(u32 *p, u32 x) { +void __sanitizer_unaligned_store32(uu32 *p, u32 x) { CHECK_SMALL_REGION(p, sizeof(*p), true); *p = x; } extern "C" SANITIZER_INTERFACE_ATTRIBUTE -void __sanitizer_unaligned_store64(u64 *p, u64 x) { +void __sanitizer_unaligned_store64(uu64 *p, u64 x) { CHECK_SMALL_REGION(p, sizeof(*p), true); *p = x; } @@ -244,13 +245,55 @@ static void PoisonAlignedStackMemory(uptr addr, uptr size, bool do_poison) { } void __asan_poison_stack_memory(uptr addr, uptr size) { - if (flags()->verbosity > 0) + if (common_flags()->verbosity > 0) Report("poisoning: %p %zx\n", (void*)addr, size); PoisonAlignedStackMemory(addr, size, true); } void __asan_unpoison_stack_memory(uptr addr, uptr size) { - if (flags()->verbosity > 0) + if (common_flags()->verbosity > 0) Report("unpoisoning: %p %zx\n", (void*)addr, size); PoisonAlignedStackMemory(addr, size, false); } + +void __sanitizer_annotate_contiguous_container(void *beg_p, void *end_p, + void *old_mid_p, + void *new_mid_p) { + uptr beg = reinterpret_cast<uptr>(beg_p); + uptr end= reinterpret_cast<uptr>(end_p); + uptr old_mid = reinterpret_cast<uptr>(old_mid_p); + uptr new_mid = reinterpret_cast<uptr>(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_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); + // 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); + if (a + granularity <= d1) + CHECK_EQ(*(u8*)MemToShadow(a), 0); + if (d2 + granularity <= c && c <= end) + CHECK_EQ(*(u8 *)MemToShadow(c - granularity), kAsanUserPoisonedMemoryMagic); + + // 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); + if (b1 != b2) { + CHECK_EQ(b2 - b1, granularity); + *(u8*)MemToShadow(b1) = static_cast<u8>(b - b1); + } +} |