MVDD stash-table wrong-index reads: entries[count] instead of entries[level] (uninitialized voltage to SMU) and cross-table mvdd_voltage_table.entries[vdd_dep_on_mclk index] (true OOB read)
Summary
Two sites: (1) populate_smc_mvdd_table reads entries[count] inside the loop over 'level' - in-bounds but reads an uninitialized slot and programs the SAME garbage MVDD into every SmioTable2 pattern. (2) populate_mvdd_value indexes mvdd_voltage_table.entries[i] with i from a DIFFERENT table (vdd_dep_on_mclk, count<=255) while capacity is 32 - for i>=32 a real heap OOB read inside struct smu7_hwmgr whose value is programmed as a voltage. Wrong-index + bound fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4073 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| verdict.json | β | 2.2 KB | view raw | |
| README.md | β | 251 B | β raw | |
| VERDICT.md | β | 1.7 KB | β raw | |
| fix.diff | β | 657 B | view raw | |
| manifest.json | β | 777 B | view raw |
DF-4073 β vegam MVDD stash-table wrong-index reads (pass 2, checklist class g)
Sites: vegam_smumgr.c:458-465 (populate_smc_mvdd_table) and :1093-1097 (populate_mvdd_value) Source-level finding. No executable PoC (hardware-gated); see VERDICT.md.
DF-4073 VERDICT β source-level certain, hardware-gated
Site 1 β wrong loop index (uninitialized slot read)
vegam_populate_smc_mvdd_table() (:458-466) reads
data->mvdd_voltage_table.entries[count].value
inside for (level = 0; level < count; level++) β the index must be level, not count.
In-bounds (entries[PP_ATOMCTRL_MAX_VOLTAGE_ENTRIES=32], count clamped to SMU_MAX_SMIO_LEVELS=4 β
ppatomctrl.h:45,211; smu75.h:53) but it reads an UNINITIALIZED slot and programs the SAME garbage
voltage into every SmioTable2.Pattern[level].Voltage β MVDD DPM misprogramming (hardware behavior).
Site 2 β cross-table index (true heap OOB read)
vegam_populate_mvdd_value() (:1093-1097) walks table_info->vdd_dep_on_mclk (count up to 255,
VBIOS u8) and on the first matching entry reads
data->mvdd_voltage_table.entries[i].value
β indexing the MVDD table by the MCLK-dependency position. mvdd_voltage_table.entries capacity is
32; for i >= 32 (reachable when dep entries with clk < mclk precede the match β a reordered/crafted
table) this reads up to ~2.5 KB past entries[] inside the struct smu7_hwmgr heap object, and the
value is programmed as a voltage (vegam_populate_smc_acpi_level:1177-1186).
Fixes
entries[count] -> entries[level] at :460; at :1095 validate/bound i against mvdd_voltage_table.count before use.
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testableHardware-gated finding (no AMD VegaM GPU / no LSI mps controller on the audit guest): fix authored at source level (fix.diff) but not build/boot-validated.
fix.diff in this pack; authored post-analysis, not hardware-validated.
Confirmed kernel references
Detail
Evidence (decisive lines)
vegam_smumgr.c:458-465 (entries[count] vs loop index 'level'); :1093-1097 (mvdd_voltage_table.entries[i] indexed by vdd_dep_on_mclk position); ppatomctrl.h:45,211 (entries[32])
PoC changes
n/a (source-level)
Verified recommended fix
entries[count] -> entries[level] at :460; at :1095 bound/validate i against mvdd_voltage_table.count (or index by mvdd table lookup).
Verdict
Two wrong-index MVDD stash reads (checklist class g). (1) vegam_populate_smc_mvdd_table():459-460 reads data->mvdd_voltage_table.entries[count] inside a loop over 'level' -- should be entries[level]. In-bounds (entries[32], count clamped to SMU_MAX_SMIO_LEVELS=4) but it reads an uninitialized slot and programs the SAME garbage MVDD voltage into every SmioTable2.Pattern[level]. (2) vegam_populate_mvdd_value():1095 indexes data->mvdd_voltage_table.entries[i] with i from a DIFFERENT table (vdd_dep_on_mclk, count up to 255) while the mvdd table's entries capacity is 32 => for i >= 32 a true heap OOB read inside struct smu7_hwmgr, value programmed as a voltage. Hardware-gated (crafted VBIOS).
No comments yet.