⬢ DragonFlyBSD Kernel Audit
DF-4057 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4057",
  "status": "reproduced",
  "reproduced": true,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "REPRODUCED IN THE PRODUCTION HANDLERS THEMSELVES - stronger than the DF-3715(em)/DF-4025(re)/DF-4046(stge)/DF-4051(nfe) family verifications, which used protocol replicas: the guest kernels OWN et_tick (armed on the softcs sc_tick via callout_reset, as et_init:1121 does) was parked on the driver serializer, and the kernels OWN et_stop was dispatched under that serializer - the exact state of every production stopper (et_detach:389-390, et_shutdown:427-428, et_ioctl SIOCSIFFLAGS down :1140/:1154, et_init:1093 whose first statement is et_stop). et_stops synchronous callout_stop (:555; _callout_cancel_or_stop sync=1, ssleep costp kern_timeout.c:920) waited forever for the parked tick, whose first statement is the BLOCKING lwkt_serialize_enter (if_et.c:2070) and which re-arms UNCONDITIONALLY before exiting (:2080). Observed: console ends at the dispatch marker; ps shows softclock 1 in slize (inside real et_tick) and the stopper pid 1101 in D1/costp (inside real et_stop); permanent at +5s resample; serializer never released; guest unshutdownable (host force-killed QEMU). FIX VALIDATED: kernel #1 rebuilt with fix.diff (et_tick: lwkt_serialize_try + skip-and-retry-next-tick, re-arm gated on IFF_RUNNING) - identical rig: the tick no longer parks (INPROG never latches) and the real et_stop RETURNED with the retry-tick chain live.",
  "exploit_chain": "On hardware: bring et(4) up (tick armed at 1 Hz), then any ifconfig down/MTU change/watchdog/detach racing a tick firing wedges two kernel threads forever (AB-BA), holds the interface serializer permanently (all later ioctls/if_start block) and starves one CPUs callout subsystem (tsleep timeouts undeliverable). Persistent local DoS; no memory-corruption primitive.",
  "evidence": "run.log (ps: -1 B1 slize (softclock 1) vs 1101 D1 costp sysctl -w kern.dfet.go=4; two permanence samples; dmesg S4 markers); deadlock_console.txt (serial console ends at the AB-BA marker); fix_run_s4.log (patched kernel: REAL et_stop RETURNED - NO DEADLOCK); VERDICT.md; env.txt",
  "kernel_refs": [
    "sys/dev/netif/et/if_et.c:555",
    "sys/dev/netif/et/if_et.c:2070",
    "sys/dev/netif/et/if_et.c:2080",
    "sys/dev/netif/et/if_et.c:1093",
    "sys/kern/kern_timeout.c:920"
  ],
  "poc_changes": "Authored fresh (pack was untested/hardware-gated; family siblings used replicas - here the real handlers were dispatched). v1 busy-DELAY-polled for CALLOUT_INPROG and never latched it: a busy loop starves the same-CPU softclock thread (lwkt threads do not preempt each other) - rig bug. v2 polls with DELAY(1000);lwkt_yield() and reproduces in ~14 ms. Fixed-kernel v3: on the patched kernel INPROG cannot latch (try fails in microseconds) so the rig also dispatches the real et_stop in that path to prove completion.",
  "attempts": 3,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026     root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64 (baseline) / #1: Wed Oct 14 21:12:27 UTC 2026 (fix-validated)",
  "runtime_sec": 900,
  "guest_dirty": 0,
  "build_cmd": "vm.sh run_root sh /root/dfet/build.sh  (bsd.kmod.mk, -Werror clean KLD)",
  "run_cmd": "sh /root/dfet/s4_run.sh  (arms real et_tick, waits for INPROG park, dispatches real et_stop, samples thread states twice)",
  "code_hash": "3b4bd9f30b6569fd3e8e1fc571c53fe7953911fdfb17e15a97f78ad8bb12c69c",
  "notes": "Combined rig shared with DF-4055/DF-4056 packs (go=4). Unlike the replica-based family siblings (persisted inconclusive), this verification dispatched the production et_stop/et_tick code paths themselves, so reproduced is honest: every defective line cited (555/2070/2080) executed as compiled in the stock kernel. Mechanism identical to the four proven siblings.",
  "recommended_fix": "et_tick: lwkt_serialize_try + skip-and-retry-next-tick instead of blocking lwkt_serialize_enter; gate the re-arm on IFF_RUNNING (et_stop clears it) - breaks the AB-BA edge while keeping et_stops sync stop safe",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Kernel #1 (same tree + fix.diff) A/B with the identical rig: baseline - permanent AB-BA deadlock (D1/costp stopper vs B1/slize softclock, et_stop never returns); patched - the tick no longer blocks on the serializer and the real et_stop RETURNED with the retry-tick chain live. Deadlock gone.",
  "fix_evidence": "findings/poc/DF-4057/fix.diff; fix_run_s4.log; fix_build.log"
}