DF-5025 / verdict.json
{ "finding_id": "DF-5025", "status": "not_reproduced", "reproduced": false, "impact": "none", "confidence": "likely", "verdict": "Source-verified TOCTOU/UAF, runtime reproduction impossible on this guest: ipsd_open sets IPS_DEV_OPEN with no lock (ips_disk.c:92) while ipsd_detach tests it with no lock (ips_disk.c:211); losing the race lets detach complete disk_destroy (:214) under a still-open fd (devfs retains the cdev until last close, kern_conf.c:345-354/devfs_core.c:1440-1459), so the later ipsd_close executes dsc->state &= ~IPS_DEV_OPEN (:103) as a use-after-free WRITE on the newbus-freed ipsdisk_softc, and any in-flight strategy touches freed devstat memory (:137). ipsd_close additionally lacks the si_drv1 NULL check its open twin has (:101-103 vs :90-91). Guest hardware probe (env.txt): no IBM/Adaptec ServeRAID PCI devices (vendor 0x1014/0x9005), no /dev/ips*, no ipsd disks -- the ips driver is compiled in (kldstat -v ids ips/ipsd, pci/ips) but attach never runs. Even with hardware the only detach initiators are privileged (kldunload/devctl), capping severity at Low (the DF-5013 mfi pattern-instance here; DF-5013 was High only because its AEN path needed no privilege). fix.diff (DF-5013-style: lock-serialized state, disabled flag, in-flight drain before destroy, close NULL check) compile-validated in the patched ips.ko build (-Werror clean).", "exploit_chain": "", "evidence": "env.txt (hardware-absence probe: no IPS PCI devices, no /dev/ips*, no ipsd disks, ips code compiled into kernel); VERDICT.md source trace with the lock-free open/detach/close/strategy citations and the disk_destroy/release_dev lifetime chain", "kernel_refs": [ "sys/dev/raid/ips/ips_disk.c:92", "sys/dev/raid/ips/ips_disk.c:103", "sys/dev/raid/ips/ips_disk.c:134", "sys/dev/raid/ips/ips_disk.c:211", "sys/dev/raid/ips/ips_disk.c:214", "sys/dev/raid/ips/ips.c:304", "sys/kern/kern_conf.c:346", "sys/vfs/devfs/devfs_core.c:1440" ], "poc_changes": "no runtime PoC possible; hardware-absence probe captured as env.txt evidence", "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": 15, "guest_dirty": 0, "build_cmd": "n/a (hardware-gated); fix compile: patched ips module make -Werror on guest /usr/src copy", "run_cmd": "probe: pciconf -l | grep -E 1014|9005 ; ls /dev/ips* (env.txt)", "code_hash": "", "notes": "ips instance of the DF-5013 (mfi_disk) lifetime pattern. Trigger requires root-initiated detach racing an unprivileged open -- privilege-gated trigger, hence Low despite the UAF-write class (memcorrupt bucket). Queued-but-unstarted bios are invisible to ips_adapter_frees used_commands gate (ips.c:533-537) and are abandoned (see DF-5026).", "recommended_fix": "Serialize the IPS_DEV_OPEN state changes with sc->queue_lock, add a disabled flag + in-flight drain (active counter, lksleep) in ipsd_detach before disk_destroy, fail-fast in ipsd_strategy once disabled, and add the missing si_drv1 NULL check in ipsd_close (fix.diff mirrors the verified DF-5013 mfi fix).", "fix_status": "not_testable", "fix_baseline_reproduced": false, "fix_patched_reproduced": false, "fix_verdict": "fix.diff compile-validated as part of the merged patched ips.ko module build on the guest (-Werror clean, fix_validation.log in DF-5026s pack; sources restored). Behavioral validation is hardware-gated (no IPS adapter on the guest), so the fix cannot be exercised end-to-end.", "fix_evidence": "fix.diff; patched ips.ko build log (fix_validation.log, referenced from DF-5026 pack); VERDICT.md fix section" } |