DF-3171 / verdict.json
{ "finding_id": "DF-3171", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "speculative", "verdict": "The mfsclose hazard is code-real (mfs_active cleared on any device close; devfs can call d_close on VRECLAIMED vnodes or on a count_dev() miscount the kernel itself marks XXX NOT SMP SAFE), but no reachable trigger was demonstrable: FWRITE opens of a mounted mfs device return EBUSY (devfs_vnops.c:1006-1020), and read-only opens migrate to the devices primary devfs vnode so reclaiming a second-devfs vnode never fires d_close. Three trigger constructions on the stock QEMU kernel all left the server alive and the mount healthy. The stock panic initially attributed to this finding was reattributed to DF-3170 after tracing the EBUSY open failure (full honesty record in VERDICT.md/run.log). Filed as Low/speculative hardening; the si_mountpoint guard in mfsclose was built and validated as harmless (normal mount/IO/umount lifecycle fully intact on two patched kernels).", "exploit_chain": "", "evidence": [ "run.log (all three trigger attempts + stock normal-teardown control)", "VERDICT.md (attribution retraction + remaining count_dev race rationale)", "panic_investigated_misattribution.txt (the reattributed panic)", "fix_run.log (guard validation matrix)" ], "kernel_refs": [ "sys/vfs/mfs/mfs_vfsops.c:136-147", "sys/vfs/mfs/mfs_vfsops.c:493-499", "sys/vfs/devfs/devfs_vnops.c:1169-1171", "sys/vfs/devfs/devfs_vnops.c:1006-1020", "sys/vfs/devfs/devfs_vnops.c:1102", "sys/kern/vfs_subr.c:1341-1352", "sys/vfs/devfs/devfs_core.c:754-763" ], "poc_changes": "Trigger revised three times while chasing the mechanism: FWRITE open -> read-only open with short-lived holder -> read-only open with persistent (sleep 90) holder across umount -f; each stages outcome recorded; the open-vnode-migration discovery explains all negatives.", "attempts": 3, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64 (stock); patched #1/#2 for guard validation", "runtime_sec": 1140, "guest_dirty": 0, "build_cmd": "(none \u2014 shell constructions; writers reuse DF-3170 mfsrace)", "run_cmd": "root: (mount_mfs -s 8192 swap /mnt/mfs &); mount -t devfs none /mnt/d2; (sh -c exec 8</mnt/d2/mfsN; sleep 90 &); umount -f /mnt/d2; then check server/mount/IO", "code_hash": "8b7d94f450763c53156353ee6f6728580f6347158154c9d14f375bc81f3848ba", "notes": "Fix retained as defense-in-depth despite the negative: mfsclose assuming finality remains one count_dev miscount away from killing a live mounts server with a freed mfsnode. Panic evidence originally in this pack moved to DF-3170 (run2_panic_serial.log, panic_run2.txt).", "recommended_fix": "mfsclose: ignore closes while dev->si_mountpoint != NULL (ffs_unmount clears it before the true final close).", "fix_status": "inconclusive", "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Mon Sep 7 16:51:08 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "The guarded behavior could not be shown bad-then-good because no construction manifested the bug on the stock kernel (baseline_reproduced=0 by absence of trigger, not by fix). The guard was proven safe: normal mount/IO/umount lifecycle intact on both patched builds, kill constructions ignored, 11+ min stress without regression.", "fix_evidence": "findings/poc/DF-3171/fix_run.log, findings/poc/DF-3171/fix_build.log" } |