# DF-4404 — u32 integer overflow in `amdgpu_uvd_cs_msg_decode()` defeats DPB/ctx buffer size validation (GPU physical-mode OOB)

**File:** `sys/dev/drm/amd/amdgpu/amdgpu_uvd.c:514-696` (decode), used by
`amdgpu_uvd_cs_pass2()` at `sys/dev/drm/amd/amdgpu/amdgpu_uvd.c:803-878`.
**Severity:** High · **Confidence:** certain (kernel-side math proven; upstream
fixed the same defect in Linux commit `05e1387d151f` "drm/amdgpu: Reject UVD
message with dimensions above 4096 — Fixes potential overflow in DPB size
calculations", 2026-07-30; the `< 16` half that fixes known DF-1595 is commit
`3e41d26c70b0`).

## Build

```
cc -O2 -I/usr/src/sys/dev/drm/include/uapi -o uvd_dim_overflow uvd_dim_overflow.c
```

(or `./build.sh` which does this on the audit guest via ssh)

## Run

```
./uvd_dim_overflow
```

(or `./run.sh` on the audit guest)

## Expected output

* **Part A (always):** replicates the kernel arithmetic and shows that for a
  UVD **MPEG2** decode message with `msg[6] = width = 0x80000000`,
  `msg[7] = height = 2`, `msg[9] = dpb_size = 0`:
  * `image_size = (width*height + width*height/2) mod 2^32` wraps to `0`
    (`amdgpu_uvd.c:531-533`),
  * `min_dpb_size = image_size*3 = 0` (`amdgpu_uvd.c:596-600`),
  * the gate `dpb_size < min_dpb_size` (`amdgpu_uvd.c:686`) **passes** with a
    zero-sized DPB,
  * `amdgpu_uvd_cs_pass2()` then only requires `(end-start) >= buf_sizes[1] = 0`
    for the DPB buffer command (`amdgpu_uvd.c:833`) — **any** mapping passes.
  * Same demonstration for **H265** (`case 16`, `amdgpu_uvd.c:666-674`) where
    `ALIGN(w,16)*ALIGN(h,16)` wraps and both `min_dpb_size` and `min_ctx_size`
    collapse.
* **Part B (needs AMD GPU):** opens `/dev/dri/renderD128` / `/dev/dri/card0`
  and submits the crafted decode message. On the audit QEMU guest there is no
  AMD GPU (only QEMU bochs VGA), so Part B prints the open failures and exits 2.

## Success criterion

On real AMD hardware (CIK..Vega UVD, amdgpu attached, user in group `video` —
DFly DRM nodes are `0660 root:video`, `sys/dev/drm/include/drm/drmP.h:108`),
the CS is accepted (no `-EINVAL`) despite the undersized DPB — proving the
validator bypass; the firmware then decodes a stream whose declared dimensions
are 2^31 wide, accessing DPB well beyond the validated object. On this guest,
Part A + line-certain static proof is the deliverable.

## Not-a-PoC note

The audit guest has **no AMD GPU** (`pciconf -lv`: only `vgapci0` bochs
`0x11111234`; `amdgpu.ko` loads but attaches to nothing, `/dev/dri` absent) —
the ioctl path cannot be executed here. Status: `inconclusive` (see
VERDICT.md), kernel-side math certain.
