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);