about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2013-08-31 01:12:00 -0400
committerRich Felker <dalias@aerifal.cx>2013-08-31 01:12:00 -0400
commit7cc49f98a2b5346259d2209ba14d7c18959f9369 (patch)
treeb51534ed3320b2621a59d4bd9d70b8a83ed8409f
parentd0f0fa484c5216710936715c176f67b3781e4b71 (diff)
downloadmusl-7cc49f98a2b5346259d2209ba14d7c18959f9369.tar.gz
musl-7cc49f98a2b5346259d2209ba14d7c18959f9369.tar.xz
musl-7cc49f98a2b5346259d2209ba14d7c18959f9369.zip
fix breakage in synccall due to incorrect signal restoration in sigqueue
commit 07827d1a82fb33262f686eda959857f0d28cd8fa seems to have
introduced this issue. sigqueue is called from the synccall core, at
which time, even implementation-internal signals are blocked. however,
pthread_sigmask removes the implementation-internal signals from the
old mask before returning, so that a process which began life with
them blocked will not be able to save a signal mask that has them
blocked, possibly causing them to become re-blocked later. however,
this was causing sigqueue to unblock the implementation-internal
signals during synccall, leading to deadlock.
-rw-r--r--src/signal/sigqueue.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/src/signal/sigqueue.c b/src/signal/sigqueue.c
index bdb12856..eb4d184f 100644
--- a/src/signal/sigqueue.c
+++ b/src/signal/sigqueue.c
@@ -3,6 +3,7 @@
 #include <unistd.h>
 #include <stdint.h>
 #include "syscall.h"
+#include "pthread_impl.h"
 
 int sigqueue(pid_t pid, int sig, const union sigval value)
 {
@@ -14,9 +15,9 @@ int sigqueue(pid_t pid, int sig, const union sigval value)
 	si.si_code = SI_QUEUE;
 	si.si_value = value;
 	si.si_uid = getuid();
-	pthread_sigmask(SIG_BLOCK, (void *)(uint64_t[1]){-1}, &set);
+	__block_app_sigs(&set);
 	si.si_pid = getpid();
 	r = syscall(SYS_rt_sigqueueinfo, pid, sig, &si);
-	pthread_sigmask(SIG_SETMASK, &set, 0);
+	__restore_sigs(&set);
 	return r;
 }