DF-2710 / verdict.json
{ "finding_id": "DF-2710", "status": "reproduced", "reproduced": 1, "impact": "dos", "confidence": "certain", "verdict": "kdmsg_state_msgtx() sets KDMSG_STATE_INTERLOCK when dequeuing a message (kern_dmsg.c:1636-1637) and only kdmsg_state_cleanuptx() after fp_write() returns clears it (:1663-1667). A peer that stops reading parks the writer inside fp_write with INTERLOCK set; kdmsg_state_msgrx() then sleeps 1s per iteration on that state (:825-828, 'dmrace') and the reader consumes nothing else - the whole cluster link freezes in both directions until the peer resumes reading. Verified with a single DELETE (no duplicates, isolating it from DF-2707): PAD probe wrote 863/1024 then EAGAIN (kernel rcvbuf full, reader stalled); after drain the probe wrote 1024/1024 and the mount unmounted cleanly. Indefinite peer-held freeze of cluster messaging; cluster-dependent VOPs on a clustered hammer2 mount block for the duration.", "exploit_chain": "", "evidence": ["run.wedge_probe.txt (WEDGE_PROBE1_WRITTEN=863/1024 stalled; WEDGE_PROBE2_WRITTEN=1024/1024 recovered; UNMOUNT_OK)", "run.attack2_ssh.log + run.attack2_trigger.out (natural occurrence during DF-2707 run 2: trigger blocked writing churn after DRAIN_DONE)"], "kernel_refs": ["sys/kern/kern_dmsg.c:1636-1637", "sys/kern/kern_dmsg.c:1663-1667", "sys/kern/kern_dmsg.c:825-828"], "poc_changes": "wedge mode of the DF-2707 trigger: parks the writer, sends a single DELETE for an in-transmission state, probes with non-blocking one-way LNK_PAD bursts before/after drain.", "attempts": 2, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1 X86_64_GENERIC x86_64 (non-INVARIANTS)", "runtime_sec": 90, "guest_dirty": 0, "build_cmd": "cc -O -I/usr/src/sys -o df2707_trigger df2707_trigger.c", "run_cmd": "cd /root/poc/df2707 && ./df2707_trigger wedge", "code_hash": "084a8b6bdb7eb1553cc425e667b44d08a71319384f1737548a40ebac95a1c6e6", "notes": "Reversible by the peer; not fixed by DF-2707's fix.diff (independent mechanism). The XXX-hack interlock comment in-source acknowledges the fragility.", "recommended_fix": "Bound the dmrace wait (bail to EALREADY after a few 1s iterations) or move the interlock from state-level to queue-level so a back-pressured writer cannot dead-wait the reader." } |