Skip to content

Reland "[sanitizer] Fix partially initialized static TLS range" #108883

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions compiler-rt/lib/asan/asan_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ bool PlatformUnpoisonStacks() {

// Since we're on the signal alternate stack, we cannot find the DEFAULT
// stack bottom using a local variable.
uptr default_bottom, tls_addr, tls_size, stack_size;
GetThreadStackAndTls(/*main=*/false, &default_bottom, &stack_size, &tls_addr,
&tls_size);
UnpoisonStack(default_bottom, default_bottom + stack_size, "default");
uptr stack_begin, stack_end, tls_begin, tls_end;
GetThreadStackAndTls(/*main=*/false, &stack_begin, &stack_end, &tls_begin,
&tls_end);
UnpoisonStack(stack_begin, stack_end, "default");
return true;
}

Expand Down
6 changes: 2 additions & 4 deletions compiler-rt/lib/asan/asan_rtl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,10 +580,8 @@ static void UnpoisonDefaultStack() {
} else {
CHECK(!SANITIZER_FUCHSIA);
// If we haven't seen this thread, try asking the OS for stack bounds.
uptr tls_addr, tls_size, stack_size;
GetThreadStackAndTls(/*main=*/false, &bottom, &stack_size, &tls_addr,
&tls_size);
top = bottom + stack_size;
uptr tls_begin, tls_end;
GetThreadStackAndTls(/*main=*/false, &bottom, &top, &tls_begin, &tls_end);
}

UnpoisonStack(bottom, top, "default");
Expand Down
9 changes: 3 additions & 6 deletions compiler-rt/lib/asan/asan_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,13 +306,10 @@ AsanThread *CreateMainThread() {
// OS-specific implementations that need more information passed through.
void AsanThread::SetThreadStackAndTls(const InitOptions *options) {
DCHECK_EQ(options, nullptr);
uptr tls_size = 0;
uptr stack_size = 0;
GetThreadStackAndTls(tid() == kMainTid, &stack_bottom_, &stack_size,
&tls_begin_, &tls_size);
stack_top_ = RoundDownTo(stack_bottom_ + stack_size, ASAN_SHADOW_GRANULARITY);
GetThreadStackAndTls(tid() == kMainTid, &stack_bottom_, &stack_top_,
&tls_begin_, &tls_end_);
stack_top_ = RoundDownTo(stack_top_, ASAN_SHADOW_GRANULARITY);
stack_bottom_ = RoundDownTo(stack_bottom_, ASAN_SHADOW_GRANULARITY);
tls_end_ = tls_begin_ + tls_size;
dtls_ = DTLS_Get();

if (stack_top_ != stack_bottom_) {
Expand Down
9 changes: 2 additions & 7 deletions compiler-rt/lib/dfsan/dfsan_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,8 @@ DFsanThread *DFsanThread::Create(thread_callback_t start_routine, void *arg,
}

void DFsanThread::SetThreadStackAndTls() {
uptr tls_size = 0;
uptr stack_size = 0;
GetThreadStackAndTls(IsMainThread(), &stack_.bottom, &stack_size, &tls_begin_,
&tls_size);
stack_.top = stack_.bottom + stack_size;
tls_end_ = tls_begin_ + tls_size;

GetThreadStackAndTls(IsMainThread(), &stack_.bottom, &stack_.top, &tls_begin_,
&tls_end_);
int local;
CHECK(AddrIsInStack((uptr)&local));
}
Expand Down
8 changes: 2 additions & 6 deletions compiler-rt/lib/hwasan/hwasan_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,12 +499,8 @@ void HwasanOnDeadlySignal(int signo, void *info, void *context) {
}

void Thread::InitStackAndTls(const InitState *) {
uptr tls_size;
uptr stack_size;
GetThreadStackAndTls(IsMainThread(), &stack_bottom_, &stack_size, &tls_begin_,
&tls_size);
stack_top_ = stack_bottom_ + stack_size;
tls_end_ = tls_begin_ + tls_size;
GetThreadStackAndTls(IsMainThread(), &stack_bottom_, &stack_top_, &tls_begin_,
&tls_end_);
}

uptr TagMemoryAligned(uptr p, uptr size, tag_t tag) {
Expand Down
8 changes: 2 additions & 6 deletions compiler-rt/lib/lsan/lsan_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,8 @@ void ThreadContext::OnStarted(void *arg) {

void ThreadStart(u32 tid, tid_t os_id, ThreadType thread_type) {
OnStartedArgs args;
uptr stack_size = 0;
uptr tls_size = 0;
GetThreadStackAndTls(tid == kMainTid, &args.stack_begin, &stack_size,
&args.tls_begin, &tls_size);
args.stack_end = args.stack_begin + stack_size;
args.tls_end = args.tls_begin + tls_size;
GetThreadStackAndTls(tid == kMainTid, &args.stack_begin, &args.stack_end,
&args.tls_begin, &args.tls_end);
GetAllocatorCacheRange(&args.cache_begin, &args.cache_end);
args.dtls = DTLS_Get();
ThreadContextLsanBase::ThreadStart(tid, os_id, thread_type, &args);
Expand Down
8 changes: 2 additions & 6 deletions compiler-rt/lib/memprof/memprof_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,8 @@ MemprofThread *CreateMainThread() {
// OS-specific implementations that need more information passed through.
void MemprofThread::SetThreadStackAndTls(const InitOptions *options) {
DCHECK_EQ(options, nullptr);
uptr tls_size = 0;
uptr stack_size = 0;
GetThreadStackAndTls(tid() == kMainTid, &stack_bottom_, &stack_size,
&tls_begin_, &tls_size);
stack_top_ = stack_bottom_ + stack_size;
tls_end_ = tls_begin_ + tls_size;
GetThreadStackAndTls(tid() == kMainTid, &stack_bottom_, &stack_top_,
&tls_begin_, &tls_end_);
dtls_ = DTLS_Get();

if (stack_top_ != stack_bottom_) {
Expand Down
9 changes: 2 additions & 7 deletions compiler-rt/lib/msan/msan_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,8 @@ MsanThread *MsanThread::Create(thread_callback_t start_routine,
}

void MsanThread::SetThreadStackAndTls() {
uptr tls_size = 0;
uptr stack_size = 0;
GetThreadStackAndTls(IsMainThread(), &stack_.bottom, &stack_size, &tls_begin_,
&tls_size);
stack_.top = stack_.bottom + stack_size;
tls_end_ = tls_begin_ + tls_size;

GetThreadStackAndTls(IsMainThread(), &stack_.bottom, &stack_.top, &tls_begin_,
&tls_end_);
int local;
CHECK(AddrIsInStack((uptr)&local));
}
Expand Down
9 changes: 2 additions & 7 deletions compiler-rt/lib/nsan/nsan_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,8 @@ NsanThread *NsanThread::Create(thread_callback_t start_routine, void *arg) {
}

void NsanThread::SetThreadStackAndTls() {
uptr tls_size = 0;
uptr stack_size = 0;
GetThreadStackAndTls(IsMainThread(), &stack_.bottom, &stack_size, &tls_begin_,
&tls_size);
stack_.top = stack_.bottom + stack_size;
tls_end_ = tls_begin_ + tls_size;

GetThreadStackAndTls(IsMainThread(), &stack_.bottom, &stack_.top, &tls_begin_,
&tls_end_);
int local;
CHECK(AddrIsInStack((uptr)&local));
}
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/sanitizer_common/sanitizer_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ int TgKill(pid_t pid, tid_t tid, int sig);
uptr GetThreadSelf();
void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
uptr *stack_bottom);
void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
uptr *tls_addr, uptr *tls_size);
void GetThreadStackAndTls(bool main, uptr *stk_begin, uptr *stk_end,
uptr *tls_begin, uptr *tls_end);

// Memory management
void *MmapOrDie(uptr size, const char *mem_type, bool raw_report = false);
Expand Down
27 changes: 17 additions & 10 deletions compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,25 +626,32 @@ uptr GetTlsSize() {
}
# endif

void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
uptr *tls_addr, uptr *tls_size) {
void GetThreadStackAndTls(bool main, uptr *stk_begin, uptr *stk_end,
uptr *tls_begin, uptr *tls_end) {
# if SANITIZER_GO
// Stub implementation for Go.
*stk_addr = *stk_size = *tls_addr = *tls_size = 0;
*stk_begin = 0;
*stk_end = 0;
*tls_begin = 0;
*tls_end = 0;
# else
GetTls(tls_addr, tls_size);
uptr tls_addr = 0;
uptr tls_size = 0;
GetTls(&tls_addr, &tls_size);
*tls_begin = tls_addr;
*tls_end = tls_addr + tls_size;

uptr stack_top, stack_bottom;
GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);
*stk_addr = stack_bottom;
*stk_size = stack_top - stack_bottom;
*stk_begin = stack_bottom;
*stk_end = stack_top;

if (!main) {
// If stack and tls intersect, make them non-intersecting.
if (*tls_addr > *stk_addr && *tls_addr < *stk_addr + *stk_size) {
if (*stk_addr + *stk_size < *tls_addr + *tls_size)
*tls_size = *stk_addr + *stk_size - *tls_addr;
*stk_size = *tls_addr - *stk_addr;
if (*tls_begin > *stk_begin && *tls_begin < *stk_end) {
if (*stk_end < *tls_end)
*tls_end = *stk_end;
*stk_end = *tls_begin;
}
}
# endif
Expand Down
27 changes: 12 additions & 15 deletions compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,21 +572,18 @@ uptr TlsSize() {
#endif
}

void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
uptr *tls_addr, uptr *tls_size) {
#if !SANITIZER_GO
uptr stack_top, stack_bottom;
GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);
*stk_addr = stack_bottom;
*stk_size = stack_top - stack_bottom;
*tls_addr = TlsBaseAddr();
*tls_size = TlsSize();
#else
*stk_addr = 0;
*stk_size = 0;
*tls_addr = 0;
*tls_size = 0;
#endif
void GetThreadStackAndTls(bool main, uptr *stk_begin, uptr *stk_end,
uptr *tls_begin, uptr *tls_end) {
# if !SANITIZER_GO
GetThreadStackTopAndBottom(main, stk_end, stk_begin);
*tls_begin = TlsBaseAddr();
*tls_end = *tls_begin + TlsSize();
# else
*stk_begin = 0;
*stk_end = 0;
*tls_begin = 0;
*tls_end = 0;
# endif
}

void ListOfModules::init() {
Expand Down
27 changes: 12 additions & 15 deletions compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -876,21 +876,18 @@ uptr GetTlsSize() {
void InitTlsSize() {
}

void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
uptr *tls_addr, uptr *tls_size) {
#if SANITIZER_GO
*stk_addr = 0;
*stk_size = 0;
*tls_addr = 0;
*tls_size = 0;
#else
uptr stack_top, stack_bottom;
GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);
*stk_addr = stack_bottom;
*stk_size = stack_top - stack_bottom;
*tls_addr = 0;
*tls_size = 0;
#endif
void GetThreadStackAndTls(bool main, uptr *stk_begin, uptr *stk_end,
uptr *tls_begin, uptr *tls_end) {
# if SANITIZER_GO
*stk_begin = 0;
*stk_end = 0;
*tls_begin = 0;
*tls_end = 0;
# else
GetThreadStackTopAndBottom(main, stk_end, stk_begin);
*tls_begin = 0;
*tls_end = 0;
# endif
}

void ReportFile::Write(const char *buffer, uptr length) {
Expand Down
33 changes: 16 additions & 17 deletions compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,30 +204,29 @@ TEST(SanitizerCommon, InternalMmapVectorSwap) {
}

void TestThreadInfo(bool main) {
uptr stk_addr = 0;
uptr stk_size = 0;
uptr tls_addr = 0;
uptr tls_size = 0;
GetThreadStackAndTls(main, &stk_addr, &stk_size, &tls_addr, &tls_size);
uptr stk_begin = 0;
uptr stk_end = 0;
uptr tls_begin = 0;
uptr tls_end = 0;
GetThreadStackAndTls(main, &stk_begin, &stk_end, &tls_begin, &tls_end);

int stack_var;
EXPECT_NE(stk_addr, (uptr)0);
EXPECT_NE(stk_size, (uptr)0);
EXPECT_GT((uptr)&stack_var, stk_addr);
EXPECT_LT((uptr)&stack_var, stk_addr + stk_size);
EXPECT_NE(stk_begin, (uptr)0);
EXPECT_GT(stk_end, stk_begin);
EXPECT_GT((uptr)&stack_var, stk_begin);
EXPECT_LT((uptr)&stack_var, stk_end);

#if SANITIZER_LINUX && defined(__x86_64__)
static __thread int thread_var;
EXPECT_NE(tls_addr, (uptr)0);
EXPECT_NE(tls_size, (uptr)0);
EXPECT_GT((uptr)&thread_var, tls_addr);
EXPECT_LT((uptr)&thread_var, tls_addr + tls_size);
EXPECT_NE(tls_begin, (uptr)0);
EXPECT_GT(tls_end, tls_begin);
EXPECT_GT((uptr)&thread_var, tls_begin);
EXPECT_LT((uptr)&thread_var, tls_end);

// Ensure that tls and stack do not intersect.
uptr tls_end = tls_addr + tls_size;
EXPECT_TRUE(tls_addr < stk_addr || tls_addr >= stk_addr + stk_size);
EXPECT_TRUE(tls_end < stk_addr || tls_end >= stk_addr + stk_size);
EXPECT_TRUE((tls_addr < stk_addr) == (tls_end < stk_addr));
EXPECT_TRUE(tls_begin < stk_begin || tls_begin >= stk_end);
EXPECT_TRUE(tls_end < stk_begin || tls_end >= stk_end);
EXPECT_TRUE((tls_begin < stk_begin) == (tls_end < stk_begin));
#endif
}

Expand Down
10 changes: 6 additions & 4 deletions compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,16 @@ void ThreadStart(ThreadState *thr, Tid tid, tid_t os_id,
#endif

uptr stk_addr = 0;
uptr stk_size = 0;
uptr stk_end = 0;
uptr tls_addr = 0;
uptr tls_size = 0;
uptr tls_end = 0;
#if !SANITIZER_GO
if (thread_type != ThreadType::Fiber)
GetThreadStackAndTls(tid == kMainTid, &stk_addr, &stk_size, &tls_addr,
&tls_size);
GetThreadStackAndTls(tid == kMainTid, &stk_addr, &stk_end, &tls_addr,
&tls_end);
#endif
uptr stk_size = stk_end - stk_addr;
uptr tls_size = tls_end - tls_addr;
thr->stk_addr = stk_addr;
thr->stk_size = stk_size;
thr->tls_addr = tls_addr;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@
// No allocator and hooks.
// XFAIL: ubsan

// FIXME: Crashes on CHECK.
// XFAIL: asan && !i386-linux
// XFAIL: msan && !i386-linux

#ifndef BUILD_SO
# include <assert.h>
# include <dlfcn.h>
Expand Down
Loading