vddInd and vddcInd fields from VBIOS-parsed tables are used to index into
voltage lookup tables without a bounds check. Return -EINVAL when any
index is out of range.

Fixes: c82baa281843 ("drm/amd/powerplay: add Tonga dpm support (v3)")

Signed-off-by: Asad Kamal <[email protected]>
Reviewed-by: Lijo Lazar <[email protected]>
---
 .../drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c   | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c 
b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
index aac6a0fa5d7b..be824e3d276b 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
@@ -2216,12 +2216,24 @@ static int 
smu7_patch_voltage_dependency_tables_with_lookup_table(
        if (data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2) {
                for (entry_id = 0; entry_id < sclk_table->count; ++entry_id) {
                        voltage_id = sclk_table->entries[entry_id].vddInd;
+                       if (voltage_id >= 
table_info->vddgfx_lookup_table->count) {
+                               pr_err("amdgpu: sclk[%u] vddgfx index %u out of 
bounds (%u)\n",
+                                      entry_id, voltage_id,
+                                      table_info->vddgfx_lookup_table->count);
+                               return -EINVAL;
+                       }
                        sclk_table->entries[entry_id].vddgfx =
                                
table_info->vddgfx_lookup_table->entries[voltage_id].us_vdd;
                }
        } else {
                for (entry_id = 0; entry_id < sclk_table->count; ++entry_id) {
                        voltage_id = sclk_table->entries[entry_id].vddInd;
+                       if (voltage_id >= table_info->vddc_lookup_table->count) 
{
+                               pr_err("amdgpu: sclk[%u] vddc index %u out of 
bounds (%u)\n",
+                                      entry_id, voltage_id,
+                                      table_info->vddc_lookup_table->count);
+                               return -EINVAL;
+                       }
                        sclk_table->entries[entry_id].vddc =
                                
table_info->vddc_lookup_table->entries[voltage_id].us_vdd;
                }
@@ -2229,12 +2241,24 @@ static int 
smu7_patch_voltage_dependency_tables_with_lookup_table(
 
        for (entry_id = 0; entry_id < mclk_table->count; ++entry_id) {
                voltage_id = mclk_table->entries[entry_id].vddInd;
+               if (voltage_id >= table_info->vddc_lookup_table->count) {
+                       pr_err("amdgpu: mclk[%u] vddc index %u out of bounds 
(%u)\n",
+                              entry_id, voltage_id,
+                              table_info->vddc_lookup_table->count);
+                       return -EINVAL;
+               }
                mclk_table->entries[entry_id].vddc =
                        
table_info->vddc_lookup_table->entries[voltage_id].us_vdd;
        }
 
        for (entry_id = 0; entry_id < mm_table->count; ++entry_id) {
                voltage_id = mm_table->entries[entry_id].vddcInd;
+               if (voltage_id >= table_info->vddc_lookup_table->count) {
+                       pr_err("amdgpu: mm[%u] vddc index %u out of bounds 
(%u)\n",
+                              entry_id, voltage_id,
+                              table_info->vddc_lookup_table->count);
+                       return -EINVAL;
+               }
                mm_table->entries[entry_id].vddc =
                        
table_info->vddc_lookup_table->entries[voltage_id].us_vdd;
        }
-- 
2.46.0

Reply via email to