⬢ DragonFlyBSD Kernel Audit
DF-3737 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3737",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Source-certain, runtime hardware-gated (same convention as the em(4) twin DF-3714): emx_tx_collect (sys/dev/netif/emx/if_emx.c:2808-2868) uses the raw TDH register read at :2817 (narrowed to int) as the cleanup walk terminator with no range validation. An out-of-range TDH - MMIO read-back 0xFFFFFFFF on surprise removal (tdh = -1) or any value >= num_tx_desc from a faulty device - makes while (first != tdh) (:2832) unreachable: first wraps mod num_tx_desc (:2853-2854) forever. First full pass frees every TX buffer incl. hardware-owned descriptors via emx_free_txbuf (bus_dmamap_unload + m_freem, :391-401) - DMA-after-free window; KKASSERT(num_avail < num_tx_desc) at :2835 then panics INVARIANTS builds, while production builds spin forever holding the TX serializer (permanent wedge of ifsq/ifconfig/watchdog paths on that ring). Walk math replicated on the guest (run.harness.log section [C]: TDH 0x1000 and 0xFFFFFFFF vs 512-entry ring - no termination at the replicas 4194304-iteration cap; in-range TDH safe). Triggering for real requires surprise removal / faulty device - absent on the audit guest -> inconclusive per family convention.",
  "exploit_chain": "",
  "evidence": "findings/poc/DF-3737/VERDICT.md; run.harness.log (section [C]); build.log; env.txt; fix.diff (bail when (uint32_t)tdh >= num_tx_desc, git-apply clean)",
  "kernel_refs": [
    "sys/dev/netif/emx/if_emx.c:2817",
    "sys/dev/netif/emx/if_emx.c:2832",
    "sys/dev/netif/emx/if_emx.c:2835",
    "sys/dev/netif/emx/if_emx.c:2853",
    "sys/dev/netif/emx/if_emx.c:1116",
    "sys/dev/netif/emx/if_emx.c:2888"
  ],
  "poc_changes": "No seed PoC. emx_bounds_harness.c section [C] authored for this finding (shared with DF-3736).",
  "attempts": 2,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026 x86_64",
  "runtime_sec": 60,
  "guest_dirty": 0,
  "build_cmd": "cc -O -o /root/emx_bounds_harness /root/emx_bounds_harness.c",
  "run_cmd": "vm.sh run_root /root/emx_bounds_harness   # section [C]",
  "code_hash": "356904408cabbb1c992f2884313b8aaf987b8ad1940444d26e0de8eeb35da0dc",
  "notes": "Device-trust DoS (surprise removal / faulty HW). emx_txeof itself walks driver-internal tx_dd[] and is safe. Twin of DF-3714.",
  "recommended_fix": "Bail out of emx_tx_collect() when (uint32_t)TDH >= num_tx_desc instead of walking the ring toward an unreachable index.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff authored against the read-only sys/ tree (git apply --check clean); cannot be runtime-validated on a guest without emx hardware.",
  "fix_evidence": "findings/poc/DF-3737/fix.diff"
}