DragonFlyBSD Kernel Audit
DF-1574 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c b/sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c
--- a/sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c
+++ b/sys/dev/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c
@@ -173,9 +173,15 @@
 	if (NULL == table)
 		return -ENOMEM;
 
-	table->count = vddc_lookup_pp_tables->ucNumEntries;
+	/* ucNumEntries comes from VBIOS (UCHAR, 0..255) but the buffer was
+	 * sized for max_levels entries.  Clamp the count and loop bound to
+	 * max_levels to prevent an out-of-bounds write past the slab object. */
+	if (vddc_lookup_pp_tables->ucNumEntries > max_levels)
+		table->count = max_levels;
+	else
+		table->count = vddc_lookup_pp_tables->ucNumEntries;
 
-	for (i = 0; i < vddc_lookup_pp_tables->ucNumEntries; i++) {
+	for (i = 0; i < table->count; i++) {
 		record = GET_FLEXIBLE_ARRAY_MEMBER_ADDR(
 					phm_ppt_v1_voltage_lookup_record,
 					entries, table, i);