# DF-4429 VERDICT — radeon_verify_access: GEM ownership check dropped

## Bottom line

**Source-verified, hardware-gated (not runnable on the audit guest): the
DragonFlyBSD radeon port's `.verify_access` TTM callback authorizes *every*
mmap of *every* user-created GPU buffer object to *any* open file descriptor
of the card node.** The upstream authorization call is `#if 0`'d out; the
sibling amdgpu driver in the same tree still performs it.

## Reproduction status

`untested` — the audit QEMU guest has no AMD/ATI GPU (`env.txt`: no
`/dev/dri`, only the QEMU bochs VGA stub 0x1234:1111), so the radeon driver
never attaches there and the trigger cannot execute. The finding is verified
by complete source-path tracing (below), matching the DF-4018/DF-4019 sibling
precedent for amdgpu_ttm hardware-gated verdicts.

## Why the bug is real — complete path, every hop cited

1. **Sink**: `sys/dev/drm/radeon/radeon_ttm.c:234-244` —
   `radeon_verify_access()` reduces to `return 0`. The only conditional calls
   `radeon_ttm_tt_has_userptr()`, which is itself hardwired `return false`
   (`radeon_ttm.c:849-861` — real body `#if 0`). Registered as
   `.verify_access` at `radeon_ttm.c:882`.
2. **Reachability of the sink**: mmap on `/dev/dri/cardN` →
   `drm_mmap_single()` (`sys/dev/drm/drm_drv.c:1254-1266`) →
   `ttm_bo_mmap_single()` (`sys/dev/drm/ttm/ttm_bo_vm.c:766-807`) →
   `ttm_bo_mmap()` (`ttm_bo_vm.c:431-473`, calls `verify_access` at :447).
   This path performs no `priv->authenticated` check — the legacy-auth gate
   exists only in the old map-hash `drm_mmap` (`sys/dev/drm/drm_vm.c:53-55`),
   not in `drm_mmap_single`.
3. **Object discovery**: `ttm_bo_vm_lookup()` (`ttm_bo_vm.c:408-429`) uses
   `drm_vma_offset_lookup_locked()` — best-match: any node *spanning* the
   requested page range matches. All user BOs (`ttm_bo_type_device`, created
   by every `RADEON_GEM_CREATE`) are registered in `bdev->vma_manager` at
   `sys/dev/drm/ttm/ttm_bo.c:1266-1271`; offsets handed to userspace come
   from exactly that node (`sys/dev/drm/radeon/radeon_object.h:117-120`).
   Therefore single-page probes from `DRM_FILE_PAGE_OFFSET` (4 GiB,
   `radeon_ttm.c:48,906`) upward enumerate and map every live user BO.
4. **Contrast in-tree**: `sys/dev/drm/amd/amdgpu/amdgpu_ttm.c:311-325`
   performs `drm_vma_node_verify_access(&abo->gem_base.vma_node,
   filp->private_data)`; the allow-side is recorded per GEM handle at
   `sys/dev/drm/drm_gem.c:471`. Upstream Linux radeon performs the same check.
5. **Access gate**: card node is root:video 0660
   (`sys/dev/drm/include/drm/drmP.h:108-110`, `sys/dev/drm/drm_drv.c:1178`).
   Attackers must be in group `video` — i.e. exactly the class of users who
   share a GPU on multi-user desktops.

## Impact

Cross-user confidentiality **and** integrity of GPU memory: any video-group
user can read/write every other user's radeon GEM BOs — Xorg's scanout
buffers (window/VT contents of other users), textures, upload buffers.
Kernel-internal BOs (`ttm_bo_type_kernel`: rings, IB pool) carry no vma node
(`ttm_bo.c:1269`) and are **not** exposed; the ceiling is user GEM objects.
No direct kernel-memory disclosure → not Critical; multi-user group-gated →
Medium.

## Exploit chain (for a hardware owner)

victim (userA): `./victim_bo` fills a 4 MiB GTT BO with `DF4429MARK`.
attacker (userB): `./poc_mmap_bo --read` sweeps 4 GiB..8 GiB mmap offsets on
the same card node; hits whose dump contains the marker prove foreign-BO
read; PROT_WRITE mappings give symmetric write.

## Fix validation

`fix.diff` restores `drm_vma_node_verify_access(&rbo->gem_base.vma_node,
filp->private_data)` (mirrors amdgpu_ttm.c). Cannot be kernel-built/tested on
this guest (no radeon hardware; the change only compiles in the radeon module
path) → `fix_status: not_testable`.

## Kernel refs

- sys/dev/drm/radeon/radeon_ttm.c:234-244 (the stub)
- sys/dev/drm/radeon/radeon_ttm.c:849-861 (has_userptr hardwired false)
- sys/dev/drm/radeon/radeon_ttm.c:882 (.verify_access registration)
- sys/dev/drm/ttm/ttm_bo_vm.c:431-473 (ttm_bo_mmap, verify at :447)
- sys/dev/drm/ttm/ttm_bo.c:1266-1271 (which BOs get vma nodes)
- sys/dev/drm/amd/amdgpu/amdgpu_ttm.c:311-325 (in-tree correct sibling)
- sys/dev/drm/drm_drv.c:1254-1266, drm_vm.c:53-55, drmP.h:108-110

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