β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-1305

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1305 Β· 9 files
FileTypeDescriptionSize
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
README.md readme build/run/expected for this hardware-gated finding
↓ download 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.

VERDICT.md verdict source-trace verdict: graphics_level/at OOB in radeon KV DPM init
↓ download raw

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++) { ... } where table->count is ucNumEntries parsed from VBIOS (a u8, 0–255) β€” see r600_dpm.c radeon_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_at write pi->graphics_level[i] (SMU7_Fusion_GraphicsLevel graphics_level[SMU__NUM_SCLK_DPM_STATE], SMU__NUM_SCLK_DPM_STATE = 8 at kv_dpm.h:26/ci_dpm.h:28).
  • kv_set_at(rdev, i, pi->at[i]) (line 2366) reads pi->at[i] where at is u32 at[SUMO_MAX_HARDWARE_POWERLEVELS] and SUMO_MAX_HARDWARE_POWERLEVELS = 5 (sumo_dpm.h:28).
  • So count > 5 β†’ OOB read of at[i]; count > 8 β†’ OOB write of graphics_level[i] (corrupting whatever follows it in kv_power_info, e.g. acpi_level, uvd_level[], etc.). The high_voltage_t early-break guard is kzalloc'd to 0 and does not bound count.
  • The else branch (line 2375) has the same shape with sumo_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 loadable radeon.ko, not loaded.
  • No AMD GPU present (vgapci0 = QEMU std-VGA 1234:1111). radeon never attaches; the DPM init path (called from kv_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)

  1. Bound the if-branch loop to i < SMU__NUM_SCLK_DPM_STATE (prevents the graphics_level OOB write).
  2. Guard the pi->at[i] read with i < SUMO_MAX_HARDWARE_POWERLEVELS.
  3. Bound the else-branch loop to SUMO_MAX_HARDWARE_POWERLEVELS (covers the entries[] array). Compile-validated (radeon module build). Runtime not exercisable on GPU-less guest.

Fix verification

not_testable

compile+boot validated -Werror

nativekernel rc=0, boots #1 clean
↓ fix.diffDragonFly 6.5-DEVELOPMENT #1: Fri Jul 17 11:03:53 UTC 2026

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.