DF-1127 / fix.diff
# DF-1127 fix: validates nonClockInfoIndex against ucNumEntries. # NOTE: the finding cited sys/dev/drm/amd/amdgpu/si_dpm.c which is # NOT compiled (absent from amdgpu Makefile SRCS). The live copy is # sys/dev/drm/radeon/si_dpm.c (compiled into radeon.ko). Both fixed. diff --git a/sys/dev/drm/amd/amdgpu/si_dpm.c b/sys/dev/drm/amd/amdgpu/si_dpm.c --- a/sys/dev/drm/amd/amdgpu/si_dpm.c +++ b/sys/dev/drm/amd/amdgpu/si_dpm.c @@ -7251,6 +7251,17 @@ u8 *idx; power_state = (union pplib_power_state *)power_state_offset; non_clock_array_index = power_state->v2.nonClockInfoIndex; + /* + * nonClockInfoIndex is read from the (untrusted) VBIOS. + * Validate against ucNumEntries exactly like the sibling + * clock loop below does for clockInfoIndex -- otherwise a + * malformed BIOS yields an OOB read from 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 si_ps), GFP_KERNEL); diff --git a/sys/dev/drm/radeon/si_dpm.c b/sys/dev/drm/radeon/si_dpm.c --- a/sys/dev/drm/radeon/si_dpm.c +++ b/sys/dev/drm/radeon/si_dpm.c @@ -6846,6 +6846,17 @@ u8 *idx; power_state = (union pplib_power_state *)power_state_offset; non_clock_array_index = power_state->v2.nonClockInfoIndex; + /* + * nonClockInfoIndex is read from the (untrusted) VBIOS. + * Validate against ucNumEntries exactly like the sibling + * clock loop below does for clockInfoIndex -- otherwise a + * malformed BIOS yields an OOB read from 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]; if (!rdev->pm.power_state[i].clock_info) |