@@ -160,33 +160,56 @@ void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset) {
160
160
CHECK_EQ(0, internal_sigprocmask(SIG_SETMASK, set, oldset));
161
161
}
162
162
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
+
163
174
// Block asynchronous signals
164
175
void 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
+
168
186
// Glibc uses SIGSETXID signal during setuid call. If this signal is blocked
169
187
// on any thread, setuid call hangs.
170
188
// 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
+
174
192
// Seccomp-BPF-sandboxed processes rely on SIGSYS to handle trapped syscalls.
175
193
// If this signal is blocked, such calls cannot be handled and the process may
176
194
// hang.
177
- internal_sigdelset(&set , 31);
195
+ KeepUnblocked(newset, currentset , 31);
178
196
197
+ # if !SANITIZER_ANDROID
179
198
// 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
188
211
189
- SetSigProcMask(&set , oldset);
212
+ SetSigProcMask(&newset , oldset);
190
213
}
191
214
192
215
ScopedBlockSignals::ScopedBlockSignals(__sanitizer_sigset_t *copy) {
0 commit comments