# DF-4863 — VERDICT

**Status: reproduced** (defect demonstrated in the verbatim-function harness,
3/3 deterministic runs)
**Impact: none (latent panic-class type confusion — no in-tree caller
reaches the default path today)**
**Severity filed: Low · confidence: certain (code defect) / reachability
latent (documented)**

## What was run

The DF-4862 harness (`cgs_mec_jt_oob.c`), scenario [4], on the DragonFly
6.5-DEVELOPMENT guest. Struct layouts are 1:1 with
`amdgpu_ucode.h:236-268` and enforced at compile time:

- `_Static_assert(AMDGPU_UCODE_ID_MAXIMUM == 21)`
- `_Static_assert(offsetof(struct amdgpu_firmware, fw_buf)
   == AMDGPU_UCODE_ID_MAXIMUM * 48 + 8)` — i.e. `ucode[21].fw` (element
  offset +8 of the one-past-end element) lands exactly on `fw_buf`.

## Observed (run.log, scenario [4])

- `&firmware.ucode[MAXIMUM].fw = 0x403758  == &firmware.fw_buf = 0x403758  :
  ALIAS CONFIRMED` — the one-past-end read is proven to fetch the
  `fw_buf` pointer.
- With `fw_buf` non-NULL (its state after `amdgpu_ucode_init_bo()` on
  SMU-load asics — `smu7_request_smu_load_fw()` calls it first thing at
  `smu7_smumgr.c:343`), the verbatim `ucode->fw == NULL` guard passes and
  the code proceeds: `header = ucode->fw->data` reads the mock bo's +8
  qword as `const uint8_t *data` (`sys/sys/firmware.h:53`), and
  `info.image_size=0x5a5a5a5a` / `info.version=0x5a5a` garbage propagates
  to the caller. The harness points that qword at a readable page so the
  run completes; on real hardware it is `ttm_buffer_object` internals —
  an arbitrary pointer, and `le32_to_cpu(header->header.ucode_size_bytes)`
  (`amdgpu_cgs.c:221`) dereferences it immediately: wild read, panic class.

## Root cause

`sys/dev/drm/amd/amdgpu/amdgpu_cgs.c:214-215` — the return of
`fw_type_convert()` (`:111-156`) is used as an array index without a bound;
its default return (`AMDGPU_UCODE_ID_MAXIMUM`, `:114`) equals
`ARRAY_SIZE(adev->firmware.ucode)` (`amdgpu_ucode.h:252-253`). The enum
`cgs_ucode_id` already contains an unhandled value
(`CGS_UCODE_ID_GMCON_RENG`, `cgs_common.h:58`).

## Reachability (why Low, not higher)

All in-tree `cgs_get_firmware_info` callers pass mapped types:
smu7 (`smu7_smumgr.c:312,489,492` via `smu7_convert_fw_type_to_cgs` — all
cases mapped, `smu7_smumgr.c:231-276`), smu8 (`smu8_smumgr.c:189,569` via
`smu8_convert_fw_type_to_cgs` — all `firmware_list[]` entries mapped),
ci (`ci_smumgr.c:2316` SMU), iceland (`:192` SMU),
vega10/12/20 (SMU). So today the path is dead code for unmapped types; the
defect is a missing defensive bound whose trigger is one future caller (or
one enum value gaining a user) away.

## Fix validation

`fix.diff` (same file as DF-4862's pack) adds
`if (id >= AMDGPU_UCODE_ID_MAXIMUM) return -EINVAL;` before the indexing.
Patched twin: scenario [4] returns `-22 (one-past-end index rejected — FIX
VALIDATED)`; no other scenario changes. 3/3 runs.

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