DF-4589 — radeon CR link-training loop has no overall iteration bound ======================================================================= Finding file: sys/dev/drm/radeon/atombios_dp.c (pass 2) Line span: 684-722 (clock-recovery loop), decisive: 707-714. What the bug is --------------- `radeon_dp_link_train_cr()` loops until clock recovery succeeds, the DPCD read fails, every lane reports DP_TRAIN_MAX_SWING_REACHED, or the sink requests the *same* voltage 5 consecutive times (`dp_info->tries`, reset to 0 on any change at atombios_dp.c:713-714). A spec-violating DP sink that never achieves CR, always requests voltage swing below level 3, and alternates its adjust-request voltage between two levels (0.4V/0.6V) defeats every terminator: the 5-try counter is reset on each alternation and the loop spins forever, sleeping `>= 100 us` (or up to ~508 ms with a crafted DPCD[0x0E] TRAINING_AUX_RD_INTERVAL) plus an AUX transaction per iteration (drm_dp_helper.c:121-134). The channel-equalization loop is bounded (`tries > 5` unconditional break at atombios_dp.c:762); only the CR loop is unbounded. Impact ------ `radeon_dp_link_train()` runs from the encoder DPMS-on/modeset path (atombios_encoders.c:1777) — i.e. either the HPD workqueue thread or the userspace thread that issued MODE_SETCRTC / a DPMS property change, holding mode_config.mutex. Outcome: an unkillable task in a non-interruptible kernel loop plus a permanently wedged display subsystem (all subsequent DRM ioctls on the card block). Precondition is a crafted DisplayPort sink (MCU dongle) — the same physical malicious-sink threat model already accepted for DF-1730 / DF-1778. No memory corruption. Reproduce (hardware required) ----------------------------- 1. Host with a radeon (AMD) GPU whose connector is driven via radeon_dp_aux_transfer_atom (pre-DCE5, or DCE5 without `radeon_auxch=1`). 2. Attach a DP dongle whose DPCD link-status replies follow trigger.c (never CR_DONE; alternate ADJUST_REQUEST voltage 0/1; DPCD[0x0E]=0). 3. Trigger a modeset on the connector (hotplug, or `xrandr --auto`). 4. EXPECTED (vulnerable): the issuing task hangs forever in radeon_dp_link_train_cr; dmesg shows no "clock recovery tried 5 times" / "clock recovery failed" messages; further DRM ioctls block. PATCHED: loop exits after the hard cap with "clock recovery failed". On the audit guest this is hardware-gated: no AMD GPU exists (Bochs 0x1234:0x1111 — run.log / env.txt), so the verdict is not_reproduced with the defect proven from source. Build / run on guest -------------------- ./run.sh # probes guest hardware; records absence in run.log Fix --- fix.diff adds an overall iteration cap to the CR loop.