Block TIMER_SIGNAL in sigprocmask(SIG_SETMASK, ...).

Previously, we were zeroing out the reserved signals, when we actually
wanted to have TIMER_SIGNAL always be blocked, and the other signals
always be unblocked. This resulted in process termination when a
SIGEV_THREAD timer callback calls sigprocmask(SIG_SETMASK, ...) with
any signal mask value, and then subsequently fails to complete its
callback and reach the sigtimedwait in bionic before the next timer
iteration triggers.

Add a how argument to filter_reserved_signals to appropriately
block/unblock our reserved signals.

Bug: http://b/116783733
Test: bionic-unit-tests32/64
Change-Id: Ie5339682cdeb914711cd4089cd26ee395704d0df
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index 52a097b..dd27aef 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -22,6 +22,7 @@
 
 #include <thread>
 
+#include <android-base/macros.h>
 #include <gtest/gtest.h>
 
 #include "SignalUtils.h"
@@ -339,6 +340,17 @@
 
 static void ClearSignalMask() {
   uint64_t sigset = 0;
+  SignalSetAdd(&sigset, __SIGRTMIN);
+  if (syscall(__NR_rt_sigprocmask, SIG_SETMASK, &sigset, nullptr, sizeof(sigset)) != 0) {
+    abort();
+  }
+}
+
+static void FillSignalMask() {
+  uint64_t sigset = ~0ULL;
+  for (int signo = __SIGRTMIN + 1; signo < SIGRTMIN; ++signo) {
+    SignalSetDel(&sigset, signo);
+  }
   if (syscall(__NR_rt_sigprocmask, SIG_SETMASK, &sigset, nullptr, sizeof(sigset)) != 0) {
     abort();
   }
@@ -352,40 +364,27 @@
   return sigset;
 }
 
-enum class SignalMaskFunctionType {
-  RtAware,
-  RtNonaware,
-};
-
-#if defined(__LP64__) || !defined(__BIONIC__)
-constexpr SignalMaskFunctionType sigset_type = SignalMaskFunctionType::RtAware;
-#else
-constexpr SignalMaskFunctionType sigset_type = SignalMaskFunctionType::RtNonaware;
-#endif
-
-static void TestSignalMaskFiltered(uint64_t sigset, SignalMaskFunctionType type) {
-  for (int signo = 1; signo <= 64; ++signo) {
+static void TestSignalMaskFiltered(uint64_t sigset) {
+#if defined(__BIONIC__)
+  for (int signo = __SIGRTMIN; signo < SIGRTMIN; ++signo) {
     bool signal_blocked = sigset & (1ULL << (signo - 1));
-    if (signo == SIGKILL || signo == SIGSTOP) {
-      // SIGKILL and SIGSTOP shouldn't be blocked.
-      EXPECT_EQ(false, signal_blocked) << "signal " << signo;
-    } else if (signo < __SIGRTMIN) {
-      // Everything else should be blocked.
+    if (signo == __SIGRTMIN) {
+      // TIMER_SIGNAL must be blocked.
       EXPECT_EQ(true, signal_blocked) << "signal " << signo;
-    } else if (signo >= __SIGRTMIN && signo < SIGRTMIN) {
-      // Reserved signals must not be blocked.
+    } else {
+      // The other reserved signals must not be blocked.
       EXPECT_EQ(false, signal_blocked) << "signal " << signo;
-    } else if (type == SignalMaskFunctionType::RtAware) {
-      // Realtime signals should be blocked, unless we blocked using a non-rt aware function.
-      EXPECT_EQ(true, signal_blocked) << "signal " << signo;
     }
   }
+#else
+  UNUSED(sigset);
+#endif
 }
 
-static void TestSignalMaskFunction(std::function<void()> fn, SignalMaskFunctionType fn_type) {
+static void TestSignalMaskFunction(std::function<void()> fn) {
   ClearSignalMask();
   fn();
-  TestSignalMaskFiltered(GetSignalMask(), fn_type);
+  TestSignalMaskFiltered(GetSignalMask());
 }
 
 TEST(signal, sigaction_filter) {
@@ -397,7 +396,7 @@
   sigaction(SIGUSR1, &sa, nullptr);
   raise(SIGUSR1);
   ASSERT_NE(0ULL, sigset);
-  TestSignalMaskFiltered(sigset, sigset_type);
+  TestSignalMaskFiltered(sigset);
 }
 
 TEST(signal, sigaction64_filter) {
@@ -409,111 +408,135 @@
   sigaction64(SIGUSR1, &sa, nullptr);
   raise(SIGUSR1);
   ASSERT_NE(0ULL, sigset);
-  TestSignalMaskFiltered(sigset, SignalMaskFunctionType::RtAware);
+  TestSignalMaskFiltered(sigset);
 }
 
 TEST(signal, sigprocmask_setmask_filter) {
-  TestSignalMaskFunction(
-      []() {
-        sigset_t sigset_libc;
-        sigfillset(&sigset_libc);
-        ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &sigset_libc, nullptr));
-      },
-      sigset_type);
+  TestSignalMaskFunction([]() {
+    ClearSignalMask();
+    sigset_t sigset_libc;
+    sigfillset(&sigset_libc);
+    ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &sigset_libc, nullptr));
+  });
 }
 
 TEST(signal, sigprocmask64_setmask_filter) {
-  TestSignalMaskFunction(
-      []() {
-        sigset64_t sigset_libc;
-        sigfillset64(&sigset_libc);
-        ASSERT_EQ(0, sigprocmask64(SIG_SETMASK, &sigset_libc, nullptr));
-      },
-      SignalMaskFunctionType::RtAware);
+  TestSignalMaskFunction([]() {
+    ClearSignalMask();
+    sigset64_t sigset_libc;
+    sigfillset64(&sigset_libc);
+    ASSERT_EQ(0, sigprocmask64(SIG_SETMASK, &sigset_libc, nullptr));
+  });
 }
 
 TEST(signal, pthread_sigmask_setmask_filter) {
-  TestSignalMaskFunction(
-      []() {
-        sigset_t sigset_libc;
-        sigfillset(&sigset_libc);
-        ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &sigset_libc, nullptr));
-      },
-      sigset_type);
+  TestSignalMaskFunction([]() {
+    ClearSignalMask();
+    sigset_t sigset_libc;
+    sigfillset(&sigset_libc);
+    ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &sigset_libc, nullptr));
+  });
 }
 
 TEST(signal, pthread_sigmask64_setmask_filter) {
-  TestSignalMaskFunction(
-      []() {
-        sigset64_t sigset_libc;
-        sigfillset64(&sigset_libc);
-        ASSERT_EQ(0, pthread_sigmask64(SIG_SETMASK, &sigset_libc, nullptr));
-      },
-      SignalMaskFunctionType::RtAware);
+  TestSignalMaskFunction([]() {
+    ClearSignalMask();
+    sigset64_t sigset_libc;
+    sigfillset64(&sigset_libc);
+    ASSERT_EQ(0, pthread_sigmask64(SIG_SETMASK, &sigset_libc, nullptr));
+  });
 }
 
 TEST(signal, sigprocmask_block_filter) {
-  TestSignalMaskFunction(
-      []() {
-        sigset_t sigset_libc;
-        sigfillset(&sigset_libc);
-        ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &sigset_libc, nullptr));
-      },
-      sigset_type);
+  TestSignalMaskFunction([]() {
+    ClearSignalMask();
+    sigset_t sigset_libc;
+    sigfillset(&sigset_libc);
+    ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &sigset_libc, nullptr));
+  });
 }
 
 TEST(signal, sigprocmask64_block_filter) {
-  TestSignalMaskFunction(
-      []() {
-        sigset64_t sigset_libc;
-        sigfillset64(&sigset_libc);
-        ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &sigset_libc, nullptr));
-      },
-      SignalMaskFunctionType::RtAware);
+  TestSignalMaskFunction([]() {
+    ClearSignalMask();
+    sigset64_t sigset_libc;
+    sigfillset64(&sigset_libc);
+    ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &sigset_libc, nullptr));
+  });
 }
 
 TEST(signal, pthread_sigmask_block_filter) {
-  TestSignalMaskFunction(
-      []() {
-        sigset_t sigset_libc;
-        sigfillset(&sigset_libc);
-        ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, &sigset_libc, nullptr));
-      },
-      sigset_type);
+  TestSignalMaskFunction([]() {
+    ClearSignalMask();
+    sigset_t sigset_libc;
+    sigfillset(&sigset_libc);
+    ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, &sigset_libc, nullptr));
+  });
 }
 
 TEST(signal, pthread_sigmask64_block_filter) {
-  TestSignalMaskFunction(
-      []() {
-        sigset64_t sigset_libc;
-        sigfillset64(&sigset_libc);
-        ASSERT_EQ(0, pthread_sigmask64(SIG_BLOCK, &sigset_libc, nullptr));
-      },
-      SignalMaskFunctionType::RtAware);
+  TestSignalMaskFunction([]() {
+    ClearSignalMask();
+    sigset64_t sigset_libc;
+    sigfillset64(&sigset_libc);
+    ASSERT_EQ(0, pthread_sigmask64(SIG_BLOCK, &sigset_libc, nullptr));
+  });
+}
+
+TEST(signal, sigprocmask_unblock_filter) {
+  TestSignalMaskFunction([]() {
+    FillSignalMask();
+    sigset_t sigset_libc;
+    sigfillset(&sigset_libc);
+    ASSERT_EQ(0, sigprocmask(SIG_UNBLOCK, &sigset_libc, nullptr));
+  });
+}
+
+TEST(signal, sigprocmask64_unblock_filter) {
+  TestSignalMaskFunction([]() {
+    FillSignalMask();
+    sigset64_t sigset_libc;
+    sigfillset64(&sigset_libc);
+    ASSERT_EQ(0, sigprocmask64(SIG_UNBLOCK, &sigset_libc, nullptr));
+  });
+}
+
+TEST(signal, pthread_sigmask_unblock_filter) {
+  TestSignalMaskFunction([]() {
+    FillSignalMask();
+    sigset_t sigset_libc;
+    sigfillset(&sigset_libc);
+    ASSERT_EQ(0, pthread_sigmask(SIG_UNBLOCK, &sigset_libc, nullptr));
+  });
+}
+
+TEST(signal, pthread_sigmask64_unblock_filter) {
+  TestSignalMaskFunction([]() {
+    FillSignalMask();
+    sigset64_t sigset_libc;
+    sigfillset64(&sigset_libc);
+    ASSERT_EQ(0, pthread_sigmask64(SIG_UNBLOCK, &sigset_libc, nullptr));
+  });
 }
 
 // glibc filters out signals via sigfillset, not the actual underlying functions.
 TEST(signal, sigset_filter) {
 #if defined(__BIONIC__)
-  TestSignalMaskFunction(
-      []() {
-        for (int i = 1; i <= 64; ++i) {
-          sigset(i, SIG_HOLD);
-        }
-      },
-      SignalMaskFunctionType::RtAware);
+  TestSignalMaskFunction([]() {
+    for (int i = 1; i <= 64; ++i) {
+      sigset(i, SIG_HOLD);
+    }
+  });
 #endif
 }
 
 TEST(signal, sighold_filter) {
 #if defined(__BIONIC__)
-  TestSignalMaskFunction(
-      []() {
-        for (int i = 1; i <= 64; ++i) {
-          sighold(i);
-        }
-      },
-      SignalMaskFunctionType::RtAware);
+  TestSignalMaskFunction([]() {
+    for (int i = 1; i <= 64; ++i) {
+      sighold(i);
+    }
+  });
 #endif
 }
 
@@ -525,23 +548,17 @@
 
 TEST(signal, sigblock_filter) {
 #if defined(__BIONIC__)
-  TestSignalMaskFunction(
-      []() {
-        int mask = ~0U;
-        ASSERT_EQ(0, sigblock(mask));
-      },
-      SignalMaskFunctionType::RtNonaware);
+  TestSignalMaskFunction([]() {
+    sigblock(~0U);
+  });
 #endif
 }
 
 TEST(signal, sigsetmask_filter) {
 #if defined(__BIONIC__)
-  TestSignalMaskFunction(
-      []() {
-        int mask = ~0U;
-        ASSERT_EQ(0, sigsetmask(mask));
-      },
-      SignalMaskFunctionType::RtNonaware);
+  TestSignalMaskFunction([]() {
+    sigsetmask(~0U);
+  });
 #endif
 }