Skip to content

Commit 7c9a435

Browse files
author
git apple-llvm automerger
committed
Merge commit '6925f3c7c7d8' from llvm.org/release/19.x into stable/20240723
2 parents b84f451 + 6925f3c commit 7c9a435

File tree

3 files changed

+116
-16
lines changed

3 files changed

+116
-16
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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
164175
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, &currentset);
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

192215
ScopedBlockSignals::ScopedBlockSignals(__sanitizer_sigset_t *copy) {

compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ set(SANITIZER_UNITTESTS
1515
sanitizer_array_ref_test.cpp
1616
sanitizer_atomic_test.cpp
1717
sanitizer_bitvector_test.cpp
18+
sanitizer_block_signals.cpp
1819
sanitizer_bvgraph_test.cpp
1920
sanitizer_chained_origin_depot_test.cpp
2021
sanitizer_common_test.cpp
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//===-- sanitizer_block_signals.cpp ---------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file is a part of sanitizer_common unit tests.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
#include <signal.h>
13+
#include <stdio.h>
14+
15+
#include "gtest/gtest.h"
16+
#include "sanitizer_common/sanitizer_linux.h"
17+
18+
namespace __sanitizer {
19+
20+
#if SANITIZER_LINUX && !SANITIZER_ANDROID
21+
volatile int received_sig = -1;
22+
23+
void signal_handler(int signum) { received_sig = signum; }
24+
25+
TEST(SanitizerCommon, NoBlockSignals) {
26+
// No signals blocked
27+
signal(SIGUSR1, signal_handler);
28+
raise(SIGUSR1);
29+
EXPECT_EQ(received_sig, SIGUSR1);
30+
31+
received_sig = -1;
32+
signal(SIGPIPE, signal_handler);
33+
raise(SIGPIPE);
34+
EXPECT_EQ(received_sig, SIGPIPE);
35+
}
36+
37+
TEST(SanitizerCommon, BlockSignalsPlain) {
38+
// ScopedBlockSignals; SIGUSR1 should be blocked but not SIGPIPE
39+
{
40+
__sanitizer_sigset_t sigset = {};
41+
ScopedBlockSignals block(&sigset);
42+
43+
received_sig = -1;
44+
signal(SIGUSR1, signal_handler);
45+
raise(SIGUSR1);
46+
EXPECT_EQ(received_sig, -1);
47+
48+
received_sig = -1;
49+
signal(SIGPIPE, signal_handler);
50+
raise(SIGPIPE);
51+
EXPECT_EQ(received_sig, SIGPIPE);
52+
}
53+
EXPECT_EQ(received_sig, SIGUSR1);
54+
}
55+
56+
TEST(SanitizerCommon, BlockSignalsExceptPipe) {
57+
// Manually block SIGPIPE; ScopedBlockSignals should not unblock this
58+
sigset_t block_sigset;
59+
sigemptyset(&block_sigset);
60+
sigaddset(&block_sigset, SIGPIPE);
61+
sigprocmask(SIG_BLOCK, &block_sigset, NULL);
62+
{
63+
__sanitizer_sigset_t sigset = {};
64+
ScopedBlockSignals block(&sigset);
65+
66+
received_sig = -1;
67+
signal(SIGPIPE, signal_handler);
68+
raise(SIGPIPE);
69+
EXPECT_EQ(received_sig, -1);
70+
}
71+
sigprocmask(SIG_UNBLOCK, &block_sigset, NULL);
72+
EXPECT_EQ(received_sig, SIGPIPE);
73+
}
74+
#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
75+
76+
} // namespace __sanitizer

0 commit comments

Comments
 (0)