DF-2780 / fix.diff
Fix for DF-2780: inherit p_mqueue_cnt across fork + >= checks + existing-path check. --- sys_mqueue.c 2026-09-01 04:01:55.500648734 +0000 +++ sys_mqueue.2780.only 2026-09-01 04:03:50.167194127 +0000 @@ -449,7 +449,7 @@ u_int i; /* Check the limit */ - if (p->p_mqueue_cnt == mq_open_max) { + if (p->p_mqueue_cnt >= mq_open_max) { kfree(name, M_MQBUF); return EMFILE; } @@ -561,6 +561,12 @@ error = EACCES; goto exit; } + + /* Enforce the per-process limit on this path too */ + if (p->p_mqueue_cnt >= mq_open_max) { + error = EMFILE; + goto exit; + } } else { /* Fail if mqueue neither exists, nor we create it */ if ((oflag & O_CREAT) == 0) { @@ -574,7 +580,7 @@ } /* Check the limit */ - if (p->p_mqueue_cnt == mq_open_max) { + if (p->p_mqueue_cnt >= mq_open_max) { error = EMFILE; goto exit; } --- kern_fork.c 2026-09-01 04:01:55.500648734 +0000 +++ kern_fork.c.new 2026-09-01 04:08:18.687790250 +0000 @@ -40,6 +40,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/sysmsg.h> +#include <sys/file.h> #include <sys/filedesc.h> #include <sys/kernel.h> #include <sys/sysctl.h> @@ -553,6 +554,22 @@ error = ENOMEM; goto done; } + { + struct filedesc *nfd = p2->p_fd; + int nfdi; + + /* + * Inherit the POSIX mqueue descriptor count so the + * decrement in mq_close_fop() (which runs in + * whichever process drops the last file ref) stays + * balanced across fork(). + */ + for (nfdi = 0; nfdi <= nfd->fd_lastfile; nfdi++) { + if (nfd->fd_files[nfdi].fp && + nfd->fd_files[nfdi].fp->f_type == DTYPE_MQUEUE) + p2->p_mqueue_cnt++; + } + } fdtol = NULL; } else { p2->p_fd = fdshare(p1); |