OD8 capability/settings arrays indexed by constants but allocated to VBIOS-supplied length -> heap OOB read
Summary
vega20_od8_set_feature_capabilities/initialize_default_settings at vega20_hwmgr.c:894-1222: read od_feature_capabilities[0..9], od_settings_min/max[0..15] using hardcoded ATOM_VEGA20 constants. Arrays allocated by copy_overdrive_feature_capabilities_array to min(VBIOS.ODFeatureCount,10)/min(ODSettingCount,16) elements. VBIOS with count<10 or <16 -> OOB read from heap. check_powerplay_tables validates neither count. OOB values surface via pp_od_clk_voltage sysfs -> heap info leak. Sibling of DF-1180/DF-1183 OD8 patterns. Fix: always allocate full ATOM_VEGA20 counts, copy only valid entries.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1254 Β· 12 files| File | Type | Description | Size | |
|---|---|---|---|---|
| trigger.c | trigger-source | documentation stub; bug path is VBIOS-parse/GPU-init, not a syscall | 1.6 KB | view raw |
| fix.diff | suggested-fix | git-apply-able fix | 2.3 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.8 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 | 21.5 KB | view raw |
| README.md | readme | human reproduce doc | 573 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-1254 PoC β vega20 OD8 OOB read (LATENT)
Status: source-confirmed real; NOT reproducible on audit guest (no AMD GPU).
Impact: heap OOB read (info leak) via crafted VBIOS powerplay table.
Driver: sys/dev/drm/amd/powerplay/hwmgr/vega20_hwmgr.c + vega20_processpptables.c (amdgpu, not in GENERIC, no HW).
Reproduce
./build.sh && ./run.sh # trigger is a stub; bug path is VBIOS-parse/GPU-init
The bug fires only at Vega20 GPU powerplay init with a crafted VBIOS. See
VERDICT.md for the full source-level trace and fix.diff for the fix.
DF-1254 β vega20 OD8 capability/settings arrays: heap OOB read (LATENT)
Verdict
NOT REPRODUCED on the audit guest (LATENT / HW-gated). The bug is
confirmed real by source-level trace; it cannot fire on this guest
because there is no AMD GPU, so the dev/drm/amd powerplay/VBIOS-parse
path is dead code at runtime.
Mechanism (confirmed in source)
vega20_processpptables.c:824-846computesod_feature_count = min(VBIOS.ODFeatureCount, ATOM_VEGA20_ODFEATURE_COUNT)(10) andod_setting_count = min(VBIOS.ODSettingCount, ATOM_VEGA20_ODSETTING_COUNT)(14).copy_overdrive_feature_capabilities_array(vega20_processpptables.c:694) allocates exactlyod_feature_countbytes (kzalloc(count)), andphm_copy_overdrive_settings_limits_array(smu_helper.c:73) allocates exactlyod_setting_countu32s. So a VBIOS reportingODFeatureCount<10orODSettingCount<14yields an undersized destination buffer.- The consumer
vega20_od8_set_feature_capabilities(vega20_hwmgr.c:906-975) indexesod_feature_capabilities[ATOM_VEGA20_ODFEATURE_*]with the hardcoded constants 0..9, andvega20_od8_initialize_default_settings(vega20_hwmgr.c:1216-1221) indexesod_settings_min/max[i]fori in 0..OD8_SETTING_COUNT. These constant indices exceed the undersized allocation β heap OOB read (kmalloc-16/32bucket). check_powerplay_tables(vega20_processpptables.c:636) validates neither count. OOB values surface viapp_od_clk_voltagesysfs β heap info leak.- VBIOS source arrays
ODFeatureCapabilities[32],ODSettingsMax[32],ODSettingsMin[32](vega20_pptable.h:80-83) are declared 32-wide, so the copy itself never over-reads; only the destination is too small.
Why it does not reproduce here
pciconf -lv shows no display/VGA device; the guest has display none.
amdgpu.ko/drm.ko ship in /boot/kernel/ but are not loaded (no AMD GPU to
probe), and even loaded they would not attach. The vulnerable code runs only
during GPU powerplay init while parsing a real (or crafted) VBIOS. Reaching it
needs a Vega20-class AMD GPU + a crafted powerplay table β neither available.
This is a valid hard blocker: the code path is unreachable at runtime on
this guest and no userspace syscall exercises it.
Exploit chain
N/A β read-only OOB (info leak), and HW-gated (latent). No escalation chain is developable on this guest. Realistic threat: a malicious/crafted VBIOS on real AMD hardware (reflashed card or hostile PCIe device) leaking heap bytes.
PoC changes
trigger.c is a documentation stub (the bug path is not a syscall); the real
deliverables are this trace and fix.diff.
Fix (fix.diff)
Always allocate the full ATOM_VEGA20 maximum so the consumer's hardcoded
indices cannot run off the end; copy only the VBIOS-declared valid entries
(the rest stay zeroed from kzalloc). Concretely:
- copy_overdrive_feature_capabilities_array: allocate
ATOM_VEGA20_ODFEATURE_MAX_COUNT (32) instead of od_feature_count.
- new vega20_copy_overdrive_settings_limits_array (vega20-local) allocates
ATOM_VEGA20_ODSETTING_MAX_COUNT (32) and copies od_setting_count entries;
the two vega20 call sites use it instead of the shared
phm_copy_overdrive_settings_limits_array (which vega12 still uses with its
own full constant count, unaffected). Applies cleanly (patch -p1 rc=0).
Supersedes the finding markdown proposal (which had no markdown; this is the
authoritative verified fix).
Fix validation
not_testable β the code path is not reachable on the audit guest, so no PoC
runs before/after. Validated: diff applies cleanly to the read-only sys/ tree
and is syntactically reviewed; building the amdgpu/powerplay stack is not
warranted for a non-reproducible latent OOB read.
Fix verification
not_testablecompile validated
kernel/module build rc=0
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. Vega20 OD8 arrays kzalloc(count) vs hardcoded indices 0..9/0..13 -> OOB read. amdgpu not in GENERIC.
No comments yet.