# DF-4566 VERDICT — VCN rings ship without any CS ib parser

**Status: untested (dynamically), certain (statically). Impact demonstrated: none
(hardware absent); defect existence: proven by inspection.**

## What was verified and how

The audited file is `sys/dev/drm/amd/amdgpu/amdgpu_vcn.c` (905 LOC, pass 2).
The pass-1 context expected a VCN decode-message parser
(`amdgpu_vcn_dec_cs_msg` / `amdgpu_vcn_cs_parse`) to exist in this file. **It
does not exist anywhere in this tree** — verified by
`rg -n "amdgpu_vcn_(cs_parse|dec_cs_msg)" sys/` → no matches (see
`static_proof.txt`). This snapshot is ~Linux-4.17/4.18-vintage amdgpu (VCN 1.0,
Raven-only, `sys/dev/drm/amd/amdgpu/amdgpu_vcn.c:65-76`); upstream Linux added
the VCN ib check (`amdgpu_vcn_cs_parse` / `amdgpu_vcn_dec_cs_msg`, wired as
`.parse_cs` on the VCN dec ring) only in the ~5.1 era. The tree never got it.

## Why this is a security gap, not just a missing feature

1. `amdgpu_cs.c:833-836` runs the whole "ib contents" path **only** when
   `ring->funcs->parse_cs || ring->funcs->patch_cs_in_place` (the code comment
   itself says "Only for UVD/VCE VM emulation"). All three VCN ring func
   tables — `vcn_v1_0_dec_ring_vm_funcs` (vcn_v1_0.c:2043-2069),
   `vcn_v1_0_enc_ring_vm_funcs` (2076-2101) and
   `vcn_v1_0_jpeg_ring_vm_funcs` (2103-2135) — set **neither** hook. Every
   UVD ring (`uvd_v4_2.c:756`, `uvd_v5_0.c:865`, `uvd_v6_0.c:1530`) and every
   VCE ring (`vce_v2_0.c:615`, `vce_v3_0.c:902`, `vce_v4_0.c:1077`) in the
   same tree *does* set one — the asymmetry is the defect.

2. Consequence: a local user with render-node access on Raven APUs
   (0x1002:0x15dd / 0x15d8, `amdgpu_drv.c:911-912`) submits an
   `AMDGPU_CHUNK_ID_IB` targeting a VCN ring whose embedded decode message
   contains an arbitrary session handle and arbitrary fb-buffer addresses and
   sizes. Nothing checks that (a) the handle was created
   (cf. `amdgpu_uvd.c` session handling / DF-1657 family), or (b) each
   fb_buffer address corresponds to a GEM object in the validated CS bo list
   with adequate size (the job upstream's `amdgpu_vcn_dec_cs_msg` performs for
   H264/HEVC messages).

3. Addressing model (severity limiter): unlike pre-VM UVD (DF-4404: physical
   addressing), VCN 1.0 runs the ib under the submitting VM's page tables —
   the dec ring programs `mmUVD_LMI_RBC_IB_VMID` with the submitter's vmid
   (vcn_v1_0.c:1372-1378; jpeg `mmUVD_LMI_JPEG_VMID` vcn_v1_0.c:1736-1741).
   So raw msg addresses can only name mappings the attacker already owns; the
   kernel-integrity angle is the bo-list/pinning divergence: buffers named in
   the message but absent from the CS bo list are not pinned/reserved for the
   job, so TTM may evict/relocate them while the firmware still DMAs through
   them → cross-process VRAM corruption (racy), plus unaccounted session
   handles and trivial GPU-hang DoS. That is why this is Medium, not High.

## Why not reproduced on the guest

The audit QEMU guest (`DragonFly dfbsd 6.5-DEVELOPMENT ... X86_64_GENERIC`,
verified 2026-09-21) has **no AMD GPU and no /dev/dri**; `amdgpu` cannot even
load, and no VCN ring exists to submit to. Building the PoC is therefore
impossible on the available target — not a code-path refutation (the cited
path is trivially reachable on any Raven APU with the amdgpu KMD bound).

## Classification mapping

- Defect existence: **certain** (grep-provable absence; ring-func tables cited).
- PoC status per audit status set: `untested` (no hardware target exists in
  the harness; nothing was built or run).
- Demonstrated impact: `none` (no runtime demonstration possible).

## Recommended fix

Backport upstream's VCN dec ib validation (`amdgpu_vcn_cs_parse` /
`amdgpu_vcn_dec_cs_msg`, incl. its follow-up bounds fixes on the fb-buffer
count for H264/HEVC messages) and wire `.parse_cs = amdgpu_vcn_ring_parse_cs`
into `vcn_v1_0_dec_ring_vm_funcs`. A full parser backport is ~200 lines from
upstream; it is not authored here because verification on real hardware was
not possible, and per audit rules `fix.diff` accompanies *reproduced*
memory-corruption findings.

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

(No fix.diff for this item: documented recommendation only - see Fix above.)
