From 7d5e6b4bc7f8a3843e052a662c55b91f3c7a042f Mon Sep 17 00:00:00 2001 From: Kirill Stoimenov Date: Mon, 24 Apr 2023 19:25:45 +0000 Subject: [PATCH] [HWASAN] Fix TLS + signal handling related crash When a signal is raised before HWASAN has a chance to initialize it's TLS entry the program crashes. This only happens when hwasan-with-tls is true, which is default value. This patch fixes the problem by disabling signals during thread initialization time. Reviewed By: vitalybuka Differential Revision: https://reviews.llvm.org/D149085 --- compiler-rt/lib/hwasan/hwasan_interceptors.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp index 16ac85e..06f4eecd 100644 --- a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp +++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp @@ -14,9 +14,10 @@ // sanitizer_common/sanitizer_common_interceptors.h //===----------------------------------------------------------------------===// -#include "interception/interception.h" #include "hwasan.h" #include "hwasan_thread.h" +#include "interception/interception.h" +#include "sanitizer_common/sanitizer_linux.h" #include "sanitizer_common/sanitizer_stackdepot.h" #if !SANITIZER_FUCHSIA @@ -28,11 +29,13 @@ using namespace __hwasan; struct ThreadStartArg { thread_callback_t callback; void *param; + __sanitizer_sigset_t starting_sigset_; }; static void *HwasanThreadStartFunc(void *arg) { __hwasan_thread_enter(); ThreadStartArg A = *reinterpret_cast(arg); + SetSigProcMask(&A.starting_sigset_, nullptr); UnmapOrDie(arg, GetPageSizeCached()); return A.callback(A.param); } @@ -43,16 +46,14 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), ScopedTaggingDisabler tagging_disabler; ThreadStartArg *A = reinterpret_cast (MmapOrDie( GetPageSizeCached(), "pthread_create")); - *A = {callback, param}; - int res; - { - // ASAN uses the same approach to disable leaks from pthread_create. + A->callback = callback; + A->param = param; + ScopedBlockSignals block(&A->starting_sigset_); + // ASAN uses the same approach to disable leaks from pthread_create. # if CAN_SANITIZE_LEAKS - __lsan::ScopedInterceptorDisabler lsan_disabler; + __lsan::ScopedInterceptorDisabler lsan_disabler; # endif - res = REAL(pthread_create)(th, attr, &HwasanThreadStartFunc, A); - } - return res; + return REAL(pthread_create)(th, attr, &HwasanThreadStartFunc, A); } INTERCEPTOR(int, pthread_join, void *t, void **arg) { -- 2.7.4