Heap OOB write in SMC UVD/VCE/ACP/SAMU level population from unbounded VBIOS count
Summary
ci_populate_smc_uvd_level(:2689)/_vce_level(:2732)/_acp_level(:2765)/_samu_level(:2797) copy VBIOS-supplied count (u8 up to 255) into fixed-size SMU7_Discrete_UvdLevel[8]/VceLevel[8]/AcpLevel[8]/SamuLevel[8] with no upper-bound check. Crafted VBIOS with numEntries>8 overflows arrays into adjacent SMU7_Discrete_DpmTable fields then ci_power_info pointer-bearing voltage tables -> write-what-where. Attacker: malicious PCIe/Thunderbolt GPU or reflashed VBIOS. Reached at DPM init. Same class as DF-1142 (amdgpu ci_dpm.c). Fix: clamp count to SMU7_MAX_LEVELS_*.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1149 Β· 9 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | clamp Uvd/Vce/Acp/Samu LevelCount to SMU7_MAX_LEVELS_* (git-apply-able) | 1.6 KB | view raw |
| build.sh | build-script | apply fix.diff + incremental compile of radeon ci_dpm.o | 462 B | view raw |
| run.sh | run-script | documents runtime-unreachable (no AMD GPU on guest) | 489 B | view raw |
| VERDICT.md | verdict | full source-trace + mechanism + fix rationale | 2.8 KB | β raw |
| env.txt | environment | guest uname, pci, driver build status | 2.0 KB | view raw |
| build.log | build-log | fix compile-validation output (patched ci_dpm.o, -Werror clean) | 1.5 KB | view raw |
| README.md | readme | human repro summary | 1.7 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-1149 β Heap OOB write in SMC UVD/VCE/ACP/SAMU level population (radeon ci_dpm.c)
Status: REPRODUCED at code level β latent at runtime on this guest (no AMD GPU). Severity (finding): High Β· CWE-787 Out-of-bounds Write
What the bug is
The radeon driver's ci_populate_smc_{uvd,vce,acp,samu}_level
(sys/dev/drm/radeon/ci_dpm.c:2689/2732/2765/2797) set each
table->*LevelCount directly from the VBIOS-derived
*_clock_voltage_dependency_table.count (unbounded u8) and loop writing
table->*Level[count] into fixed [SMU7_MAX_LEVELS_*=8] arrays
(sys/dev/drm/radeon/smu7_discrete.h:327-330, smu7.h:45-48). No clamp.
This is the same bug class as DF-1142; the radeon copy of ci_dpm.c was
simply not fixed alongside amdgpu.
Why it does not trigger here
No AMD GPU on the QEMU/KVM guest (0x1234:0x1111 std VGA); radeon is not
in X86_64_GENERIC (only in LINT64 as a test config). Latent on physical
Sea Islands HW with a malicious/reflashed VBIOS.
What was validated
- Source trace confirmed (see VERDICT.md
kernel_refs). - Baseline
radeon.ko(incl.ci_dpm.o) builds clean under-Werror. - Fix
fix.diffapplies (4 hunks) and patchedci_dpm.orebuilds clean under-Werror(ci_dpm.o: 55424 -> 55456 bytes).
Reproduce (compile-validation only)
scp this-folder/fix.diff root@guest:/root/df1149.diff cd /usr/src && patch -p1 --forward < /root/df1149.diff cd sys/dev/drm/radeon && rm -f ci_dpm.o && make ci_dpm.o # -Werror clean
Fix
fix.diff clamps each *LevelCount to its SMU7_MAX_LEVELS_* via
min_t(u8, ...) before the loop β same shape as the DF-1142 amdgpu fix;
matches the finding recommendation.
DF-1149 β Heap OOB write in SMC UVD/VCE/ACP/SAMU level population (radeon ci_dpm.c)
Verdict
REPRODUCED (code-level, latent at runtime). The radeon driver carries the
identical unbounded SMC-level-table OOB as amdgpu (DF-1142), confirmed by
source trace. Not triggerable at runtime on this guest (no AMD GPU; radeon
not in GENERIC) -> runtime not_testable. fix.diff validated to
apply + compile under -Werror.
Mechanism (trigger -> primitive -> effect)
- Sink arrays (in
SMU7_Discrete_DpmTable,sys/dev/drm/radeon/smu7_discrete.h:327-330):UvdLevel[SMU7_MAX_LEVELS_UVD],VceLevel[SMU7_MAX_LEVELS_VCE],AcpLevel[SMU7_MAX_LEVELS_ACP],SamuLevel[SMU7_MAX_LEVELS_SAMU], all= 8(sys/dev/drm/radeon/smu7.h:45-48). CountsUvdLevelCount/VceLevelCount/AcpLevelCount/SamuLevelCountareuint8_t(smu7_discrete.h:314-317). - Unbounded count + loop in
sys/dev/drm/radeon/ci_dpm.c: ci_populate_smc_uvd_level:2689-2692:table->UvdLevelCount = rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.count;thenfor (count = 0; count < table->UvdLevelCount; count++) table->UvdLevel[count]...ci_populate_smc_vce_level:2732-2735(writesVceLevel[count]).ci_populate_smc_acp_level:2765-2768(writesAcpLevel[count]; original already(u8)-casts but never clamps to 8).ci_populate_smc_samu_level:2797-2800(writesSamuLevel[count]).- Count source: each
*_clock_voltage_dependency_table.countis parsed from the VBIOS by radeon's atom-bios PowerPlay parser (unboundedu8-class count), exactly mirroring amdgpu. - Effect: crafted VBIOS with
count > 8runs each loop off its[8]Level array into the adjacent Level array and downstream SMU state, a write-what-where into radeon SMU control state. Same primitive class as DF-1142; the radeon copy ofci_dpm.csimply was not fixed when the bug class was identified.
Threat model / reachability
- Attacker: malicious/reflashed VBIOS or malicious PCIe/Thunderbolt AMD GPU (radeon CIK path). Reached at radeon DPM init.
- On this guest: NOT reachable (QEMU std VGA only; radeon not in GENERIC). Valid hard blocker: runtime-unreachable here, latent on physical AMD CIK HW.
Exploit chain
None developed β valid hard blocker (HW-dependent VBIOS-parsing write; no
userspace-guest path to supply a VBIOS). Demonstrated work is the source-level
confirmation + compiling fix. No exploit.c (not userspace-reachable).
PoC changes
No trigger PoC seeded. This folder adds fix.diff, build.sh, run.sh,
VERDICT.md, manifest.json, env.txt, build.log, README.md.
Recommended fix
Clamp each *LevelCount to its SMU7_MAX_LEVELS_* (=8) using min_t(u8, ...)
before the loop. Implemented in fix.diff for all four functions β identical
shape to the DF-1142 amdgpu fix. Matches the finding proposal.
Fix verification
not_testablecompile validated -Werror
module build rc=0
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed+compile. radeon ci_populate_smc_*_level same bug as DF-1142 (sibling driver). radeon not in GENERIC.
No comments yet.