DF-1307 / fix.diff
diff --git a/sys/dev/drm/radeon/kv_dpm.c b/sys/dev/drm/radeon/kv_dpm.c --- a/sys/dev/drm/radeon/kv_dpm.c +++ b/sys/dev/drm/radeon/kv_dpm.c @@ -2703,6 +2703,16 @@ for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) { u32 sclk; clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx; + /* DF-1307: VCE clk_idx is a VBIOS-controlled 6-bit value (0..63, from + * state_entry->ucClockInfoIndex & 0x3f at r600_dpm.c:1128). It byte-indexes + * clockInfo[] (UCHAR flex[1]); clamp it against ucNumEntries like the + * main clock loop at the ucNumEntries check above, otherwise a crafted + * VBIOS reads up to 63*255 = 16065 bytes past clockInfo[0] -> heap OOB. */ + if (clock_array_index >= clock_info_array->ucNumEntries) { + rdev->pm.dpm.vce_states[i].sclk = 0; + rdev->pm.dpm.vce_states[i].mclk = 0; + 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); |