DF-5099 / verdict.json
{ "finding_id": "DF-5099", "status": "inconclusive", "reproduced": false, "impact": "none", "confidence": "certain", "verdict": "Defect proven from source: joyopen() implements exclusive access as an unsynchronized check-then-set on joy->timeout[i] (joy.c:159-162) and joyclose() clears the flag unconditionally (joy.c:173); racing opens both succeed past the EBUSY check and a close by one holder drops the claim for the rest. Not runtime-exercisable on this guest: joy(4) is module-only and attaches only to ISA/PnP gameport hardware โ /dev/joy* is absent even after kldload joy (run.log), so both triggers exit 2 at open() ENOENT. Impact ceiling is Info: the node is 0600 root-only (joy.c:133) and the raced state is plain ints in a never-freed softc, so there is no memory-safety or privilege consequence โ PoC skipped per contract for Info hardening findings, guest evidence captured instead.", "exploit_chain": "", "evidence": "VERDICT.md (source proof + environment blocker); run.log (ENOENT at open, kldload joy creates no node); build.log (clean -Wall build on guest cc 8.3); env.txt (no ISA gameport, virtio-only PCI); fix.diff (git-apply-clean one-word atomic claim).", "kernel_refs": [ "sys/dev/misc/joy/joy.c:159-162", "sys/dev/misc/joy/joy.c:173", "sys/dev/misc/joy/joy.c:133" ], "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_open_race joy_open_race.c", "run_cmd": "./joy_open_race", "code_hash": "d6d01d7ef1fd421a7b182e5da2fd251faf76db96e860db3b3ae0fd2a9cd292bc", "notes": "Info hardening finding; PoC intentionally skipped per reviewer contract (Low/Info). Guest probe attempts: device absent, module loads but never attaches (no ISA hints/PnP IDs), module unloaded after test โ guest left clean. Known sibling DF-2108 (NULL softc derefs) not re-reported.", "recommended_fix": "Claim the device with atomic_cmpset_int(&joy->timeout[i], 0, JOY_TIMEOUT) in joyopen() instead of the unlocked check-then-set (see fix.diff).", "fix_status": "not_testable", "fix_baseline_reproduced": false, "fix_patched_reproduced": false, "fix_verdict": "fix.diff is git-apply-clean against the unmodified tree and correct by construction, but behavioral fix validation is impossible on this guest: the joy driver never attaches (no ISA gameport), so neither baseline nor patched kernel ever executes joyopen().", "fix_evidence": "fix.diff; run.log (device absent on guest); git apply --check output in session log." } |