⬢ DragonFlyBSD Kernel Audit
DF-4288 / fix.diff
← back to finding ↓ download raw
--- 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) ;
 	}