DF-4652 / verdict.json
{ "finding_id": "DF-4652", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "amdgpu_atombios_dp_link_train_cr() (sys/dev/drm/amd/amdgpu/atombios_dp.c:605-644) has no overall iteration bound \u2014 it is the line-for-line twin of the radeon loop filed as DF-4589: all four exits are sink-controlled and the 5-try counter is reset to 0 on ANY voltage change (atombios_dp.c:634-635), so a crafted DP sink that alternates its adjust-request voltage between levels < 3 while never achieving clock recovery spins the loop forever (>= 100 us delay + DPCD read per iteration, drm_dp_helper.c:121-134). The caller chain (atombios_encoders.c:1441 -> amdgpu_atombios_encoder_dpms :1477 -> dce_v6/8/10/11 .dpms) runs in the DRM modeset path holding mode_config.mutex (drm_crtc.c:601/776), producing an unkillable task and a permanently wedged display subsystem. Not reproduced on the audit guest: no AMD GPU exists (Bochs 0x1234:0x1111, run.log/env.txt) and QEMU cannot emulate the crafted DP sink, so execution is hardware-gated; the loop analysis is exhaustive and the defect is certain from source (the CE loop by contrast IS bounded at atombios_dp.c:685/695). Realistic impact ceiling: local physical DoS via malicious DP sink (same threat model as DF-4589/DF-1778/DF-1730), no memory corruption.", "exploit_chain": "", "evidence": "VERDICT.md (exit-condition enumeration + caller-chain proof + twin diff); trigger.c (deterministic oscillating-sink state machine with iteration trace table); build.log (guest cc -Wall -Wextra -O2 compile clean); run.log/guest_probe.log/env.txt (no 0x1002 device on guest); fix.diff (50-iteration hard cap, git apply --check clean)", "kernel_refs": [ "sys/dev/drm/amd/amdgpu/atombios_dp.c:605", "sys/dev/drm/amd/amdgpu/atombios_dp.c:614", "sys/dev/drm/amd/amdgpu/atombios_dp.c:620", "sys/dev/drm/amd/amdgpu/atombios_dp.c:628", "sys/dev/drm/amd/amdgpu/atombios_dp.c:634", "sys/dev/drm/amd/amdgpu/atombios_dp.c:685", "sys/dev/drm/amd/amdgpu/atombios_encoders.c:1441", "sys/dev/drm/amd/amdgpu/atombios_encoders.c:1477", "sys/dev/drm/drm_dp_helper.c:121" ], "poc_changes": "No seed pack existed; trigger authored as a documented malicious-sink state machine mirroring DF-4589s pack (guest DragonFly cc compile-check passed, zero warnings; runtime needs amdgpu HW + crafted DP dongle).", "attempts": 1, "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": 21, "guest_dirty": 0, "build_cmd": "guest: cc -Wall -Wextra -O2 -o df4652_trigger df4652_trigger.c (see build.sh)", "run_cmd": "./run.sh", "code_hash": "ce58b8ad867259a2820072b251bc3f031a1280a8535ad7935ce75d2baef5a707", "notes": "Hardware-gated (amdgpu GPU + crafted DP sink required; guest has Bochs VGA only). Ceiling: unkillable modeset task holding mode_config.mutex -> all DRM ioctls on the card block; physical-access DoS, no privilege gain. Twin of DF-4589 (radeon, same loop shape); the >4-lane DPCD issue in this file is DF-1790 and is NOT re-reported.", "recommended_fix": "Add an overall iteration cap (50) to the CR loop so a spec-violating sink cannot wedge the modeset path (see fix.diff).", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "Fix not validated at runtime on guest: baseline cannot run (no amdgpu GPU). fix.diff applies cleanly (git apply --check) against atombios_dp.c:591-606 and bounds the loop unconditionally with a top-of-loop counter check; validated by inspection.", "fix_evidence": "findings/poc/DF-4652/fix.diff" } |