# DF-4288 VERDICT — VRAM_Info path unvalidated geometry

## Status: inconclusive (code-trace certain; not runnable on guest — no AMD dGPU)

## What was verified

Full read of `sys/dev/drm/amd/powerplay/hwmgr/ppatomctrl.c` (1563 lines) and
every supporting definition/caller:

* `smu_atom_get_data_table()` — `sys/dev/drm/amd/powerplay/hwmgr/smu_helper.c:660-673`:
  returns `NULL` whenever `amdgpu_atom_parse_data_header()` fails; the atom
  parser (`sys/dev/drm/amd/amdgpu/atom.c:1384-1403`) performs **zero** bounds
  validation — it trusts the VBIOS master-table offset (`idx = CU16(...)`)
  and returns `bios + data_start` directly. Both `*size` and any inner
  `usStructureSize` are raw VBIOS values.
* `atomctrl_initialize_mc_reg_table()` — `ppatomctrl.c:144-168`:
  * :146 `smu_atom_get_data_table(...VRAM_Info...)` → result stored in `vram_info`
  * :148 `vram_info->ucNumOfVRAMModule` **dereferenced with no NULL check**
    (contrast the guarded pattern used elsewhere in the same file, e.g.
    :494 `if (fw_info == NULL)` and :614 `PP_ASSERT_WITH_CODE(NULL != table_address...)`).
  * :157-158 `reg_block = (uint8_t *)vram_info + le16_to_cpu(vram_info->usMemClkPatchTblOffset)`
    — USHORT offset, never validated against the table `size`.
* `atomctrl_set_mc_reg_address_table()` — `ppatomctrl.c:102-131`:
  walks `ATOM_INIT_REG_INDEX_FORMAT` entries from the unchecked `reg_block`
  base; loop bound `num_entries = usRegIndexTblSize/sizeof(entry)` (:107-108)
  is VBIOS-controlled; only guarded against exceeding the *destination*
  array (`:113 num_entries <= VBIOS_MC_REGISTER_ARRAY_SIZE(32)`), not against
  reading past the *source* table. (Note `:111 num_entries--` wraps 0→255 for
  `usRegIndexTblSize < sizeof(entry)`, but 255 > 32 so the assert catches it —
  no bug there.)
* `atomctrl_retrieve_ac_timing()` — `ppatomctrl.c:48-93`:
  * :55-56 `reg_data = reg_block + 4 + le16(usRegIndexTblSize)` — second
    unvalidated offset.
  * :60-86 walk: exit conditions are only the 0xFFFFFFFF sentinel word and
    `num_ranges < VBIOS_MAX_AC_TIMING_ENTRIES(20)`; `num_ranges` increments
    **only on tmem_id match** (:64-81). `usRegDataBlkSize == 0` +
    non-matching index ⇒ infinite loop (same address re-read forever,
    non-preemptible kldload context). Non-matching index + any stride ⇒
    walk continues past the BIOS image until a 0xFFFFFFFF word happens to
    appear (unbounded OOB read); :88 dereferences the final pointer again.
  * callers: `ci_smumgr.c:2708`, `iceland_smumgr.c:2638`, `tonga_smumgr.c:3120`
    (`*_initialize_mc_reg_table` during SMU backend init at attach).
* Destination-array bounds verified safe (so the bug is strictly an OOB
  **read**/hang, not a write): `mc_reg_address[32]` written for `i < num_entries ≤ 32`
  (ppatomctrl.h:251); `mc_reg_table_entry[20]` indexed by `num_ranges < 20`
  (ppatomctrl.h:250); `mc_data[i-1]` at i==0 (ppatomctrl.c:77-78) aliases
  `mclk_max` within the same struct (ppatomctrl.h:219-222) — in-bounds.

## Why inconclusive (not not_reproduced)

The DragonFly QEMU guest used by this audit has no AMD dGPU (QEMU ships no
AMD GPU model; `kldstat` shows no drm modules — env.txt). The powerplay
attach path — the only reachable route into `atomctrl_initialize_mc_reg_table` —
cannot be entered, so no live PoC is possible in this environment. The
defects themselves are proven by trace; impact is boot/module-load kernel
panic (CWE-476), unbounded OOB read (CWE-125), or infinite-loop hang
(CWE-835) under a crafted VBIOS, i.e. the same threat model and severity
band as DF-1498 (Medium).

## Exploit chain

None — this is a read-only/hang primitive in the DRM attach path, gated on
attacker-controlled GPU firmware (physical supply-chain or malicious-reflash
threat). No unprivileged-local or remote path exists to this code.

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