--- a/sys/dev/drm/amd/powerplay/hwmgr/ppatomctrl.c +++ b/sys/dev/drm/amd/powerplay/hwmgr/ppatomctrl.c @@ -138,6 +138,7 @@ int atomctrl_initialize_mc_reg_table( ATOM_VRAM_INFO_HEADER_V2_1 *vram_info; ATOM_INIT_REG_BLOCK *reg_block; + uint16_t vram_info_size; int result = 0; u8 frev, crev; u16 size; vram_info = (ATOM_VRAM_INFO_HEADER_V2_1 *) smu_atom_get_data_table(hwmgr->adev, GetIndexIntoMasterTable(DATA, VRAM_Info), &size, &frev, &crev); - if (module_index >= vram_info->ucNumOfVRAMModule) { + if (vram_info == NULL) { + pr_err("Invalid VramInfo table."); + result = -1; + } else if (module_index >= vram_info->ucNumOfVRAMModule) { pr_err("Invalid VramInfo table."); result = -1; } else if (vram_info->sHeader.ucTableFormatRevision < 2) { pr_err("Invalid VramInfo table."); result = -1; } if (0 == result) { + vram_info_size = size; + if (le16_to_cpu(vram_info->usMemClkPatchTblOffset) >= vram_info_size) { + pr_err("Invalid VramInfo table."); + result = -1; + } else { reg_block = (ATOM_INIT_REG_BLOCK *) ((uint8_t *)vram_info + le16_to_cpu(vram_info->usMemClkPatchTblOffset)); result = atomctrl_set_mc_reg_address_table(reg_block, table); } } if (0 == result) { result = atomctrl_retrieve_ac_timing(module_index, reg_block, table); } return result; } @@ -45,10 +47,14 @@ static int atomctrl_retrieve_ac_timing( uint8_t num_ranges = 0; + uint16_t blk = le16_to_cpu(reg_block->usRegDataBlkSize); + + if (blk < sizeof(uint32_t)) /* zero stride = infinite loop */ + return -1; - while (*(uint32_t *)reg_data != END_OF_REG_DATA_BLOCK && + while ((uint32_t)((uint8_t *)reg_data - (uint8_t *)reg_block) < + le16_to_cpu(reg_block->usRegIndexTblSize) && + *(uint32_t *)reg_data != END_OF_REG_DATA_BLOCK && num_ranges < VBIOS_MAX_AC_TIMING_ENTRIES) { @@ -82,7 +88,7 @@ - reg_data = (ATOM_MEMORY_SETTING_DATA_BLOCK *) - ((uint8_t *)reg_data + le16_to_cpu(reg_block->usRegDataBlkSize)) ; + reg_data = (ATOM_MEMORY_SETTING_DATA_BLOCK *) + ((uint8_t *)reg_data + blk) ; }