[compiler-rt] 1e09dbb - [asan] Fix stack-use-after-free checks on non-main thread on Fuchsia

Roland McGrath via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 24 14:29:43 PDT 2020


Author: Drew Fisher
Date: 2020-10-24T14:29:32-07:00
New Revision: 1e09dbb6a942ec5558dc84b5dbc8a842891135d4

URL: https://github.com/llvm/llvm-project/commit/1e09dbb6a942ec5558dc84b5dbc8a842891135d4
DIFF: https://github.com/llvm/llvm-project/commit/1e09dbb6a942ec5558dc84b5dbc8a842891135d4.diff

LOG: [asan] Fix stack-use-after-free checks on non-main thread on Fuchsia

While some platforms call `AsanThread::Init()` from the context of the
thread being started, others (like Fuchsia) call `AsanThread::Init()`
from the context of the thread spawning a child.  Since
`AsyncSignalSafeLazyInitFakeStack` writes to a thread-local, we need to
avoid calling it from the spawning thread on Fuchsia.  Skipping the call
here on Fuchsia is fine; it'll get called from the new thread lazily on first
attempted access.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D89607

Added: 
    

Modified: 
    compiler-rt/lib/asan/asan_thread.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/asan/asan_thread.cpp b/compiler-rt/lib/asan/asan_thread.cpp
index 68138c26d440..fb09af0eccab 100644
--- a/compiler-rt/lib/asan/asan_thread.cpp
+++ b/compiler-rt/lib/asan/asan_thread.cpp
@@ -188,7 +188,7 @@ uptr AsanThread::stack_size() {
   return bounds.top - bounds.bottom;
 }
 
-// We want to create the FakeStack lazyly on the first use, but not eralier
+// We want to create the FakeStack lazily on the first use, but not earlier
 // than the stack size is known and the procedure has to be async-signal safe.
 FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {
   uptr stack_size = this->stack_size();
@@ -211,6 +211,7 @@ FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {
     stack_size_log =
         Max(stack_size_log, static_cast<uptr>(flags()->min_uar_stack_size_log));
     fake_stack_ = FakeStack::Create(stack_size_log);
+    DCHECK_EQ(GetCurrentThread(), this);
     SetTLSFakeStack(fake_stack_);
     return fake_stack_;
   }
@@ -230,8 +231,17 @@ void AsanThread::Init(const InitOptions *options) {
   }
   ClearShadowForThreadStackAndTLS();
   fake_stack_ = nullptr;
-  if (__asan_option_detect_stack_use_after_return)
+  if (__asan_option_detect_stack_use_after_return &&
+      tid() == GetCurrentTidOrInvalid()) {
+    // AsyncSignalSafeLazyInitFakeStack makes use of threadlocals and must be
+    // called from the context of the thread it is initializing, not its parent.
+    // Most platforms call AsanThread::Init on the newly-spawned thread, but
+    // Fuchsia calls this function from the parent thread.  To support that
+    // approach, we avoid calling AsyncSignalSafeLazyInitFakeStack here; it will
+    // be called by the new thread when it first attempts to access the fake
+    // stack.
     AsyncSignalSafeLazyInitFakeStack();
+  }
   int local = 0;
   VReport(1, "T%d: stack [%p,%p) size 0x%zx; local=%p\n", tid(),
           (void *)stack_bottom_, (void *)stack_top_, stack_top_ - stack_bottom_,


        


More information about the llvm-commits mailing list