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 @@ -2666,6 +2666,15 @@ u8 *idx; power_state = (union pplib_power_state *)power_state_offset; non_clock_array_index = power_state->v2.nonClockInfoIndex; + /* DF-1306: nonClockInfoIndex is a VBIOS-controlled u8 (0..255) used to + * index nonClockInfo[] (flex[1]); clamp it against ucNumEntries like the + * clock path below does at the ucNumEntries check, otherwise a crafted + * VBIOS reads up to 255*sizeof(ATOM_PPLIB_NONCLOCK_INFO) past the array + * -> heap OOB read. */ + if (non_clock_array_index >= non_clock_info_array->ucNumEntries) { + kfree(rdev->pm.dpm.ps); + return -EINVAL; + } non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; if (!rdev->pm.power_state[i].clock_info)