DragonFlyBSD Kernel Audit
DF-1269 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/drm/amd/amdgpu/kv_dpm.c b/sys/dev/drm/amd/amdgpu/kv_dpm.c
--- a/sys/dev/drm/amd/amdgpu/kv_dpm.c
+++ b/sys/dev/drm/amd/amdgpu/kv_dpm.c
@@ -2743,6 +2743,13 @@
 		u8 *idx;
 		power_state = (union pplib_power_state *)power_state_offset;
 		non_clock_array_index = power_state->v2.nonClockInfoIndex;
+		/* Bounds-check the VBIOS index against ucNumEntries (DF-1269):
+		 * an out-of-range nonClockInfoIndex would read past the
+		 * non-clock-info array out of the BIOS mapping. */
+		if (non_clock_array_index >= non_clock_info_array->ucNumEntries) {
+			power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
+			continue;
+		}
 		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
 			&non_clock_info_array->nonClockInfo[non_clock_array_index];
 		ps = kzalloc(sizeof(struct kv_ps), GFP_KERNEL);
@@ -2778,6 +2785,10 @@
 	for (i = 0; i < adev->pm.dpm.num_of_vce_states; i++) {
 		u32 sclk;
 		clock_array_index = adev->pm.dpm.vce_states[i].clk_idx;
+		/* Bounds-check clk_idx against ucNumEntries (DF-1269): an
+		 * unchecked index reads past clockInfo[] in the BIOS mapping. */
+		if (clock_array_index >= clock_info_array->ucNumEntries)
+			continue;
 		clock_info = (union pplib_clock_info *)
 			&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
 		sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);