Unbounded VBIOS dependency-table counts overflow fixed SMU7 level arrays (heap OOB write)
Summary
kv_init_graphics_levels (:2426), kv_populate_uvd/vce/samu/acp_table (:915/986/1049/1115): for(i=0;i<table->count;i++) write pi->graphics_level[i]/uvd_level[i]/etc[SMU7_MAX_LEVELS=8]. count from VBIOS atom ucNumEntries (amdgpu_dpm.c:302/617/650), u8 0-255, uncapped. Dead guard if(pi->high_voltage_t&&...) break: high_voltage_t kzalloc-zeroed, never assigned -> always false. Sibling of DF-1136/DF-1141/DF-1166 dpm_levels overflow. Crafted VBIOS count>8 -> heap OOB write past kv_power_info. Fix: cap i<SMU7_MAX_LEVELS_*.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1268 Β· 12 files| File | Type | Description | Size | |
|---|---|---|---|---|
| trigger.c | trigger-source | documentation stub; bug path is VBIOS-parse/GPU-init, not a syscall | 1.3 KB | view raw |
| fix.diff | suggested-fix | git-apply-able fix | 1.9 KB | view raw |
| build.sh | repro-script | build the stub | 470 B | view raw |
| run.sh | repro-script | run the stub | 244 B | view raw |
| build.log | build-log | trigger build output | 71 B | view raw |
| run.log | run-log | trigger run output (no effect; latent) | 65 B | view raw |
| VERDICT.md | verdict | full source-level trace + fix rationale | 3.1 KB | β raw |
| env.txt | environment | guest uname, modules, PCI (no GPU) | 1.7 KB | view raw |
| fix_build.log | build-log | compile-validation: kernel+module build with fix applied, rc=0, no errors | 26.4 KB | view raw |
| README.md | readme | human reproduce doc | 516 B | β 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-1268 PoC β kv_dpm unbounded VBIOS counts: heap OOB WRITE (LATENT)
Status: source-confirmed real (certain); NOT reproducible on audit guest (no AMD GPU).
Impact: heap OOB write past kv_power_info.*_level[] via crafted VBIOS count>8.
Driver: sys/dev/drm/amd/amdgpu/kv_dpm.c (amdgpu kv path, not in GENERIC, no HW).
The high_voltage_t guard is dead (never assigned).
Reproduce
./build.sh && ./run.sh # stub; bug path is VBIOS-parse at GPU dpm init
See VERDICT.md + fix.diff.
DF-1268 β kv_dpm unbounded VBIOS dependency-table counts: heap OOB WRITE (LATENT)
Verdict
NOT REPRODUCED on the audit guest (LATENT / HW-gated). The bug is
confirmed real by source-level trace (and marked confidence=certain in the
DB finding); it cannot fire here because there is no AMD APU/GPU, so the
dev/drm/amd/amdgpu/kv_dpm.c code path is dead at runtime.
Mechanism (confirmed in source)
- Five loops iterate
for (i = 0; i < table->count; i++)writing fixed-size destination arrays: kv_populate_uvd_table(kv_dpm.c:915) βpi->uvd_level[i](SMU7_MAX_LEVELS_UVD=8,kv_dpm.h:159)kv_populate_vce_table(kv_dpm.c:986) βpi->vce_level[i](SMU7_MAX_LEVELS_VCE=8,:160)kv_populate_samu_table(kv_dpm.c:1049) βpi->samu_level[i](SMU7_MAX_LEVELS_SAMU=8,:162)kv_populate_acp_table(kv_dpm.c:1115) βpi->acp_level[i](SMU7_MAX_LEVELS_ACP=8,:161)kv_init_graphics_levels(kv_dpm.c:2426and else-branch:2446) βpi->graphics_level[i](SMU__NUM_SCLK_DPM_STATE=8,:157)table->countis the VBIOS atomucNumEntriesβ au8, 0..255, uncapped at all these sites.- The apparent guard
if (pi->high_voltage_t && ...) break;is DEAD:piiskzalloc-zeroed (kv_dpm.callocateskv_power_infowithkzalloc) andhigh_voltage_tis never assigned anywhere inkv_dpm.c(grep 'high_voltage_t ='β no hits), so the condition is always false and the break never fires. - A crafted VBIOS with
count > 8therefore writes past the embedded arrays instruct kv_power_infoβ heap OOB write at dpm init. Sibling of DF-1136/DF-1141/DF-1166 (dpm_levels overflow).
Why it does not reproduce here
pciconf -lv shows no AMD display device; amdgpu.ko is present in
/boot/kernel/ but not loaded (nothing to probe). kv_dpm attaches only to
Kabini/Kaveri-class AMD APUs. Reaching the bug needs that hardware + a crafted
VBIOS. Valid hard blocker: path unreachable at runtime on this guest.
Exploit chain
N/A for this guest β the write primitive is HW-gated (latent). On real AMD
hardware with a crafted VBIOS it is a kernel-heap OOB write (more severe
than DF-1254's read): controllable-ish content (VBIOS table entries) written
past kv_power_info into adjacent slab objects. No chain developed here
because the path is dead on the audit guest; characterization would require
the matching GPU.
PoC changes
trigger.c is a documentation stub (bug path is VBIOS parse, not a syscall).
Fix (fix.diff)
Cap each loop at its SMU7_MAX_LEVELS_* constant so a VBIOS count > 8
cannot overflow:
for (i = 0; i < table->count && i < SMU7_MAX_LEVELS_<X>; i++)
applied to all six loops (uvd/vce/samu/acp + the two graphics-level branches).
Applies cleanly (patch -p1 rc=0). Matches the finding proposal ("cap i<SMU7_MAX_LEVELS_*").
Fix validation
not_testable β code path unreachable on audit guest; diff validated to apply
cleanly and is syntactically reviewed. Building the amdgpu stack is not
warranted for a non-reproducible latent OOB write.
Fix verification
not_testablecompile validated
kernel/module build rc=0
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. kv_dpm 5 loops uncapped vs [8] + dead high_voltage_t guard -> heap OOB WRITE. amdgpu not in GENERIC.
No comments yet.