# DF-1271 — tonga VBIOS mm_dep_table->count drives heap overflow

## Verdict
**INCONCLUSIVE (hardware-gated latent bug, not triggerable on this guest).**
The overflow is **confirmed real by source tracing**; not reachable on the audit
QEMU guest because the sink lives in the loadable `amdgpu.ko` module and runs
only on AMD Tonga hardware driven by a (crafted/buggy) VBIOS PowerPlay table
(absent). fix.diff authored and **validated to apply + compile** (nativekernel
`rc=0`, `-Werror`).

## Mechanism (source trace)
Three sibling functions in `sys/dev/drm/amd/powerplay/smumgr/tonga_smumgr.c`:
- `tonga_populate_smc_uvd_level` (`:1307`): `table->UvdLevelCount = (uint8_t)mm_table->count;`
  then `for (count=0; count<UvdLevelCount; count++) table->UvdLevel[count] = ...;` (`:1323`)
- `tonga_populate_smc_vce_level` (`:1367`): `table->VceLevelCount = ...; VceLevel[count]=...` (`:1383`)
- `tonga_populate_smc_acp_level` (`:1413`): `table->AcpLevelCount = ...; AcpLevel[count]=...` (`:1428`)

Array bounds / caps:
- `SMU72_MAX_LEVELS_UVD = SMU72_MAX_LEVELS_VCE = SMU72_MAX_LEVELS_ACP = 8`
  (`smu72.h:113-115`).
- `SMU72_Discrete_DpmTable`: `UvdLevel[8]`, `VceLevel[8]`, `AcpLevel[8]`
  (`smu72_discrete.h:270-272`).

Count source:
- `mm_table->count` = the VBIOS PowerPlay `ucNumEntries` (a `u8`, 1–255),
  assigned in `processpptables.c:391` (`dep_table->count = (unsigned
  long)table->ucNumEntries;`) with only a `!= 0` validity check during parse.
  So `count` can be up to 255.

With `mm_table->count > 8`, the loop writes `UvdLevel/VceLevel/AcpLevel[8..]`,
overflowing the level arrays into the adjacent `SMU72_Discrete_DpmTable` fields
and, far enough, into the `tonga_smumgr` `power_tune_defaults` pointer
(subsequently dereferenced) → heap corruption / controlled-pointer deref. The
written values (frequencies, voltage indices) are partly VBIOS-derived.

## Reachability on the audit guest
- `tonga_smumgr.c` is **module-only**: in `amdgpu.ko`
  (`nm /boot/kernel/amdgpu.ko` ⇒ `tonga_populate_all_graphic_levels` etc.), NOT
  in the base kernel. `amdgpu.ko` is not loaded on the guest.
- The functions run during PowerPlay SMC table population on an AMD Tonga GPU,
  fed by the card's VBIOS. The guest has no AMD GPU (`vgapci0` is virtio-class).
  Not triggerable here.

## Exploit chain
None — not exercisable on this guest (module-only + no AMD Tonga HW). The
primitive is an OOB write of VBIOS-derived values past `UvdLevel/VceLevel/
AcpLevel[8]` in an SMU table; reachable only on Tonga hardware with a malformed
VBIOS (a malicious discrete-GPU VBIOS is a strong local-attacker primitive on
such systems).

## PoC changes
Authored `tonga_mm_dep_overflow.c` — documentation stub recording the
module-only / VBIOS-driven reachability finding.

## Fix validation
- `fix.diff` applies cleanly: `git apply --check -p1` ⇒ OK (3 hunks).
- Compiles: `make nativekernel` rebuilt `amdgpu.ko` ⇒ `NK_DONE rc=0`,
  `tonga_smumgr.c` built with `-Werror` (`fix_build.log`).
- Functional test: **not_testable** (no AMD Tonga HW).

## Recommended fix
Clamp each level count to its array cap with `min()`:
`table->UvdLevelCount = (uint8_t)min(mm_table->count, (uint32_t)SMU72_MAX_LEVELS_UVD);`
(and likewise VCE/ACP). See `fix.diff`.
