[compiler-rt] [asan][win] Fix CreateThread leak (PR #126738)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 16 07:54:19 PST 2025
https://github.com/GkvJwa updated https://github.com/llvm/llvm-project/pull/126738
>From 2fcd13ef61c69e2b90590cfe9a39569c614bd80d Mon Sep 17 00:00:00 2001
From: GkvJwa <gkvjwa at gmail.com>
Date: Sun, 16 Feb 2025 23:54:01 +0800
Subject: [PATCH] [asan][win] Fix ExitThread leak
Use tls to store the memory created by `VirtualAlloc`, Then
intercept `ExitThread` and release the memory
---
compiler-rt/lib/asan/asan_win.cpp | 36 ++++++++++++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/compiler-rt/lib/asan/asan_win.cpp b/compiler-rt/lib/asan/asan_win.cpp
index 09a13b11cff1f..5ab6351c25219 100644
--- a/compiler-rt/lib/asan/asan_win.cpp
+++ b/compiler-rt/lib/asan/asan_win.cpp
@@ -136,7 +136,32 @@ struct ThreadStartParams {
void *arg;
};
+static atomic_uint32_t g_native_tls_key{TLS_OUT_OF_INDEXES};
+
+bool AllocTLS(DWORD *key) {
+ DWORD value = TlsAlloc();
+ if (value != TLS_OUT_OF_INDEXES) {
+ *key = value;
+ return true;
+ }
+ return false;
+}
+
static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
+ DWORD key = atomic_load(&g_native_tls_key, memory_order_relaxed);
+ if (key == TLS_OUT_OF_INDEXES) {
+ // Leak global key
+ CHECK(AllocTLS(&key));
+ DWORD old_key = TLS_OUT_OF_INDEXES;
+ // Prevent another thread already store
+ if (!atomic_compare_exchange_strong(&g_native_tls_key, (u32 *)&old_key,
+ (u32)key, memory_order_relaxed)) {
+ TlsFree(key);
+ key = atomic_load(&g_native_tls_key, memory_order_relaxed);
+ }
+ }
+ CHECK(key != TLS_OUT_OF_INDEXES);
+ TlsSetValue(key, arg);
AsanThread *t = (AsanThread *)arg;
SetCurrentThread(t);
t->ThreadStart(GetTid());
@@ -145,7 +170,6 @@ static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
t->GetStartData(params);
auto res = (*params.start_routine)(params.arg);
- t->Destroy(); // POSIX calls this from TSD destructor.
return res;
}
@@ -166,6 +190,15 @@ INTERCEPTOR_WINAPI(HANDLE, CreateThread, LPSECURITY_ATTRIBUTES security,
thr_flags, tid);
}
+INTERCEPTOR_WINAPI(void, ExitThread, DWORD dwExitCode) {
+ DWORD key = atomic_load(&g_native_tls_key, memory_order_relaxed);
+ AsanThread *t = (AsanThread *)TlsGetValue(key);
+ if (t) {
+ t->Destroy();
+ }
+ REAL(ExitThread)(dwExitCode);
+}
+
// }}}
namespace __asan {
@@ -181,6 +214,7 @@ void InitializePlatformInterceptors() {
(LPCWSTR)&InitializePlatformInterceptors, &pinned));
ASAN_INTERCEPT_FUNC(CreateThread);
+ ASAN_INTERCEPT_FUNC(ExitThread);
ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter);
#ifdef _WIN64
More information about the llvm-commits
mailing list