Heap OOB write/read in kv_init_graphics_levels via unbounded VBIOS table->count
Summary
kv_init_graphics_levels at kv_dpm.c:2355: for(i=0;i<table->count;i++) where table=vddc_dependency_on_sclk, count from VBIOS ucNumEntries (u8 0-255, r600_dpm.c:841). Writes pi->graphics_level[i] (SMU__NUM_SCLK_DPM_STATE=8) and reads pi->at[i] (SUMO_MAX_HARDWARE_POWERLEVELS=5). count>5 -> at[] OOB read; count>8 -> graphics_level OOB write. Dead guard high_voltage_t (kzalloc 0). Sibling of DF-1268 (amdgpu kv_dpm). Crafted VBIOS. Fix: cap loop at min(count,SUMO_MAX_HARDWARE_POWERLEVELS).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1305 Β· 9 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | source-trace verdict: graphics_level/at OOB in radeon KV DPM init | 2.6 KB | β raw |
| README.md | readme | build/run/expected for this hardware-gated finding | 2.0 KB | β raw |
| trigger_path.c | trigger-source | documents the unreachable trigger path (no AMD GPU on guest) | 1.1 KB | view raw |
| fix.diff | suggested-fix | bound loops to SMU__NUM_SCLK_DPM_STATE / SUMO_MAX_HARDWARE_POWERLEVELS | 1.2 KB | view raw |
| build.sh | build-log | no userspace PoC; documents hardware-gated nature | 389 B | view raw |
| run.sh | run-log | reachability check (module/PCI/CPU) | 677 B | view raw |
| env.txt | environment | guest uname, cc, PCI, CPU, module presence | 2.2 KB | view 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-1298 / DF-1305 / DF-1314 / DF-1315 β hardware-gated driver findings
These four findings are kernel driver/virtualization bugs that are confirmed real by source trace but that cannot run on the QEMU audit guest because the required hardware is absent (see env.txt):
| Finding | Subsystem | Required hardware | Present on guest? |
|---|---|---|---|
| DF-1298 | amdgpu display VBIOS parser | AMD GPU (amdgpu) | NO (QEMU std-VGA only) |
| DF-1305 | radeon kv DPM | AMD radeon KV APU | NO |
| DF-1314 | radeon btc/evergreen DPM | AMD radeon NI GPU | NO |
| DF-1315 | nvmm AMD-SVM backend | AMD-SVM CPU | NO (guest CPU has no SVM bit) |
Build
./build.sh
There is no userspace PoC binary to compile for these β the vulnerable code
is inside a kernel driver/VMM module that only executes when the relevant device
attaches or the SVM backend runs. build.sh documents this.
Run
./run.sh
run.sh performs a reachability check (kldstat, pciconf, dmesg) and
reports that the path is unreachable on this guest. No panic/leak is expected
here because the trigger hardware is absent.
Expected (bug present, on a host WITH the hardware)
Each VERDICT.md describes the exact trigger and the kernel-level effect (heap overflow / OOB write / host DR7 persistence). On this guest those are latent.
Reproduce the FIX validation
The fix for each is fix.diff. To compile-validate a module fix:
1. scp fix.diff to the guest; cd /usr/src && patch -p1 < fix.diff
2. Build the relevant module, e.g.
cd /usr/src && make -j6 MODULES_OVERRIDE=... or a full
make -j6 nativekernel KERNCONF=X86_64_GENERIC (which also builds modules).
3. Confirm the module/object compiles with no errors (see fix_build.log).
Runtime fix-behaviour cannot be compared on this guest because the PoC paths
are hardware-gated; the fix is therefore classified not_testable with a
compile + source-trace validation.
DF-1305 β kv_init_graphics_levels heap OOB write/read (radeon DPM)
Verdict
NOT TESTABLE AT RUNTIME on this guest β confirmed real latent vulnerability in source.
Mechanism (confirmed by source trace)
sys/dev/drm/radeon/kv_dpm.c:2344 kv_init_graphics_levels() programs the
graphics DPM levels from rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.
- Line 2355:
for (i = 0; i < table->count; i++) { ... }wheretable->countisucNumEntriesparsed from VBIOS (au8, 0β255) β seer600_dpm.cradeon_atom_get_voltage_dependency_table. - Inside the loop, indices flow into two fixed arrays in
struct kv_power_info(kv_dpm.h:106): kv_set_divider_value/kv_set_vid/kv_set_atwritepi->graphics_level[i](SMU7_Fusion_GraphicsLevel graphics_level[SMU__NUM_SCLK_DPM_STATE],SMU__NUM_SCLK_DPM_STATE= 8 atkv_dpm.h:26/ci_dpm.h:28).kv_set_at(rdev, i, pi->at[i])(line 2366) readspi->at[i]whereatisu32 at[SUMO_MAX_HARDWARE_POWERLEVELS]andSUMO_MAX_HARDWARE_POWERLEVELS= 5 (sumo_dpm.h:28).- So
count > 5β OOB read ofat[i];count > 8β OOB write ofgraphics_level[i](corrupting whatever follows it inkv_power_info, e.g.acpi_level,uvd_level[], etc.). Thehigh_voltage_tearly-break guard iskzalloc'd to 0 and does not boundcount. - The
elsebranch (line 2375) has the same shape withsumo_sclk_voltage_mapping_table.entries[SUMO_MAX_HARDWARE_POWERLEVELS=5].
Why it does not reproduce on this guest
- radeon is not in
X86_64_GENERIC; only the loadableradeon.ko, not loaded. - No AMD GPU present (
vgapci0= QEMU std-VGA1234:1111). radeon never attaches; the DPM init path (called fromkv_dpm_enable/kv_dpm_hw_init) never runs. (Case d.)
Severity / realistic ceiling
On a host with an affected Kaveri/Kabini/Mullins APU (radeon KV family) whose VBIOS reports >8 SCLK/voltage entries, this is a kernel heap OOB write in the DPM bring-up path β heap corruption / panic; attacker-shaped entries (clock + voltage from VBIOS) partially control the written bytes. Firmware-data-driven, so realistic vector is a malformed/malicious VBIOS.
Fix (see fix.diff)
- Bound the if-branch loop to
i < SMU__NUM_SCLK_DPM_STATE(prevents thegraphics_levelOOB write). - Guard the
pi->at[i]read withi < SUMO_MAX_HARDWARE_POWERLEVELS. - Bound the else-branch loop to
SUMO_MAX_HARDWARE_POWERLEVELS(covers theentries[]array). Compile-validated (radeon module build). Runtime not exercisable on GPU-less guest.
Fix verification
not_testablecompile+boot validated -Werror
nativekernel rc=0, boots #1 clean
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. radeon kv_init_graphics_levels count unbounded vs graphics_level[8] and at[5]. radeon not in GENERIC.
No comments yet.