@@ -172,33 +172,56 @@ void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset) {
172172 CHECK_EQ (0 , internal_sigprocmask (SIG_SETMASK, set, oldset));
173173}
174174
175+ # if SANITIZER_LINUX
176+ // Deletes the specified signal from newset, if it is not present in oldset
177+ // Equivalently: newset[signum] = newset[signum] & oldset[signum]
178+ static void KeepUnblocked (__sanitizer_sigset_t &newset,
179+ __sanitizer_sigset_t &oldset, int signum) {
180+ // FIXME: https://github.com/google/sanitizers/issues/1816
181+ if (SANITIZER_ANDROID || !internal_sigismember (&oldset, signum))
182+ internal_sigdelset (&newset, signum);
183+ }
184+ # endif
185+
175186// Block asynchronous signals
176187void BlockSignals (__sanitizer_sigset_t *oldset) {
177- __sanitizer_sigset_t set;
178- internal_sigfillset (&set);
179- # if SANITIZER_LINUX && !SANITIZER_ANDROID
188+ __sanitizer_sigset_t newset;
189+ internal_sigfillset (&newset);
190+
191+ # if SANITIZER_LINUX
192+ __sanitizer_sigset_t currentset;
193+
194+ # if !SANITIZER_ANDROID
195+ // FIXME: https://github.com/google/sanitizers/issues/1816
196+ SetSigProcMask (NULL , ¤tset);
197+
180198 // Glibc uses SIGSETXID signal during setuid call. If this signal is blocked
181199 // on any thread, setuid call hangs.
182200 // See test/sanitizer_common/TestCases/Linux/setuid.c.
183- internal_sigdelset (&set , 33 );
184- # endif
185- # if SANITIZER_LINUX
201+ KeepUnblocked (newset, currentset , 33 );
202+ # endif // !SANITIZER_ANDROID
203+
186204 // Seccomp-BPF-sandboxed processes rely on SIGSYS to handle trapped syscalls.
187205 // If this signal is blocked, such calls cannot be handled and the process may
188206 // hang.
189- internal_sigdelset (&set , 31 );
207+ KeepUnblocked (newset, currentset , 31 );
190208
209+ # if !SANITIZER_ANDROID
191210 // Don't block synchronous signals
192- internal_sigdelset (&set, SIGSEGV);
193- internal_sigdelset (&set, SIGBUS);
194- internal_sigdelset (&set, SIGILL);
195- internal_sigdelset (&set, SIGTRAP);
196- internal_sigdelset (&set, SIGABRT);
197- internal_sigdelset (&set, SIGFPE);
198- internal_sigdelset (&set, SIGPIPE);
199- # endif
211+ // but also don't unblock signals that the user had deliberately blocked.
212+ // FIXME: https://github.com/google/sanitizers/issues/1816
213+ KeepUnblocked (newset, currentset, SIGSEGV);
214+ KeepUnblocked (newset, currentset, SIGBUS);
215+ KeepUnblocked (newset, currentset, SIGILL);
216+ KeepUnblocked (newset, currentset, SIGTRAP);
217+ KeepUnblocked (newset, currentset, SIGABRT);
218+ KeepUnblocked (newset, currentset, SIGFPE);
219+ KeepUnblocked (newset, currentset, SIGPIPE);
220+ # endif // ! SANITIZER_ANDROID
221+
222+ # endif // SANITIZER_LINUX
200223
201- SetSigProcMask (&set , oldset);
224+ SetSigProcMask (&newset , oldset);
202225}
203226
204227ScopedBlockSignals::ScopedBlockSignals (__sanitizer_sigset_t *copy) {
0 commit comments