@@ -160,33 +160,56 @@ void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset) {
160160 CHECK_EQ (0 , internal_sigprocmask (SIG_SETMASK, set, oldset));
161161}
162162
163+ # if SANITIZER_LINUX
164+ // Deletes the specified signal from newset, if it is not present in oldset
165+ // Equivalently: newset[signum] = newset[signum] & oldset[signum]
166+ static void KeepUnblocked (__sanitizer_sigset_t &newset,
167+ __sanitizer_sigset_t &oldset, int signum) {
168+ // FIXME: https://github.com/google/sanitizers/issues/1816
169+ if (SANITIZER_ANDROID || !internal_sigismember (&oldset, signum))
170+ internal_sigdelset (&newset, signum);
171+ }
172+ # endif
173+
163174// Block asynchronous signals
164175void BlockSignals (__sanitizer_sigset_t *oldset) {
165- __sanitizer_sigset_t set;
166- internal_sigfillset (&set);
167- # if SANITIZER_LINUX && !SANITIZER_ANDROID
176+ __sanitizer_sigset_t newset;
177+ internal_sigfillset (&newset);
178+
179+ # if SANITIZER_LINUX
180+ __sanitizer_sigset_t currentset;
181+
182+ # if !SANITIZER_ANDROID
183+ // FIXME: https://github.com/google/sanitizers/issues/1816
184+ SetSigProcMask (NULL , ¤tset);
185+
168186 // Glibc uses SIGSETXID signal during setuid call. If this signal is blocked
169187 // on any thread, setuid call hangs.
170188 // See test/sanitizer_common/TestCases/Linux/setuid.c.
171- internal_sigdelset (&set , 33 );
172- # endif
173- # if SANITIZER_LINUX
189+ KeepUnblocked (newset, currentset , 33 );
190+ # endif // !SANITIZER_ANDROID
191+
174192 // Seccomp-BPF-sandboxed processes rely on SIGSYS to handle trapped syscalls.
175193 // If this signal is blocked, such calls cannot be handled and the process may
176194 // hang.
177- internal_sigdelset (&set , 31 );
195+ KeepUnblocked (newset, currentset , 31 );
178196
197+ # if !SANITIZER_ANDROID
179198 // Don't block synchronous signals
180- internal_sigdelset (&set, SIGSEGV);
181- internal_sigdelset (&set, SIGBUS);
182- internal_sigdelset (&set, SIGILL);
183- internal_sigdelset (&set, SIGTRAP);
184- internal_sigdelset (&set, SIGABRT);
185- internal_sigdelset (&set, SIGFPE);
186- internal_sigdelset (&set, SIGPIPE);
187- # endif
199+ // but also don't unblock signals that the user had deliberately blocked.
200+ // FIXME: https://github.com/google/sanitizers/issues/1816
201+ KeepUnblocked (newset, currentset, SIGSEGV);
202+ KeepUnblocked (newset, currentset, SIGBUS);
203+ KeepUnblocked (newset, currentset, SIGILL);
204+ KeepUnblocked (newset, currentset, SIGTRAP);
205+ KeepUnblocked (newset, currentset, SIGABRT);
206+ KeepUnblocked (newset, currentset, SIGFPE);
207+ KeepUnblocked (newset, currentset, SIGPIPE);
208+ # endif // ! SANITIZER_ANDROID
209+
210+ # endif // SANITIZER_LINUX
188211
189- SetSigProcMask (&set , oldset);
212+ SetSigProcMask (&newset , oldset);
190213}
191214
192215ScopedBlockSignals::ScopedBlockSignals (__sanitizer_sigset_t *copy) {
0 commit comments