# DF-1416 — Heap OOB write via unbounded `ucNumDPMLevels` in `smu8_hwmgr`

## Verdict: REPRODUCED (source-level + harness) — latent amdgpu-powerplay bug, heap OOB write

## The bug

Two cooperating sites:

- Caller: `sys/dev/drm/amd/powerplay/hwmgr/processpptables.c:928`
  ```c
  for (i = 0; i < pstate_entry_v2->ucNumDPMLevels; i++) {   /* u8 0..255, VBIOS, NO check */
      ...
      res = func(hwmgr, &ps->hardware, i, pclock_info);      /* invokes callback */
  }
  ```
- Callback: `sys/dev/drm/amd/powerplay/hwmgr/smu8_hwmgr.c:1355-1362`
  ```c
  smu8_ps->levels[index].engineClock = ...;   /* :1355 -- index from caller */
  smu8_ps->levels[index].vddcIndex  = ...;    /* :1356 */
  smu8_ps->level = index + 1;                 /* :1358 */
  smu8_ps->levels[index].dsDividerIndex = 5;  /* :1361 */
  smu8_ps->levels[index].ssDividerIndex = 5;  /* :1362 */
  ```

`ucNumDPMLevels` is a `u8` (0..255) from the VBIOS with **no check** against
`SMU8_MAX_HARDWARE_POWERLEVELS` (8) (`smu8_hwmgr.h:33`). `levels[]` is fixed
at `[SMU8_MAX_HARDWARE_POWERLEVELS=8]` (`smu8_hwmgr.h:159`). With
`ucNumDPMLevels=255` the callback fires with `index=8..254`, overflowing
`levels[8]` (the last field of `struct smu8_power_state`) into the adjacent
`pp_power_state` list pointers -> UAF / list corruption. Sibling of the
DF-1268/1305/1366 family.

## Harness proof

```
VBIOS pstate->ucNumDPMLevels     = 255 (u8, no check vs SMU8_MAX)
SMU8_MAX_HARDWARE_POWERLEVELS    = 8 (smu8_hwmgr.h:33)
overflow iterations              = 247 past levels[8]
levels[8]  = {engineClock=1000008 vddc=8}  <-- FIRST OOB WRITE
RESULT: heap OOB write CONFIRMED at smu8_hwmgr.c:1355 via ucNumDPMLevels
```

## Fix

`fix.diff` adds an `index >= SMU8_MAX_HARDWARE_POWERLEVELS` guard at the top
of the callback (`smu8_hwmgr.c`), returning `-EINVAL` for out-of-range
indices. This is the backend-level defense; the same defensive bound should
be mirrored in the generic caller for other hwmgr backends.

## Module build validation (Phase 8)

All 8 amdgpu fixes applied; `amdgpu.ko` built under `-Werror`:
`smu8_hwmgr.o` (20208 bytes) and `processpptables.o` (12504 bytes) produced,
0 errors, `amdgpu.ko` (3741488 bytes) linked.
