gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/sigprocmask.cc (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <signal.h> 16 #include <stddef.h> 17 #include <sys/syscall.h> 18 #include <unistd.h> 19 20 #include "gtest/gtest.h" 21 #include "test/util/signal_util.h" 22 #include "test/util/test_util.h" 23 24 namespace gvisor { 25 namespace testing { 26 27 namespace { 28 29 // Signals numbers used for testing. 30 static constexpr int kTestSignal1 = SIGUSR1; 31 static constexpr int kTestSignal2 = SIGUSR2; 32 33 static int raw_sigprocmask(int how, const sigset_t* set, sigset_t* oldset) { 34 return syscall(SYS_rt_sigprocmask, how, set, oldset, _NSIG / 8); 35 } 36 37 // count of the number of signals received 38 int signal_count[kMaxSignal + 1]; 39 40 // signal handler increments the signal counter 41 void SigHandler(int sig, siginfo_t* info, void* context) { 42 TEST_CHECK(sig > 0 && sig <= kMaxSignal); 43 signal_count[sig] += 1; 44 } 45 46 // The test fixture saves and restores the signal mask and 47 // sets up handlers for kTestSignal1 and kTestSignal2. 48 class SigProcMaskTest : public ::testing::Test { 49 protected: 50 void SetUp() override { 51 // Save the current signal mask. 52 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, nullptr, &mask_), 53 SyscallSucceeds()); 54 55 // Setup signal handlers for kTestSignal1 and kTestSignal2. 56 struct sigaction sa; 57 sa.sa_sigaction = SigHandler; 58 sigfillset(&sa.sa_mask); 59 sa.sa_flags = SA_SIGINFO; 60 EXPECT_THAT(sigaction(kTestSignal1, &sa, &sa_test_sig_1_), 61 SyscallSucceeds()); 62 EXPECT_THAT(sigaction(kTestSignal2, &sa, &sa_test_sig_2_), 63 SyscallSucceeds()); 64 65 // Clear the signal counters. 66 memset(signal_count, 0, sizeof(signal_count)); 67 } 68 69 void TearDown() override { 70 // Restore the signal mask. 71 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, &mask_, nullptr), 72 SyscallSucceeds()); 73 74 // Restore the signal handlers for kTestSignal1 and kTestSignal2. 75 EXPECT_THAT(sigaction(kTestSignal1, &sa_test_sig_1_, nullptr), 76 SyscallSucceeds()); 77 EXPECT_THAT(sigaction(kTestSignal2, &sa_test_sig_2_, nullptr), 78 SyscallSucceeds()); 79 } 80 81 private: 82 sigset_t mask_; 83 struct sigaction sa_test_sig_1_; 84 struct sigaction sa_test_sig_2_; 85 }; 86 87 // Both sigsets nullptr should succeed and do nothing. 88 TEST_F(SigProcMaskTest, NullAddress) { 89 EXPECT_THAT(raw_sigprocmask(SIG_BLOCK, nullptr, NULL), SyscallSucceeds()); 90 EXPECT_THAT(raw_sigprocmask(SIG_UNBLOCK, nullptr, NULL), SyscallSucceeds()); 91 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, nullptr, NULL), SyscallSucceeds()); 92 } 93 94 // Bad address for either sigset should fail with EFAULT. 95 TEST_F(SigProcMaskTest, BadAddress) { 96 sigset_t* bad_addr = reinterpret_cast<sigset_t*>(-1); 97 98 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, bad_addr, nullptr), 99 SyscallFailsWithErrno(EFAULT)); 100 101 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, nullptr, bad_addr), 102 SyscallFailsWithErrno(EFAULT)); 103 } 104 105 // Bad value of the "how" parameter should fail with EINVAL. 106 TEST_F(SigProcMaskTest, BadParameter) { 107 int bad_param_1 = -1; 108 int bad_param_2 = 42; 109 110 sigset_t set1; 111 sigemptyset(&set1); 112 113 EXPECT_THAT(raw_sigprocmask(bad_param_1, &set1, nullptr), 114 SyscallFailsWithErrno(EINVAL)); 115 116 EXPECT_THAT(raw_sigprocmask(bad_param_2, &set1, nullptr), 117 SyscallFailsWithErrno(EINVAL)); 118 } 119 120 // Check that we can get the current signal mask. 121 TEST_F(SigProcMaskTest, GetMask) { 122 sigset_t set1; 123 sigset_t set2; 124 125 sigemptyset(&set1); 126 sigfillset(&set2); 127 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, nullptr, &set1), SyscallSucceeds()); 128 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, nullptr, &set2), SyscallSucceeds()); 129 EXPECT_THAT(set1, EqualsSigset(set2)); 130 } 131 132 // Check that we can set the signal mask. 133 TEST_F(SigProcMaskTest, SetMask) { 134 sigset_t actual; 135 sigset_t expected; 136 137 // Try to mask all signals 138 sigfillset(&expected); 139 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, &expected, nullptr), 140 SyscallSucceeds()); 141 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, nullptr, &actual), 142 SyscallSucceeds()); 143 // sigprocmask() should have silently ignored SIGKILL and SIGSTOP. 144 sigdelset(&expected, SIGSTOP); 145 sigdelset(&expected, SIGKILL); 146 EXPECT_THAT(actual, EqualsSigset(expected)); 147 148 // Try to clear the signal mask 149 sigemptyset(&expected); 150 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, &expected, nullptr), 151 SyscallSucceeds()); 152 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, nullptr, &actual), 153 SyscallSucceeds()); 154 EXPECT_THAT(actual, EqualsSigset(expected)); 155 156 // Try to set a mask with one signal. 157 sigemptyset(&expected); 158 sigaddset(&expected, kTestSignal1); 159 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, &expected, nullptr), 160 SyscallSucceeds()); 161 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, nullptr, &actual), 162 SyscallSucceeds()); 163 EXPECT_THAT(actual, EqualsSigset(expected)); 164 } 165 166 // Check that we can add and remove signals. 167 TEST_F(SigProcMaskTest, BlockUnblock) { 168 sigset_t actual; 169 sigset_t expected; 170 171 // Try to set a mask with one signal. 172 sigemptyset(&expected); 173 sigaddset(&expected, kTestSignal1); 174 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, &expected, nullptr), 175 SyscallSucceeds()); 176 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, nullptr, &actual), 177 SyscallSucceeds()); 178 EXPECT_THAT(actual, EqualsSigset(expected)); 179 180 // Try to add another signal. 181 sigset_t block; 182 sigemptyset(&block); 183 sigaddset(&block, kTestSignal2); 184 EXPECT_THAT(raw_sigprocmask(SIG_BLOCK, &block, nullptr), SyscallSucceeds()); 185 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, nullptr, &actual), 186 SyscallSucceeds()); 187 sigaddset(&expected, kTestSignal2); 188 EXPECT_THAT(actual, EqualsSigset(expected)); 189 190 // Try to remove a signal. 191 sigset_t unblock; 192 sigemptyset(&unblock); 193 sigaddset(&unblock, kTestSignal1); 194 EXPECT_THAT(raw_sigprocmask(SIG_UNBLOCK, &unblock, nullptr), 195 SyscallSucceeds()); 196 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, nullptr, &actual), 197 SyscallSucceeds()); 198 sigdelset(&expected, kTestSignal1); 199 EXPECT_THAT(actual, EqualsSigset(expected)); 200 } 201 202 // Test that the signal mask actually blocks signals. 203 TEST_F(SigProcMaskTest, SignalHandler) { 204 sigset_t mask; 205 206 // clear the signal mask 207 sigemptyset(&mask); 208 EXPECT_THAT(raw_sigprocmask(SIG_SETMASK, &mask, nullptr), SyscallSucceeds()); 209 210 // Check the initial signal counts. 211 EXPECT_EQ(0, signal_count[kTestSignal1]); 212 EXPECT_EQ(0, signal_count[kTestSignal2]); 213 214 // Check that both kTestSignal1 and kTestSignal2 are not blocked. 215 raise(kTestSignal1); 216 raise(kTestSignal2); 217 EXPECT_EQ(1, signal_count[kTestSignal1]); 218 EXPECT_EQ(1, signal_count[kTestSignal2]); 219 220 // Block kTestSignal1. 221 sigaddset(&mask, kTestSignal1); 222 EXPECT_THAT(raw_sigprocmask(SIG_BLOCK, &mask, nullptr), SyscallSucceeds()); 223 224 // Check that kTestSignal1 is blocked. 225 raise(kTestSignal1); 226 raise(kTestSignal2); 227 EXPECT_EQ(1, signal_count[kTestSignal1]); 228 EXPECT_EQ(2, signal_count[kTestSignal2]); 229 230 // Unblock kTestSignal1. 231 sigaddset(&mask, kTestSignal1); 232 EXPECT_THAT(raw_sigprocmask(SIG_UNBLOCK, &mask, nullptr), SyscallSucceeds()); 233 234 // Check that the unblocked kTestSignal1 has been delivered. 235 EXPECT_EQ(2, signal_count[kTestSignal1]); 236 EXPECT_EQ(2, signal_count[kTestSignal2]); 237 } 238 239 // Check that sigprocmask correctly handles aliasing of the set and oldset 240 // pointers. Regression test for b/30502311. 241 TEST_F(SigProcMaskTest, AliasedSets) { 242 sigset_t mask; 243 244 // Set a mask in which only kTestSignal1 is blocked. 245 sigset_t mask1; 246 sigemptyset(&mask1); 247 sigaddset(&mask1, kTestSignal1); 248 mask = mask1; 249 ASSERT_THAT(raw_sigprocmask(SIG_SETMASK, &mask, nullptr), SyscallSucceeds()); 250 251 // Exchange it with a mask in which only kTestSignal2 is blocked. 252 sigset_t mask2; 253 sigemptyset(&mask2); 254 sigaddset(&mask2, kTestSignal2); 255 mask = mask2; 256 ASSERT_THAT(raw_sigprocmask(SIG_SETMASK, &mask, &mask), SyscallSucceeds()); 257 258 // Check that the exchange succeeeded: 259 // mask should now contain the previously-set mask blocking only kTestSignal1. 260 EXPECT_THAT(mask, EqualsSigset(mask1)); 261 // The current mask should block only kTestSignal2. 262 ASSERT_THAT(raw_sigprocmask(0, nullptr, &mask), SyscallSucceeds()); 263 EXPECT_THAT(mask, EqualsSigset(mask2)); 264 } 265 266 } // namespace 267 268 } // namespace testing 269 } // namespace gvisor