DF-5362 / verdict.json
{ "finding_id": "DF-5362", "status": "reproduced", "verdict": "REPRODUCED at the verbatim-rig level on the DragonFly guest; kernel entry hardware-gated (no PCMCIA bridge). pccard_scan_cis terminates only when longlink_present==0 AND mfc_index>=mfc_count (:398-409); the in-chain truncation check (:164) only forces a synthetic END WITHIN a chain. On the verbatim parser: a LINKTARGET(CIS) chain at attr 0x10 whose LONGLINK_A targets 0x10 itself re-arms longlink_present (:209-212) on every revisit -- the rigs read-offset ring shows the bus-read stream PERIODIC with period 12 reads for >=3 full cycles and the scan fails to return within a 200000-read budget the kernel does not have; the alarm variant measured ~570-695 million bus reads in 2 seconds of wall clock and was still spinning when killed (one CPU burned in kernel mode; on the socket event thread the insertion never completes and bus_release_resource at :441 never runs). With FUNCID/CONFIG/CFTABLE in the cycle each iteration allocates one cfe (leakloop): LIVE cfe=4545 at budget 100000 vs 9090 at 200000 -- exactly +1 cfe per 22-read cycle, unbounded inside a single insertion (with DF-5361 the pf is never freed either). mfc hops alone are bounded (mfc_index monotonic <= 50); only the LONGLINK re-arm makes the graph cyclic. Fix validated: hop budget 64 -- all livelock scenarios return normally (65 CARD_SET_RES_FLAGS switches = 64 hops + initial), leakloop capped at 64 cfes independent of budget, benign 3-hop card unaffected; combined-five-fix kernel built -Werror, booted, rig re-driven from the running kernels patched source: all terminate.", "reproduced": true, "impact": "dos", "confidence": "certain", "exploit_chain": "evil card -> pccard_attach_card (socket event thread) -> pccard_read_cis -> pccard_scan_cis -> cycle {LINKTARGET validates, LONGLINK_A re-arms longlink, END jumps back to the same LINKTARGET} -> infinite kernel-mode loop: CPU livelock + wedged socket thread + leaked CIS window (:441 unreached); with FUNCID/CONFIG/CFTABLE inside the cycle it is unbounded kmalloc exhaustion (+1 cfe/iteration, DF-5361 amplifier)", "evidence": "run.log (livelock: READ BUDGET EXHAUSTED ... has NOT returned + RING: ... PERIODIC, period=12 reads; livelock_alarm: SIGALRM after wall-clock budget; bus_reads=630837765; leakloop LIVE cfe=4545@100k / 9090@200k in matrix.log); fixed_run.log (f5362: normal return, 65 flag switches = hop budget, LIVE cfe=64); postboot_run.log (all terminate)", "kernel_refs": [ "sys/bus/pccard/pccard_cis.c:156", "sys/bus/pccard/pccard_cis.c:164", "sys/bus/pccard/pccard_cis.c:200", "sys/bus/pccard/pccard_cis.c:209", "sys/bus/pccard/pccard_cis.c:212", "sys/bus/pccard/pccard_cis.c:386", "sys/bus/pccard/pccard_cis.c:394", "sys/bus/pccard/pccard_cis.c:398", "sys/bus/pccard/pccard_cis.c:409", "sys/bus/pccard/pccard_cis.c:413", "sys/bus/pccard/pccard_cis.c:425", "sys/bus/pccard/pccard_cis.c:441", "sys/bus/pccard/pccard.c:195" ], "poc_changes": "Upgraded the seeded model to the verbatim rig; leakloop initially terminated because a NO_LINK tuple in chain 0 disarmed the longlink (exactly the mechanism this finding describes) -- removed it so the LONGLINK_A re-arm drives the cycle; ring-based periodicity detection and read-budget longjmp added to shims.", "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": 1400, "guest_dirty": 0, "build_cmd": "sh extract.sh . && cc -O2 -Wall -o rig rig_main.c", "run_cmd": "./rig livelock && ./rig leakloop && ./rig livelock_alarm (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": "Add a chain-hop budget (64) to the link-follow loop; exceeding it device_prints and goto done, exactly like the existing truncation path at :164-167.", "fix_status": "fixed", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "VALIDATED. (1) Single-fix rig A/B: hop budget 64 -> livelock and leakloop return normally (65 flag switches), leakloop LIVE cfe=64 at any read budget, livelock_alarm returns before the 2 s alarm, benign 3-hop card unaffected. (2) Combined five-fix kernel build+boot+running-source re-run: all scenarios terminate.", "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)" } |