# DF-4000 — VERDICT

**Finding:** The iceland (Topaz) SMU manager feeds the raw VBIOS PowerPlay
SCLK/MCLK dependency-table counts (`u8 ucNumEntries`, never clamped) into
every SMC-table populate walk, indexing arrays dimensioned 8/4 — the
DF-3909/DF-3940 family on iceland's tighter bounds, including a
**kernel-stack** OOB write:

- `iceland_populate_all_graphic_levels` — writes
  `smc_state_table.GraphicsLevel[i]` for `i < dpm_table->sclk_table.count`
  (iceland_smumgr.c:980-990); array is `GraphicsLevel[SMU71_MAX_LEVELS_GRAPHICS=8]`
  (smu71_discrete.h:270). Also the `[count-1]` store at :997 and the
  `pcieDpmLevel` loop at :1026-1028.
- `iceland_populate_all_memory_levels` — writes
  `MemoryLevel[i]` for `i < mclk_table.count` (:1361-1369) plus
  `MemoryLevel[count-1]` (:1385); array is
  `MemoryLevel[SMU71_MAX_LEVELS_MEMORY=4]` (smu71_discrete.h:272) — **count 5
  already overflows** (CI needed 7 against its 6).
- `iceland_program_memory_timing_parameters` — **stack** object
  `SMU71_Discrete_MCArbDramTimingTable arb_regs` (:1616) with
  `entries[8][4]` (:179 smu71_discrete.h) indexed `[i][j]` for
  `i < sclk_count`, `j < mclk_count` (:1621-1632) — the DF-3908/DF-3939 twin;
  mclk count 5 suffices for iceland (CI needed 7).
- `iceland_convert_mc_reg_table_to_smc` — writes `mc_regs->data[i]` for
  `i < mclk_table.count` (:1761-1766); `data[SMU71_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT=4]`
  (smu71_discrete.h:370), and `iceland_update_and_upload_mc_reg_table`
  copies `sizeof(MCRegisterSet)*count` bytes from `mc_regs.data[0]`
  (:1796-1799) — OOB read of the softc into SMC SRAM.

**Provenance of the counts (all three hops verified in-tree):**
`ATOM_PPLIB` dep table `ucNumEntries` (u8) →
`get_clock_voltage_dependency_table` processpptables.c:375-401 (kzalloc of
exactly `count` entries, no upper bound) → `hwmgr->dyn_state.vddc_dependency_on_{s,m}clk`
→ `smu7_setup_dpm_tables_v0` smu7_hwmgr.c:689-697/704-711 (copies every
entry, incrementing `dpm_table.{s,m}clk_table.count` with no clamp — and
itself writes past `dpm_levels[MAX_REGULAR_DPM_NUMBER=8]`, smu7_hwmgr.h:100,
already filed as DF-1166) → the iceland loops above. Topaz is pinned to
this path: `hwmgr.c:114-122` (`CHIP_TOPAZ → iceland_smu_funcs`,
`PP_TABLE_V0`). Voltages and PCIE are trimmed upstream
(smu7_construct_voltage_tables smu7_hwmgr.c:323-349; pcie table count
capped ≤ 7 with the boot-level reservation smu7_hwmgr.c:560-605) — the
clock DPM counts are the untrimmed family.

**Status: inconclusive (hardware-gated) — source-certain.** The guest
demonstrator reproduces the exact index math with verbatim struct replicas
(sizeof GraphicsLevel=48, MemoryLevel=72, MCArbDramTimingTable=384): for a
crafted VBIOS with sclk=12/mclk=6 dep entries — 4/12 GraphicsLevel writes
(+192 B past the array), 2/6 MemoryLevel writes (+144 B past, walking
LinkLevel/ACPILevel/… inside the kzalloc'd `iceland_smumgr`), **26 of 72
stack arb_regs writes OOB (max linear entry 49 of 32, +216 B past the
384-byte stack object)**, 2/6 mc_regs.data writes OOB. The in-kernel fault
could not be observed: the QEMU guest has no AMD GPU (env.txt: amd-gpu=0)
and the trigger requires a Topaz card whose VBIOS carries the crafted
PowerPlay tables — matching the DF-3908/3939/3940 precedent for this
family (physical-attacker / malicious-VBIOS threat model; also reachable
via a corrupted vbios image flashed or supplied to the driver).

## Why each checklist item is or is not a finding

- (a) SMC table populate walks → **this finding**.
- (b) firmware header parses: `iceland_smu_upload_firmware_image`
  checks `image_size & 3` (:195) and `> ICELAND_SMC_SIZE` (:200);
  `iceland_upload_smc_firmware_data` checks `limit >= byte_count` (:163);
  firmware comes from root-controlled /lib/firmware — no defect.
- (c) AVFS dep-table walks: **no AVFS code exists in iceland_smumgr.c**
  (grep -i avfs → no matches; Topaz AVFS is handled in smu7_hwmgr) — n/a.
- (d) `iceland_get_dependency_volt_by_clk` (:506-528): `count == 0`
  rejected at :513 before the `entries[i-1]` fallback at :525 — safe.
  (`iceland_populate_mvdd_value` (:1395-1419) does cross-index
  `mvdd_voltage_table.entries[i]` by the dependency-table count, which can
  exceed the trimmed 4-entry voltage table — but its only caller passes
  mclk=0 (:1504), which always matches at i=0; unreachable as written,
  noted as latent.)
- (e) data table version gating: Topaz is pinned to PP_TABLE_V0
  (hwmgr.c:114-122) and every iceland populate function consistently
  consumes V0 `dyn_state`/`dpm_table` sources with SMU71 structures — no
  V1/SMU-mismatch path reaches this file. `iceland_get_mac_definition`
  returns the SMU71 limits consistently.
- Killed candidates: `iceland_populate_smc_link_level` `i <= count`
  off-by-one (:772) — pcie count ≤ 7 by construction (boot-level
  reservation, smu7_hwmgr.c:560-569) so max index 7 < LinkLevel[8] — safe;
  BAPMTI default walk (:1893-1902) — 5×3×1 = 15 == bapmti_r[15] exact fit;
  `iceland_set_mc_special_registers` j-bounds asserted before every write
  (:2516,2532,2549); `iceland_copy_vbios_smc_reg_table` asserts
  last ≤ 16 / num_entries ≤ MAX_AC_TIMING_ENTRIES (:2484-2487); fan-table
  div0 = DF-1323 and mvdd loop bound = DF-1324 (knowns, not re-reported);
  `iceland_populate_vddc_vid`/`bapm_vddc_vid_sidd` assert counts ≤ 8
  (:398-399, :422); voltage-level arrays bounded by the upstream trims
  (smu7_hwmgr.c:323-349) to SMU71 limits 8/4/4.

## Fix

`fix.diff` (8 hunks, applies clean to pristine /usr/src — md5 verified):
clamp every walk to its array bound — `sclk_count =
min(count, SMU71_MAX_LEVELS_GRAPHICS)`, `mclk_count =
min(count, SMU71_MAX_LEVELS_MEMORY)` used for the loops, the `[count-1]`
stores and the reported `*DpmLevelCount`; `&&` guards in the arb-timing
and mc_reg loops; upload size clamped to
SMU71_DISCRETE_MC_REGISTER_ARRAY_SET_COUNT. The structural fix belongs
upstream in `smu7_setup_dpm_tables_v0` (DF-1166's domain: clamp counts
before they enter `dpm_table` / `dpm_levels[8]`).

**Fix validation:** applied to the guest's clean /usr/src
(patch-OK, md5 e3bce6…→1f1e44…), full `make nativekernel KERNCONF=X86_64_GENERIC`
rebuild: started 11:31:31, **completed 11:59:41, error_count=0** with the
patched iceland_smumgr.c compiled under `-Werror` at fix_kernel_full.log:11214
(fix_build.log summary). Runtime re-test impossible on this guest (no AMD
GPU). Patch reverted after validation (md5 back to pristine).

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