From 560764d8d2ef5e531bb0fb99bcd092169abafbe0 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 10 Feb 2023 11:22:45 -0500 Subject: [PATCH 3/4] 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 a42888d2..ab718732 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; @@ -69,7 +75,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