diff options
author | Alexey Samsonov <samsonov@google.com> | 2012-12-04 01:38:15 +0000 |
---|---|---|
committer | Alexey Samsonov <samsonov@google.com> | 2012-12-04 01:38:15 +0000 |
commit | d4b5db8cb8a7a13bb5cc1d4ce53e8e088303c854 (patch) | |
tree | b79200d3544deb3a33815de2fee61cdad8eaba96 /lib/asan/asan_poisoning.cc | |
parent | ad91267d45fef531c1082ab7974e4cc78aba5280 (diff) |
ASan: add new interface functions - __asan_(un)poison_stack_memory. Calls to these functions are inserted by the instrumentation pass in use-after-scope mode
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@169201 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/asan/asan_poisoning.cc')
-rw-r--r-- | lib/asan/asan_poisoning.cc | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/asan/asan_poisoning.cc b/lib/asan/asan_poisoning.cc index ce9de9278..dcdc7f8ac 100644 --- a/lib/asan/asan_poisoning.cc +++ b/lib/asan/asan_poisoning.cc @@ -151,3 +151,40 @@ void __asan_unpoison_memory_region(void const volatile *addr, uptr size) { bool __asan_address_is_poisoned(void const volatile *addr) { return __asan::AddressIsPoisoned((uptr)addr); } + +// 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) { + if (size == 0) return; + uptr aligned_size = size & ~(SHADOW_GRANULARITY - 1); + PoisonShadow(addr, aligned_size, + do_poison ? kAsanStackUseAfterScopeMagic : 0); + if (size == aligned_size) + return; + s8 end_offset = (s8)(size - aligned_size); + s8* shadow_end = (s8*)MemToShadow(addr + aligned_size); + s8 end_value = *shadow_end; + if (do_poison) { + // If possible, mark all the bytes mapping to last shadow byte as + // unaddressable. + if (end_value > 0 && end_value <= end_offset) + *shadow_end = kAsanStackUseAfterScopeMagic; + } else { + // If necessary, mark few first bytes mapping to last shadow byte + // as addressable + if (end_value != 0) + *shadow_end = Max(end_value, end_offset); + } +} + +void __asan_poison_stack_memory(uptr addr, uptr size) { + if (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) + Report("unpoisoning: %p %zx\n", (void*)addr, size); + PoisonAlignedStackMemory(addr, size, false); +} |