DF-2318 / verdict.json
{ "finding_id": "DF-2318", "status": "reproduced", "verdict": "REPRODUCED at the verbatim-rig level on the DragonFly guest (3/3 deterministic runs); the kernel entry path itself is hardware-gated (no PCMCIA bridge in QEMU -- env.txt). The production pccard.c was machine-extracted BYTE-IDENTICAL from the guests own /usr/src (extract2.sh; sha256 gate 5b610669...; PCCARD_BYTE_IDENTICAL=yes + SUBR_BUS_BYTE_IDENTICAL=yes in extract2_manifest.txt) and driven through the real entry pccard_attach_card(). A perfectly-legal CIS that omits CISTPL_VERS_1 parses with card.error=0 and a non-empty pf_head (run.log PRE line), so pccard_attach_card proceeds and creates children (pccard.c:205-259); cis1_info[0]/[1] remain NULL (only CISTPL_VERS_1 ever sets them, pccard_cis.c:735-760). Every production pnpinfo surface then faults: devadded on driver-attach success (subr_bus.c:645 via :2114), devnomatch on probe failure (subr_bus.c:673), and the unprivileged hw.bus.devices walk used by devinfo(8)/sysctl -a (subr_bus.c:3899, DEVICE_SYSCTL_PNPINFO at :174 -- the walk was verified live as user maxx on this guest). All three scenarios die with SIGSEGV si_addr=0x0 pinned by disassembly to movzbl (%rcx),%r8d == pccard.c:1001 (if (*src == \")) with rcx loaded from sc+0x110 == &sc->card.cis1_info[0] (rig prints offsetof=0x110, exact match; disasm_proof.txt). In kernel context: deterministic panic at card insertion, re-triggerable on demand by any unprivileged local user while the card is seated. Negative control vers1_pnpinfo_ok (same card WITH VERS_1) builds the pnpinfo string cleanly.", "reproduced": true, "impact": "panic", "confidence": "certain", "exploit_chain": "evil PC Card without CISTPL_VERS_1 -> socket insert event -> pccard_attach_card (pccard.c:178) -> CIS parses with no error, cis1_info stays NULL -> child created+probed -> devadded/devnomatch or later unprivileged devinfo -v / sysctl hw.bus.devices walk -> bus_child_pnpinfo_str -> pccard_child_pnpinfo_str -> pccard_safe_quote(cis0, NULL, 128) -> kernel read at NULL (pccard.c:1001) -> panic. No privilege boundary crossed: fixed read at NULL, no attacker-controlled mapping.", "evidence": "run.log (decisive: PRE line error=0/cis1_info[0]=0x0 + 3x RIG SIGSEGV si_addr=0x0); run.2.log/run.3.log (determinism); disasm_proof.txt (faulting movzbl (%rcx) with rcx from sc+0x110, offsetof printed =0x110); extract2_manifest.txt (byte-identity); build.log; matrix.log (f2318 variant flips exactly the three no_vers1 scenarios to clean exit 0 with cisvendor=\"\" strings); postboot_run.log (combined-fix kernel, running-source re-extraction); env.txt", "kernel_refs": [ "sys/bus/pccard/pccard.c:993", "sys/bus/pccard/pccard.c:1001", "sys/bus/pccard/pccard.c:1020", "sys/bus/pccard/pccard.c:1021", "sys/bus/pccard/pccard.c:205", "sys/bus/pccard/pccard.c:256", "sys/bus/pccard/pccard.c:1340", "sys/bus/pccard/pccard_cis.c:86", "sys/bus/pccard/pccard_cis.c:735", "sys/kern/subr_bus.c:174", "sys/kern/subr_bus.c:645", "sys/kern/subr_bus.c:673", "sys/kern/subr_bus.c:2114", "sys/kern/subr_bus.c:3899" ], "poc_changes": "No seed PoC existed for DF-2318 (pack was missing entirely). Wrote the verbatim lifecycle rig (rig2): machine-extracted pccard.c/subr_bus.c/pccard_cis.c cores, kernel-env shims (device tree + devadded/devnomatch/sysctl-walk surfaces mirroring subr_bus.c, bridge-window bus_alloc_resource model, ledgered kmalloc), CIS builders, and 7 scenarios covering DF-2318/5355/5356 plus two negative controls. Extraction needed the production forward-decl block (pccard.c:83-90), ccr_read/write, the PCCARD_IVAR_* enum and PFF_ENABLED ranges, and the subr_bus prototype block to compile verbatim; byte-identity cross-checked sed-vs-awk.", "attempts": 8, "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 all (success = 3x RIG SIGSEGV si_addr=0x0 for the no_vers1 scenarios + controls green; per-scenario: ./rig2 no_vers1_devadded)", "code_hash": "6746055beafbffae93e5758ec0373a40694ee704e9b4ebcd1915ea7e4d82b658", "notes": "Guest has no PCMCIA/CardBus hardware (env.txt), so in-kernel behavioral exercise is impossible -- same gating as DF-1040/1041/2319; the verbatim rig proves behavior of the exact shipped text, and the combined-fix kernel build+boot (below) proves compile/boot/source-of-running-kernel. devinfo -v / sysctl -a were confirmed working unprivileged on this guest for the re-trigger surface. The other consumers guard NULL (pccard.c:159, :373-387, :974); pccard_child_pnpinfo_str did not.", "recommended_fix": "Guard both pccard_safe_quote calls in pccard_child_pnpinfo_str on cis1_info[i] != NULL (emit empty string otherwise); 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): only the three no_vers1 scenarios change -- clean exit 0, devadded prints sane manufacturer=0x1234 product=0x5678 cisvendor=\"\" cisproduct=\"\" strings; busypanic (DF-5355) and reentry_leak (DF-5356) unchanged under the f2318 variant; negative controls green. (2) Combined three-fix kernel: -Werror nativekernel rc=0, installkernel rc=0, booted kernel #1; rig re-extracted from the RUNNING kernels patched source (--allow-patched) and re-driven: every scenario clean (postboot_run.log). In-kernel behavioral test impossible (no PCMCIA bridge) -- DF-1040/1041/2319 precedent.", "fix_evidence": "fix.diff; matrix.log; postboot_extract_manifest.txt; postboot_run.log; kernel_apply.log; kernel_build.tail.log" } |