@@ -141,15 +141,6 @@ __nptl_set_robust (struct pthread *self)
static void
sigcancel_handler (int sig, siginfo_t *si, void *ctx)
{
- /* Safety check. It would be possible to call this function for
- other signals and send a signal from another process. This is not
- correct and might even be a security problem. Try to catch as
- many incorrect invocations as possible. */
- if (sig != SIGCANCEL
- || si->si_pid != __getpid()
- || si->si_code != SI_TKILL)
- return;
-
struct pthread *self = THREAD_SELF;
int oldval = THREAD_GETMEM (self, cancelhandling);
@@ -29,13 +29,10 @@ pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask)
/* The only thing we have to make sure here is that SIGCANCEL and
SIGSETXID is not blocked. */
- if (newmask != NULL
- && (__builtin_expect (__sigismember (newmask, SIGCANCEL), 0)
- || __builtin_expect (__sigismember (newmask, SIGSETXID), 0)))
+ if (newmask != NULL && __contain_internal_signal (newmask))
{
local_newmask = *newmask;
- __sigdelset (&local_newmask, SIGCANCEL);
- __sigdelset (&local_newmask, SIGSETXID);
+ __clear_internal_signals (&local_newmask);
newmask = &local_newmask;
}
@@ -29,6 +29,12 @@ __is_internal_signal (int sig)
return false;
}
+static inline bool
+__contain_internal_signal (const sigset_t *set)
+{
+ return false;
+}
+
static inline void
__clear_internal_signals (sigset_t *set)
{
@@ -19,13 +19,9 @@
#include <signal.h>
#include <nptl/pthreadP.h>
-#if SIGTIMER != SIGCANCEL
-# error "SIGTIMER and SIGCANCEL must be the same"
-#endif
-
/* This tells the generic code (included below) how many signal
numbers need to be reserved for libpthread's private uses
- (SIGCANCEL and SIGSETXID). */
-#define RESERVED_SIGRT 2
+ (SIGCANCEL, SIGSETXID, and SIGTIMER). */
+#define RESERVED_SIGRT 3
#include <signal/allocrtsig.c>
@@ -29,21 +29,27 @@
#define SIGCANCEL __SIGRTMIN
-/* Signal needed for the kernel-supported POSIX timer implementation.
- We can reuse the cancellation signal since we can distinguish
- cancellation from timer expirations. */
-#define SIGTIMER SIGCANCEL
-
-
/* Signal used to implement the setuid et.al. functions. */
#define SIGSETXID (__SIGRTMIN + 1)
+/* Signal needed for the kernel-supported POSIX timer implementation. */
+#define SIGTIMER (__SIGRTMIN + 2)
+
+
/* Return is sig is used internally. */
static inline bool
__is_internal_signal (int sig)
{
- return (sig == SIGCANCEL) || (sig == SIGSETXID);
+ return (sig == SIGCANCEL) || (sig == SIGSETXID) || (sig == SIGTIMER);
+}
+
+/* Return true is SIG is withing the signal set SET, or false otherwise. */
+static inline bool
+__contain_internal_signal (const sigset_t *set)
+{
+ return __sigismember (set, SIGCANCEL) || __sigismember (set, SIGSETXID)
+ || __sigismember (set, SIGTIMER);
}
/* Remove internal glibc signal from the mask. */
@@ -52,6 +58,7 @@ __clear_internal_signals (sigset_t *set)
{
__sigdelset (set, SIGCANCEL);
__sigdelset (set, SIGSETXID);
+ __sigdelset (set, SIGTIMER);
}
static const sigset_t sigall_set = {
@@ -44,7 +44,7 @@ __pthread_kill (pthread_t threadid, int signo)
/* Disallow sending the signal we use for cancellation, timers,
for the setxid implementation. */
- if (signo == SIGCANCEL || signo == SIGTIMER || signo == SIGSETXID)
+ if (__is_internal_signal (signo))
return EINVAL;
/* We have a special syscall to do the work. */
@@ -46,7 +46,7 @@ pthread_sigqueue (pthread_t threadid, int signo, const union sigval value)
/* Disallow sending the signal we use for cancellation, timers,
for the setxid implementation. */
- if (signo == SIGCANCEL || signo == SIGTIMER || signo == SIGSETXID)
+ if (__is_internal_signal (signo))
return EINVAL;
pid_t pid = getpid ();
@@ -26,13 +26,10 @@ __sigprocmask (int how, const sigset_t *set, sigset_t *oset)
/* The only thing we have to make sure here is that SIGCANCEL and
SIGSETXID are not blocked. */
- if (set != NULL
- && __glibc_unlikely (__sigismember (set, SIGCANCEL)
- || __glibc_unlikely (__sigismember (set, SIGSETXID))))
+ if (set != NULL && __contain_internal_signal (set))
{
local_newmask = *set;
- __sigdelset (&local_newmask, SIGCANCEL);
- __sigdelset (&local_newmask, SIGSETXID);
+ __clear_internal_signals (&local_newmask);
set = &local_newmask;
}
@@ -167,7 +167,7 @@ __start_helper_thread (void)
sigset_t ss;
sigset_t oss;
sigfillset (&ss);
- __sigaddset (&ss, SIGCANCEL);
+ __sigaddset (&ss, SIGTIMER);
INTERNAL_SYSCALL_DECL (err);
INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, &oss, _NSIG / 8);