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

Thurston Dang via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 10 10:54:52 PDT 2024


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

>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 1/2] [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;

>From da136f93104731c689c89e417430f34a391a3134 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Wed, 10 Jul 2024 17:54:26 +0000
Subject: [PATCH 2/2] Unconditionally block asynchronous signals only

---
 .../lib/sanitizer_common/sanitizer_linux.cpp  | 29 +++++++++----------
 .../lib/sanitizer_common/sanitizer_linux.h    |  6 ++--
 2 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index fa32ab998bbd9..54f972c74794b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -155,9 +155,8 @@ void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset) {
   CHECK_EQ(0, internal_sigprocmask(SIG_SETMASK, set, 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) {
+// Block asynchronous signals
+void BlockSignals(__sanitizer_sigset_t *oldset) {
   __sanitizer_sigset_t set;
   internal_sigfillset(&set);
 #  if SANITIZER_LINUX && !SANITIZER_ANDROID
@@ -172,21 +171,21 @@ void BlockSignals(__sanitizer_sigset_t *oldset, bool block_async_only) {
   // 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);
-  }
+
+  // Don't block synchronous signals
+  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,
-                                       bool block_async_only) {
-  BlockSignals(&saved_, block_async_only);
+ScopedBlockSignals::ScopedBlockSignals(__sanitizer_sigset_t *copy) {
+  BlockSignals(&saved_);
   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 7f3da79a2c03b..c30f0326793d5 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
@@ -51,11 +51,9 @@ 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,
-                  bool block_async_only = false);
+void BlockSignals(__sanitizer_sigset_t *oldset = nullptr);
 struct ScopedBlockSignals {
-  explicit ScopedBlockSignals(__sanitizer_sigset_t *copy,
-                              bool block_async_only = false);
+  explicit ScopedBlockSignals(__sanitizer_sigset_t *copy);
   ~ScopedBlockSignals();
 
   ScopedBlockSignals &operator=(const ScopedBlockSignals &) = delete;



More information about the llvm-commits mailing list