DragonFlyBSD Kernel Audit
DF-1306 / 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
@@ -2666,6 +2666,15 @@
 		u8 *idx;
 		power_state = (union pplib_power_state *)power_state_offset;
 		non_clock_array_index = power_state->v2.nonClockInfoIndex;
+		/* DF-1306: nonClockInfoIndex is a VBIOS-controlled u8 (0..255) used to
+		 * index nonClockInfo[] (flex[1]); clamp it against ucNumEntries like the
+		 * clock path below does at the ucNumEntries check, otherwise a crafted
+		 * VBIOS reads up to 255*sizeof(ATOM_PPLIB_NONCLOCK_INFO) past the array
+		 * -> heap OOB read. */
+		if (non_clock_array_index >= non_clock_info_array->ucNumEntries) {
+			kfree(rdev->pm.dpm.ps);
+			return -EINVAL;
+		}
 		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
 			&non_clock_info_array->nonClockInfo[non_clock_array_index];
 		if (!rdev->pm.power_state[i].clock_info)