# DF-3701 VERDICT — vega10 clock-getter stack overflow (DF-3684 twin)

**status: inconclusive (hardware-gated) — source-certain. reproduced=0 on audit guest.**

## Why this is a real bug (line-by-line)
1. `vega10_get_socclocks` (sys/dev/drm/amd/powerplay/hwmgr/vega10_hwmgr.c:4177-4191):
   for (i = 0; i < dep_table->count; i++) { clocks->data[i]... ; clocks->num_levels++; }
   — the ONLY bound is `dep_table->count`.
2. `dep_table` = `table_info->vdd_dep_on_socclk`, built by
   `get_socclk_voltage_dependency_table` (vega10_processpptables.c:520-540):
   `clk_table->count = (uint32_t)clk_dep_table->ucNumEntries;` — ucNumEntries is an
   untrusted uint8 from the VBIOS powerplay table, unbounded (allocation matches it,
   so no earlier corruption is needed; counts up to 255 flow through intact).
3. `clocks` points at `struct pp_clock_levels_with_latency pp_clks = { 0 };` declared
   ON THE CALLER'S STACK in `dm_pp_get_clock_levels_by_type_with_latency`
   (display/amdgpu_dm/amdgpu_dm_pp_smu.c:375); the struct is
   `{ uint32_t num_levels; struct pp_clock_with_latency data[PP_MAX_CLOCK_LEVELS]; }`
   (include/dm_pp_interface.h:174-177, PP_MAX_CLOCK_LEVELS=16).
   => ucNumEntries > 16 writes past a 132-byte stack object with 32-bit
   attacker-influenced values (`le32_to_cpu(ulClk) * 10`); this smashes the adjacent
   frame(s) — classic kernel stack control-flow hijack primitive (no SMEP/SMAP/KASLR
   on many deployments, incl. DragonFly defaults).
4. Identical pattern: get_sclks :4125-4131, get_dcefclocks :4170-4174,
   get_clock_by_type_with_voltage :4246-4251 (stack twin at amdgpu_dm_pp_smu.c:399),
   and get_memclocks :4146-4158 which ADDITIONALLY heap-overflows
   `data->mclk_latency_table.entries[j]` (fixed `entries[MAX_REGULAR_DPM_NUMBER=8]`,
   vega10_hwmgr.h:218-220) inside the `struct vega10_hwmgr` backend allocation when the
   MCLK dep count exceeds 8.

## Reachability
DC calls `dm_pp_get_clock_levels_by_type_with_latency` during display/clock-manager
initialization on Vega10 (amdgpu_dm); no sysfs/ioctl needed — it fires during normal
driver bring-up once the crafted-VBIOS card is present.

## Why not reproduced on the guest
`pciconf -l` on the audit guest shows zero AMD (0x1002) PCI devices; the display
adapter is QEMU std VGA. `/boot/kernel/amdgpu.ko` exists and prints
"[drm] amdgpu kernel modesetting enabled", but `hwmgr_hw_init`/`vega10_hwmgr_backend_init`
are only reached per-AMD-device, so no vega10_hwmgr object ever exists on this guest.
Honest classification: inconclusive (cannot exercise the driver on this hardware);
the defect itself is proven at source level with exact types/bounds above.

## Exploit chain (if the hardware precondition is met)
crafted VBIOS pptable (physical reflash / malicious eGPU / VFIO-passthrough of a
doctored card) -> driver load -> DC clock query -> stack smash with attacker-scaled
32-bit writes -> kernel ROP -> uid=0. (Chain not demonstrated: no Vega10 hardware
in the audit environment.)

## Fix
fix.diff clamps every getter loop to the destination capacity
(`i < dep_table->count && i < PP_MAX_CLOCK_LEVELS`), mirroring the guard upstream
Linux added (and the one already present in vega10_populate_single_display_type:1850).

## 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.
