DF-3604 / verdict.json
{ "finding_id": "DF-3604", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "Source-level certain: bce_rx_intr (sys/dev/netif/bce/if_bce.c:4396-4439) sets m->m_pkthdr.len = m->m_len from the NIC-DMAd l2_fhdr_pkt_len after only len -= ETHER_CRC_LEN (unsigned underflow for pkt_len<4) and an 18-byte m_adj, with no MCLBYTES(2048) bound anywhere on the path \u2014 a faulty/malicious BCM5706-5716 can hand the stack an mbuf describing up to 65531 bytes in a 2048-byte cluster (heap OOB read / info leak) or ~4GB (guaranteed panic). Runtime verification is honestly inconclusive: the audit guest has virtio-net only; bce code is in the running kernel (kldstat -v shows pci/if_bce) but no Broadcom PCI device exists, so bce_attach/bce_rx_intr are unreachable (run.log: NO_BROADCOM_DEVICE, NO_BCE_PCIID, ifconfig=vtnet0 lo0, no hw.bce.* sysctls). Guest /usr/src if_bce.c is byte-identical to the audited tree (md5 786cd4c4a8e26f5eab0c12c3987f68b9).", "exploit_chain": "On real hardware: (1) device DMAs RX frame with l2_fhdr_pkt_len=65535 and clear error bits into a posted 2048B cluster; (2) driver hands stack mbuf with m_len=65531; (3) unprivileged user with a bpf/raw socket on bce0 reads up to ~63.5KB of adjacent kernel heap (info leak); pkt_len<4 variant gives m_len~4GB -> immediate panic (local DoS). No write primitive from this bug alone (NIC DMA bounded by posted BD len).", "evidence": "run.log (guest proof: driver present in kernel, zero Broadcom devices, no attach), VERDICT.md (full path:line trace), trigger.c (annotated hardware precondition), fix.diff (drop-frame clamp)", "kernel_refs": [ "sys/dev/netif/bce/if_bce.c:4394", "sys/dev/netif/bce/if_bce.c:4396", "sys/dev/netif/bce/if_bce.c:4399", "sys/dev/netif/bce/if_bce.c:4437", "sys/dev/netif/bce/if_bce.c:4439", "sys/dev/netif/bce/if_bce.c:3851", "sys/dev/netif/bce/if_bce.c:2298", "sys/dev/netif/bce/if_bcereg.h:815", "sys/sys/param.h:497" ], "poc_changes": "Seed sketch rewritten into an annotated hardware-precondition trigger + canary skeleton; the PoC as originally sketched (syscall-level) is meaningless for a DMA-device bug; honest hardware-absent verification substituted per contract.", "attempts": 2, "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": 95, "guest_dirty": 0, "build_cmd": "cc -o trigger trigger.c", "run_cmd": "./run.sh (guest: kldstat/kldload/pciconf/ifconfig/sysctl hw.bce / md5 of if_bce.c)", "code_hash": "282678ae862dbaa58c213e90b877e00a4577c8ce79870bde7c878aced8e6f7e1", "notes": "Pass-2 calibration: identical pattern filed Medium in pass 1 for my(DF-1478), vr(DF-1481), tx(DF-1490), ste(DF-1514), lge(DF-1519), pcn(DF-1562), nfe(DF-1351). No bce file findings existed in pass 1 (verified via DB query) so this is not a re-report. Ring-mask arithmetic (TOTAL_RX_BD=256*pages), DMA map swap protocol, defrag error paths, and callout_stop sync semantics were all verified clean during this pass.", "recommended_fix": "In bce_rx_intr, drop and recycle the frame when l2_fhdr_pkt_len is outside [sizeof(l2_fhdr)+ETHER_ALIGN+ETHER_CRC_LEN, MCLBYTES] before using it (see fix.diff).", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff adds the MCLBYTES/minimum clamp using the files own error-recovery idiom (ierrors + bce_setup_rxdesc_std + goto bce_rx_int_next_rx, cf. if_bce.c:4402-4414). Cannot be runtime-validated: the guest has no BCM5706-5716 device, so neither baseline nor patched behavior is exercisable (same reason the PoC is inconclusive). The patch touches only existing symbols on an already-compiled path.", "fix_evidence": "fix.diff; baseline absence proof in run.log (NO_BROADCOM_DEVICE / NO_BCE_PCIID)" } |