DF-5450 / verdict.json
{ "finding_id": "DF-5450", "status": "reproduced", "verdict": "REPRODUCED on the live guest: nexus_activate_resource() (nexus.c:420-451) maps MMIO with pmap_mapdev() before the idempotent rman_activate_resource() and overwrites r_virtual, so re-activating an active resource returns success but allocates a second kernel_map range + RW PTEs for the same physical window, orphaning the first permanently. 16 alloc/activate/release cycles stranded exactly 16 pages (kernel_map->size +65536, never returned) and left the first mapping dereferenceable after full release (stale RW PTE). Fix (idempotence guard + failure rollback) validated on a rebuilt kernel: single mapping, 0 leaked pages, no orphan PTE.", "reproduced": true, "impact": "leak", "confidence": "certain", "exploit_chain": "No userland chain: trigger is driver-side re-activation (pci.c:4073-4085 re-activates an allocated rid with RF_ACTIVE; acpi/exca/pccbb same pattern; any driver calling bus_activate_resource() on an active resource). Each re-activation permanently leaks roundup(size,PAGE) of kernel_map KVA and a stale RW MMIO PTE set -> long-run KVA exhaustion / kernel-pmap hygiene degradation. Not a data disclosure or privesc.", "evidence": "run.log lines err2ndact=0 vaddr1=...2601000 vaddr2=...2611000 same_phys=YES + leaked pages: 16 + stale RW PTE still present: YES; run.2.log single-cycle +1 page; fix_run.log (patched): vaddr1==vaddr2, leaked pages: 0", "kernel_refs": [ "sys/platform/pc64/x86_64/nexus.c:427-450", "sys/platform/pc64/x86_64/nexus.c:446", "sys/platform/pc64/x86_64/nexus.c:450", "sys/platform/pc64/x86_64/nexus.c:513-515", "sys/platform/pc64/x86_64/pmap.c:6192-6219", "sys/kern/subr_rman.c:419-424", "sys/bus/pci/pci.c:4073-4085" ], "poc_changes": "Added 16-cycle accumulation loop, kernel_map->size accounting, guarded orphan-read (safe on patched kernels); final module builds clean with -Werror", "attempts": 3, "guest_uname": "DragonFly dfbsd 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": 420, "guest_dirty": 0, "build_cmd": "cd /root/poc/nxmap && make (KMOD=nxmap SRCS=nxmap.c device_if.h bus_if.h, bsd.kmod.mk)", "run_cmd": "kldload /root/poc/nxmap/nxmap.ko; sleep 1; dmesg | grep -E nxmap|DF-5450", "code_hash": "d770f3783f526d1fd4405bcb13b8088ef5dcc2f1cadacb80ecaa2fccc31eb929", "notes": "Impact leak = kernel_map KVA + PTE resource leak (not data disclosure). Fix validated with guest nativekernel rebuild #1 (Oct 5 17:59:42): baseline reproduced, patched behavior gone, boot/attach regression-free.", "recommended_fix": "Guard nexus_activate_resource(): if (rman_get_flags(r) & RF_ACTIVE) return rman_activate_resource(r); and pmap_unmapdev() the fresh mapping when rman_activate_resource() fails", "fix_status": "fixed", "fix_baseline_reproduced": true, "fix_patched_reproduced": false, "fix_verdict": "fix.combined.diff applied in guest /usr/src, nativekernel rebuilt and booted (kernel #1): second activation is now a no-op for the mapping (vaddr1==vaddr2), kernel_map->size unchanged over 16 cycles (leaked pages: 0), no orphan mapping after release", "fix_evidence": "findings/poc/DF-5450/fix_run.log (patched-kernel dmesg: leaked pages: 0, stale: N/A (v1 == v2, single mapping))" } |