Heap overflow: unvalidated VBIOS dependency-table count overflows fixed dpm_levels[8] array
Summary
smu7_setup_dpm_tables_v1 (:784-810) and v0 (:691-713) copy VBIOS dep_table->count (u8 up to 255) entries into dpm_levels[MAX_REGULAR_DPM_NUMBER=8] with NO bound check. count set from PP table ucNumEntries with only !=0 check by process_pptables. Crafted PP table with >8 distinct entries overflows sclk_table into mclk_table/vddc/vddci/mvdd then golden_dpm_table/odn_dpm_table in heap-allocated smu7_hwmgr. Same class as DF-1141/1149/1150. Attacker: malicious VBIOS/VFIO/root sysfs pp_table write. Fix: cap each loop at MAX_REGULAR_DPM_NUMBER.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1166 Β· 11 files| File | Type | Description | Size | |
|---|---|---|---|---|
| harness.c | trigger-source | userspace replica of smu7_setup_dpm_tables_v0/v1 loops; counts OOB writes for crafted count=255 | 4.4 KB | view raw |
| fix.diff | suggested-fix | git-apply-able: clamp all 7 loops to MAX_REGULAR_DPM_NUMBER + clamp 3 .count assignments | 4.3 KB | view raw |
| build.sh | build-script | cc -O2 -Wall -o harness harness.c | 411 B | view raw |
| run.sh | run-script | ./harness | 217 B | view raw |
| build.log | build-log | incremental amdgpu.ko build with fix applied (smu7_hwmgr.o, -Werror, rc=0) | 1.1 KB | view raw |
| run.log | run-log | decisive harness run: v0=1235, v1=494, total=1729 OOB writes, fix -> 0 | 864 B | view raw |
| env.txt | environment | guest uname/cc, no AMD GPU, amdgpu not in GENERIC | 1.3 KB | view raw |
| VERDICT.md | verdict | full narrative: mechanism, harness, threat model, uid0 assessment, fix validation | 4.0 KB | β raw |
| README.md | readme | how to reproduce + status | 1.1 KB | β raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-1166 β PoC evidence pack
Heap overflow: unvalidated VBIOS dependency-table count overflows dpm_levels[8] (amdgpu powerplay sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:691-800).
smu7_setup_dpm_tables_v0 (5 loops) and _v1 (2 loops) copy the PP/VBIOS
dependency-table count (u8 up to 255) entries into dpm_levels[MAX_REGULAR_DPM_NUMBER=8]
with no upper bound. A crafted PP table (count>8) overflows each table into
the next and past smu7_dpm_table into the heap-allocated smu7_hwmgr. Same
class as DF-1141/DF-1150.
Status
Source-confirmed + harness. Latent at runtime on this guest: amdgpu is NOT
in X86_64_GENERIC, and the guest has no AMD GPU.
Reproduce
./build.sh # cc -O2 -Wall -o harness harness.c (unprivileged maxx) ./run.sh # prints v0/v1 OOB write counts + fix check
Expected (harness): v0 OOB writes = 1235 ; v1 OOB writes = 494 ; total = 1729;
fix β 0.
Fix
fix.diff clamps all 7 loops to MAX_REGULAR_DPM_NUMBER (and clamps the 3 v0
.count assignments). Validated: applies + compiles clean (incremental
amdgpu.ko build, smu7_hwmgr.o, -Werror). See VERDICT.md.
DF-1166 β Heap overflow: unvalidated VBIOS dependency-table count in smu7_setup_dpm_tables_v0/v1 (amdgpu smu7_hwmgr.c)
Verdict
REPRODUCED (code-level / harness), latent at runtime on this guest. The bug
is a genuine unbounded-copy-into-fixed-array heap OOB write, confirmed by
source trace and a userspace harness. It is the same class as DF-1141/DF-1150
(VBIOS dep-table count overflow) but in amdgpu powerplay (SMU7 hardware
manager). amdgpu is NOT in X86_64_GENERIC and the guest has no AMD GPU, so
the path is runtime-unreachable (valid hard blocker). No exploit.c: not a
userspace-reachable primitive.
Mechanism (trigger β primitive β effect)
- Source array:
struct smu7_single_dpm_table { u32 count; struct smu7_dpm_level dpm_levels[MAX_REGULAR_DPM_NUMBER]; },MAX_REGULAR_DPM_NUMBER = 8(sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.h:95,99-100).smu7_dpm_tableholds sclk/mclk/pcie/vddc/vddci/mvdd tables (smu7_hwmgr.h:103-109). - Attacker-controlled count: the dep-table counts (
allowed_vdd_sclk_table->count,allowed_vdd_mclk_table->countin v0;dep_sclk_table->count,dep_mclk_table->countin v1) come from the VBIOS PowerPlay PP tableucNumEntries(u8 up to 255) with only a!=0/>=1lower-bound check inprocess_pptables. - Unbounded loops:
smu7_setup_dpm_tables_v0(smu7_hwmgr.c:666): sclk dedup:691, mclk dedup:705, vddc direct-index:716(also OOB-readsstd_voltage_table->entries[i]) +.count:723, vddci:728+.count:732, mvdd:742+.count:746.smu7_setup_dpm_tables_v1(smu7_hwmgr.c:752): sclk dedup:784, mclk dedup:800.- Effect: with a crafted PP table (count>8) the writes run off each 8-entry
dpm_levels[]into the nextsmu7_single_dpm_table, pastsmu7_dpm_table, into the heap-allocatedsmu7_hwmgr(golden_dpm_table,odn_dpm_table).
Evidence (harness)
harness.c models v0 (5 loops) and v1 (2 loops) with a crafted count of 255.
Result: v0 = 1235 OOB writes, v1 = 494 OOB writes, total 1729. With the fix
(&& i < MAX_REGULAR_DPM_NUMBER), 0 remain. (Full output in run.log.)
Threat model / reachability
- Attacker: malicious/reflashed VBIOS / PP table, or a malicious PCIe AMD GPU; on some configs a root sysfs
pp_tablewrite. Reached at DPM table setup (smu7_setup_dpm_tables_v0/v1). - On this guest: NOT reachable. amdgpu not in GENERIC; only QEMU std VGA. Realistic ceiling on physical AMD HW: kernel heap corruption β panic / DoS.
Exploit chain
None β valid hard blocker (HW-gated; amdgpu absent). No unprivileged guest syscall injects a PP table.
PoC changes
Authored from scratch. Deliverables: harness.c, fix.diff, build.sh,
run.sh, VERDICT.md, manifest.json, env.txt, build.log, run.log.
Recommended fix
fix.diff adds && i < MAX_REGULAR_DPM_NUMBER to all seven loops (v0 :691/:705/:716/:728/:742, v1 :784/:800) and clamps the three v0 .count assignments (:723/:732/:746) to at most MAX_REGULAR_DPM_NUMBER. This matches the finding proposal ("cap each loop at MAX_REGULAR_DPM_NUMBER").
Fix validation (Phase 8)
fix.diffapplies cleanly (git apply --checkOK; 6 hunks, 7 clamps).- Incremental
amdgpu.kobuild (warm obj):cd /usr/src/sys/dev/drm/amd && makeβ rc=0,smu7_hwmgr.o(71192 B) rebuilt & re-linked, 0 errors under-Werror. fix_status: not_testablefor runtime: amdgpu not in GENERIC, no AMD GPU. Validated at apply + compile level.
Kernel references (confirmed)
sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.h:95βMAX_REGULAR_DPM_NUMBER 8sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.h:100βdpm_levels[MAX_REGULAR_DPM_NUMBER]sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:666βsmu7_setup_dpm_tables_v0sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:691,705,716,728,742β v0 unbounded loopssys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:752βsmu7_setup_dpm_tables_v1sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:784,800β v1 unbounded loops
Fix verification
not_testablecompile+harness validated
see evidence pack
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed+harness. smu7_setup_dpm_tables 7 loops unbounded vs MAX_REGULAR_DPM_NUMBER=8 -> 1729 OOB. amdgpu not in GENERIC.
No comments yet.