>From 0968c0c29252eb5fbca147fca901a53fb1b8ae04 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 11 Feb 2023 19:13:10 -0500 Subject: [PATCH 5/5] mq_notify: block all (application) signals in the worker thread until the mq notification event arrives, it is mandatory that signals be blocked. otherwise, a signal can be received, and its handler executed, in a thread which does not yet exist on the abstract machine. after the point of the event arriving, having signals blocked is not a conformance requirement but a QoI requirement. while the application can unblock any signals it wants unblocked in the event handler thread, if they did not start out blocked, it could not block them without a race window where they are momentarily unblocked, and this would preclude controlled delivery or other forms of acceptance (sigwait, etc.) anywhere in the application. --- src/mq/mq_notify.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mq/mq_notify.c b/src/mq/mq_notify.c index 0ffee7d1..01ec3517 100644 --- a/src/mq/mq_notify.c +++ b/src/mq/mq_notify.c @@ -53,6 +53,7 @@ int mq_notify(mqd_t mqd, const struct sigevent *sev) pthread_t td; int s; int cs; + sigset_t allmask, origmask; if (!sev || sev->sigev_notify != SIGEV_THREAD) return syscall(SYS_mq_notify, mqd, sev); @@ -67,11 +68,15 @@ int mq_notify(mqd_t mqd, const struct sigevent *sev) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); sem_init(&args.sem, 0, 0); + sigfillset(&allmask); + pthread_sigmask(SIG_BLOCK, &allmask, &origmask); if (pthread_create(&td, &attr, start, &args)) { __syscall(SYS_close, s); + pthread_sigmask(SIG_SETMASK, &origmask, 0); errno = EAGAIN; return -1; } + pthread_sigmask(SIG_SETMASK, &origmask, 0); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); sem_wait(&args.sem); -- 2.21.0