diff mbox series

[v2,3/8] nptl: Make pthread_kill async-signal-safe

Message ID 20201207212757.3948164-3-adhemerval.zanella@linaro.org
State New
Headers show
Series [v2,1/8] nptl: Move Linux pthread_kill to nptl | expand

Commit Message

Adhemerval Zanella Dec. 7, 2020, 9:27 p.m. UTC
Changes from previous version:

  * Move __libc_signal_block_all prior TID read.

--

Simiar to raise (BZ #15368), pthread_kill is also defined as
async-signal-safe (POSIX.1-2008 TC1).  However, similar to raise
it has the same issues relating to signal handling.

Different than raise, all the signal are blocked so it would be
possible to implement pthread_cancel (which also should be
async-cancel safe).

Checked on x86_64-linux-gnu.
---
 nptl/pthread_kill.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c
index 7ef68d1572..006322ea9f 100644
--- a/nptl/pthread_kill.c
+++ b/nptl/pthread_kill.c
@@ -27,6 +27,11 @@  __pthread_kill (pthread_t threadid, int signo)
   if (__is_internal_signal (signo))
     return EINVAL;
 
+  sigset_t set;
+  __libc_signal_block_all (&set);
+
+  int val;
+
   /* Force load of pd->tid into local variable or register.  Otherwise
      if a thread exits between ESRCH test and tgkill, we might return
      EINVAL, because pd->tid would be cleared by the kernel.  */
@@ -34,13 +39,19 @@  __pthread_kill (pthread_t threadid, int signo)
   pid_t tid = atomic_forced_read (pd->tid);
   if (__glibc_unlikely (tid <= 0))
     /* Not a valid thread handle.  */
-    return ESRCH;
+    val = ESRCH;
+  else
+    {
+      /* We have a special syscall to do the work.  */
+      pid_t pid = __getpid ();
+
+      val = INTERNAL_SYSCALL_CALL (tgkill, pid, tid, signo);
+      val = (INTERNAL_SYSCALL_ERROR_P (val)
+	    ? INTERNAL_SYSCALL_ERRNO (val) : 0);
+    }
 
-  /* We have a special syscall to do the work.  */
-  pid_t pid = __getpid ();
+  __libc_signal_restore_set (&set);
 
-  int val = INTERNAL_SYSCALL_CALL (tgkill, pid, tid, signo);
-  return (INTERNAL_SYSCALL_ERROR_P (val)
-	  ? INTERNAL_SYSCALL_ERRNO (val) : 0);
+  return val;
 }
 strong_alias (__pthread_kill, pthread_kill)