[llvm-branch-commits] [sanitizer] Fix partially initialized static TLS range (PR #108685)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Sep 13 23:20:07 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-pgo
Author: Vitaly Buka (vitalybuka)
<details>
<summary>Changes</summary>
Fixes asan,msan crash on check added in #<!-- -->108684.
The #<!-- -->108684 includes reproducer of the issue.
Change interface of `GetThreadStackAndTls` to
set `tls_begin` and `tls_end` at the same time.
---
Full diff: https://github.com/llvm/llvm-project/pull/108685.diff
16 Files Affected:
- (modified) compiler-rt/lib/asan/asan_posix.cpp (+4-4)
- (modified) compiler-rt/lib/asan/asan_rtl.cpp (+2-4)
- (modified) compiler-rt/lib/asan/asan_thread.cpp (+3-6)
- (modified) compiler-rt/lib/dfsan/dfsan_thread.cpp (+2-7)
- (modified) compiler-rt/lib/hwasan/hwasan_linux.cpp (+2-6)
- (modified) compiler-rt/lib/lsan/lsan_posix.cpp (+2-6)
- (modified) compiler-rt/lib/memprof/memprof_thread.cpp (+2-6)
- (modified) compiler-rt/lib/msan/msan_thread.cpp (+2-7)
- (modified) compiler-rt/lib/nsan/nsan_thread.cpp (+2-7)
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_common.h (+2-2)
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp (+18-10)
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp (+12-15)
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_win.cpp (+12-15)
- (modified) compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp (+16-17)
- (modified) compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp (+6-4)
- (modified) compiler-rt/test/sanitizer_common/TestCases/Linux/tls_malloc_hook.c (-4)
``````````diff
diff --git a/compiler-rt/lib/asan/asan_posix.cpp b/compiler-rt/lib/asan/asan_posix.cpp
index 76564538bd5d77..cd57f750d897cc 100644
--- a/compiler-rt/lib/asan/asan_posix.cpp
+++ b/compiler-rt/lib/asan/asan_posix.cpp
@@ -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;
}
diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp
index d42a75e9e5211a..a390802af28d09 100644
--- a/compiler-rt/lib/asan/asan_rtl.cpp
+++ b/compiler-rt/lib/asan/asan_rtl.cpp
@@ -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");
diff --git a/compiler-rt/lib/asan/asan_thread.cpp b/compiler-rt/lib/asan/asan_thread.cpp
index c79c33ab01342f..c1a804b9fcccd3 100644
--- a/compiler-rt/lib/asan/asan_thread.cpp
+++ b/compiler-rt/lib/asan/asan_thread.cpp
@@ -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_) {
diff --git a/compiler-rt/lib/dfsan/dfsan_thread.cpp b/compiler-rt/lib/dfsan/dfsan_thread.cpp
index c1d47514f4bd99..55d38916ead9e0 100644
--- a/compiler-rt/lib/dfsan/dfsan_thread.cpp
+++ b/compiler-rt/lib/dfsan/dfsan_thread.cpp
@@ -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));
}
diff --git a/compiler-rt/lib/hwasan/hwasan_linux.cpp b/compiler-rt/lib/hwasan/hwasan_linux.cpp
index 68294b5962569f..d174fb882ca483 100644
--- a/compiler-rt/lib/hwasan/hwasan_linux.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_linux.cpp
@@ -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) {
diff --git a/compiler-rt/lib/lsan/lsan_posix.cpp b/compiler-rt/lib/lsan/lsan_posix.cpp
index 422c29acca69f3..ddd9fee07e89d2 100644
--- a/compiler-rt/lib/lsan/lsan_posix.cpp
+++ b/compiler-rt/lib/lsan/lsan_posix.cpp
@@ -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);
diff --git a/compiler-rt/lib/memprof/memprof_thread.cpp b/compiler-rt/lib/memprof/memprof_thread.cpp
index e2bca9bb422f71..50072bb91ee74c 100644
--- a/compiler-rt/lib/memprof/memprof_thread.cpp
+++ b/compiler-rt/lib/memprof/memprof_thread.cpp
@@ -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_) {
diff --git a/compiler-rt/lib/msan/msan_thread.cpp b/compiler-rt/lib/msan/msan_thread.cpp
index e5bdedcd415119..1a1725faa66500 100644
--- a/compiler-rt/lib/msan/msan_thread.cpp
+++ b/compiler-rt/lib/msan/msan_thread.cpp
@@ -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));
}
diff --git a/compiler-rt/lib/nsan/nsan_thread.cpp b/compiler-rt/lib/nsan/nsan_thread.cpp
index 85706aea80ebd1..6662c9bbfbd00d 100644
--- a/compiler-rt/lib/nsan/nsan_thread.cpp
+++ b/compiler-rt/lib/nsan/nsan_thread.cpp
@@ -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));
}
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index 182dc8f26c88fd..082d2158e579bd 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
@@ -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);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
index 579d163479858c..6e1092be569c9f 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -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
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
index 35717c610771c1..b4a5d687dbdf4c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
@@ -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() {
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
index 8a80d54751364e..d8f51bf020e242 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
@@ -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) {
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp
index 918d824f8bc76b..7fd6bad4c0e6c1 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp
@@ -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
}
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
index 5316a7862e449c..8d29e25a6dd203 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
@@ -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;
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/tls_malloc_hook.c b/compiler-rt/test/sanitizer_common/TestCases/Linux/tls_malloc_hook.c
index c582372ab9763d..587f3b1401f100 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Linux/tls_malloc_hook.c
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/tls_malloc_hook.c
@@ -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>
``````````
</details>
https://github.com/llvm/llvm-project/pull/108685
More information about the llvm-branch-commits
mailing list