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