DF-5591 / verdict.json
{ "finding_id": "DF-5591", "status": "not_reproduced", "reproduced": false, "impact": "none", "confidence": "certain", "verdict": "Hardening finding, negative runtime result by construction: isavga_probe() (sys/bus/isa/vga_isa.c:108) declares video_adapter_t adp uninitialized and vga_probe_unit() (sys/dev/video/fb/vga.c:76-78) returns 0 WITHOUT writing *buf when vid_get_switch() is NULL, whereupon vga_isa.c:118-121 programs adp.va_io_base/va_io_size/va_mem_base/va_mem_size \u2014 four ints of stale kernel stack (sys/sys/fbio.h:298-301) \u2014 into the device resource list, which devinfo -rv exposes to unprivileged users (verified live). The branch is structurally unreachable in every shipped configuration because vga_isa.c and vga.c are gated on the SAME optional vga option (sys/platform/pc64/conf/files:72,199), so the VIDEO_DRIVER(vga,...) linker-set entry (vga.c:244, walked by vid_get_switch at fb.c:210) is always present when isavga_probe runs; live proof: guest vga0 windows are exactly the static biosadapter values 0x3c0-0x3df/0xa0000-0xbffff (IO_VGA/32, EGA_BUF_BASE/EGA_BUF_SIZE, vga.c:175-179), not garbage. Filed Info: the return-0-without-initializing API contract is a booby trap one Makefile split away from a kernel-stack info leak plus garbage rman claims and probe-fails-open (Generic ISA VGA advertised with no switch registered).", "exploit_chain": "", "evidence": "findings/poc/DF-5591/run.log (dmesg port 0x3c0-0x3df iomem 0xa0000-0xbffff == static init; devinfo -rv works via run_user; conf/files:72+199 single gate); VERDICT.md (full structural proof: vga.c:76-78 -> fb.c:203-220 linker set -> vga.c:244 -> conf/files gate; single-caller check for the ENXIO fix)", "kernel_refs": [ "sys/bus/isa/vga_isa.c:108", "sys/bus/isa/vga_isa.c:116-121", "sys/dev/video/fb/vga.c:70-84", "sys/dev/video/fb/fb.c:203-220", "sys/dev/video/fb/vga.c:244", "sys/platform/pc64/conf/files:72", "sys/platform/pc64/conf/files:199", "sys/sys/fbio.h:298-301" ], "poc_changes": "No seeded PoC; authored introspection harness (trigger.sh/run.sh) whose deliverable is the NEGATIVE result: live window values matching the static initializer plus the host-side conf/files gate proving structural unreachability.", "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": 70, "guest_dirty": 0, "build_cmd": "./build.sh (none required)", "run_cmd": "./run.sh (root dmesg/devinfo + run_user devinfo + host conf/files grep)", "code_hash": "", "notes": "Info/hardening per severity rubric (no demonstrated impact). Reproducing the uninit read itself would require editing kernel build files to split vga.c from vga_isa.c \u2014 out of scope (sys/ read-only). Companion defensive fix is two one-liners (bzero + ENXIO); vga_probe_unit has exactly one caller (vga_isa.c:116) so the semantic change is safe.", "recommended_fix": "bzero(&adp, sizeof(adp)) in isavga_probe() and make vga_probe_unit() return ENXIO instead of 0 when the video switch is absent (fix.diff, patch dry-run OK).", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff authored against the read-only sys/ tree (bzero in isavga_probe + vga_probe_unit ENXIO; patch -p1 dry-run OK on both files). Kernel-rebuild validation not performed: Info hardening finding, nothing reproduced to flip (contract mandates rebuild validation only for reproduced memory corruption).", "fix_evidence": "findings/poc/DF-5591/fix.diff (two-file unified diff, dry-run applied clean)" } |