{
  "finding_id": "DF-3738",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Mechanism PROVEN on the guest kernel by deterministic replica of if_emx.cs exact callout/serializer protocol; emx-specific runtime hardware-gated (inconclusive per family convention, same standard as the em(4) twin DF-3715). emx_timer (sys/dev/netif/emx/if_emx.c:1908-1931) is an MP callout whose callback BLOCKS in lwkt_serialize_enter(&sc->main_serialize) (:1914) and self re-arms inside the serializer (:1928); emx_stop tears it down with callout_stop(&sc->timer) (:2030) while holding ALL serializers (ASSERT_IFNET_SERIALIZED_ALL :2026; callers: SIOCSIFFLAGS :1227, emx_init :1354, emx_detach :989, emx_suspend :1059); the same stop-under-serializer exists in emx_intr_body LSC path (:1534, ISR holds main + skipmain serializers) and emx_npoll_status (:4196). DragonFly callout_stop synchronously waits for an in-progress callback (sys/kern/kern_timeout.c:1091 -> _callout_cancel_or_stop sync=1, ssleep costp at :920) while lwkt_serialize_enter blocks (tsleep slize, sys/kern/lwkt_serialize.c:234). A callback dequeued and parked on the serializer therefore deadlocks against the stopper (AB-BA): both threads wedge permanently and the affected CPUs softclock thread stops delivering callouts. Kernel-module replica on the guest: stop under a held serializer with the emx_timer-shaped handler parked -> callout_stop NEVER returns (ps: 1105 D4 costp sysctl kern.emxreplica.stop_blk=1; ps -ax: (softclock 0) B0 slize; console output ends at the pre-callout_stop marker line). Negative control: the try-based emx_txgc_timer shape is fully unloaded by callout_stop (pending=0) - so the try-based gc timers done: re-arm (:448) cannot survive callout_stop post-processing on this kern_timeout.c, and no separate post-stop re-arm finding is filed (same judgment as em(4) pass 2). Fix validated at protocol level: replica of the fix.diff shape (try + 1-tick retry + double-check) completes the same stop cleanly (pending=0, clean kldunload).",
  "exploit_chain": "",
  "evidence": "findings/poc/DF-3738/VERDICT.md; run.log (replica session transcript + serial console + ps captures: stopper D3/D4 wchan costp = kern_timeout.c:920; softclock 0 B0 wchan slize = lwkt_serialize.c:234; fixed-shape validation callout_stop returned, pending=0); build.log (module built on guest, -Werror clean); fix.diff (try-enter + 1-tick retry for emx_timer)",
  "kernel_refs": [
    "sys/dev/netif/emx/if_emx.c:1914",
    "sys/dev/netif/emx/if_emx.c:1928",
    "sys/dev/netif/emx/if_emx.c:2030",
    "sys/dev/netif/emx/if_emx.c:1534",
    "sys/dev/netif/emx/if_emx.c:4196",
    "sys/dev/netif/emx/if_emx.c:2026",
    "sys/dev/netif/emx/if_emx.c:1227",
    "sys/kern/kern_timeout.c:1091",
    "sys/kern/kern_timeout.c:920",
    "sys/kern/lwkt_serialize.c:234"
  ],
  "poc_changes": "No seed PoC. Authored emx_callout_replica.ko (out-of-tree kmodule replicating the emx callout protocol; adapted from DF-3715s em replica with emx line citations) plus emx_callout_replica_fixed.c (fix.diff shape) because the guest has no emx hardware; the deadlock is in the generic protocol emx uses, so the replica exercises the identical kernel paths. One replica iteration had a module-local bug (fx_c missing callout_init_mp -> KKASSERT panic in MY module); fixed and rerun.",
  "attempts": 3,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026 x86_64",
  "runtime_sec": 480,
  "guest_dirty": 0,
  "build_cmd": "cd /root/emxkmod && make   (fixed-shape: /root/emxkmod3)",
  "run_cmd": "vm.sh run_root kldload /root/emxkmod/emx_callout_replica.ko; sysctl kern.emxreplica.arm=1; sysctl kern.emxreplica.stop_gc=1; (sysctl kern.emxreplica.stop_blk=1 &)  # then vm.sh reset with-src",
  "code_hash": "7bb51ebf6949e731abd35dcd6dbe651378562ff034cb64d7fca24f31acf98004",
  "notes": "Triggers on emx hardware from ordinary privileged operations: ifconfig emx0 down/up, SIOCSIFMTU/SIOCSIFCAP on a running interface, detach/kldunload, suspend/resume, watchdog reinit, LSC interrupt - any path reaching emx_stop/emx_intr_body while emx_timer is INPROG-parked. Narrow per-call window (~1/s timer) but repeatable; impact is permanent system degradation (two wedged threads + CPU-wide callout starvation). Fixed-shape replica hash: 134c8fdfdf6c9d5defaf0d4e501ab5425ace17191a01b4678528109c9494db4e.",
  "recommended_fix": "Make emx_timer() non-blocking: lwkt_serialize_try() with a 1-tick callout_reset retry (emx_txgc_timer pattern).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Protocol-level validation on the guest: baseline (current emx_timer shape) = permanent AB-BA wedge (stopper D4 costp, softclock B0 slize); patched shape (exact fix.diff protocol: try + 1-tick retry + double-check under serializer) = the same emx_stop-shaped callout_stop completes, pending=0, module unloads cleanly. Full driver-kernel rebuild validation not possible without emx hardware.",
  "fix_evidence": "findings/poc/DF-3738/fix.diff; run.log fixed-shape validation section"
}