DF-4158 / verdict.json
{ "finding_id": "DF-4158", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "vga_save_font/vga_load_font perform no internal validation of the glyph index/count, making them a latent OOB-write/OOB-read API (ch*32 int overflow -> wild KVA via bcopy_toio/bcopy_fromio) that one unshackled future caller could trigger; today every caller is kernel-internal and clamped (mouse_char pre-clamped to <=251 by MOUSE_MOUSECHAR), so no user-reachable trigger exists and none could be produced on the live guest. The accompanying vgafuzz run on the guest (root on /dev/ttyv0) proves the entire user-reachable vga.c ioctl surface rejects or safely consumes hostile scalars: all hostile FBIO_SETMODE/FBIO_MODEINFO values rejected (get_mode_param NULL gate), all hostile palette index/count combinations rejected (base/count gate), FBIO_SETDISPSTART/FBIO_SETLINEWIDTH extremes accepted but landing only in CRTC register bytes and the va_line_width int with no unclamped memory-op consumer. Guest stayed up throughout.", "exploit_chain": "", "evidence": "vga.c:1189-1233+1241-1286 (missing ch/count validation), scmouse.c:881-889 (user-influenced mouse_char flows in, clamped upstream), run.log (vgafuzz results + unpriv EPERM + /dev/vga absent), build.log", "kernel_refs": ["sys/dev/video/fb/vga.c:1189", "sys/dev/video/fb/vga.c:1212", "sys/dev/video/fb/vga.c:1241", "sys/dev/video/fb/vga.c:1264", "sys/dev/misc/syscons/scmouse.c:881"], "poc_changes": "authored fresh exerciser (no seed); expected-accept labels adjusted after observing FBIO_SETLINEWIDTH INT_MAX lands only in hw regs", "attempts": 2, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 x86_64", "runtime_sec": 9, "guest_dirty": 0, "build_cmd": "cc -O -Wall -o /root/vgafuzz /root/vgafuzz.c", "run_cmd": "/root/vgafuzz /dev/ttyv0 (root); su -m maxx -c /tmp/vgafuzz /dev/ttyv0 (EPERM expected)", "code_hash": "e158200e236197d1452a1a44cc73fe9ebf585802aa809e4b1e8240791d4a4459", "notes": "Info hardening. Additional file-level negative results carried by run.log: no FBIO_*STATE ioctls exist (vga_save/load_state only reachable from isavga suspend/resume with kernel-sized buffers and size-validated), FBIO_ADPINFO copy is imin-bounded, vga_mmap_buf offset is unsigned and window-size-bounded (no DF-3879-style signed-offset issue), /dev/vga absent (FB_INSTALL_CDEV off; 02660 root:wheel when compiled).", "recommended_fix": "Validate ch/count against the 512-glyph (0x4000/32-byte) font page in vga_save_font and vga_load_font", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "Nothing observable to diff on this kernel (no userland path can reach the font functions with unchecked values), so baseline/patched comparison is not meaningful. fix.diff applies cleanly (git apply --check) and adds the ch/count bounds gate to both functions.", "fix_evidence": "findings/poc/DF-4158/fix.diff (git apply --check clean, two hunks: save_font + load_font)" } |