⬢ DragonFlyBSD Kernel Audit
DF-3715 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3715",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Mechanism PROVEN on the guest kernel by deterministic replica of if_em.cs exact callout/serializer protocol; em-specific runtime hardware-gated (inconclusive per family convention). em_timer (sys/dev/netif/em/if_em.c:2216-2239) and em_82547_move_tail (:2027-2036) are MP callouts whose callbacks BLOCK in lwkt_serialize_enter (:2222/:2033) on the driver serializer; em_stop tears them down with callout_stop (:2343-2344) while holding that same serializer; DragonFly callout_stop synchronously waits for an in-progress callback (sys/kern/kern_timeout.c:859-932, ssleep costp at :923). A callback dequeued and parked on the serializer therefore deadlocks against the stopper (AB-BA): both threads wedge permanently, the interface serializer is never released and the affected CPUs softclock thread stops delivering all callouts. Kernel-module replica on the guest: stop under a held serializer with the em_timer-shaped handler parked -> callout_stop NEVER returns (caller D3 wchan costp); negative control: the try-based em_txgc_timer shape is fully unloaded by callout_stop (pending=0) - which also shows the DF-3669/DF-3681 re-arm survives callout_stop premise does not hold on this kern_timeout.c, so for em the defect is the deadlock, not a post-stop re-arm UAF.",
  "exploit_chain": "",
  "evidence": "findings/poc/DF-3715/VERDICT.md; run.log (replica session transcript + raw dmesg/ps captures: IF THIS IS THE LAST replica LINE then silence; ps 1051 D3 costp sysctl kern.emreplica.stop_blk=1); build.log (module built on guest, BUILD_RC=0); fix.diff (try-enter + 1-tick retry for em_timer/em_82547_move_tail)",
  "kernel_refs": [
    "sys/dev/netif/em/if_em.c:2222",
    "sys/dev/netif/em/if_em.c:2236",
    "sys/dev/netif/em/if_em.c:2033",
    "sys/dev/netif/em/if_em.c:2016",
    "sys/dev/netif/em/if_em.c:2343",
    "sys/dev/netif/em/if_em.c:2350",
    "sys/dev/netif/em/if_em.c:1049",
    "sys/kern/kern_timeout.c:859",
    "sys/kern/kern_timeout.c:923",
    "sys/kern/kern_timeout.c:1091"
  ],
  "poc_changes": "No seed PoC. Authored callout_replica.ko (out-of-tree kmodule replicating the em callout protocol) because the guest has no em hardware; the deadlock is in the generic protocol em uses, so the replica exercises the identical kernel paths.",
  "attempts": 3,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026 x86_64",
  "runtime_sec": 240,
  "guest_dirty": 0,
  "build_cmd": "cd /root/kmod && make",
  "run_cmd": "vm.sh run_root kldload /root/kmod/callout_replica.ko; sysctl kern.emreplica.arm=1; sysctl kern.emreplica.stop_gc=1; (sysctl kern.emreplica.stop_blk=1 &)",
  "code_hash": "6c8ac128db5d02d977f1815a072002c62a81721023acc990044688fd2ee81f0a",
  "notes": "Triggers on em hardware: ifconfig em0 down/up, SIOCSIFMTU on running interface, detach/kldunload, suspend/resume, watchdog reinit - any em_stop while em_timer is INPROG-parked. Narrow per-call race window but repeatable; impact is permanent system degradation (two wedged threads + CPU-wide callout starvation). Environment note: first guest instance had kldload wedged guest-wide by a PRE-EXISTING stuck kldload arcms (since 7:21PM, before this session); after vm.sh reset with-src, kldload works - the wedge is not driver-related.",
  "recommended_fix": "Make em_timer() and em_82547_move_tail() non-blocking: lwkt_serialize_try() with a 1-tick callout_reset retry (em_txgc_timer pattern).",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff authored against the read-only sys/ tree (patch --dry-run clean); cannot be validated on a guest without em hardware.",
  "fix_evidence": "findings/poc/DF-3715/fix.diff"
}