Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: missing bounds check in amdgpu_set_pp_force_state()

There is no limit on high "idx" can go. It should be less than
ARRAY_SIZE(data.states) which is 16.

The "data" variable wasn't declared in that scope so I shifted the code
around a bit to make it work. Also I made "idx" unsigned.

Fixes: f3898ea12fc1 ('drm/amd/powerplay: add some sysfs interfaces for powerplay.')
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Dan Carpenter and committed by
Alex Deucher
041bf022 0ab15bde

+13 -15
+13 -15
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
··· 270 270 struct drm_device *ddev = dev_get_drvdata(dev); 271 271 struct amdgpu_device *adev = ddev->dev_private; 272 272 enum amd_pm_state_type state = 0; 273 - long idx; 273 + unsigned long idx; 274 274 int ret; 275 275 276 276 if (strlen(buf) == 1) 277 277 adev->pp_force_state_enabled = false; 278 - else { 279 - ret = kstrtol(buf, 0, &idx); 278 + else if (adev->pp_enabled) { 279 + struct pp_states_info data; 280 280 281 - if (ret) { 281 + ret = kstrtoul(buf, 0, &idx); 282 + if (ret || idx >= ARRAY_SIZE(data.states)) { 282 283 count = -EINVAL; 283 284 goto fail; 284 285 } 285 286 286 - if (adev->pp_enabled) { 287 - struct pp_states_info data; 288 - amdgpu_dpm_get_pp_num_states(adev, &data); 289 - state = data.states[idx]; 290 - /* only set user selected power states */ 291 - if (state != POWER_STATE_TYPE_INTERNAL_BOOT && 292 - state != POWER_STATE_TYPE_DEFAULT) { 293 - amdgpu_dpm_dispatch_task(adev, 294 - AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL); 295 - adev->pp_force_state_enabled = true; 296 - } 287 + amdgpu_dpm_get_pp_num_states(adev, &data); 288 + state = data.states[idx]; 289 + /* only set user selected power states */ 290 + if (state != POWER_STATE_TYPE_INTERNAL_BOOT && 291 + state != POWER_STATE_TYPE_DEFAULT) { 292 + amdgpu_dpm_dispatch_task(adev, 293 + AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL); 294 + adev->pp_force_state_enabled = true; 297 295 } 298 296 } 299 297 fail: