summaryrefslogtreecommitdiff
path: root/lib/asan/asan_poisoning.cc
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2012-12-04 01:38:15 +0000
committerAlexey Samsonov <samsonov@google.com>2012-12-04 01:38:15 +0000
commitd4b5db8cb8a7a13bb5cc1d4ce53e8e088303c854 (patch)
treeb79200d3544deb3a33815de2fee61cdad8eaba96 /lib/asan/asan_poisoning.cc
parentad91267d45fef531c1082ab7974e4cc78aba5280 (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.cc37
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);
+}