DF-2704 / verdict.json
{ "finding_id": "DF-2704", "status": "untested", "reproduced": 0, "impact": "none", "confidence": "speculative", "verdict": "vop_cache_operate_ap (sys/kern/vfs_vopops.c:1781-1782) loads and dispatches through mp->mnt_vn_journal_ops with no token or refcount; journal_detach (sys/kern/vfs_jops.c:247-252) via vfs_rm_vnodeops (sys/kern/vfs_init.c:143-162) NULLs and kfrees that same struct vop_ops, also unsynchronized. A racing VOP thread can VOCALL through freed M_VNODEOP memory (use-after-free function dispatch). The free side is reachable only by root (mountctl gated by SYSCAP_RESTRICTEDROOT, sys/kern/vfs_syscalls.c:1277-1283), and no in-tree workload detaches journals under I/O load, so this is a genuine protocol flaw with low practical exploitability. Phase V skipped per contract (Low/speculative/root-gated); would need a root mountctl storm plus scheduler injection to demo.", "exploit_chain": "", "evidence": [ "sys/kern/vfs_vopops.c:1774-1786 unlocked mnt_vn_journal_ops read + VOCALL", "sys/kern/vfs_jops.c:247-252 journal_detach -> vfs_rm_vnodeops", "sys/kern/vfs_init.c:143-162 vfs_rm_vnodeops: *ops_pp=NULL then kfree, no lock", "sys/kern/vfs_syscalls.c:1277-1283 mountctl root gate", "findings/poc/DF-2704/VERDICT.md full protocol analysis" ], "kernel_refs": [ "sys/kern/vfs_vopops.c:1774", "sys/kern/vfs_vopops.c:1781", "sys/kern/vfs_jops.c:247", "sys/kern/vfs_init.c:143", "sys/kern/vfs_mount.c:209", "sys/kern/vfs_syscalls.c:1277" ], "poc_changes": "no PoC built: race window is a single load-to-call sequence and the free side needs root; not reproducible honestly without scheduler injection", "attempts": 0, "guest_uname": "", "runtime_sec": 0, "guest_dirty": 0, "build_cmd": "", "run_cmd": "", "code_hash": "", "notes": "Pass-2 lock-protocol depth result. If promoted for verification later: root loop of mountctl install/remove journal on tmpfs while unprivileged writer hammers the mount. Fix direction: hold mnt_token (or refcount vop_ops) across the journal_ops read in vop_cache_operate_ap and across the swap+free in vfs_rm_vnodeops.", "recommended_fix": "Serialize the journal-ops swap with the dispatch layer (mnt_token around the mnt_vn_journal_ops read in vop_cache_operate_ap and the NULL+ kfree in vfs_rm_vnodeops), or refcount struct vop_ops before freeing." } |