⬢ DragonFlyBSD Kernel Audit
DF-4304 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4304",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "Source-certain invariant break, runtime honestly inconclusive (hardware-gated). bfe_txeof (sys/dev/netif/bfe/if_bfe.c:1064-1083) and bfe_rxeof (:1106-1147) decode the DMA engines 12-bit current descriptor byte offset (BFE_STAT_CDMASK 0xfff, if_bfereg.h:69) into a descriptor index and use it directly as the walks termination target, with NO range validation and NO work bound. The fields encoding space maps to indices 0..511 (4095/8) but the rings hold 511 descriptors (valid 0..510, EOT at 510) and BFE_INC cycles software indices over 0..510 only - so any hardware-reported offset in [4088..4095] (index 511) makes while(current != cons)/while(i != chipidx) NON-TERMINATING in interrupt context while holding the ifnet serializer: bfe_rxeof spins allocating cluster mbufs and loading DMA maps forever (len=0-4 underflows into the error branch each pass); bfe_txeof spins the same way or trips KKASSERT(tx_cnt>0) (:1080) into a panic. The off-range encoding is architecturally used on this register interface - the driver itself programs 511*8=4088 into BFE_DMARX_PTR at if_bfe.c:549 - and the drivers error-reinit path (ISTAT_ERRORS -> bfe_init, :1176-1187) runs BEFORE bfe_rxeof (:1190) so it cannot rescue a walk begun with a bogus index. Guest index-space/loop-termination harness proves index 511 never terminates (run.log, HARN_RC=0); the guest has no Broadcom PCI device and QEMU provides no BCM4401 model (env.txt: NO_BROADCOM_PCI, hw.bfe unknown oid), so the instance cannot be fired - per family convention (DF-3761/DF-3715) recorded inconclusive. Availability only: software indices never leave 0..510, so no OOB memory access - no corruption, no uid=0 route.",
  "exploit_chain": "Precondition: bfe(4) hardware (BCM4401/4402) whose DMARX_STAT/DMATX_STAT current-descriptor field transiently or persistently reports byte offset 4088..4095 (post-EOT increment-before-wrap transient, DMA engine error state, or register corruption). The next RX/TX interrupt enters bfe_rxeof/bfe_txeof, the walk never terminates, one CPU pegs at interrupt priority holding the serializer, the interface and its ioctls/timers wedge permanently, and the rxeof variant additionally hammers the cluster allocator - system-wide livelock until reboot. No remote packet can set the register directly; the trigger is hardware-state-dependent.",
  "evidence": "run.log (harness output: index 511 is OUTSIDE the ring, current=511: walk NEVER TERMINATES, plus presence probes NO_BROADCOM_PCI / hw.bfe unknown oid / guest-src md5 == audited tree); build.log (cc clean); bfe_walk_harness.c (index-space enumeration + BFE_INC walk simulation); VERDICT.md (path:line trace + negative results incl. the killed DF-3604-family length-trust candidate); fix.diff (range guards in both walks, patch -p1 --dry-run clean)",
  "kernel_refs": [
    "sys/dev/netif/bfe/if_bfe.c:1064",
    "sys/dev/netif/bfe/if_bfe.c:1070",
    "sys/dev/netif/bfe/if_bfe.c:1080",
    "sys/dev/netif/bfe/if_bfe.c:1106",
    "sys/dev/netif/bfe/if_bfe.c:1109",
    "sys/dev/netif/bfe/if_bfe.c:549",
    "sys/dev/netif/bfe/if_bfe.c:1176",
    "sys/dev/netif/bfe/if_bfe.c:1190",
    "sys/dev/netif/bfe/if_bfereg.h:69",
    "sys/dev/netif/bfe/if_bfereg.h:405",
    "sys/dev/netif/bfe/if_bfereg.h:426"
  ],
  "poc_changes": "No seed PoC. Authored bfe_walk_harness.c (userland index-space + loop-termination proof of the exact driver arithmetic) because the guest has no BCM4401 and QEMU cannot emulate one; plus guest-side presence probes.",
  "attempts": 1,
  "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": 30,
  "guest_dirty": 0,
  "build_cmd": "cc -o /root/bfe_walk_harness /root/bfe_walk_harness.c",
  "run_cmd": "vm.sh run_root /root/bfe_walk_harness; ifconfig -l; pciconf -l | grep -i -E \"14e4|broadcom\" || echo NO_BROADCOM_PCI; sysctl hw.bfe",
  "code_hash": "26a23d9c0b835cdd77a1e6ad69d671483e2b3862fcf609094e1ec68384d293bd",
  "notes": "Checklist items (a)/(b) result: the DF-3604-family length trust is KILLED (underflow caught by the len>ETHER_MAX_LEN+32 filter at :1121; max touch 1550+30=1580 < MCLBYTES 2048) and software TX invariants hold; the surviving defect is the unbounded, range-unvalidated completion walk (DF-3761/DF-3604 hybrid: register-trust + no work bound). The DF-3761 flood-livelock aspect is also unbounded here (no process_limit-style cap), though a 100Mbit NIC cannot sustain a line-rate walk overrun the way gigabit alc can.",
  "recommended_fix": "Range-validate the decoded index in both walks (return with a rate-limited error print if chipidx/current >= BFE_xX_LIST_CNT) and optionally cap iterations per interrupt; see fix.diff.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff authored against the read-only sys/ tree (patch -p1 --dry-run clean); cannot be runtime-validated without BCM4401 hardware.",
  "fix_evidence": "findings/poc/DF-4304/fix.diff"
}