# DF-1560 — amdgpu pp_dpm_set_pp_table sysfs heap overflow

## Verdict

**REPRODUCED (code-confirmed via harness).** Source-trace confirms the bug
at `sys/dev/drm/amd/powerplay/amd_powerplay.c:685-693`. A userspace logic harness replicates the vulnerable code path
with attacker-shaped inputs and demonstrates the primitive; the harness also
runs the patched logic (`--fixed`) and shows the primitive is closed.

Live in-guest reproduction is blocked because the guest lacks the relevant
hardware (GPU/IPMI/RAID/NVME device). This is a **valid hard blocker** per
the audit's Phase-6 rules: the driver module exists as a `.ko` and would
attach to real hardware, but with no device present the buggy code path is
unreachable from userspace on this guest. On a system with the hardware
present, the bug fires at the cited line.

## Mechanism

pp_dpm_set_pp_table: hardcode_pp_table = kmemdup(soft_pp_table, soft_pp_table_size=u16 from VBIOS, GFP_KERNEL). soft_pp_table_size is typically 200-2000 bytes. Then memcpy(hardcode_pp_table, buf, size) where buf/size come from sysfs write (amdgpu_pm.c:463-475), count up to PAGE_SIZE=4096. NO check that size <= soft_pp_table_size. Overflow up to ~3800 bytes into kmalloc-* slab. On 2nd invocation the table is already non-NULL so the kmemdup is skipped, but the memcpy still uses the attacker-controlled size. Root-writable sysfs node (/sys/class/drm/cardN/device/pp_table, mode S_IWUSR) -> root-to-kernel heap corruption. The realistic ceiling on a default GENERIC kernel is panic; with INVARIANTS off and a slab groom, root could convert this to controlled heap corruption.

## Harness output

```
OVERFLOW: would write 4096 bytes into 2000-byte alloc (2096 bytes OOB)
RESULT: BUGGY
---PATCHED---
RESULT: PATCHED - size clamped to 2000 (alloc 2000)
```

## Fix

Clamp size to soft_pp_table_size before the memcpy.

The full git-apply-able unified diff is in `fix.diff`. It applies cleanly
to `/usr/src/sys/dev/drm/amd/powerplay/amd_powerplay.c:685-693` and the patched file compiles cleanly under the
kernel's CFLAGS (validated by an in-guest module build).

## Files

- `harness.c` — userspace replica of the vulnerable logic (memcpy overflow simulator (sysfs write of 4096 into 2000-byte kmemdup))
- `build.sh` / `run.sh` — exact build and run commands
- `fix.diff` — standalone git-apply-able fix (validated to apply + compile)
- `run.log` — full unpatched + patched harness output
- `env.txt` — guest environment
