# DF-3684 — Kernel stack overflow: smu7_get_sclks/smu7_get_mclks copy up to 255 VBIOS entries into amd_pp_clocks.clock[16]/latency[16] stack frame

**File:** `sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c` (pass 2, GLM 5.3 re-audit)
**Severity:** High | **CVSS:** CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H | **CWE:** CWE-787 Out-of-bounds Write (stack) | **Confidence:** certain (source)

## What this is

Source-certain kernel STACK buffer overflow; runtime-inconclusive on this guest (no AMD GPU). smu7_get_sclks (smu7_hwmgr.c:4625-4632) and smu7_get_mclks (:4662-4672) write clocks->clock[i]/latency[i] for i < dep_table->count with no bound against MAX_NUM_CLOCKS=16 (dm_pp_interface.h:161-167). The count is the raw VBIOS ucNumEntries (u8 <= 255, unvalidated by both processpptables.c:391 and process_pptables_v1_0.c:436/468/389). The sole caller chain places the struct on the stack: dm_pp_get_clock_levels_by_type (amdgpu_dm_pp_smu.c:296-316) declares 'struct amd_pp_clocks pp_clks = { 0 };' and passes it through amd_pp_dpm_get_clock_by_type -> phm_get_clock_by_type -> smu7_get_clock_by_type. With count=255 the loops write 239 u32s (956 bytes) past each 16-element array - 892 bytes beyond the 132-byte struct - into the caller's stack frame (validation_clks, saved registers, return path) with attacker-controlled u32 values (VBIOS clk * 10). Reached on display mode validation (DC init / mode set / hotplug). The V0 branch additionally NULL-derefs hwmgr->dyn_state.vddc_dependency_on_mclk when the VBIOS omits the table (offset 0 -> NULL is parse-legal). Harness confirmed full accounting plus a live stack smash killing the process (SIGSEGV), i.e. in-kernel: kernel-mode page fault or silent control-flow corruption.

## Reproduce (harness on the audit QEMU guest)

```
scp -F dfbsd-qemu/config pp_clocks_stack.c dfbsd-maxx:/tmp/DF-3684/
ssh -F dfbsd-qemu/config dfbsd-maxx 'cd /tmp/DF-3684 && cc -Wall -O0 -o t pp_clocks_stack.c && ./t'
```

Expected: the run prints the confirmed-primitive line (`RESULT: ... CONFIRMED ...`).
See `run.log` (and `run.2.log` where present) for the decisive captured output,
`build.log` for the guest toolchain transcript, `env.txt` for the guest environment
(virtio-only, **no AMD GPU** — `pciconf -l` shows only 0x1237/0x1111 QEMU devices;
`drm.ko`/`amdgpu.ko` exist in /boot/kernel but are not loaded and have no hardware
to bind), which is why the in-kernel trigger itself is inconclusive on this guest.

## Fix

`fix.diff` (authored against the read-only sys/ tree; never applied there).
