Skip to content

Commit

Permalink
[asan] Fix stack-use-after-free checks on non-main thread on Fuchsia
Browse files Browse the repository at this point in the history
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
  • Loading branch information
zarvox authored and frobtech committed Oct 24, 2020
1 parent 29480c6 commit 1e09dbb
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions compiler-rt/lib/asan/asan_thread.cpp
Expand Up @@ -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();
Expand All @@ -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_;
}
Expand All @@ -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_,
Expand Down

0 comments on commit 1e09dbb

Please sign in to comment.