tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

unpoison-thread-stacks_clang_21.patch (2584B)


      1 [winasan] Unpoison the stack in NtTerminateThread
      2 
      3 In long-running builds we've seen some ASan complaints during thread creation
      4 that we suspect are due to leftover poisoning from previous threads whose stacks
      5 occupied that memory. This patch adds a hook that unpoisons the stack just
      6 before the NtTerminateThread syscall.
      7 
      8 Differential Revision: https://reviews.llvm.org/D52091
      9 
     10 ** Update for clang 9 ** : After some backouts, this patch eventually landed
     11 upstream in a different form, as the TLS handler `asan_thread_exit`, but that
     12 variant causes failures in our test suite, so revert the TLS handler in favor of
     13 the interceptor approach from the first patch.
     14 
     15 diff --git a/compiler-rt/lib/asan/asan_win.cpp b/compiler-rt/lib/asan/asan_win.cpp
     16 index 027340280e06..fbc06cf2b6c3 100644
     17 --- a/compiler-rt/lib/asan/asan_win.cpp
     18 +++ b/compiler-rt/lib/asan/asan_win.cpp
     19 @@ -172,6 +172,14 @@ INTERCEPTOR_WINAPI(void, ExitThread, DWORD dwExitCode) {
     20   REAL(ExitThread)(dwExitCode);
     21 }
     22 
     23 +INTERCEPTOR_WINAPI(void, NtTerminateThread, void *rcx) {
     24 +  // Unpoison the terminating thread's stack because the memory may be re-used.
     25 +  NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
     26 +  uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
     27 +  __asan_unpoison_memory_region(tib->StackLimit, stackSize);
     28 +  return REAL(NtTerminateThread(rcx));
     29 +}
     30 +
     31 // }}}
     32 
     33 namespace __asan {
     34 @@ -189,7 +197,9 @@ void InitializePlatformInterceptors() {
     35   ASAN_INTERCEPT_FUNC(CreateThread);
     36   ASAN_INTERCEPT_FUNC(ExitThread);
     37   ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter);
     38 -
     39 +  CHECK(::__interception::OverrideFunction("NtTerminateThread",
     40 +                                           (uptr)WRAP(NtTerminateThread),
     41 +                                           (uptr *)&REAL(NtTerminateThread)));
     42 #ifdef _WIN64
     43   ASAN_INTERCEPT_FUNC(__C_specific_handler);
     44 #else
     45 @@ -399,19 +409,6 @@ __declspec(allocate(".CRT$XLAB")) void(NTAPI *__asan_tls_init)(
     46     void *, unsigned long, void *) = asan_thread_init;
     47 #endif
     48 
     49 -static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) {
     50 -  if (reason == DLL_THREAD_DETACH) {
     51 -    // Unpoison the thread's stack because the memory may be re-used.
     52 -    NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
     53 -    uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
     54 -    __asan_unpoison_memory_region(tib->StackLimit, stackSize);
     55 -  }
     56 -}
     57 -
     58 -#pragma section(".CRT$XLY", long, read)
     59 -__declspec(allocate(".CRT$XLY")) void(NTAPI *__asan_tls_exit)(
     60 -    void *, unsigned long, void *) = asan_thread_exit;
     61 -
     62 WIN_FORCE_LINK(__asan_dso_reg_hook)
     63 
     64 // }}}