DF-5100 / verdict.json
{ "finding_id": "DF-5100", "status": "inconclusive", "reproduced": false, "impact": "none", "confidence": "certain", "verdict": "Mechanism proven from source: joyread() spins inside crit_enter() (joy.c:190) until WALL-CLOCK nanotime() passes start+timeout (joy.c:193-204); nanotime() adds the settimeofday/NTP-steppable basetime (kern_clock.c:1579-1586), so a backward clock step during the loop extends the interrupt-masked critical section by roughly the step magnitude, and even without a step every read masks interrupts on its CPU for up to 10ms (JOY_SETTIMEOUT cap, joy.c:243). Not runtime-exercisable on this guest: joy(4) attaches only to ISA/PnP gameport hardware โ /dev/joy* absent even after kldload joy; trigger exits 2 at open() ENOENT (run.log). Impact ceiling Info: node is 0600 root-only (joy.c:133), so the realistic scenario is a root joystick reader plus an NTP backward step โ a latent local DoS/latency hazard, not an unprivileged primitive. PoC skipped per contract for Info hardening findings; guest evidence captured instead.", "exploit_chain": "", "evidence": "VERDICT.md (wall-clock proof: joy.c loop vs kern_clock.c basetime); run.log (ENOENT at open; kldload joy creates no node); build.log (clean -Wall build on guest cc 8.3); env.txt (no gameport hardware); fix.diff (nanotime->nanouptime, git-apply-clean).", "kernel_refs": [ "sys/dev/misc/joy/joy.c:190-213", "sys/dev/misc/joy/joy.c:193", "sys/dev/misc/joy/joy.c:204", "sys/kern/kern_clock.c:1562-1587", "sys/dev/misc/joy/joy.c:243" ], "poc_changes": "None material โ trigger written fresh for this pass; guest-built heredoc trimmed comments only (functionally identical to pack source).", "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": 95, "guest_dirty": 0, "build_cmd": "cc -O2 -Wall -o joy_crit_loop joy_crit_loop.c", "run_cmd": "./joy_crit_loop", "code_hash": "42e308cc1fec85678ee17c27784c6feaf77c9a90a4e3f621acd95397517fd389", "notes": "Info hardening finding; PoC intentionally skipped per reviewer contract. Baseline 10ms crit spin is by-design 1995 ISA behavior; the defect is the wall-clock (non-monotonic) deadline. Guest left clean (joy module unloaded).", "recommended_fix": "Use monotonic nanouptime() instead of nanotime() for the joyread() timing loop (joy.c:193,204); nanouptime exists at sys/sys/time.h:185 (see fix.diff).", "fix_status": "not_testable", "fix_baseline_reproduced": false, "fix_patched_reproduced": false, "fix_verdict": "fix.diff is git-apply-clean and correct by construction (monotonic deadline immune to wall-clock steps), but behavioral validation is impossible on this guest: the joy driver never attaches, so neither baseline nor patched kernel executes joyread().", "fix_evidence": "fix.diff; run.log (device absent on guest); git apply --check output in session log." } |