DF-1269 / fix.diff
diff --git a/sys/dev/drm/amd/amdgpu/kv_dpm.c b/sys/dev/drm/amd/amdgpu/kv_dpm.c --- a/sys/dev/drm/amd/amdgpu/kv_dpm.c +++ b/sys/dev/drm/amd/amdgpu/kv_dpm.c @@ -2743,6 +2743,13 @@ u8 *idx; power_state = (union pplib_power_state *)power_state_offset; non_clock_array_index = power_state->v2.nonClockInfoIndex; + /* Bounds-check the VBIOS index against ucNumEntries (DF-1269): + * an out-of-range nonClockInfoIndex would read past the + * non-clock-info array out of the BIOS mapping. */ + if (non_clock_array_index >= non_clock_info_array->ucNumEntries) { + power_state_offset += 2 + power_state->v2.ucNumDPMLevels; + continue; + } non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; ps = kzalloc(sizeof(struct kv_ps), GFP_KERNEL); @@ -2778,6 +2785,10 @@ for (i = 0; i < adev->pm.dpm.num_of_vce_states; i++) { u32 sclk; clock_array_index = adev->pm.dpm.vce_states[i].clk_idx; + /* Bounds-check clk_idx against ucNumEntries (DF-1269): an + * unchecked index reads past clockInfo[] in the BIOS mapping. */ + if (clock_array_index >= clock_info_array->ucNumEntries) + continue; clock_info = (union pplib_clock_info *) &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize]; sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow); |