[PATCH] [asan] Wipe all poisoned memory in fake stack frames before passing them to LSan
Sergey Matveev
earthdok at google.com
Thu Oct 17 12:06:20 PDT 2013
Hi kcc,
Reduce the impact that reusing a fake stack frame. Garbage pointers
which end up in a red zone, or in the unused portion of the fake frame, will no
longer be considered valid by LSan.
http://llvm-reviews.chandlerc.com/D1962
Files:
lib/asan/asan_fake_stack.cc
lib/asan/asan_fake_stack.h
lib/asan/asan_thread.cc
Index: lib/asan/asan_fake_stack.cc
===================================================================
--- lib/asan/asan_fake_stack.cc
+++ lib/asan/asan_fake_stack.cc
@@ -148,6 +148,30 @@
}
}
+void FakeStack::WipePoisonedCallback(uptr begin, uptr end, void *arg) {
+ uptr ptr = begin + sizeof(FakeFrame);
+ CHECK_EQ(0, ptr % 8);
+ CHECK_EQ(0, end % 8);
+ u8 *shadow_ptr = (u8 *)MemToShadow(ptr);
+ uptr poisoned_begin = 0;
+ while (ptr < end) {
+ u8 shadow = *shadow_ptr;
+ if (poisoned_begin > 0) {
+ if (shadow < 8) {
+ internal_memset((void *)poisoned_begin, 0, ptr - poisoned_begin);
+ poisoned_begin = (shadow > 0) ? (ptr + shadow) : 0;
+ }
+ } else {
+ if (shadow)
+ poisoned_begin = ptr + ((shadow < 8) ? shadow : 0);
+ }
+ shadow_ptr++;
+ ptr += 8;
+ }
+ if (poisoned_begin > 0)
+ internal_memset((void *)poisoned_begin, 0, end - poisoned_begin);
+}
+
#if SANITIZER_LINUX && !SANITIZER_ANDROID
static THREADLOCAL FakeStack *fake_stack_tls;
Index: lib/asan/asan_fake_stack.h
===================================================================
--- lib/asan/asan_fake_stack.h
+++ lib/asan/asan_fake_stack.h
@@ -149,6 +149,7 @@
void GC(uptr real_stack);
void ForEachFakeFrame(RangeIteratorCallback callback, void *arg);
+ static void WipePoisonedCallback(uptr begin, uptr end, void *arg);
private:
FakeStack() { }
Index: lib/asan/asan_thread.cc
===================================================================
--- lib/asan/asan_thread.cc
+++ lib/asan/asan_thread.cc
@@ -323,8 +323,13 @@
void ForEachExtraStackRange(uptr os_id, RangeIteratorCallback callback,
void *arg) {
__asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id);
- if (t && t->has_fake_stack())
+ if (t && t->has_fake_stack()) {
+ // Overwrite all poisoned memory ranges with zeros. This should help
+ // against garbage pointers contained in reused stack frames.
+ t->fake_stack()->ForEachFakeFrame(&__asan::FakeStack::WipePoisonedCallback,
+ 0);
t->fake_stack()->ForEachFakeFrame(callback, arg);
+ }
}
void LockThreadRegistry() {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1962.1.patch
Type: text/x-patch
Size: 2196 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131017/e1dfd166/attachment.bin>
More information about the llvm-commits
mailing list