@@ -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