# DF-3939 — Kernel stack OOB write in ci_program_memory_timing_parameters (CI/SMU7 ARB timing table)

## Finding
`sys/dev/drm/amd/powerplay/smumgr/ci_smumgr.c:1648-1681`

```c
static int ci_program_memory_timing_parameters(struct pp_hwmgr *hwmgr)
{
	...
	SMU7_Discrete_MCArbDramTimingTable  arb_regs;          /* 576-byte STACK object */
	...
	for (i = 0; i < data->dpm_table.sclk_table.count; i++) {
		for (j = 0; j < data->dpm_table.mclk_table.count; j++) {
			result = ci_populate_memory_timing_parameters
				(hwmgr, ..., &arb_regs.entries[i][j]);
```

`arb_regs.entries` is `[SMU__NUM_SCLK_DPM_STATE=8][SMU__NUM_MCLK_DPM_LEVELS=6]`
(`sys/dev/drm/amd/powerplay/inc/smu7_discrete.h:233-236`, CI constants from
`sys/dev/drm/amd/powerplay/smumgr/ci_smumgr.h:26-27`). The loop bounds come
from the VBIOS-parsed DPM table counts (`dpm_table->sclk_table.count`,
`dpm_table->mclk_table.count`), which for MCLK can legitimately reach
`MAX_REGULAR_DPM_NUMBER = 8` (`sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.h:95`,
`smu7_hwmgr.h:100`) — nothing trims them to the SMC table's 6
(`smu7_setup_dpm_tables_v0`, `sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:704-710`,
copies the VBIOS `ucNumEntries`-sized dependency table
(`processpptables.c:391`) into `dpm_levels[8]` with no SMU7_MAX_LEVELS_MEMORY clamp).

## Trigger
Crafted VBIOS powerplay table on a Bonaire/Hawaii (AMDGPU_FAMILY_CI) GPU with
`vdd_dep_on_mclk` containing **>= 7 distinct MCLK entries** (and, to push the
write past the end of the whole stack object, **8 distinct SCLK entries** so
the outer loop reaches row i=7):

- mclk count 7-8 ⇒ `j ∈ {6,7}`:
  - rows i<7: writes alias into `entries[i+1][0..1]` — in-object but wrong
    cells (corrupt SMC timing data — logic corruption);
  - row i=7: `entries[7][6]` at byte offset 7*72+6*12 = **576 = exactly
    past the 576-byte object**, and `entries[7][7]` at +588..599 —
    **~24 bytes past the stack object**, values `McArbDramTiming` /
    `McArbDramTiming2` (u32 MMIO reads of MC_ARB_DRAM_TIMING{,2} computed by
    the VBIOS `atomctrl_set_engine_dram_timings_rv770` from the attacker's
    chosen engine/memory clocks) plus `McArbBurstTime` (u8).

Called at DPM init: `ci_init_smc_table` → `ci_program_memory_timing_parameters`
(`ci_smumgr.c:2002`), and on OD updates `ci_update_sclk_threshold` →
`ci_program_mem_timing_parameters` (`ci_smumgr.c:2239`).

## Why inconclusive on this guest
Requires an AMD Sea Islands GPU plus a modified VBIOS. The audit QEMU guest
has **no AMD PCI device at all** (env.txt: only Intel PIIX4, QEMU virtio-gpu,
virtio-net/blk — no vendor 0x1002), so the path cannot execute. The struct
math is source-certain: this is the CI twin of the verified tonga finding
DF-3908 (`tonga_smumgr.c:1492-1507`, entries[8][4] vs MCLK counts up to 8).

## Reproduce (on hardware)
Flash a CI board VBIOS whose ATOM powerplay `vdd_dep_on_mclk` table has 7-8
distinct entries (and sclk dep table with 8), boot with amdgpu dpm enabled;
`ci_program_memory_timing_parameters` scribbles past the 576-byte stack object
during `ci_init_smc_table` — expect corruption/panic on stack canary kernels,
silent adjacent-stack corruption otherwise.
