DragonFlyBSD Kernel Audit
DF-1254 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/drm/amd/powerplay/hwmgr/vega20_processpptables.c b/sys/dev/drm/amd/powerplay/hwmgr/vega20_processpptables.c
--- a/sys/dev/drm/amd/powerplay/hwmgr/vega20_processpptables.c
+++ b/sys/dev/drm/amd/powerplay/hwmgr/vega20_processpptables.c
@@ -681,6 +681,32 @@
 	return 0;
 }
 
+static int vega20_copy_overdrive_settings_limits_array(
+		struct pp_hwmgr *hwmgr,
+		uint32_t **pptable_info_array,
+		const uint32_t *pptable_array,
+		uint32_t od_setting_count)
+{
+	uint32_t array_size, i;
+	uint32_t *table;
+
+	/* Always allocate ATOM_VEGA20_ODSETTING_MAX_COUNT so the consumer's
+	 * hardcoded ATOM_VEGA20_ODSETTING_* indices stay in-bounds when the
+	 * VBIOS reports a smaller ODSettingCount (DF-1254).  Only od_setting_count
+	 * valid entries are copied; the remainder stays zeroed. */
+	array_size = sizeof(uint32_t) * ATOM_VEGA20_ODSETTING_MAX_COUNT;
+	table = kzalloc(array_size, GFP_KERNEL);
+	if (NULL == table)
+		return -ENOMEM;
+
+	for (i = 0; i < od_setting_count; i++)
+		table[i] = le32_to_cpu(pptable_array[i]);
+
+	*pptable_info_array = table;
+
+	return 0;
+}
+
 static int copy_overdrive_feature_capabilities_array(
 		struct pp_hwmgr *hwmgr,
 		uint8_t **pptable_info_array,
@@ -691,7 +717,11 @@
 	uint8_t *table;
 	bool od_supported = false;
 
-	array_size = sizeof(uint8_t) * od_feature_count;
+	/* Always allocate the full ATOM_VEGA20 maximum so the consumer's
+	 * hardcoded ATOM_VEGA20_ODFEATURE_* indices cannot run off the end
+	 * when the VBIOS reports fewer entries (DF-1254).  Only the valid
+	 * od_feature_count entries are copied; the rest stay zeroed. */
+	array_size = sizeof(uint8_t) * ATOM_VEGA20_ODFEATURE_MAX_COUNT;
 	table = kzalloc(array_size, GFP_KERNEL);
 	if (NULL == table)
 		return -ENOMEM;
@@ -836,11 +866,11 @@
 				&pptable_information->od_feature_capabilities,
 				powerplay_table->OverDrive8Table.ODFeatureCapabilities,
 				od_feature_count);
-		phm_copy_overdrive_settings_limits_array(hwmgr,
+		vega20_copy_overdrive_settings_limits_array(hwmgr,
 				&pptable_information->od_settings_max,
 				powerplay_table->OverDrive8Table.ODSettingsMax,
 				od_setting_count);
-		phm_copy_overdrive_settings_limits_array(hwmgr,
+		vega20_copy_overdrive_settings_limits_array(hwmgr,
 				&pptable_information->od_settings_min,
 				powerplay_table->OverDrive8Table.ODSettingsMin,
 				od_setting_count);