# DF-1496 — Unbounded `ucSclkEntryNum` overflows fixed 8-entry stack array (`ppatomctrl.c`)

## Verdict: REPRODUCED (source-level + harness) — latent amdgpu-powerplay bug, stack smash

## The bug

`sys/dev/drm/amd/powerplay/hwmgr/ppatomctrl.c`, function
`atomctrl_get_smc_sclk_range_table`, lines 1361-1386:

```c
ATOM_SMU_INFO_V2_1 *psmu_info =
    (ATOM_SMU_INFO_V2_1 *)smu_atom_get_data_table(...);   /* may return NULL */
...
for (i = 0; i < psmu_info->ucSclkEntryNum; i++) {          /* :1374 NO bound */
    table->entry[i].ucVco_setting    = psmu_info->asSclkFcwRangeEntry[i]....;  /* :1375 */
    table->entry[i].ucPostdiv        = ...;                                     /* :1376 */
    table->entry[i].usFcw_pcc        = le16_to_cpu(...);                        /* :1378 */
    ...
}
```

`ucSclkEntryNum` is a `UCHAR` (0..255) from the VBIOS `SMU_Info` table with
**no comparison** vs `MAX_SCLK_RANGE` (8). The source VBIOS array
`asSclkFcwRangeEntry[8]` (`atombios.h:5640`) and the dest
`table->entry[8]` (`ppatomctrl.h:232,244`, 8 entries * 8 bytes = 64 bytes)
are both fixed at 8. Callers `polaris10_smumgr.c:803` and `vegam_smumgr.c:673`
allocate a 64-byte **stack-local** `struct pp_atom_ctrl_sclk_range_table`. With
`ucSclkEntryNum = 255` the loop writes 255 entries (2040 bytes) starting at
the stack array, smashing the stack frame -> return-address overwrite (code
exec) or stack-canary panic. `psmu_info` is also deref'd without a NULL check.
POLARIS10/11/12/VEGAM.

## Harness proof

```
VBIOS psmu_info->ucSclkEntryNum  = 255 (u8, NO check vs MAX_SCLK_RANGE)
MAX_SCLK_RANGE                   = 8 (ppatomctrl.h:232)
dest stack table                 = 64 bytes (entry[8])
loop would write                 = 2040 bytes (255 entries)
OVERSHOOT past entry[8]          = 1976 bytes of stack smash
entry[7]  = {vco=0x17 postdiv=0x27}  (in-bounds, last legal)
bytes past entry[8] = 0x10 0x20 0x00 0x10 ... (was zero)
post_canary = 0x3000200010002010  (expected 0x2222222222222222)
RESULT: stack overflow CONFIRMED at ppatomctrl.c:1375
```

## Fix

`fix.diff` adds two `PP_ASSERT_WITH_CODE` guards before the loop:
1. NULL check on `psmu_info` (smu_atom_get_data_table can return NULL).
2. `ucSclkEntryNum <= MAX_SCLK_RANGE` bound check.

## Module build validation (Phase 8)

All 8 amdgpu fixes applied; `amdgpu.ko` built under `-Werror`:
`ppatomctrl.o` (14240 bytes) produced, 0 errors, `amdgpu.ko` linked.
