# 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`). Counts `UvdLevelCount/VceLevelCount/AcpLevelCount/SamuLevelCount` are `uint8_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;` then `for (count = 0; count < table->UvdLevelCount; count++) table->UvdLevel[count]...`
  - `ci_populate_smc_vce_level` `:2732-2735` (writes `VceLevel[count]`).
  - `ci_populate_smc_acp_level` `:2765-2768` (writes `AcpLevel[count]`; original already `(u8)`-casts but never clamps to 8).
  - `ci_populate_smc_samu_level` `:2797-2800` (writes `SamuLevel[count]`).
- **Count source:** each `*_clock_voltage_dependency_table.count` is parsed from the VBIOS by radeon's atom-bios PowerPlay parser (unbounded `u8`-class count), exactly mirroring amdgpu.
- **Effect:** crafted VBIOS with `count > 8` runs 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 of `ci_dpm.c` simply 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**.
