DF-3590 / verdict.json
{ "finding_id": "DF-3590", "status": "reproduced", "reproduced": 1, "impact": "dos", "confidence": "certain", "verdict": "Reproduced live on the QEMU guest as uid 1001: /dev/psm0 is created 0666 and psmioctl() has no privilege check, so an unprivileged user opened the device (arming the aux device + IRQ12), reprogrammed sampling rate/resolution via MOUSE_SETMODE (state persisted, verified with MOUSE_GETMODE), forced PSM_LEVEL_NATIVE, performed MOUSE_READDATA controller transactions, and measured ~6.8ms of shared-i8042 keyboard-disabled time per ioctl (tight loop = console keyboard starvation). Holding the fd open denied the device to root (EBUSY) -- moused(8)/X/syscons cannot use the mouse while an unprivileged user holds it. No memory corruption; no escalation path. Also stress-injected 1535+ PS/2 events via QEMU monitor with concurrent readers: no panic (hardirq lockmgr race killed as a finding).", "exploit_chain": "unprivileged open(/dev/psm0) [0666, no perm check] -> (a) hold fd -> EBUSY for moused/X/syscons (persistent mouse DoS); (b) ioctl hammer -> ~7ms keyboard-port-disable per call on the shared i8042 (console input starvation); (c) MOUSE_SETMODE/MOUSE_SETLEVEL -> persistent device misconfiguration breaking the userspace mouse protocol.", "evidence": "run.log (full unprivileged run: 56 ioctls, 0 failures, rate persisted, root Device busy); VERDICT.md (observation->code mapping + negative results); env.txt (guest kernel, device mode crw-rw-rw-, model IntelliMouse Explorer)", "kernel_refs": [ "sys/dev/misc/psm/psm.c:2025", "sys/dev/misc/psm/psm.c:2629-2935", "sys/dev/misc/psm/psm.c:2720-2805", "sys/dev/misc/psm/psm.c:2811-2816", "sys/dev/misc/psm/psm.c:2539-2575", "sys/dev/misc/psm/psm.c:2222-2224" ], "poc_changes": "Seed sketch used MOUSE_SETRATE/MOUSE_SETRESOLUTION which are #if 0 notyet in sys/mouse.h (those psm.c ioctl branches are dead code); rewrote to the live MOUSE_SETMODE path; added hold/EBUSY phase, ioctl timing, and root-side hold_probe.", "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", "runtime_sec": 95, "guest_dirty": 0, "build_cmd": "cc -O2 -Wall -o psm_ioctl_poc psm_ioctl_poc.c && cc -O2 -Wall -o hold_probe hold_probe.c", "run_cmd": "./psm_ioctl_poc ; ./psm_ioctl_poc hold & ; /tmp/hold_probe (as root)", "code_hash": "7f786538f08f10671509fa9af755fd067b28085bae65ecae232a3c8ecea399f2", "notes": "Fix not kernel-rebuild-validated: Low-severity permission finding (not memcorrupt class); fix.diff is a one-line make_dev 0666->0600 and passes git apply --check. Guest left clean (no kernel changes; transient device state only).", "recommended_fix": "Create /dev/psm0 with mode 0600 (or add priv_check on mutating ioctls if unprivileged read access must be kept)", "fix_status": "not_testable", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "Baseline reproduced. The fix is a devfs-permission change (make_dev 0666->0600, psm.c:2025); rebuild validation skipped per contract (not a memory-corruption finding). With 0600 the unprivileged open fails at devfs and every demonstrated phase is unreachable.", "fix_evidence": "findings/poc/DF-3590/fix.diff (git apply --check OK)" } |