DF-5445 / verdict.json
{ "finding_id": "DF-5445", "status": "reproduced", "reproduced": true, "impact": "dos", "confidence": "certain", "verdict": "REPRODUCED on DragonFly 6.5-DEVELOPMENT (baseline #0), both faces. Face 1 (no-END stream): a card that keeps resource-data-ready asserted and never sends tag 0x78 keeps pnp_read_resources() (pnp.c:546-574) looping and pnp_read_bytes() growing the kmalloc buffer in 1 KiB steps with NO total-length cap \u2014 kldload NEVER returned (local timeout RC=124 after 50 s), the buffer reached a single 5.57 MB allocation at t+50 s and 12.41 MB at t+125 s and was still growing, a parallel vmstat ssh starved (RC=124), and the guest never recovered (reset required): kernel wedge + unbounded kernel-memory exhaustion. Face 2 (logical-device spray): 6000 PNP_TAG_LOGICAL_DEVICE tags (36 KB card stream) create 6000 bus children, each with an 8640-byte configs[] kmalloc inside pnp_parse_resources() plus ivars and a never-freed 24-byte csnldn \u2014 measured M_DEVBUF growth 208K->6.11MB (+5.9MB permanent, 211->11.9K chunks) for the 36 KB stream (~164x amplification); ldn is an unbounded int although the LDN register is 8-bit, so the face is unbounded. FIX VALIDATED on rebuilt kernel #1 (fix.diff: PNP_MAX_RESOURCE_DATA=64 KiB cap in pnp_read_resources + 256-LDN cap in pnp_create_devices): the exact wedge stream now completes in 4.26 s with pnp_read_resources: too much resource data and kldload RC=0 (guest healthy); the LD spray stops at isa0: too many logical devices with devbuf delta +258K (vs +5.9MB baseline).", "exploit_chain": "crafted ISA-PnP card -> endless ready-or-data byte service, no END tag -> pnp_read_resources infinite loop -> pnp_read_bytes unbounded kmalloc growth (1 KiB steps) -> kernel-memory exhaustion + permanently busy kldload/boot thread (wedge). Alternate face: endless LOGICAL_DEVICE tags -> per-tag device + ivars + csnldn (leaked) + 8640-byte configs[] allocation -> unbounded permanent kernel memory from a ~6-bytes-per-device card stream.", "evidence": "run_endless.log (SSH_RC=124, verbatim kmalloc growth samples 5566464..5570560 at t+50s and 12407808..12409856 at t+125s, starved second command, reset required); run_ldspray.log (baseline: devbuf 208K->6.11MB, 211->11.9K chunks, found=1, 6.57s load); fix_run_endless.log (patched: 4.26 s, RC=0, 7x too much resource data); fix_run_ldspray.log (patched: isa0: too many logical devices, devbuf +258K); rig/ (hack_dfc endless wrapper, hack_dfd spray wrapper)", "kernel_refs": [ "sys/bus/isa/pnp.c:536-581", "sys/bus/isa/pnp.c:546-574", "sys/bus/isa/pnp.c:493-526", "sys/bus/isa/pnp.c:428-460", "sys/bus/isa/pnp.c:453-458", "sys/bus/isa/pnpparse.c:425-426" ], "poc_changes": "Same rig as DF-5443 (see its poc_changes). Script 3 synthesizes an endless 0x09/0x00 small-tag stream; script 4 emits 6000 finite LD tags + END.", "attempts": 2, "guest_uname": "baseline: DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 / fixed: #1: Mon Oct 5 16:47:13 UTC 2026 (fix-validated kernel)", "runtime_sec": 1500, "guest_dirty": 0, "build_cmd": "(cd /usr/src/sys/bus/isa/hack_dfc && make obj && make depend && make); likewise hack_dfd", "run_cmd": "timeout 50 kldload .../rigdfc.ko # baseline: RC=124 wedge; fixed: 4.3 s RC=0 ; kldload .../rigdfd.ko", "code_hash": "e4db996c97f7a4791e143a54d555297b7493f7759a96af75f02e72d484daba75", "notes": "Low severity: card-data DoS at boot/driver-load (no unprivileged-user path), but strictly unbounded by construction (no length or LDN cap anywhere in the engine) and demonstrated live. The csnldn kmalloc (pnp.c:453) is additionally leaked per logical device even in normal operation. The 64 KiB cap chosen in fix.diff is ~16x the largest real-world PnP card resource data; maintainers may tune.", "recommended_fix": "Cap total ingested resource bytes per card (PNP_MAX_RESOURCE_DATA=64 KiB) in pnp_read_resources() and cap logical devices at 256 (LDN register width) in pnp_create_devices() \u2014 full unified diff in fix.diff.", "fix_status": "fixed", "fix_baseline_reproduced": true, "fix_patched_reproduced": false, "fix_verdict": "Single-fix kernel (fix.diff, #1 Mon Oct 5 16:47:13): the exact wedge stream completes in 4.26 s with pnp_read_resources: too much resource data (RC=0, guest healthy, no unbounded growth); the LD spray stops at 256 devices with isa0: too many logical devices and devbuf delta +258K vs +5.9MB baseline. Baseline bad behavior GONE on both faces.", "fix_evidence": "fix_run_endless.log, fix_run_ldspray.log; fix_build.log + fix.diff (in DF-5443 pack)", "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Mon Oct 5 16:47:13 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64" } |