⬢ DragonFlyBSD Kernel Audit
DF-5356 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5356",
  "status": "reproduced",
  "verdict": "REPRODUCED at the verbatim-rig level (deterministic, linear unbounded growth), upgrading the seeded static-only verification to executed evidence. The production pccard_attach_card/pccard_detach_card/pccard_read_cis chain was machine-extracted BYTE-IDENTICAL from the guests /usr/src (sha256 gates; PCCARD_BYTE_IDENTICAL=yes) and driven through the exact re-entry sequence the cbb event thread produces on a card-detect bounce (pccbb.c:621-627 -> :479-483 -> :458-461 -> exca.c:759-764 -> CARD_ATTACH_CARD, no already-attached guard anywhere): attach, re-attach with NO intervening detach, final detach, x51 cycles. Measured damage per cycle: 376 bytes (pf 216 + cfe 160) permanently orphaned by the STAILQ_INIT at pccard.c:189 (and pccard_cis.c:104) -- the detach free path walks only the CURRENT list (pccard.c:303, :317-324); plus one zombie child (device_add_child at :256 stacking a duplicate driver instance over the live card); plus one leaked bridge I/O window and one leaked CCR mapping (orphaned rl entries keep res busy forever). 51 bounce cycles: 102 orphaned blocks / 19176 bytes / 51 zombies / 28 held io + 28 held ccr (window pool exhausts; the pf/cfe leak continues linearly regardless) -- unbounded kernel-memory exhaustion at ~2 s CD-glitch periods, and the leaked busy windows prime DF-5355s panic on subsequent inserts. Negative control benign_cycle (attach->detach x51, no bounce): leak=0/zombies=0/held=0, isolating the defect to the no-detach re-attach. Kernel entry itself is hardware-gated (no PCMCIA bridge in QEMU, env.txt) -- DF-1040/1041/2319 precedent; the trigger trace pccbb.c:458/479/621 + exca.c:759 was verified line-by-line in the guests own tree.",
  "reproduced": true,
  "impact": "dos",
  "confidence": "certain",
  "exploit_chain": "evil card grounds CD1#/CD2# -> card attaches -> card ungrounds CD briefly (CSC intr, pccbb.c:621-627 clears CBB_CARD_OK, wakes event thread) -> card regrounds CD -> thread debounce pccbb.c:479-483 observes present -> cbb_insert :458 -> exca_insert exca.c:759 -> CARD_ATTACH_CARD -> pccard_attach_card re-entered, no detach ran -> STAILQ_INIT (pccard.c:189, pccard_cis.c:104) orphans previous pf/cfe chain (376+ bytes/cycle permanent kmem leak, linear, unbounded) + device_add_child (:256) stacks duplicate children over live drivers -> bridge I/O + CCR windows leaked (busy rl entries never released) -> repeat ~every 2 s: kmem exhaustion + zombie device tree over destroyed windows; window exhaustion primes DF-5355 busy-panic on next insert",
  "evidence": "run.log (baseline decisive: per-cycle cycle-0 trace + TOTAL after 51 bounce cycles: orphaned-kmalloc-blocks=102 leak=19176 bytes | zombie-children=51 | io-held=28 ccr-held=28); fixed_run.log (running-kernel fixed source: 0/0/0/0 across all 51 cycles); matrix.log (f5356 variant flips exactly reentry_leak; benign_cycle + no_vers1 + busypanic unchanged); extract2_manifest.txt; build.log; DF-2318 pack run.log/run.2.log/run.3.log (determinism incl. benign_cycle zero-leak control)",
  "kernel_refs": [
    "sys/bus/pccard/pccard.c:189",
    "sys/bus/pccard/pccard.c:256",
    "sys/bus/pccard/pccard.c:268",
    "sys/bus/pccard/pccard.c:303",
    "sys/bus/pccard/pccard.c:317",
    "sys/bus/pccard/pccard_cis.c:104",
    "sys/dev/pccard/pccbb/pccbb.c:458",
    "sys/dev/pccard/pccbb/pccbb.c:479",
    "sys/dev/pccard/pccbb/pccbb.c:621",
    "sys/dev/pccard/exca/exca.c:759"
  ],
  "poc_changes": "No seed PoC existed (pack was a static trace only). Wrote the reentry_leak scenario in the verbatim lifecycle rig (shared with DF-2318/DF-5355): CD-bounce re-attach driven through the byte-identical attach/detach chain with ledgered kmalloc, tracked device tree, and io/ccr window accounting; 51-cycle amplifier plus benign_cycle negative control. The seeded fix.diff was malformed (patch: malformed patch at line 19, declarations after statements) and was regenerated with the same EBUSY-guard semantics placed correctly.",
  "attempts": 9,
  "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": 12,
  "guest_dirty": 0,
  "build_cmd": "sh build.sh   (= sh extract2.sh extracted /usr/src/sys && cc -O2 -g -Wall -I extracted -o rig2 rig2_main.c)",
  "run_cmd": "./rig2 reentry_leak    (baseline success = TOTAL after 51 bounce cycles: orphaned-kmalloc-blocks=102 leak=19176 ...; ./rig2 benign_cycle = leak 0)",
  "code_hash": "6746055beafbffae93e5758ec0373a40694ee704e9b4ebcd1915ea7e4d82b658",
  "notes": "No PCMCIA hardware in QEMU (env.txt); rig proves the shipped codes behavior on the exact bounce re-entry path, combined-fix kernel build+boot proves compile/boot of the guard. Leak rate is per-single-function-card (pf+cfe); multi-function/multi-CFE cards cost proportionally more (findings hundreds-of-KB estimate). The kernels own comment at pccbb.c:562-567 treats CD jitter as routine, making the bounce scenario operationally realistic.",
  "recommended_fix": "Guard pccard_attach_card against re-entry: return EBUSY when sc->card.pf_head is non-empty (the removal path empties the list at pccard.c:317-324, keeping the marker correct across insert/remove cycles); validated by rig A/B and combined-fix kernel.",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "VALIDATED. (1) Single-fix rig A/B (matrix.log): reentry_leak TOTAL becomes 0 orphaned / 0 bytes / 0 zombies / 0 held windows across all 51 bounce cycles; benign_cycle (attach->detach x51) still attaches cleanly every cycle, proving the guard does not break normal insert/remove; no_vers1 (DF-2318) and busypanic (DF-5355) scenarios unchanged under the f5356 variant. (2) Combined three-fix kernel: -Werror nativekernel rc=0, installkernel rc=0, booted kernel #1 (sha256 4faad36e...); rig re-extracted from the RUNNING kernels patched source (--allow-patched) and re-driven: fixed_run.log shows 0 leak / 0 zombies / 0 held over 51 bounce cycles. In-kernel behavioral test impossible (no PCMCIA bridge).",
  "fix_evidence": "fix.diff; fixed_run.log; matrix.log; postboot_extract_manifest.txt + postboot_run.log + kernel_apply.log + kernel_build.tail.log (in DF-2318 pack)"
}