DF-5049 / verdict.json
{ "finding_id": "DF-5049", "status": "not_reproduced", "reproduced": false, "impact": "none", "confidence": "likely", "verdict": "Hardware-gated on the audit guest (no MegaRAID PCI device: pciconf empty, /dev/mfisyspd* absent \u2014 run.log/env.txt), so the UAF could not be executed. Source-proven end-to-end: AEN MR_EVT_PD_REMOVED (mfi.c:1513-1532, live by default via mfi_detect_jbod_change=1) deletes the syspd child locklessly with no mfi_syspd_disable() gate and no drain; mfi_syspd_detach (mfi_syspd.c:155-177) frees pd_info and the softc (subr_bus.c:1944 kfree in device_delete_child) while (a) operator-group fds hold the 0640 cdev with dangling si_drv1, (b) bios parked on mfi_bioq carry bio_driver_info=sc and are later dereferenced+written by mfi_bio_command/mfi_build_syspdio/mfi_disk_complete, and (c) the lockless TAILQ walk can chase a concurrently freed pd_link. Syspd twin of DF-5013. fix.diff (AEN lock+gate; detach open-gate+DISABLED+drain; strategy DISABLED re-check) compile-validated on stock X86_64_GENERIC via make nativekernel; behavior could not be exercised without hardware.", "exploit_chain": "operator-group user holds /dev/mfisyspdN open with readers in flight -> drive removal raises MR_EVT_PD_REMOVED -> lockless device_delete_child frees mfi_system_pd slab -> slab re-groomed via M_BUS/kmalloc spray of softc-sized objects -> held fds pread(2) re-enters mfi_syspd_strategy which writes devstat_start_transaction(&sc->pd_devstat) into the reoccupied object and enqueues bios whose completion writes devstat_end_transaction_buf -> repeatable post-free write; forge pd_controller/pd_devstat toward arbitrary write (no KASLR/SMAP on audit-target class) -> uid0. Not executable on this guest (hardware gate).", "evidence": "run.log: open(/dev/mfisyspd0) ENOENT on guest; env.txt: no AMD/mfi PCI, hw.mfi.detect_jbod_change=1, mfisyspd in stock kernel; VERDICT.md sections 2-4: path:line proof of all three trigger paths, the synchronous softc free, and the three surviving-reference sinks; fix.diff + VERDICT.md section 6: nativekernel compile validation", "kernel_refs": [ "sys/dev/raid/mfi/mfi_syspd.c:155", "sys/dev/raid/mfi/mfi_syspd.c:162", "sys/dev/raid/mfi/mfi_syspd.c:278", "sys/dev/raid/mfi/mfi_syspd.c:281", "sys/dev/raid/mfi/mfi.c:149", "sys/dev/raid/mfi/mfi.c:1513", "sys/dev/raid/mfi/mfi.c:1344", "sys/dev/raid/mfi/mfi.c:1962", "sys/dev/raid/mfi/mfi_disk.c:304", "sys/kern/subr_bus.c:1944", "sys/kern/subr_disk.c:740" ], "poc_changes": "Seed had no PoC; wrote syspd_hold.c (open-hold + 4 pread readers as the in-flight-bio precondition). One compile fix: missing <signal.h> for sig_atomic_t.", "attempts": 1, "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": 30, "guest_dirty": 0, "build_cmd": "cc -O -o syspd_hold syspd_hold.c", "run_cmd": "./syspd_hold /dev/mfisyspd0", "code_hash": "323687e60cc0fc52848e117f1f12efa644b6ef4a4d148db4e3992d17a5953371", "notes": "Known/not re-reported: DF-2066 (strategy bio leak), DF-2067 (si_iosize_max), DF-5013 (mfi_disk LD half of the lifetime bug), DF-3874 (firmware pdlist->count OOB). This finding is the syspd half: distinct file, distinct delete paths (AEN MR_EVT_PD_REMOVED lockless walk; syspdprobe delete), distinct sinks. Residual window after fix documented in VERDICT.md section 7. Guest /usr/src restored byte-identical after fix compile-validation; guest reset with-src before return.", "recommended_fix": "AEN PD_REMOVED: take config+io locks and gate via mfi_syspd_disable(); mfi_syspd_detach: refuse while open (unless detaching), set DISABLED, drain parked bios referencing the softc; strategy: re-check DISABLED under the io lock (see fix.diff)", "fix_status": "not_testable", "fix_baseline_reproduced": false, "fix_patched_reproduced": false, "fix_verdict": "fix.diff applied cleanly to guest /usr/src copy and compile-validated (make -DNO_CLEAN nativekernel KERNCONF=X86_64_GENERIC -> Kernel build completed, exit 0); source reverted afterwards. Baseline/patched behavior not exercisable without MegaRAID hardware, so operational fix validation not_testable; logic reviewed line-by-line in VERDICT.md.", "fix_evidence": "VERDICT.md section 6; fix.diff applies via patch -p1 (Hunk #1/#2/#3 succeeded, mfi.c + mfi_syspd.c)" } |