# DF-4357 — AMDGPU_INFO_READ_MMR_REG missing upstream count cap (Low, hardening)

## Build / Run / Expected

```sh
cc -O2 -o trigger trigger.c
./trigger /dev/dri/renderD128     # unprivileged, needs an AMD GPU
# vulnerable kernel: iterations print ENOMEM (512MiB kmalloc attempted)
#                    or EFAULT-after-alloc
# patched kernel  : iterations print EINVAL instantly (count > 128 cap)
```

This audit's QEMU guest has no AMD GPU and no /dev/dri — runtime half is
hardware-gated; see VERDICT.md.

## Bug

`amdgpu_kms.c:668-684` (AMDGPU_INFO_READ_MMR_REG): user-controlled
`info->read_mmr_reg.count` (u32) goes straight into
`kmalloc_array(count, 4, GFP_KERNEL)` with no upper bound. Upstream Linux
(v5.4, and every release since the cap landed) begins the same block with:

```c
		if (info->read_mmr_reg.count > 128)
			return -EINVAL;
```

The DF tree's amdgpu port is a ~v5.0 base (verified: v5.0 upstream also
lacks the cap) and never received it.

Consequences without the cap:
* per-call kernel allocation of `count*4` bytes attempted from an
  unprivileged render client (bounded only by allocation failure; the
  `alloc_size` `unsigned` truncation at count >= 2^30 additionally requires
  a successful >= 4 GiB kmalloc, which DF's malloc(9) will happily *attempt*
  with M_WAITOK semantics, stalling the caller and pressuring kernel memory);
* the register-read loop runs one allowlist check + MMIO read per dword —
  in practice it bails at the first disallowed offset, so the loop-DoS is
  self-limiting; the allocation pressure is the real (weak) DoS vector.

This is a hardening/DoS-low finding, not memory corruption: all copies are
`min(size, alloc_size)`-bounded and the loop cannot overrun `regs`.

## Fix

`fix.diff` — add the upstream cap verbatim.
