DragonFlyBSD Kernel Audit
DF-1307 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/drm/radeon/kv_dpm.c b/sys/dev/drm/radeon/kv_dpm.c
--- a/sys/dev/drm/radeon/kv_dpm.c
+++ b/sys/dev/drm/radeon/kv_dpm.c
@@ -2703,6 +2703,16 @@
 	for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) {
 		u32 sclk;
 		clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx;
+		/* DF-1307: VCE clk_idx is a VBIOS-controlled 6-bit value (0..63, from
+		 * state_entry->ucClockInfoIndex & 0x3f at r600_dpm.c:1128). It byte-indexes
+		 * clockInfo[] (UCHAR flex[1]); clamp it against ucNumEntries like the
+		 * main clock loop at the ucNumEntries check above, otherwise a crafted
+		 * VBIOS reads up to 63*255 = 16065 bytes past clockInfo[0] -> heap OOB. */
+		if (clock_array_index >= clock_info_array->ucNumEntries) {
+			rdev->pm.dpm.vce_states[i].sclk = 0;
+			rdev->pm.dpm.vce_states[i].mclk = 0;
+			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);