drm/amdgpu: missing bounds check in amdgpu_set_pp_force_state()
Subsystems (3)
PATCH 1/1 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.
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +12 -14
@@ -275,25 +275,23 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,if (strlen (buf) ==1 ) adev->pp_force_state_enabled = false; -else { - ret =kstrtol (buf,0 , &idx); +else if (adev->pp_enabled) { +struct pp_states_info data; -if (ret) { + ret =kstrtol (buf,0 , &idx); +if (ret || idx >=ARRAY_SIZE (data.states)) { count = -EINVAL ; goto fail; } -if (adev->pp_enabled) { -struct pp_states_info data; -amdgpu_dpm_get_pp_num_states (adev, &data); - state = data.states[idx]; -/* only set user selected power states */ -if (state !=POWER_STATE_TYPE_INTERNAL_BOOT && - state !=POWER_STATE_TYPE_DEFAULT ) { -amdgpu_dpm_dispatch_task (adev, -AMD_PP_EVENT_ENABLE_USER_STATE , &state,NULL ); - adev->pp_force_state_enabled = true; - } +amdgpu_dpm_get_pp_num_states (adev, &data); + state = data.states[idx]; +/* only set user selected power states */ +if (state !=POWER_STATE_TYPE_INTERNAL_BOOT && + state !=POWER_STATE_TYPE_DEFAULT ) { +amdgpu_dpm_dispatch_task (adev, +AMD_PP_EVENT_ENABLE_USER_STATE , &state,NULL ); + adev->pp_force_state_enabled = true; } } fail:
Am 16.06.2016 08:41, schrieb Dan Carpenter:
Quoted 18 lines
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.
Fixes f3898ea12fc1 ('drm/amd/powerplay: add some sysfs interfaces for powerplay.')Signed-off-by Dan Carpenter <[email protected]>drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +0
-1@@ -275,25 +275,23 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,if (strlen (buf) ==1 ) adev->pp_force_state_enabled = false; -else {
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c static ssize_t amdgpu_set_pp_force_state(struct device *dev, · line 285
Quoted 10 lines
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +4
-2- ret =kstrtol (buf,0 , &idx); +else if (adev->pp_enabled) { +struct pp_states_info data; -if (ret) { + ret =kstrtol (buf,0 , &idx); +if (ret || idx >=ARRAY_SIZE (data.states)) { count = -EINVAL ; goto fail; }
i would also expect a check idx < 0, does it mean this can not happen ? otherwise maybe kstrtoul is a solution ?
re,
wh
Quoted 28 lines
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +8
-12-if (adev->pp_enabled) { -struct pp_states_info data; -amdgpu_dpm_get_pp_num_states (adev, &data); - state = data.states[idx]; -/* only set user selected power states */ -if (state !=POWER_STATE_TYPE_INTERNAL_BOOT && - state !=POWER_STATE_TYPE_DEFAULT ) { -amdgpu_dpm_dispatch_task (adev, -AMD_PP_EVENT_ENABLE_USER_STATE , &state,NULL ); - adev->pp_force_state_enabled = true; - } +amdgpu_dpm_get_pp_num_states (adev, &data); + state = data.states[idx]; +/* only set user selected power states */ +if (state !=POWER_STATE_TYPE_INTERNAL_BOOT && + state !=POWER_STATE_TYPE_DEFAULT ) { +amdgpu_dpm_dispatch_task (adev, +AMD_PP_EVENT_ENABLE_USER_STATE , &state,NULL ); + adev->pp_force_state_enabled = true; } } fail: --To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 25 lines · walter harms
Am 16.06.2016 08:41, schrieb Dan Carpenter:
Quoted 22 lines
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.
Fixes f3898ea12fc1 ('drm/amd/powerplay: add some sysfs interfaces for powerplay.')Signed-off-by Dan Carpenter <[email protected]>drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +2
-2@@ -275,25 +275,23 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,if (strlen (buf) =1 ) adev->pp_force_state_enabled = false; -else { - ret =kstrtol (buf,0 , &idx); +else if (adev->pp_enabled) { +struct pp_states_info data;
Quoted 10 lines
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c static ssize_t amdgpu_set_pp_force_state(struct device *dev, · line 285
Quoted 6 lines
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +2
-1-if (ret) { + ret =kstrtol (buf,0 , &idx); +if (ret || idx >=ARRAY_SIZE (data.states)) { count = -EINVAL ; goto fail; }i would also expect a check idx < 0, does it mean this can not happen ? otherwise maybe kstrtoul is a solution ?
The original code could underflow, but my code can't. ARRAY_SIZE() means the comparison is type promoted to size_t which is unsigned long.
regards,
dan carpenter
Christian König
maintainerAm 16.06.2016 um 09:54 schrieb Dan Carpenter:
Quoted 34 lines · walter harms
Quoted 24 lines
Am 16.06.2016 08:41, schrieb Dan Carpenter:
Quoted 22 lines
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.
Fixes f3898ea12fc1 ('drm/amd/powerplay: add some sysfs interfaces for powerplay.')Signed-off-by Dan Carpenter <[email protected]>drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +2
-2@@ -275,25 +275,23 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,if (strlen (buf) ==1 ) adev->pp_force_state_enabled = false; -else { - ret =kstrtol (buf,0 , &idx); +else if (adev->pp_enabled) { +struct pp_states_info data;Quoted 9 lines
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c static ssize_t amdgpu_set_pp_force_state(struct device *dev, · line 285
Quoted 6 lines
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +2
-1-if (ret) { + ret =kstrtol (buf,0 , &idx); +if (ret || idx >=ARRAY_SIZE (data.states)) { count = -EINVAL ; goto fail; }i would also expect a check idx < 0, does it mean this can not happen ? otherwise maybe kstrtoul is a solution ?
Quoted 2 lines
The original code could underflow, but my code can't.
ARRAY_SIZE()means the comparison is type promoted tosize_twhich is unsigned long.
That's probably true, but not very obvious (not that I understand much of the power related code anyway).
Using kstrtoul() in the first place would make it a bit less obscure and probably generate a nice error code when somebody really tries to use a negative index here.
Cheers,
Christian.
Quoted 3 lines
regards,
dan carpenter
Sure, I'll resend. Unsigned is a little cleaner. There is no new error code/message or change in behavior though either way.
regards,
dan carpenter
PATCH v2 1/1 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.
---
v2: make idx unsigned
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +13 -15
@@ -270,30 +270,28 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,struct drm_device *ddev =dev_get_drvdata (dev);struct amdgpu_device *adev = ddev->dev_private;enum amd_pm_state_type state =0 ; -long idx; +unsigned long idx;int ret;if (strlen (buf) =1 ) adev->pp_force_state_enabled = false; -else { - ret =kstrtol (buf,0 , &idx); +else if (adev->pp_enabled) { +struct pp_states_info data; -if (ret) { + ret =kstrtoul (buf,0 , &idx); +if (ret || idx >=ARRAY_SIZE (data.states)) { count = -EINVAL ; goto fail; } -if (adev->pp_enabled) { -struct pp_states_info data; -amdgpu_dpm_get_pp_num_states (adev, &data); - state = data.states[idx]; -/* only set user selected power states */ -if (state !=POWER_STATE_TYPE_INTERNAL_BOOT && - state !=POWER_STATE_TYPE_DEFAULT ) { -amdgpu_dpm_dispatch_task (adev, -AMD_PP_EVENT_ENABLE_USER_STATE , &state,NULL ); - adev->pp_force_state_enabled = true; - } +amdgpu_dpm_get_pp_num_states (adev, &data); + state = data.states[idx]; +/* only set user selected power states */ +if (state !=POWER_STATE_TYPE_INTERNAL_BOOT && + state !=POWER_STATE_TYPE_DEFAULT ) { +amdgpu_dpm_dispatch_task (adev, +AMD_PP_EVENT_ENABLE_USER_STATE , &state,NULL ); + adev->pp_force_state_enabled = true; } } fail:
Am 16.06.2016 um 10:30 schrieb Dan Carpenter:
Quoted 8 lines
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.')Signed-off-by Dan Carpenter <[email protected]>
Quoted 41 lines
---
v2: make idx unsigneddrivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +6
-15@@ -270,30 +270,28 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,struct drm_device *ddev =dev_get_drvdata (dev);struct amdgpu_device *adev = ddev->dev_private;enum amd_pm_state_type state =0 ; -long idx; +unsigned long idx;int ret;if (strlen (buf) =1 ) adev->pp_force_state_enabled = false; -else { - ret =kstrtol (buf,0 , &idx); +else if (adev->pp_enabled) { +struct pp_states_info data; -if (ret) { + ret =kstrtoul (buf,0 , &idx); +if (ret || idx >=ARRAY_SIZE (data.states)) { count = -EINVAL ; goto fail; } -if (adev->pp_enabled) { -struct pp_states_info data; -amdgpu_dpm_get_pp_num_states (adev, &data); - state = data.states[idx]; -/* only set user selected power states */ -if (state !=POWER_STATE_TYPE_INTERNAL_BOOT && - state !=POWER_STATE_TYPE_DEFAULT ) { -amdgpu_dpm_dispatch_task (adev, -AMD_PP_EVENT_ENABLE_USER_STATE , &state,NULL ); - adev->pp_force_state_enabled = true; - } +amdgpu_dpm_get_pp_num_states (adev, &data);
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c static ssize_t amdgpu_set_pp_force_state(struct device *dev, · line 297
Quoted 10 lines
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +7
-0+ state = data.states[idx]; +/* only set user selected power states */ +if (state !=POWER_STATE_TYPE_INTERNAL_BOOT && + state !=POWER_STATE_TYPE_DEFAULT ) { +amdgpu_dpm_dispatch_task (adev, +AMD_PP_EVENT_ENABLE_USER_STATE , &state,NULL ); + adev->pp_force_state_enabled = true; } } fail:
--
To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Alex Deucher
AppliedQuoted 8 lines · Christian König
Am 16.06.2016 um 10:30 schrieb Dan Carpenter:
Quoted 7 lines
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.
Quoted 7 lines
Quoted 3 lines
Fixes f3898ea12fc1 ('drm/amd/powerplay: add some sysfs interfaces forpowerplay.')
Signed-off-by Dan Carpenter <[email protected]>Acked-by Christian König <[email protected]>.
Applied. thanks!
Alex
Quoted 51 lines
Quoted 51 lines
---
v2: make idx unsigneddrivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +13
-13@@ -270,30 +270,28 @@ static ssize_t amdgpu_set_pp_force_state(structdevice *dev, struct drm_device *ddev = dev_get_drvdata(dev);struct amdgpu_device *adev = ddev->dev_private;enum amd_pm_state_type state =0 ; -long idx; +unsigned long idx;int ret;if (strlen (buf) ==1 ) adev->pp_force_state_enabled = false; -else { - ret =kstrtol (buf,0 , &idx); +else if (adev->pp_enabled) { +struct pp_states_info data; - if (ret) { + ret =kstrtoul (buf,0 , &idx); +if (ret || idx >=ARRAY_SIZE (data.states)) { count = -EINVAL ; goto fail; } - if (adev->pp_enabled) { -struct pp_states_info data; -amdgpu_dpm_get_pp_num_states (adev, &data); - state = data.states[idx]; -/* only set user selected power states */ -if (state !=POWER_STATE_TYPE_INTERNAL_BOOT && - state !=POWER_STATE_TYPE_DEFAULT ) { -amdgpu_dpm_dispatch_task (adev, - AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL); - adev->pp_force_state_enabled = true; - } +amdgpu_dpm_get_pp_num_states (adev, &data); + state = data.states[idx]; +/* only set user selected power states */ +if (state !=POWER_STATE_TYPE_INTERNAL_BOOT && + state !=POWER_STATE_TYPE_DEFAULT ) { +amdgpu_dpm_dispatch_task (adev, +AMD_PP_EVENT_ENABLE_USER_STATE , &state,NULL ); + adev->pp_force_state_enabled = true; }
Quoted 8 lines
Quoted 2 lines
}fail:
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
--
To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html