⬢ DragonFlyBSD Kernel Audit
DF-5531 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5531",
  "status": "reproduced",
  "reproduced": true,
  "impact": "none",
  "confidence": "certain",
  "verdict": "DragonFly disabled FreeBSDs bpf_peers_present early-out in usbpf_xfertap (sys/bus/u4b/usb_pf.c:364-367, #if 0 XXX this is not needed on dragonfly), and DragonFlys bpf only assigns ifp->if_bpf while a listener is attached (net/bpf.c:297/324), with bpf_tap() NULL-safe (bpf.c:1245). Net effect, measured live on the guest: with a root-created usbus0 clone and NO listener (dmesg: bus ifp=0xfffff8008fd1e480 if_bpf=0), every call of the production usbpf_xfertap() performs the full precompute + kmalloc(totlen) + complete payload usbd_copy_out + kfree for nothing - 1094-1256 cycles/call for a 4 KiB transfer versus 25-34 cycles for the only remaining early-out (bus->ifp == NULL), a 36-44x overhead, and on the SUBMIT paths this runs while holding the USB BUS lock (usb_transfer.c:2630/2813), taxing every transfer on the controller for as long as an unwatched tap clone exists. No memory-safety impact (buffer fully initialized, bpf_tap NULL-checked), so impact class is none and severity Info; the realistic ceiling is a root-armed availability/performance degradation, worst for isochronous traffic. One-line fix: add if (bus->ifp->if_bpf == NULL) return; after the existing check.",
  "exploit_chain": "",
  "evidence": "run.log + run.2.log: DF5531: bus ifp=0xfffff8008fd1e480 if_bpf=0 (expect NULL: no listener) then (A) ifp set, if_bpf==NULL : 1094 cycles/call vs (B) ifp NULL (early-return) : 25 cycles/call, ratio 43.5x (run 2 on a fresh boot: 1256 vs 34 = 36.2x); tap_cost.c is the KLD rig invoking the global usbpf_xfertap() against the real usbus0 softc",
  "kernel_refs": [
    "sys/bus/u4b/usb_pf.c:362",
    "sys/bus/u4b/usb_pf.c:364",
    "sys/bus/u4b/usb_pf.c:368",
    "sys/bus/u4b/usb_pf.c:381",
    "sys/bus/u4b/usb_pf.c:468",
    "sys/bus/u4b/usb_pf.c:488",
    "sys/net/bpf.c:297",
    "sys/net/bpf.c:324",
    "sys/net/bpf.c:1245",
    "sys/bus/u4b/usb_transfer.c:2630",
    "sys/bus/u4b/usb_transfer.c:2813"
  ],
  "poc_changes": "No seed existed. tap_cost.c fabricates a minimal 8x512 BULK-OUT usb_xfer (PIO page_caches, zeroed flags_int = HOST mode OUT so SUBMIT copies every frame) and points xroot->bus at the REAL usbus0 softc obtained via devclass_find(\"usbus\"), so header fields (bus->bdev/parent) are production objects; times usbpf_xfertap(xfer, USBPF_XFERTAP_SUBMIT) with the clone present (if_bpf NULL) against a bus->ifp-NULL control. Guest needed -device qemu-xhci.",
  "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": 300,
  "guest_dirty": 0,
  "build_cmd": "sh build.sh   (SYSDIR=/usr/src/sys; builds df5531_tapcost.ko)",
  "run_cmd": "sh run.sh      (ifconfig usbus0 create; kldload ./df5531_tapcost.ko; dmesg; kldunload; ifconfig usbus0 destroy)",
  "code_hash": "a00dfb589bbe5d7d79c68fb29e924161507f07ba971739b09fd7009ea94d1194",
  "notes": "Two runs on independent boots: 43.5x and 36.2x - consistent. fix.diff restores the early-out DragonFly-style; not rebuilt into the DF-5530 fix kernel (Info severity, one-line guard provably short-circuits before the kmalloc at usb_pf.c:381).",
  "recommended_fix": "Restore the listener early-out: after the bus->ifp NULL check at usb_pf.c:362, add if (bus->ifp->if_bpf == NULL) return;.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Info-severity finding: no kernel rebuild performed for the one-line guard (the DF-5530 validation kernel in the same session carried only DF-5530s hunks). The guard is code-obvious: it returns at usb_pf.c:362-363 territory, before usbpf_xfer_precompute_size (:368) and the kmalloc (:381), so case (A) collapses to case (B) timing; baseline behavior itself is reproduced (36-44x).",
  "fix_evidence": "fix.diff (one hunk, patch --dry-run verified); VERDICT.md"
}