⬢ DragonFlyBSD Kernel Audit
DF-4545 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/amd/powerplay/hwmgr/vega20_processpptables.c
+++ b4545/sys/dev/drm/amd/powerplay/hwmgr/vega20_processpptables.c	2026-09-21 11:11:05.527390404 +0000
@@ -832,20 +832,38 @@
 			ATOM_VEGA20_ODSETTING_COUNT :
 			le32_to_cpu(powerplay_table->OverDrive8Table.ODSettingCount);
 
-		copy_overdrive_feature_capabilities_array(hwmgr,
+		result = copy_overdrive_feature_capabilities_array(hwmgr,
 				&pptable_information->od_feature_capabilities,
 				powerplay_table->OverDrive8Table.ODFeatureCapabilities,
 				od_feature_count);
-		phm_copy_overdrive_settings_limits_array(hwmgr,
+		PP_ASSERT_WITH_CODE(result == 0,
+				"Failed to allocate OD feature capabilities!",
+				return result);
+		result = phm_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,
+		PP_ASSERT_WITH_CODE(result == 0,
+				"Failed to allocate OD settings max array!",
+				return result);
+		result = phm_copy_overdrive_settings_limits_array(hwmgr,
 				&pptable_information->od_settings_min,
 				powerplay_table->OverDrive8Table.ODSettingsMin,
 				od_setting_count);
+		PP_ASSERT_WITH_CODE(result == 0,
+				"Failed to allocate OD settings min array!",
+				return result);
 	}
 
+	/* vega20_hwmgr.c dereferences these unconditionally during init
+	 * (vega20_od8_set_feature_capabilities) -- never report success
+	 * without them (DF-4545). */
+	PP_ASSERT_WITH_CODE(pptable_information->od_feature_capabilities != NULL &&
+			    pptable_information->od_settings_max != NULL &&
+			    pptable_information->od_settings_min != NULL,
+			"Unsupported OverDrive8 table revision!",
+			return -EINVAL);
+
 	pptable_information->us_small_power_limit1 = le16_to_cpu(powerplay_table->usSmallPowerLimit1);
 	pptable_information->us_small_power_limit2 = le16_to_cpu(powerplay_table->usSmallPowerLimit2);
 	pptable_information->us_boost_power_limit = le16_to_cpu(powerplay_table->usBoostPowerLimit);
@@ -867,14 +885,20 @@
 			 ATOM_VEGA20_PPCLOCK_COUNT) ?
 			ATOM_VEGA20_PPCLOCK_COUNT :
 			le32_to_cpu(powerplay_table->PowerSavingClockTable.PowerSavingClockCount);
-		phm_copy_clock_limits_array(hwmgr,
+		result = phm_copy_clock_limits_array(hwmgr,
 				&pptable_information->power_saving_clock_max,
 				powerplay_table->PowerSavingClockTable.PowerSavingClockMax,
 				power_saving_clock_count);
-		phm_copy_clock_limits_array(hwmgr,
+		PP_ASSERT_WITH_CODE(result == 0,
+				"Failed to allocate power saving clock max array!",
+				return result);
+		result = phm_copy_clock_limits_array(hwmgr,
 				&pptable_information->power_saving_clock_min,
 				powerplay_table->PowerSavingClockTable.PowerSavingClockMin,
 				power_saving_clock_count);
+		PP_ASSERT_WITH_CODE(result == 0,
+				"Failed to allocate power saving clock min array!",
+				return result);
 	}
 
 	pptable_information->smc_pptable = (PPTable_t *)kmalloc(sizeof(PPTable_t), M_DRM, GFP_KERNEL);