DF-4644 / verdict.json
{ "finding_id": "DF-4644", "status": "untested", "reproduced": 0, "impact": "none", "confidence": "likely", "verdict": "Race window proven by inspection, not drivable on the audit guest. vid_realloc_array (fb.c:76-122) frees and swaps the global adapter/vidsw/vidcdevsw arrays under only per-CPU crit_enter, outside vga_token (called from vid_register fb.c:162 before the token at fb.c:168), while tokenless readers vid_find_adapter (fb.c:235-243), vid_get_adapter (fb.c:288-290, reachable from console ioctls via scvidctl.c:474) and the token-holding writer vid_unregister (fb.c:196) run on other CPUs \u2014 a UAF read/write window on the freed array. Additionally vid_registers free-slot scan (fb.c:157-160) precedes the token, so concurrent registrations can claim the same index and cross-wire adapter/vidsw slots, giving type-confused dispatch in fb_commonioctl (fb.c:706/714/723). Guest constraints: single built-in vga0 (adapters never exceeds 1, realloc never runs), FB_INSTALL_CDEV LINT64-only so the cdev block is not compiled, and no loadable fb modules \u2014 no concurrent registration exists to race with. Dispatch surroundings were validated live on the guest (fb_dispatch_probe.c/probe_run.log): ADPINFO fields all kernel-written + va_reserved zeroed (no uninit-leak class; only known DF-1786 pointer leak), out-of-range FBIO_MODEINFO ids rejected ENODEV.", "exploit_chain": "", "evidence": "VERDICT.md (defect map with fb.c line cites + guest constraints + fix sketch); fb_dispatch_probe.c + probe_run.log (live dispatch sanity on /dev/ttyv0); README.md", "kernel_refs": [ "sys/dev/video/fb/fb.c:104", "sys/dev/video/fb/fb.c:110", "sys/dev/video/fb/fb.c:162", "sys/dev/video/fb/fb.c:168", "sys/dev/video/fb/fb.c:196", "sys/dev/video/fb/fb.c:235", "sys/dev/video/fb/fb.c:288", "sys/dev/video/fb/fb.c:706", "sys/dev/misc/syscons/scvidctl.c:474" ], "poc_changes": "n/a \u2014 no PoC seed; a dispatch-sanity probe (fb_dispatch_probe.c) was written and run instead to ground the negative results around the finding", "attempts": 0, "guest_uname": "DragonFly dfbsd 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": 12, "guest_dirty": 0, "build_cmd": "cc -o /root/probe /root/probe.c", "run_cmd": "/root/probe (root, /dev/ttyv0; files removed afterwards)", "code_hash": "482674a10dba163945f3d7942e30c5ede43156397e0a1b518fd9ba5ada63bd27", "notes": "Phase V skipped for the race itself (Low, platform-gated: needs >=2 adapters / concurrent registration, impossible on guest). The probe that WAS run validates the surrounding fb_commonioctl dispatch analysis, not the race. Guest was cleaned (rm /root/probe /root/probe.c).", "recommended_fix": "Serialize the adapter-array lifecycle with vga_token: take the token across vid_register (including the free-slot scan and the vid_realloc_array call) and in vid_find_adapter/vid_get_adapter/vid_allocate.", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "No runtime verification possible (single-adapter guest); fix sketch in VERDICT.md.", "fix_evidence": "VERDICT.md fix section." } |