DF-4144 / fix.diff
--- a/dev/drm/radeon/trinity_dpm.c +++ b/dev/drm/radeon/trinity_dpm.c @@ -1771,14 +1771,39 @@ for (i = 0; i < state_array->ucNumEntries; i++) { u8 *idx; power_state = (union pplib_power_state *)power_state_offset; + if (i >= rdev->pm.num_power_states) { + DRM_ERROR("state count exceeds power_state table\n"); + for (k = i - 1; k >= 0; k--) + kfree(rdev->pm.dpm.ps[k].ps_priv); + kfree(rdev->pm.dpm.ps); + rdev->pm.dpm.ps = NULL; + rdev->pm.dpm.boot_ps = NULL; + rdev->pm.dpm.uvd_ps = NULL; + return -EINVAL; + } non_clock_array_index = power_state->v2.nonClockInfoIndex; 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) { + DRM_ERROR("invalid power state %d\n", i); + for (k = i - 1; k >= 0; k--) + kfree(rdev->pm.dpm.ps[k].ps_priv); + kfree(rdev->pm.dpm.ps); + rdev->pm.dpm.ps = NULL; + rdev->pm.dpm.boot_ps = NULL; + rdev->pm.dpm.uvd_ps = NULL; + return -EINVAL; + } if (!rdev->pm.power_state[i].clock_info) return -EINVAL; ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); if (ps == NULL) { + for (k = i - 1; k >= 0; k--) + kfree(rdev->pm.dpm.ps[k].ps_priv); kfree(rdev->pm.dpm.ps); + rdev->pm.dpm.ps = NULL; + rdev->pm.dpm.boot_ps = NULL; + rdev->pm.dpm.uvd_ps = NULL; return -ENOMEM; } rdev->pm.dpm.ps[i].ps_priv = ps; @@ -2087,7 +2112,9 @@ kfree(rdev->pm.dpm.ps[i].ps_priv); } kfree(rdev->pm.dpm.ps); + rdev->pm.dpm.ps = NULL; kfree(rdev->pm.dpm.priv); + rdev->pm.dpm.priv = NULL; r600_free_extended_power_table(rdev); } |