diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp --- a/compiler-rt/lib/asan/asan_interceptors.cpp +++ b/compiler-rt/lib/asan/asan_interceptors.cpp @@ -224,12 +224,9 @@ auto args = asanThreadArgRetval().GetArgs(self); t->ThreadStart(GetTid()); -# if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS __sanitizer_sigset_t sigset; t->GetStartData(sigset); SetSigProcMask(&sigset, nullptr); -# endif thread_return_t retval = (*args.routine)(args.arg_retval); asanThreadArgRetval().Finish(self, retval); @@ -252,10 +249,7 @@ u32 current_tid = GetCurrentTidOrInvalid(); __sanitizer_sigset_t sigset; -# if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS ScopedBlockSignals block(&sigset); -# endif AsanThread *t = AsanThread::Create(sigset, current_tid, &stack, detached); diff --git a/compiler-rt/lib/asan/asan_posix.cpp b/compiler-rt/lib/asan/asan_posix.cpp --- a/compiler-rt/lib/asan/asan_posix.cpp +++ b/compiler-rt/lib/asan/asan_posix.cpp @@ -110,6 +110,9 @@ key.key = nullptr; // Make sure that signal handler can not see a stale current thread pointer. atomic_signal_fence(memory_order_seq_cst); + // After this point it's unsafe to execute signal handlers which may be + // instrumented. + BlockSignals(); AsanThread::TSDDtor(tsd); } #else @@ -138,12 +141,9 @@ CHECK_EQ(0, pthread_setspecific(tsd_key, tsd)); return; } -# if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS // After this point it's unsafe to execute signal handlers which may be - // instrumented. It's probably not just a Linux issue. + // instrumented. BlockSignals(); -# endif AsanThread::TSDDtor(tsd); } #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -46,22 +46,7 @@ // Syscall wrappers. uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count); -uptr internal_sigaltstack(const void* ss, void* oss); -uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, - __sanitizer_sigset_t *oldset); - -void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset); -void BlockSignals(__sanitizer_sigset_t *oldset = nullptr); -struct ScopedBlockSignals { - explicit ScopedBlockSignals(__sanitizer_sigset_t *copy); - ~ScopedBlockSignals(); - - ScopedBlockSignals &operator=(const ScopedBlockSignals &) = delete; - ScopedBlockSignals(const ScopedBlockSignals &) = delete; - - private: - __sanitizer_sigset_t saved_; -}; +uptr internal_sigaltstack(const void *ss, void *oss); # if SANITIZER_GLIBC uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -156,36 +156,6 @@ namespace __sanitizer { -void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset) { - CHECK_EQ(0, internal_sigprocmask(SIG_SETMASK, set, oldset)); -} - -void BlockSignals(__sanitizer_sigset_t *oldset) { - __sanitizer_sigset_t set; - internal_sigfillset(&set); -# if SANITIZER_LINUX && !SANITIZER_ANDROID - // Glibc uses SIGSETXID signal during setuid call. If this signal is blocked - // on any thread, setuid call hangs. - // See test/sanitizer_common/TestCases/Linux/setuid.c. - internal_sigdelset(&set, 33); -# endif -# if SANITIZER_LINUX - // Seccomp-BPF-sandboxed processes rely on SIGSYS to handle trapped syscalls. - // If this signal is blocked, such calls cannot be handled and the process may - // hang. - internal_sigdelset(&set, 31); -# endif - SetSigProcMask(&set, oldset); -} - -ScopedBlockSignals::ScopedBlockSignals(__sanitizer_sigset_t *copy) { - BlockSignals(&saved_); - if (copy) - internal_memcpy(copy, &saved_, sizeof(saved_)); -} - -ScopedBlockSignals::~ScopedBlockSignals() { SetSigProcMask(&saved_, nullptr); } - # if SANITIZER_LINUX && defined(__x86_64__) # include "sanitizer_syscall_linux_x86_64.inc" # elif SANITIZER_LINUX && SANITIZER_RISCV64 diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h @@ -98,6 +98,8 @@ void internal_sigfillset(__sanitizer_sigset_t *set); void internal_sigemptyset(__sanitizer_sigset_t *set); bool internal_sigismember(__sanitizer_sigset_t *set, int signum); +uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, + __sanitizer_sigset_t *oldset); uptr internal_execve(const char *filename, char *const argv[], char *const envp[]); @@ -124,6 +126,19 @@ # define __sanitizer_dirsiz(dp) ((dp)->d_reclen) # endif +void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset); +void BlockSignals(__sanitizer_sigset_t *oldset = nullptr); +struct ScopedBlockSignals { + explicit ScopedBlockSignals(__sanitizer_sigset_t *copy); + ~ScopedBlockSignals(); + + ScopedBlockSignals &operator=(const ScopedBlockSignals &) = delete; + ScopedBlockSignals(const ScopedBlockSignals &) = delete; + + private: + __sanitizer_sigset_t saved_; +}; + } // namespace __sanitizer #endif // SANITIZER_POSIX diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp @@ -406,6 +406,35 @@ return res; } +void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset) { + CHECK_EQ(0, internal_sigprocmask(SIG_SETMASK, set, oldset)); +} + +void BlockSignals(__sanitizer_sigset_t *oldset) { + __sanitizer_sigset_t set; + internal_sigfillset(&set); +# if SANITIZER_LINUX && !SANITIZER_ANDROID + // Glibc uses SIGSETXID signal during setuid call. If this signal is blocked + // on any thread, setuid call hangs. + // See test/sanitizer_common/TestCases/Linux/setuid.c. + internal_sigdelset(&set, 33); +# endif +# if SANITIZER_LINUX + // Seccomp-BPF-sandboxed processes rely on SIGSYS to handle trapped syscalls. + // If this signal is blocked, such calls cannot be handled and the process may + // hang. + internal_sigdelset(&set, 31); +# endif + SetSigProcMask(&set, oldset); +} + +ScopedBlockSignals::ScopedBlockSignals(__sanitizer_sigset_t *copy) { + BlockSignals(&saved_); + if (copy) + internal_memcpy(copy, &saved_, sizeof(saved_)); +} + +ScopedBlockSignals::~ScopedBlockSignals() { SetSigProcMask(&saved_, nullptr); } } // namespace __sanitizer