[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