[compiler-rt] [sanitizer_common] Add option to block only asynchronous signals (PR #98200)

Thurston Dang via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 9 11:42:56 PDT 2024


https://github.com/thurstond created https://github.com/llvm/llvm-project/pull/98200

This does not change the existing behavior of sanitizers, since BlockSignal will still default to blocking (nearly) all signals.

This extension is intended to be used in a future fix for MSan (block async signals during MsanThread::Destroy).

>From 6a744ae9cb21ce12752ea0212945b3e014ba7480 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Tue, 9 Jul 2024 18:38:49 +0000
Subject: [PATCH] [sanitizer_common] Add option to block only asynchronous
 signals

This does not change the existing behavior of sanitizers, since
BlockSignal will still default to blocking (nearly) all signals.

This extension is intended to be used in a future fix for MSan (block
async signals during MsanThread::Destroy).
---
 .../lib/sanitizer_common/sanitizer_linux.cpp   | 18 +++++++++++++++---
 .../lib/sanitizer_common/sanitizer_linux.h     |  6 ++++--
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 12df3ef73da4b..fa32ab998bbd9 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -155,7 +155,9 @@ 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) {
+// If block_async_only is true: blocks only asynchronous signals; otherwise,
+// blocks (nearly) all signals.
+void BlockSignals(__sanitizer_sigset_t *oldset, bool block_async_only) {
   __sanitizer_sigset_t set;
   internal_sigfillset(&set);
 #  if SANITIZER_LINUX && !SANITIZER_ANDROID
@@ -170,11 +172,21 @@ void BlockSignals(__sanitizer_sigset_t *oldset) {
   // hang.
   internal_sigdelset(&set, 31);
 #  endif
+  if (block_async_only) {
+    internal_sigdelset(&set, SIGSEGV);
+    internal_sigdelset(&set, SIGBUS);
+    internal_sigdelset(&set, SIGILL);
+    internal_sigdelset(&set, SIGTRAP);
+    internal_sigdelset(&set, SIGABRT);
+    internal_sigdelset(&set, SIGFPE);
+    internal_sigdelset(&set, SIGPIPE);
+  }
   SetSigProcMask(&set, oldset);
 }
 
-ScopedBlockSignals::ScopedBlockSignals(__sanitizer_sigset_t *copy) {
-  BlockSignals(&saved_);
+ScopedBlockSignals::ScopedBlockSignals(__sanitizer_sigset_t *copy,
+                                       bool block_async_only) {
+  BlockSignals(&saved_, block_async_only);
   if (copy)
     internal_memcpy(copy, &saved_, sizeof(saved_));
 }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
index c30f0326793d5..7f3da79a2c03b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
@@ -51,9 +51,11 @@ 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);
+void BlockSignals(__sanitizer_sigset_t *oldset = nullptr,
+                  bool block_async_only = false);
 struct ScopedBlockSignals {
-  explicit ScopedBlockSignals(__sanitizer_sigset_t *copy);
+  explicit ScopedBlockSignals(__sanitizer_sigset_t *copy,
+                              bool block_async_only = false);
   ~ScopedBlockSignals();
 
   ScopedBlockSignals &operator=(const ScopedBlockSignals &) = delete;



More information about the llvm-commits mailing list