Filter out reserved signals in functions that take sigset_t.

Prevent processes from blocking libc-reserved signals by filtering them
out.

Bug: http://b/73144101
Test: 32/64-bit bionic-unit-tests-glibc
Test: 32/64-bit bionic-unit-tests on taimen
Change-Id: Ibadcaa7f668ed8be885cc61b67fb4b611fce8b17
diff --git a/libc/bionic/__libc_current_sigrtmin.cpp b/libc/bionic/__libc_current_sigrtmin.cpp
index 04caa89..d2ea75d 100644
--- a/libc/bionic/__libc_current_sigrtmin.cpp
+++ b/libc/bionic/__libc_current_sigrtmin.cpp
@@ -28,14 +28,8 @@
 
 #include <signal.h>
 
-// Realtime signals reserved for internal use:
-//   32 (__SIGRTMIN + 0)        POSIX timers
-//   33 (__SIGRTMIN + 1)        libbacktrace
-//   34 (__SIGRTMIN + 2)        libcore
-//   35 (__SIGRTMIN + 3)        debuggerd -b
+#include "private/sigrtmin.h"
 
-int __libc_current_sigrtmin(void) {
-  // If you change this, also change __ndk_legacy___libc_current_sigrtmin
-  // in <android/legacy_signal_inlines.h> to match.
-  return __SIGRTMIN + 4;
+int __libc_current_sigrtmin() {
+  return __SIGRTMIN + __SIGRT_RESERVED;
 }
diff --git a/libc/bionic/poll.cpp b/libc/bionic/poll.cpp
index 1a54832..3df8b18 100644
--- a/libc/bionic/poll.cpp
+++ b/libc/bionic/poll.cpp
@@ -31,6 +31,7 @@
 #include <sys/select.h>
 
 #include "private/bionic_time_conversions.h"
+#include "private/sigrtmin.h"
 #include "private/SigSetConverter.h"
 
 extern "C" int __ppoll(pollfd*, unsigned int, timespec*, const sigset64_t*, size_t);
@@ -66,7 +67,15 @@
     mutable_ts = *ts;
     mutable_ts_ptr = &mutable_ts;
   }
-  return __ppoll(fds, fd_count, mutable_ts_ptr, ss, sizeof(*ss));
+
+  sigset64_t mutable_ss;
+  sigset64_t* mutable_ss_ptr = nullptr;
+  if (ss != nullptr) {
+    mutable_ss = filter_reserved_signals(*ss);
+    mutable_ss_ptr = &mutable_ss;
+  }
+
+  return __ppoll(fds, fd_count, mutable_ts_ptr, mutable_ss_ptr, sizeof(*mutable_ss_ptr));
 }
 
 int select(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds, timeval* tv) {
@@ -109,6 +118,13 @@
     mutable_ts_ptr = &mutable_ts;
   }
 
+  sigset64_t mutable_ss;
+  sigset64_t* mutable_ss_ptr = nullptr;
+  if (ss != nullptr) {
+    mutable_ss = filter_reserved_signals(*ss);
+    mutable_ss_ptr = &mutable_ss;
+  }
+
   // The Linux kernel only handles 6 arguments and this system call really needs 7,
   // so the last argument is a void* pointing to:
   struct pselect6_extra_data_t {
@@ -116,8 +132,8 @@
     size_t ss_len;
   };
   pselect6_extra_data_t extra_data;
-  extra_data.ss_addr = reinterpret_cast<uintptr_t>(ss);
-  extra_data.ss_len = sizeof(*ss);
+  extra_data.ss_addr = reinterpret_cast<uintptr_t>(mutable_ss_ptr);
+  extra_data.ss_len = sizeof(*mutable_ss_ptr);
 
   return __pselect6(fd_count, read_fds, write_fds, error_fds, mutable_ts_ptr, &extra_data);
 }
diff --git a/libc/bionic/posix_timers.cpp b/libc/bionic/posix_timers.cpp
index 2edfe97..1abeb1f 100644
--- a/libc/bionic/posix_timers.cpp
+++ b/libc/bionic/posix_timers.cpp
@@ -35,6 +35,8 @@
 #include <time.h>
 
 // System calls.
+extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
+extern "C" int __rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t);
 extern "C" int __timer_create(clockid_t, sigevent*, __kernel_timer_t*);
 extern "C" int __timer_delete(__kernel_timer_t);
 extern "C" int __timer_getoverrun(__kernel_timer_t);
@@ -77,7 +79,7 @@
   while (true) {
     // Wait for a signal...
     siginfo_t si = {};
-    if (sigtimedwait64(&sigset, &si, nullptr) == -1) continue;
+    if (__rt_sigtimedwait(&sigset, &si, nullptr, sizeof(sigset)) == -1) continue;
 
     if (si.si_code == SI_TIMER) {
       // This signal was sent because a timer fired, so call the callback.
@@ -146,11 +148,13 @@
   sigset64_t sigset = {};
   sigaddset64(&sigset, TIMER_SIGNAL);
   sigset64_t old_sigset;
-  sigprocmask64(SIG_BLOCK, &sigset, &old_sigset);
+
+  // Use __rt_sigprocmask instead of sigprocmask64 to avoid filtering out TIMER_SIGNAL.
+  __rt_sigprocmask(SIG_BLOCK, &sigset, &old_sigset, sizeof(sigset));
 
   int rc = pthread_create(&timer->callback_thread, &thread_attributes, __timer_thread_start, timer);
 
-  sigprocmask64(SIG_SETMASK, &old_sigset, nullptr);
+  __rt_sigprocmask(SIG_BLOCK, &old_sigset, nullptr, sizeof(old_sigset));
 
   if (rc != 0) {
     free(timer);
diff --git a/libc/bionic/sigaction.cpp b/libc/bionic/sigaction.cpp
index 19a08e6..41923cf 100644
--- a/libc/bionic/sigaction.cpp
+++ b/libc/bionic/sigaction.cpp
@@ -29,6 +29,8 @@
 #include <signal.h>
 #include <string.h>
 
+#include "private/sigrtmin.h"
+
 extern "C" void __restore_rt(void);
 extern "C" void __restore(void);
 
@@ -41,7 +43,7 @@
   if (bionic_new_action != NULL) {
     kernel_new_action.sa_flags = bionic_new_action->sa_flags;
     kernel_new_action.sa_handler = bionic_new_action->sa_handler;
-    kernel_new_action.sa_mask = bionic_new_action->sa_mask;
+    kernel_new_action.sa_mask = filter_reserved_signals(bionic_new_action->sa_mask);
 #if defined(SA_RESTORER)
     kernel_new_action.sa_restorer = bionic_new_action->sa_restorer;
 #if defined(__aarch64__)
@@ -120,6 +122,7 @@
       kernel_new.sa_restorer = (kernel_new.sa_flags & SA_SIGINFO) ? &__restore_rt : &__restore;
     }
 #endif
+    kernel_new.sa_mask = filter_reserved_signals(kernel_new.sa_mask);
   }
 
   return __rt_sigaction(signal,
diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp
index f2e19c2..175182b 100644
--- a/libc/bionic/signal.cpp
+++ b/libc/bionic/signal.cpp
@@ -38,6 +38,7 @@
 
 #include "private/ErrnoRestorer.h"
 #include "private/SigSetConverter.h"
+#include "private/sigrtmin.h"
 
 extern "C" int __rt_sigpending(const sigset64_t*, size_t);
 extern "C" int ___rt_sigqueueinfo(pid_t, int, siginfo_t*);
@@ -255,21 +256,33 @@
 int sigsuspend(const sigset_t* bionic_set) {
   SigSetConverter set = {};
   set.sigset = *bionic_set;
-  return __rt_sigsuspend(&set.sigset64, sizeof(set.sigset64));
+  return sigsuspend64(&set.sigset64);
 }
 
 int sigsuspend64(const sigset64_t* set) {
-  return __rt_sigsuspend(set, sizeof(*set));
+  sigset64_t mutable_set;
+  sigset64_t* mutable_set_ptr = nullptr;
+  if (set) {
+    mutable_set = filter_reserved_signals(*set);
+    mutable_set_ptr = &mutable_set;
+  }
+  return __rt_sigsuspend(mutable_set_ptr, sizeof(*set));
 }
 
 int sigtimedwait(const sigset_t* bionic_set, siginfo_t* info, const timespec* timeout) {
   SigSetConverter set = {};
   set.sigset = *bionic_set;
-  return __rt_sigtimedwait(&set.sigset64, info, timeout, sizeof(set.sigset64));
+  return sigtimedwait64(&set.sigset64, info, timeout);
 }
 
 int sigtimedwait64(const sigset64_t* set, siginfo_t* info, const timespec* timeout) {
-  return __rt_sigtimedwait(set, info, timeout, sizeof(*set));
+  sigset64_t mutable_set;
+  sigset64_t* mutable_set_ptr = nullptr;
+  if (set) {
+    mutable_set = filter_reserved_signals(*set);
+    mutable_set_ptr = &mutable_set;
+  }
+  return __rt_sigtimedwait(mutable_set_ptr, info, timeout, sizeof(*set));
 }
 
 int sigwait(const sigset_t* bionic_set, int* sig) {
diff --git a/libc/bionic/sigprocmask.cpp b/libc/bionic/sigprocmask.cpp
index 00b5df4..36866f3 100644
--- a/libc/bionic/sigprocmask.cpp
+++ b/libc/bionic/sigprocmask.cpp
@@ -28,6 +28,7 @@
 
 #include <signal.h>
 
+#include "private/sigrtmin.h"
 #include "private/SigSetConverter.h"
 
 extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
@@ -64,5 +65,11 @@
 int sigprocmask64(int how,
                   const sigset64_t* new_set,
                   sigset64_t* old_set) __attribute__((__noinline__)) {
-  return __rt_sigprocmask(how, new_set, old_set, sizeof(*new_set));
+  sigset64_t mutable_new_set;
+  sigset64_t* mutable_new_set_ptr = nullptr;
+  if (new_set) {
+    mutable_new_set = filter_reserved_signals(*new_set);
+    mutable_new_set_ptr = &mutable_new_set;
+  }
+  return __rt_sigprocmask(how, mutable_new_set_ptr, old_set, sizeof(*new_set));
 }