Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
28 changes: 18 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,33 @@ 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;
CHECK_GE(*tls_begin, *stk_begin);
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_begin, stk_end);
*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
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ DTLS::DTV *DTLS_on_tls_get_addr(void *arg_void, void *res,
DTLS::DTV *dtv = DTLS_Find(dso_id);
if (!dtv || dtv->beg)
return nullptr;
CHECK_LE(static_tls_begin, static_tls_end);
uptr tls_size = 0;
uptr tls_beg = reinterpret_cast<uptr>(res) - arg->offset - kDtvOffset;
VReport(2,
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_begin, stk_end);
*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
@@ -0,0 +1,56 @@
// Test that we don't crash accessing DTLS from malloc hook.

// RUN: %clang %s -o %t
// RUN: %clang %s -DBUILD_SO -fPIC -o %t-so.so -shared
// RUN: %run %t 2>&1 | FileCheck %s

// REQUIRES: glibc

// No allocator and hooks.
// XFAIL: ubsan

#ifndef BUILD_SO
# include <assert.h>
# include <dlfcn.h>
# include <pthread.h>
# include <stdio.h>
# include <stdlib.h>

typedef long *(*get_t)();
get_t GetTls;
void *Thread(void *unused) { return GetTls(); }

__thread long recursive_hook;

// CHECK: __sanitizer_malloc_hook:
void __sanitizer_malloc_hook(const volatile void *ptr, size_t sz)
__attribute__((disable_sanitizer_instrumentation)) {
++recursive_hook;
if (recursive_hook == 1 && GetTls)
fprintf(stderr, "__sanitizer_malloc_hook: %p\n", GetTls());
--recursive_hook;
}

int main(int argc, char *argv[]) {
char path[4096];
snprintf(path, sizeof(path), "%s-so.so", argv[0]);
int i;

void *handle = dlopen(path, RTLD_LAZY);
if (!handle)
fprintf(stderr, "%s\n", dlerror());
assert(handle != 0);
GetTls = (get_t)dlsym(handle, "GetTls");
assert(dlerror() == 0);

pthread_t t;
pthread_create(&t, 0, Thread, 0);
pthread_join(t, 0);
pthread_create(&t, 0, Thread, 0);
pthread_join(t, 0);
return 0;
}
#else // BUILD_SO
__thread long huge_thread_local_array[1 << 17];
long *GetTls() { return &huge_thread_local_array[0]; }
#endif