{
  "finding_id": "DF-5321",
  "status": "reproduced",
  "reproduced": true,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "Reproduced on the QEMU guest with the production firewire.c compiled into a KLD harness: the split-transaction watchdog firewire_xfer_timeout() and the fw_rcv() response path (plus the FW_ASYREQ waiters fw_xfer_free_buf/fw_tl_free) race with no cross-CPU serialization, panicking the kernel on the first attempt (tlabel use-after-free read inside firewire_xfer_timeout, movq 0x8(%rax),%rax, fault 0x8; same for the production fw_asy_callback_free double-free variant). Demonstrated impact: reliable kernel panic; characterized primitive: UAF read of a freed 16-byte tlabel (wild-pointer deref when not reused zeroed), double fw_xfer_done -> double kfree of fw_xfer, and stale wire-data stores into a freed/re-used fw_xfer while its owner frees it. uid=0 chain not built (hardware-gated trigger); fix validated: panics and leak gone with fix.diff applied to /usr/src.",
  "exploit_chain": "open /dev/fwN.M (operator group) -> FW_ASYREQ split transaction to a node whose response lands at the 200 ms split timeout -> fw_rcv() and firewire_xfer_timeout() both complete the xfer / the waiter frees xfer+tlabel under the scanning watchdog -> freed struct tlabel dereferenced (or fw_xfer double-freed / stale wire-data written into re-used slab object) -> kernel panic; with slab grooming on the permissive guest the double-free/UAF-write is a path to controlled corruption (not built: hardware-gated).",
  "evidence": "panic.txt and run_mode1_console.log (Fatal trap 12, Stopped at firewire_xfer_timeout+0xbc, pri 12 CRIT), run.log (both modes panic on attempt #1, baseline), fix_run.log (fixed: mode1 3000 attempts 0 double-completions / mode2 SURVIVED 5000 / leak 0), fix_build.log, fix.diff",
  "kernel_refs": [
    "sys/bus/firewire/firewire.c:320",
    "sys/bus/firewire/firewire.c:336",
    "sys/bus/firewire/firewire.c:341",
    "sys/bus/firewire/firewire.c:348",
    "sys/bus/firewire/firewire.c:349",
    "sys/bus/firewire/firewire.c:890",
    "sys/bus/firewire/firewire.c:910",
    "sys/bus/firewire/firewire.c:1757",
    "sys/bus/firewire/firewire.c:1779",
    "sys/bus/firewire/firewire.c:1786",
    "sys/bus/firewire/firewire.c:1789",
    "sys/bus/firewire/firewire.c:1078",
    "sys/bus/firewire/firewire.c:2169",
    "sys/bus/firewire/firewirereg.h:130"
  ],
  "poc_changes": "Harness written fresh for this file (DF-5230/DF-5302 KLD pattern): compiles the production firewire.c in via #include with -D-renamed globals (incl. -Dfirewire, -D_hw_firewire, MALLOC_DEFINE types, and a MODULE_VERSION no-op shim because the #name stringify defeats -D renames and would hit interface firewire.1 already present); three lwkt threads model the receiving interrupt, the 10 Hz watchdog callout, and the fwdev FW_ASYREQ waiter; response packet hand-built per LE bitfield layout; tlabel/xfer zones prewarmed so the known DF-1021 M_WAITOK-in-crit site cannot hijack the result; fixed during bring-up: g_stop release at receiver exit, xfer->sc publish before tlabel insertion, 90 s wall-clock deadline, paced watchdog.",
  "attempts": 4,
  "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",
  "runtime_sec": 61,
  "guest_dirty": 0,
  "build_cmd": "sh build.sh  (cd /root/df5321 && make; compiles production /sys/bus/firewire/firewire.c into df5321.ko)",
  "run_cmd": "sh run_mode1.sh  (sysctl kern.df5321_mode=1; kern.df5321_iters=3000; kern.df5321_fire=1)  /  sh run.sh (mode 2)",
  "code_hash": "858fff8bd4cba49ad2c2a3d25388b80ca2b18eee26b30dc02c1ef27f16d7122d",
  "notes": "Baseline panics were captured on two separate fresh vm.sh reset boots (mode 1 and mode 2), identical signature. Mode-1 instrumented counters never got to print because the tlabel-UAF panic dominates on the first race hit; the counters are exercised on the FIXED kernel (0/0/0 over 3000 attempts), which also proves the fix removes every manifestation. The fw_get_tlabel restructuring in fix.diff additionally removes the known DF-1021 sleep-in-crit for this function (not claimed as DF-1021s fix).",
  "recommended_fix": "Serialize the tlabel lists with fc->tlabel_lock and claim xfer completion atomically with the lookup (CAS FWXF_SENT->FWXF_RCVD); kfree the tlabel unlinked by firewire_xfer_timeout; run fw_xfer_done outside the lock (fix.diff).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": true,
  "fix_patched_reproduced": false,
  "fix_verdict": "Baseline: panic attempt #1 in both race modes + 5000-object tlabel leak. Patched (fix.diff on /usr/src, module rebuilt, identical triggers): mode1 completes 3000 attempts with double-completions=0 / act.hand-after-free=0 / stale-stores=0; mode2 SURVIVED 5000 attempts; leak delta 0; guest stays up.",
  "fix_evidence": "fix_run.log, fix_build.log, fix.diff"
}