⬢ DragonFlyBSD Kernel Audit
DF-5360 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5360",
  "status": "untested",
  "verdict": "Statically certain and model-reproduced data poison, latent today; kernel path not enterable in QEMU (no PCMCIA bridge). The CISTPL_CFTABLE_ENTRY handler queues the cfe (pccard_cis.c:908-917) and stores the card-supplied counts BEFORE validating them: cfe->num_iospace = 1+(reg&0x0F) at pccard_cis.c:1044 admits 16 against iospace[4] (pccardvar.h:102), cfe->num_memspace = (reg&0x07)+1 at pccard_cis.c:1164 admits 8 against memspace[2] (pccardvar.h:109); the too many error-breaks at pccard_cis.c:1047-1055 and :1167-1175 leave the out-of-range count on the live cfe, and the default-copy *cfe = *state->default_cfe at :914 propagates it to later queue entries (model S5: cfe#2 inherits num_iospace=16 and adds num_memspace=8). The only count-iterating consumers, pccard_function_init (pccard.c:429-450 io, :452-474 mem) and pccard_print_cis (pccard_cis.c:550-571), would read up to ~128 bytes past the ~176-byte kmalloc chunk and feed OOB-read start/length into bus_alloc_resource (pccard.c:439-440) - model-instrumented as 8 and 6 OOB element reads. HONEST GATE: every poison path also does state->card->error++ and pccard_attach_card rejects error cards at pccard.c:204-208 before any consumer runs, so todays impact is none; reported Low as a stored-out-of-range-index landmine (CWE-129) one refactor away from a heap OOB read.",
  "reproduced": false,
  "impact": "none",
  "confidence": "certain",
  "exploit_chain": "",
  "evidence": "run.log (scenario poison: card.error=2, live cfe num_iospace=16 (array 4), second cfe num_iospace=16/num_memspace=8 via the :914 copy, consumer loops -> 8/6 OOB element reads deepest 120/128 bytes past the chunk, plus the GATE line documenting pccard.c:204-208); VERDICT.md (line-accurate trace); fix.diff",
  "kernel_refs": [
    "sys/bus/pccard/pccard_cis.c:908",
    "sys/bus/pccard/pccard_cis.c:914",
    "sys/bus/pccard/pccard_cis.c:916",
    "sys/bus/pccard/pccard_cis.c:1044",
    "sys/bus/pccard/pccard_cis.c:1047",
    "sys/bus/pccard/pccard_cis.c:1054",
    "sys/bus/pccard/pccard_cis.c:1164",
    "sys/bus/pccard/pccard_cis.c:1167",
    "sys/bus/pccard/pccard_cis.c:1174",
    "sys/bus/pccard/pccardvar.h:102",
    "sys/bus/pccard/pccardvar.h:109",
    "sys/bus/pccard/pccard.c:204",
    "sys/bus/pccard/pccard.c:429",
    "sys/bus/pccard/pccard.c:452"
  ],
  "poc_changes": "Wrote the full model (poc_pccard_cis2.c) mirroring the walk, all pass-2-relevant handlers and the pccard.c consumer loops; fixed the models CIS-image encoding after the first guest run (attribute-space tuple bytes are 2 bus-bytes apart per pccardvar.h:255-259).",
  "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": 40,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -Wall -o poc_pccard_cis2 poc_pccard_cis2.c",
  "run_cmd": "./poc_pccard_cis2 poison   (also: ./poc_pccard_cis2 all)",
  "code_hash": "8e2bc6a40bc89ac989f57c3b43ed66138d8f5236877f64149fe2ca53df1e3e47",
  "notes": "No PCMCIA hardware in the QEMU guest, so the kernel path cannot be entered; verified statically line-by-line plus deterministic model on the guest toolchain (DF-5355 pattern). Impact honestly none because the poisoning error-break also sets card->error and pccard_attach_card bails at pccard.c:204-208 before any consumer; the print consumer (pccard_cis.c:550-571) is likewise behind the gate.",
  "recommended_fix": "Zero cfe->num_iospace / cfe->num_memspace on the too many spaces error paths before the break so no queued or copied cfe carries a count larger than its array.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff authored post-verification; cannot be exercised against real PCMCIA hardware in this environment. Reviewed for correctness: zeroing the count before break leaves the cfe on the queue with num_iospace=0, which every consumer loop (pccard.c:429/:452, pccard_cis.c:550/:561) treats as no spaces; card->error++ still rejects the card at pccard.c:204.",
  "fix_evidence": "findings/poc/DF-5360/fix.diff"
}