DF-4224 / verdict.json
{ "finding_id": "DF-4224", "status": "untested", "reproduced": 0, "impact": "dos", "confidence": "certain", "verdict": "Kernel path untestable on this guest (no DRM device: Bochs VGA 0x1234:1111, /dev/dri absent), but the vulnerable arithmetic is proven on the guests own toolchain: verbatim extracts of drm_cvt_mode()/drm_gtf_mode_complex() fed the exact intake value produced by simple_strtol(\"2147483648\") (u32 0x80000000 -> int INT_MIN, matching drm_modes.c:1465 + drm_connector.h:813) raise SIGFPE (exit=136) at drm_modes.c:243, :302, :459 and :481 for the four trigger variants; dbg.c prints the wrapped divisors as 0. In-kernel the same idiv is #DE -> panic during early connector probe from a video= boot parameter. No memory corruption; boot-cmdline-gated DoS.", "exploit_chain": "video=640x480M@2147483648 (kernel cmdline / fb_mode_option) -> fb_get_options -> drm_connector.c:132 drm_mode_parse_command_line_for_connector (refresh unvalidated) -> drm_probe_helper.c:162 drm_mode_create_from_cmdline_mode -> drm_modes.c:1600 drm_cvt_mode(vrefresh=INT_MIN) -> drm_modes.c:243 division by 0 -> #DE -> boot-time kernel panic (persistent until param removed). Variants: MR->:302/:304, GTF odd vdisplay->:459, @134217728->:481.", "evidence": "run.log: marker drm_modes.c:243 followed by Floating point exception (core dumped) exit=136 (case1 -O2); run.2.log/run.O0.log for :302/:459/:481; dbg.log den243=0, den459=0, hfreq_est=0; fixdemo.log shows fix.diff layers rejecting all poisoned refresh values; env.txt documents absence of DRM device.", "kernel_refs": [ "sys/dev/drm/drm_modes.c:1465", "sys/dev/drm/drm_modes.c:1474", "sys/dev/drm/drm_modes.c:243", "sys/dev/drm/drm_modes.c:302", "sys/dev/drm/drm_modes.c:459", "sys/dev/drm/drm_modes.c:481", "sys/dev/drm/drm_connector.c:131", "sys/dev/drm/include/drm/drm_connector.h:811", "sys/dev/drm/drm_probe_helper.c:162" ], "poc_changes": "self-authored; inputs taken from argv after first iteration compiled them as constants and GCC legitimately deleted the always-UB divisions (kernel values arrive at runtime, so the fold was an artifact)", "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": 900, "guest_dirty": 0, "build_cmd": "cd /tmp && cc -O2 -Wall -o harness harness.c && cc -O0 -g -o harness_O0 harness.c", "run_cmd": "cd /tmp && ./harness 1 -2147483648 640 480; ./harness_O0 3 -2147483648 640 479; ...", "code_hash": "c4dc7f52393275f62ec75a0f94800c11c15dae9d3ecb5a16a95e1d2ff41b3c72", "notes": "Guest has no DRM device (pciconf: vgapci0 chip=0x11111234 Bochs; no /dev/dri) so the in-kernel path cannot be invoked; SIGFPE on the same ABI/toolchain is the strongest achievable evidence. The @134217728 variant survives an INT_MAX-only cap (value in range), which is why fix.diff adds the vfieldrate sanity bound inside cvt/gtf. The -<bpp> intake (drm_modes.c:1474) shares the missing range check; huge bpp flows into fbdev allocation math (flagged in audit result, not part of this finding).", "recommended_fix": "Range-check the simple_strtol results for @refresh/-bpp at drm_modes.c:1465/1474 (reject <0 or >INT_MAX) and add a vfieldrate sanity bound (reject 0 or >1000) at the top of drm_cvt_mode/drm_gtf_mode_complex.", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "Patched-kernel boot test impossible on this guest (no DRM hardware to run the parse path). fix.diff logic demonstrated instead: fixdemo (fixdemo.log) shows layer (a) rejecting 2147483648/4294967295/-5 and layer (b) rejecting 134217728, while legitimate 60/500 pass; both trapping sites become unreachable because vfieldrate can no longer wrap.", "fix_evidence": "fixdemo.log (guest run); fix.diff" } |