DF-3237 / verdict.json
{ "finding_id": "DF-3237", "status": "not_reproduced", "reproduced": 0, "impact": "leak", "confidence": "speculative", "verdict": "Speculative and not dynamically exercised: after nfssvc_iod_stop1 the reader can still requeue an EINPROGRESS (server TRYLATER) request onto nm_reqtxq whose only consumer is exiting, and nfssvc_iod_writer_wakeup is a no-op once txstate leaves WAITING - stranding a nfsreq + nfsm_info + bio (biodone never called, buffer stuck B_BUSY) whose queue head lives inside the nfsmount that nfs_unmount then frees. The window is sub-millisecond inside an umount -f racing async I/O against a JUKEBOX server; constructing that NFS topology exceeded this batch budget. Fix (drain reqtxq when the writer is dead) authored as a structural sketch in fix.diff and compile-validated in its minimal form.", "exploit_chain": "", "evidence": "VERDICT.md walk over nfs_iod.c:120-142/:180-181/:217-218/:244-247", "kernel_refs": [ "sys/vfs/nfs/nfs_iod.c:134-137", "sys/vfs/nfs/nfs_iod.c:180-181", "sys/vfs/nfs/nfs_iod.c:244-247" ], "poc_changes": "", "attempts": 2, "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", "runtime_sec": 60, "guest_dirty": 0, "build_cmd": "n/a", "run_cmd": "n/a (umount -f vs JUKEBOX server race)", "code_hash": "", "notes": "", "recommended_fix": "drain nm_reqtxq once the writer thread is STOPPING/DONE" } |