>From 70dea58630dedb26b2fbf03422ad7a36f8e95c92 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 10 Feb 2023 11:22:45 -0500 Subject: [PATCH 2/3] mq_notify: fix use-after-close/double-close bug in error path in the error path where the mq_notify syscall fails, the initiating thread may close the socket before the worker thread calls recv on it. even if this does not happen, both threads perform the close operation, resulting in double-close. move the close to a cancellation cleanup handler so this cannot happen. this fix is based on one of the alternate proposals in Alexey Izbyshev's original report of the bug. --- src/mq/mq_notify.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/mq/mq_notify.c b/src/mq/mq_notify.c index 7d3dff5f..a42e6afc 100644 --- a/src/mq/mq_notify.c +++ b/src/mq/mq_notify.c @@ -13,6 +13,11 @@ struct args { const struct sigevent *sev; }; +static void cleanup(void *p) +{ + __syscall(SYS_close, *(int *)p); +} + static void *start(void *p) { struct args *args = p; @@ -23,8 +28,9 @@ static void *start(void *p) union sigval val = args->sev->sigev_value; sem_post(&args->sem); + pthread_cleanup_push(cleanup, &s); n = recv(s, buf, sizeof(buf), MSG_NOSIGNAL|MSG_WAITALL); - close(s); + pthread_cleanup_pop(1); if (n==sizeof buf && buf[sizeof buf - 1] == 1) func(val); return 0; @@ -66,7 +72,6 @@ int mq_notify(mqd_t mqd, const struct sigevent *sev) if (syscall(SYS_mq_notify, mqd, &sev2) < 0) { pthread_cancel(td); - __syscall(SYS_close, s); return -1; } -- 2.21.0