DF-5005 / verdict.json
{ "finding_id": "DF-5005", "status": "reproduced", "reproduced": 1, "impact": "panic", "confidence": "certain", "verdict": "REPRODUCED (function-level, deterministic, on-guest): amdgpu_atombios.c:592-593 installs usReferenceClock from the VBIOS into ppll->reference_freq (cloned to all ppll[1..] at :628-629) with NO zero check even though the same function fixups pll_out_min (:610-611), lcd_pll_out_* (:603-608), spll/mpll pll_out_min (:642/:669) and max_pixel_clock (:708-709). With reference_freq==0, amdgpu_pll_compute (reached from atombios_crtc.c:854 with ppll[0..2]) sets den=0 (amdgpu_pll.c:187); gcd(nom,0)=nom leaves den=0 and DIV_ROUND_UP(den_min,0) traps at amdgpu_pll.c:63 \u2014 guest harness SIGFPE 3/3, gdb pins harness:114==amdgpu_pll.c:63 with den_min=11 (post_div_min for the 600MHz input), proving the zero divisor is the reference clock. gcd(0,0)=0 additionally traps :51 if the mode clock is also 0; atombios_crtc.c:875-879 (ss step size / (ref_freq/100)) is a sibling zero-divisor for ref<100. Gated on corrupt/malicious VBIOS (or skipped get_clock_info) rather than runtime user input -> Low severity, deterministic panic at first modeset, no corruption/escalation.", "exploit_chain": "", "evidence": "run.log (ref0 SIGFPE, control completes dot=14850 fb=880 ref=2 post=80); gdb_lines.txt (#0 amdgpu_pll_reduce_ratio ... at pll_harness.c:114, den_min=11); DF-5004/run.2.log (3/3 determinism); env.txt (no AMD GPU on guest)", "kernel_refs": [ "sys/dev/drm/amd/amdgpu/amdgpu_atombios.c:592", "sys/dev/drm/amd/amdgpu/amdgpu_atombios.c:610", "sys/dev/drm/amd/amdgpu/amdgpu_atombios.c:628", "sys/dev/drm/amdgpu/amdgpu_pll.c:63", "sys/dev/drm/amd/amdgpu/atombios_crtc.c:876" ], "poc_changes": "no seed; harness shared with DF-5004 (verbatim amdgpu_pll.c copies, ref0 case exercises this producer)", "attempts": 3, "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": 60, "guest_dirty": 0, "build_cmd": "cc -g -O0 -Wall -o pll_harness pll_harness.c", "run_cmd": "./run.sh (pll_harness control | ref0)", "code_hash": "14588c16c97b5b5b039608dfbd48bdf542ad9165976a8e44a2d0ffb336b6b883", "notes": "the rs400/r100 reference_freq==0 lead confirmed end-to-end at function level. Severity Low strictly because the producer is firmware-gated; the consumer-side hardening is DF-5004s fix.diff, this packs fix.diff fixes the producer (same fixup pattern the file already uses for neighbouring fields).", "recommended_fix": "amdgpu_atombios.c: if (ppll->reference_freq == 0) ppll->reference_freq = 2700; (and equivalents for spll/mpll) \u2014 mirrors the existing ==0 fixups in the same function", "fix_status": "fixed", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 1, "fix_verdict": "producer fix maps reference_freq 0 -> 2700, which is exactly the control input that completes with sane dividers (run.log); consumer guards (DF-5004 fix.diff) additionally complete the unfixed-producer case (DF-5004 fix_run.log ref0). Kernel-level rebuild validation not possible on this guest (no AMD GPU).", "fix_evidence": "run.log control case; DF-5004/fix_run.log ref0 case" } |