# DF-1133 — gfx_v8_0_init_microcode RLC v2.0 register-list integer overflow + OOB

## Verdict
**CONFIRMED (source-trace + harness) — INCONCLUSIVE on-guest (HW-gated).** Real bug;
not triggerable on the QEMU guest (no AMD GPU; amdgpu not compiled into GENERIC,
only LINT64).

## Bug (one line)
`kmalloc(reg_list_format_size_bytes + reg_list_size_bytes, ...)` computes the size
as `u32 + u32` (both fields are `u32`), which wraps mod 2^32 *before* widening to
`size_t` -> a tiny allocation; the copy loop then writes `reg_list_format_size_bytes>>2`
dwords into it. Separately `reg_list_format_array_offset_bytes` is unvalidated, so the
read pointer can pass the firmware blob.

## Mechanism (path:line)
- `gfx_v8_0.c:1101-1104` — both sizes read as `u32` (`amdgpu_gfx.h:76-77`).
- `gfx_v8_0.c:1106-1108` — `kmalloc(fmt_size + lst_size, ...)`: the addition is
  `u32 + u32`, wraps before promotion to `size_t`.
  e.g. `0x80000000 + 0x80000008 -> 0x8` (8-byte alloc).
- `gfx_v8_0.c:1117-1118` — loop writes `(fmt_size >> 2)` dwords into the allocation
  -> massive heap OOB write (firmware-controlled content).
- `gfx_v8_0.c:1115-1116` — `tmp = rlc_hdr + reg_list_format_array_offset_bytes`
  (offset **unvalidated**) -> `tmp[i]` reads past the firmware blob -> heap OOB read.
- `amdgpu_ucode.c:251-260` — `amdgpu_ucode_validate()` only checks
  `fw->datasize == hdr->size_bytes`; it does NOT validate the reg-list sizes/offsets.

## Trigger / threat model
A crafted `rlc` firmware blob (matching `datasize==size_bytes`) supplied via reflash,
KVM GPU passthrough, or an emulated AMD GPU. `PR:H` per the CVSS (local privileged
loader), but the corruption is a kernel heap OOB write with firmware-controlled data.

## Reproduction on the audit guest
Not possible — no AMD GPU; amdgpu not in GENERIC. `harness.c` replicates the exact
arithmetic, proving (A) the integer-overflow -> undersized alloc -> OOB write, and
(B) the unvalidated-offset OOB read, then runs the fixed logic to show both are blocked.

## Build / run
```
./build.sh && ./run.sh
```
Expected: `DF-1133: CONFIRMED (A) heap OOB write ... AND (B) heap OOB read ...`
then `DF-1133 FIX: VALIDATED - size_t add prevents wrap, offset validation rejects OOB read`.

## Fix
`fix.diff` (a) casts both operands to `size_t` before the add, and (b) validates
`offset + size <= fw->datasize` for both register-list arrays, returning `-EINVAL` if
violated. Applies cleanly; compiles in the amdgpu module build (`gfx_v8_0.o`, rc=0).
