# DF-3684 — verdict narrative

## Finding

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.

## Root cause (kernel references)

- `sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:4625`
- `sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:4632`
- `sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:4662`
- `sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c:4667`
- `sys/dev/drm/amd/include/dm_pp_interface.h:161`
- `sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c:296`
- `sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c:303`

## What was verified, and how

1. **Source-level certainty.** Full-file pass-2 audit of smu7_hwmgr.c (5147 lines) with
   the parse-side preconditions traced into processpptables.c / process_pptables_v1_0.c
   (VBIOS u8 counts unvalidated; offset==0 subtables parse-legal NULL) and the struct
   geometry verified in ppatomctrl.h / smu7_hwmgr.h / hardwaremanager.h /
   dm_pp_interface.h.
2. **Harness on the guest** (DragonFly 6.5-DEVELOPMENT x86_64, `cc` base toolchain):
   `pp_clocks_stack.c` reproduces the exact kernel code shape and/or arithmetic with 1:1 struct
   layouts. Output in `run.log`; `run.2.log` for the live-crash phase.
   Compiled with `-O0` — at `-O2` the compiler detects the array-index UB and
   misoptimizes the accounting loops (itself a hint of what the kernel code does).
3. **Hardware absence.** The guest is virtio-only: no AMD GPU on PCI, amdgpu not
   loaded. The in-kernel trigger requires an SMU7 ASIC (CI/Topaz/Tonga/Fiji/Polaris/
   Vegam) with a crafted VBIOS, VFIO passthrough of a malicious card, or a root
   sysfs pp_table write. Per pass-2 spawn instructions this is recorded as
   **inconclusive** (matching DF-3585/DF-3619/DF-3644 precedent for the same class),
   impact none *on this guest*.

## Fix validation

fix.diff authored post-verification against the read-only sys/ tree. Not built: a
kernel rebuild with drm cannot be exercised on a GPU-less guest, so fix validation is
`not_testable`; the diffs are minimal, local, and mechanically checkable against the
cited lines.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
