DF-5393 / verdict.json
{ "finding_id": "DF-5393", "status": "reproduced", "reproduced": true, "impact": "dos", "confidence": "certain", "verdict": "REPRODUCED (measured) on DragonFly 6.5-DEVELOPMENT (X86_64_GENERIC, QEMU). isa_find_memory (isa_common.c:128-148) iterates a PnP-supplied memory window one candidate at a time with no attempt cap and no wrap guard; iteration count is bounded only by (end-start)/align. Harness: a child whose single MEMORY32_RANGE descriptor covers 4MB ([0xE0000000-0xE03FFFFF], size=1, align=1 \u2014 all values MEMORY32_RANGE accepts, pnpparse.c:295-300) with the whole window pre-claimed by a blocker child, driven through the real isa_driver_added -> isa_assign_resources -> isa_find_memory path. Serial-timestamped callbacks: prior childs disable callback at +302,946us, stall childs at +1,059,964us -> ~757ms in isa_find_memory for 4,194,304 rman alloc cycles (~0.18us each), then (null) cant assign resources (memory). Extrapolated ceiling: a crafted start=0/end=0xFFFFFFFF/size=1/align=1 descriptor burns ~13 minutes per descriptor (x8 descriptors x9 configs per logical device, inside single-threaded boot probing) \u2014 hours of unresponsive boot from a few PnP bytes. FIX VALIDATED in the same cycle: with ISA_FIND_MAX_TRIES(65536) + wrap guard (fix.diff in ../DF-5392/), the same 4MB window completes in ~17-30ms (cap reached) \u2014 25x faster at 4MB and bounded at ~12ms worst-case regardless of window size.", "exploit_chain": "crafted ISA-PnP card supplies MEMORY32_RANGE {start=0, endbase=0xFFFFFFFF, align=1, size=1} -> pnp_parse_desc stores ir_start=0, ir_end=0xFFFFFFFF, ir_align=1 -> isa_assign_resources at boot -> isa_find_memory loops start=0..0xFFFFFFFF stepping 1 -> every bus_alloc_resource fails when the candidate space is claimed (arranged by the cards own overlapping descriptors or system usage) -> ~2^32 rman iterations x ~0.18us = ~13 min/descriptor, serialized inside isa_probe_children -> boot-time kernel CPU lockup (DoS).", "evidence": "../DF-5392/run_a.log lines: PNPHACK[stall]: ice[0] prio=0 nmem=1, PNPHACK[block]: window [0xe0000000-0xe03fffff] held: YES, config_cb(p61) ... (+302946 usec), config_cb(stall) ... (+1059964 usec) (delta ~757ms = the find_memory grind), (null) cant assign resources (memory). Patched: fix_run.log config_cb(p61) ... (+190001 usec) / config_cb(stall) ... (+220044 usec) (delta ~30ms, cap-bound).", "kernel_refs": [ "sys/bus/isa/isa_common.c:128-148", "sys/bus/isa/pnpparse.c:295-300" ], "poc_changes": "same harness as DF-5392 (pnphack.c, stall children created unconditionally in identify); blocker child must be created LAST so isa_driver_addeds per-child release loop does not free the window before the stall child is processed", "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 (baseline) / #1: Sat Oct 3 23:39:17 UTC 2026 (fix-validated kernel)", "runtime_sec": 900, "guest_dirty": 0, "build_cmd": "(cd /usr/src/sys/bus/isa/hack_a && make obj && make depend && make)", "run_cmd": "kldload /usr/obj/usr/src/sys/bus/isa/hack_a/pnphack.ko # stall children run as part of run-A", "code_hash": "f16b7fcc8465a42a125e235999f3c4604e9fe55f1cc61d8d0cfc53157e723d28", "notes": "hardware-supplied trigger (crafted PnP card / emulated device), boot-time; measured 757ms/4MB on-guest with clean arithmetic to ~13min/4GB/descriptor. Same run also demonstrated on the patched kernel (~30ms, ISA_FIND_MAX_TRIES). The port variant isa_find_port (isa_common.c:192-212) is inherently bounded by 16-bit ioport ceilings; memory32 ranges are the 32-bit exposure.", "recommended_fix": "isa_find_memory: add wrap guard (start <= end && start+size-1 <= end) and cap candidate attempts at ISA_FIND_MAX_TRIES (65536) \u2014 included in ../DF-5392/fix.diff.", "fix_status": "fixed", "fix_baseline_reproduced": true, "fix_patched_reproduced": false, "fix_verdict": "Patched kernel (fix.diff, same build as DF-5392): the identical 4MB fully-claimed window now takes ~17-30ms (attempt cap reached) instead of ~757ms; worst case is bounded (~12ms) for any window size including 2^32/align=1. Baseline stall no longer reproducible.", "fix_evidence": "fix_run.log: patched-kernel callbacks p61 (+190001 usec) -> stall (+220044 usec) = ~30ms delta vs baseline 757ms; ISA_FIND_MAX_TRIES guard compiled in (fix_build.log)", "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Sat Oct 3 23:39:17 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64" } |