DF-3161 / fix.diff
fix for DF-3161: umount -f force-close never balances fifo reader/writer counts (vclearn force-close flags for VFIFO + clamped decrements in fifo_close) Verified on the audit QEMU guest (see VERDICT.md in this directory). --- a/sys/kern/vfs_subr.c 2026-09-07 10:23:09.490800059 +0000 +++ b/sys/kern/vfs_subr.c 2026-09-07 10:23:09.514799742 +0000 @@ -1340,7 +1340,16 @@ */ if (active && (flags & DOCLOSE)) { while ((n = vp->v_opencount) != 0) { - if (vp->v_writecount) + /* + * FIFO opens are not modelled by v_writecount alone; + * fifo_close() needs FREAD/FWRITE to balance + * fi_readers/fi_writers or the fifoinfo leaks. + */ + if (vp->v_type == VFIFO && vp->v_writecount) + VOP_CLOSE(vp, FREAD|FWRITE|FNONBLOCK, NULL); + else if (vp->v_type == VFIFO) + VOP_CLOSE(vp, FREAD|FNONBLOCK, NULL); + else if (vp->v_writecount) VOP_CLOSE(vp, FWRITE|FNONBLOCK, NULL); else VOP_CLOSE(vp, FNONBLOCK, NULL); @@ -608,13 +609,11 @@ return 0; } if (ap->a_fflag & FREAD) { - fip->fi_readers--; - if (fip->fi_readers == 0) + if (fip->fi_readers > 0 && --fip->fi_readers == 0) soisdisconnected(fip->fi_writesock); } if (ap->a_fflag & FWRITE) { - fip->fi_writers--; - if (fip->fi_writers == 0) + if (fip->fi_writers > 0 && --fip->fi_writers == 0) soisdisconnected(fip->fi_readsock); } if (fip->fi_readers == 0 && fip->fi_writers == 0) { |