@@ -164,33 +164,45 @@ void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset) {
164164 CHECK_EQ (0 , internal_sigprocmask (SIG_SETMASK, set, oldset));
165165}
166166
167+ // Deletes the specified signal from newset, if it is not present in oldset
168+ // Equivalently: newset[signum] = newset[signum] & oldset[signum]
169+ static void KeepUnblocked (__sanitizer_sigset_t &newset,
170+ __sanitizer_sigset_t &oldset, int signum) {
171+ if (!internal_sigismember (&oldset, signum))
172+ internal_sigdelset (&newset, signum);
173+ }
174+
167175// Block asynchronous signals
168176void BlockSignals (__sanitizer_sigset_t *oldset) {
169- __sanitizer_sigset_t set;
170- internal_sigfillset (&set);
177+ __sanitizer_sigset_t currentset;
178+ SetSigProcMask (NULL , ¤tset);
179+
180+ __sanitizer_sigset_t newset;
181+ internal_sigfillset (&newset);
171182# if SANITIZER_LINUX && !SANITIZER_ANDROID
172183 // Glibc uses SIGSETXID signal during setuid call. If this signal is blocked
173184 // on any thread, setuid call hangs.
174185 // See test/sanitizer_common/TestCases/Linux/setuid.c.
175- internal_sigdelset (&set , 33 );
186+ KeepUnblocked (newset, currentset , 33 );
176187# endif
177188# if SANITIZER_LINUX
178189 // Seccomp-BPF-sandboxed processes rely on SIGSYS to handle trapped syscalls.
179190 // If this signal is blocked, such calls cannot be handled and the process may
180191 // hang.
181- internal_sigdelset (&set , 31 );
192+ KeepUnblocked (newset, currentset , 31 );
182193
183194 // Don't block synchronous signals
184- internal_sigdelset (&set, SIGSEGV);
185- internal_sigdelset (&set, SIGBUS);
186- internal_sigdelset (&set, SIGILL);
187- internal_sigdelset (&set, SIGTRAP);
188- internal_sigdelset (&set, SIGABRT);
189- internal_sigdelset (&set, SIGFPE);
190- internal_sigdelset (&set, SIGPIPE);
195+ // but also don't unblock signals that the user had deliberately blocked.
196+ KeepUnblocked (newset, currentset, SIGSEGV);
197+ KeepUnblocked (newset, currentset, SIGBUS);
198+ KeepUnblocked (newset, currentset, SIGILL);
199+ KeepUnblocked (newset, currentset, SIGTRAP);
200+ KeepUnblocked (newset, currentset, SIGABRT);
201+ KeepUnblocked (newset, currentset, SIGFPE);
202+ KeepUnblocked (newset, currentset, SIGPIPE);
191203# endif
192204
193- SetSigProcMask (&set , oldset);
205+ SetSigProcMask (&newset , oldset);
194206}
195207
196208ScopedBlockSignals::ScopedBlockSignals (__sanitizer_sigset_t *copy) {
0 commit comments