# DF-2710 — peer-freezable iocom reader: parked writer turns the
# "dmrace" INTERLOCK wait (kern_dmsg.c:827) into an indefinite cluster
# link stall

## What was verified (non-INVARIANTS kernel #1)

`kdmsg_state_msgtx()` sets `KDMSG_STATE_INTERLOCK` on the state of each
message it dequeues for transmission (kern_dmsg.c:1636-1637); the bit is
cleared only by the *same* thread's `kdmsg_state_cleanuptx()` **after**
`fp_write()` returns (:1663-1667). If the peer stops reading, the writer
parks inside `fp_write()` (unix-socket send buffer full) with INTERLOCK
set. `kdmsg_state_msgrx()` for any subsequent message resolving to that
state — e.g. the peer's DELETE for that msgid — hits the interlock and
sleeps 1 second per iteration in the `again:` loop (kern_dmsg.c:825-828)
**while holding no other progress**: the reader cannot consume anything
else, so the kernel-side receive buffer fills and *all* cluster traffic
in both directions stalls until the peer resumes reading.

PoC: `df2707_trigger wedge` (shared source) — parks the writer with
SO_SNDBUF=2048 + junk transactions, sends a **single** DELETE (no
duplicates — this is the benign control for DF-2707), then probes with
non-blocking one-way LNK_PAD bursts:

```
WEDGE_PROBE1_WRITTEN=863/1024 <== reader stalled (rcvbuf full)
WEDGE_PROBE2_WRITTEN=1024/1024 (reader recovered after drain)
UNMOUNT_OK
```

Reader demonstrably stops consuming (send-side EAGAIN after 863 frames
≈ rcvbuf capacity) and recovers the moment the peer drains. A peer can
hold the link frozen indefinitely; on a clustered hammer2 mount any
cluster-dependent VOP then blocks (recoverable system-wide DoS while
the peer withholds reads).

## Build & run

```
scp -F dfbsd-qemu/config findings/poc/DF-2710/df2707_trigger.c dfbsd:/root/poc/df2707/
dfbsd-qemu/vm.sh run_root 'cd /root/poc/df2707 && cc -O -I/usr/src/sys -o t df2707_trigger.c && ./t wedge'
```

## Fix direction

Bound the interlock wait (e.g. break out after a few iterations and
treat the message as EALREADY), or clear INTERLOCK before blocking in
`fp_write()` (queue-level interlock instead of state-level), so a
back-pressured writer cannot dead-wait the reader.
