DF-2320 / verdict.json
{ "finding_id": "DF-2320", "status": "reproduced", "verdict": "REPRODUCED at the verbatim-rig level on the DragonFly guest; kernel entry hardware-gated (no PCMCIA bridge). The 32-bit link targets are copied verbatim into tuple.ptr (longlink_addr read at :212 -> :394; mfc[].addr read at :334 -> :406) and dereferenced at :413/:419/:425-427 with NO bounds check -- the only check (:164) sits in the inner walk and is structurally bypassed by the link-follow loop. The instrumented bus_space_read_1 of the rig (guard buffer: 4096-byte mapping + canary zone; wild offsets recorded without dereference) counted: a read at offset 16777216 (2 * 0x00800000, 4096x the mapping) from a LONGLINK_A tuple, and from an MFC tuple an adjacent read at EXACTLY 4096 plus a wild common-space read at 67108864. On real hardware these are reads outside the bus_alloc_resource(PCCARD_CIS_SIZE=4096) mapping (:62/:130-131): CardBus -> master abort (panic or 0xFF), ISA -> adjacent-mapping read / potential bus hang. Read values only feed parse decisions (LINKTARGET compare) -- no userspace disclosure path. Fix validated: single-fix rig A/B (0 OOB, links skipped, everything else unchanged) and combined-five-fix kernel built -Werror, booted, rig re-driven from the running kernels patched source: 0 OOB.", "reproduced": true, "impact": "panic", "confidence": "certain", "exploit_chain": "evil card -> pccard_attach_card -> pccard_read_cis -> pccard_scan_cis: CISTPL_LONGLINK_A/MFC supply a 32-bit target -> :394/:406 tuple.ptr = target -> :413 pccard_cis_read_1 dereferences mult*ptr with no bound -> bus_space_read_1 up to 2*(2^32-1) bytes past the 4096-byte mapping -> bridge-dependent master abort panic / adjacent-mapping read / ISA bus hang (DoS; no disclosure channel)", "evidence": "run.log (wildlink_long OOB: 1 ... first=16777216; wildlink_mfc OOB: 2 ... first=4096 max=67108864 wild=1, flag_switches=3); fixed_run.log (f2320: OOB: 0, out-of-range links skipped); matrix.log (only f2320 flips); postboot_run.log (0 OOB on the booted fixed kernel)", "kernel_refs": [ "sys/bus/pccard/pccard_cis.c:62", "sys/bus/pccard/pccard_cis.c:130", "sys/bus/pccard/pccard_cis.c:131", "sys/bus/pccard/pccard_cis.c:145", "sys/bus/pccard/pccard_cis.c:164", "sys/bus/pccard/pccard_cis.c:212", "sys/bus/pccard/pccard_cis.c:334", "sys/bus/pccard/pccard_cis.c:394", "sys/bus/pccard/pccard_cis.c:406", "sys/bus/pccard/pccard_cis.c:413", "sys/bus/pccard/pccard_cis.c:419", "sys/bus/pccard/pccard_cis.c:425" ], "poc_changes": "Pack created fresh (no seeded rig). Same verbatim rig; the two wild-link scenarios encode LONGLINK_A/MFC targets per pccardvar.h read macros; MFC common/attribute flag-switch emulation added to the shims so the common-space wild read is driven through the real CARD_SET_RES_FLAGS path.", "attempts": 4, "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": 1200, "guest_dirty": 0, "build_cmd": "sh extract.sh . && cc -O2 -Wall -o rig rig_main.c", "run_cmd": "./rig wildlink_long && ./rig wildlink_mfc (A/B: sh run_matrix.sh)", "code_hash": "908c166959ac485b7dadf00c66e9ec963ba421de027b157ddc056f2ed3837319", "notes": "Verbatim-rig standard (orchestrator-approved method for this hardware-gated parser; DF-1040/1041 precedent): the compiled parser text is the guests own /usr/src production code, sha256-gated at extraction (extract_manifest.txt). Kernel entry unreachable on this guest: no PCMCIA bridge, no /dev/pccard*, no pccardc (env.txt) -- impact statements are the in-kernel consequences of the demonstrated production-code behavior. Deterministic across two independent boots (identical matrix). Guest left up and clean on the with-src snapshot; pristine pccard_cis.c sha256 acdd2484... re-verified after reset. Incidental: poweroff of the freshly-installed test kernel #1 required a QEMU kill on both takes (no panic trace in the serial console; stock kernel shuts down cleanly) -- VM artifact, not a parser finding.", "recommended_fix": "Bounds-check tuple.mult * tuple.ptr against PCCARD_CIS_SIZE-1-32 in the link-follow loop before the first dereference (same formula as :164); skip out-of-range links.", "fix_status": "fixed", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "VALIDATED. (1) Single-fix rig A/B: bound check (same formula as the :164 inner-walk check) before the :413 dereference -> 0 OOB reads on both wild-link scenarios, links skipped with a printf, in-window links (benign cards MFC chains at 0x30/0x50) still followed; only this findings scenarios change. (2) Combined five-fix kernel build+boot+running-source re-run: 0 OOB.", "fix_evidence": "fix.diff; fixed_run.log; matrix.log (single-fix A/B); kernel_apply.log + kernel_build.tail.log + env.txt + postboot_extract_manifest.txt + postboot_run.log (combined-fix kernel build/boot/running-source rerun)" } |