{
  "finding_id": "DF-4576",
  "status": "untested",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "Code-trace-proven: amdgpu_gem_va_ioctl (amdgpu_gem.c:637-646 MAP, :657-666 REPLACE) calls amdgpu_vm_alloc_pts() on the raw va_address/map_size BEFORE amdgpu_vm_bo_map() validates offset_in_bo/map_size; a deliberately-rejected mapping strands ~(map_size>>18) bytes of page-table BOs in the per-fd VM until close (~1 GiB per 256 TiB span ioctl, 4 KiB BO needed). Repeat with fresh render-node fds -> GTT/kernel exhaustion, GPU wedge for all processes (unprivileged, DRM_AUTH|DRM_RENDER_ALLOW). PoC built clean on the DragonFly guest but could not be executed to effect: the QEMU guest has no AMD GPU (virtio VGA only), /dev/dri absent, amdgpu not in the guest kernel build -> status untested (device absent), expected impact on real hardware: dos.",
  "exploit_chain": "open /dev/dri/renderD128 -> GEM_CREATE 4 KiB GTT BO -> GEM_VA MAP {va>=1 MiB, map_size=span, offset_in_bo=0x1000000000000000} -> alloc_pts allocates all page tables for span -> bo_map rejects -EINVAL -> page tables stay owned by vm->root until fd close -> repeat with new fds until GTT exhausted -> amdgpu allocation failures for every GPU process",
  "evidence": "run.log (PoC run as unprivileged user on guest: ENOENT, exit 2), build.log (BUILD_RC=0 on DF 6.5-DEVELOPMENT), env.txt (virtio VGA 0x1111:1234, no /dev/dri, amdgpu absent from guest sys/conf/files), VERDICT.md (line-level trace amdgpu_gem.c:637-646/657-666 -> amdgpu_vm.c:945-1023 -> amdgpu_vm.c:2493-2512 -> amdgpu_gem.c:675-680)",
  "kernel_refs": [
    "sys/dev/drm/amd/amdgpu/amdgpu_gem.c:637",
    "sys/dev/drm/amd/amdgpu/amdgpu_gem.c:657",
    "sys/dev/drm/amd/amdgpu/amdgpu_vm.c:945",
    "sys/dev/drm/amd/amdgpu/amdgpu_vm.c:2503",
    "sys/dev/drm/amd/amdgpu/amdgpu_kms.c:1211"
  ],
  "poc_changes": "seed sketch was only a description; wrote a fully self-contained PoC (Linux-ioctl-encoding macros hand-rolled since DragonFly <sys/ioccom.h> uses the BSD _IOC layout; uapi structs inlined; render-node + card0 fallback); fixed a premature comment termination (dri/*/ inside the block comment) found by the first guest build",
  "attempts": 2,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
  "runtime_sec": 45,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -Wall -o /tmp/df4576/gem_va_pt_exhaust /tmp/df4576/gem_va_pt_exhaust.c",
  "run_cmd": "/tmp/df4576/gem_va_pt_exhaust 4 0x800000000000",
  "code_hash": "8941d3b082c6438609d1cce077371fd1966dcb6b3676fee10bc97db5a25c3dd2",
  "notes": "DB poc status enum has no not_testable: untested records attempted-but-device-absent. Expected impact on real AMD hardware: dos (GTT exhaustion, cross-process GPU wedge). Guest left clean (no kernel changes, /tmp scratch only). Fix validation not_testable: guest cannot attach an AMD GPU; fix.diff is a pure argument pre-check before the operation switch using already-visible symbols.",
  "recommended_fix": "Validate map_size/offset_in_bo (alignment, non-zero, va_address+map_size and offset_in_bo+map_size wrap, offset+size <= amdgpu_bo_size) in amdgpu_gem_va_ioctl BEFORE calling amdgpu_vm_alloc_pts, so rejected mappings cannot allocate page tables (see fix.diff)",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": null,
  "fix_verdict": "fix.diff inserts the bo_map-equivalent argument validation before amdgpu_vm_alloc_pts() in the MAP/REPLACE paths; a doomed mapping then fails with -EINVAL before any page-table BO is created, eliminating the stranding. Cannot be validated on this guest (no AMD GPU hardware; amdgpu not in the guest kernel build) \u2014 not_testable. The added wrap guards also pre-fix the DF-1719 offset+size wrap for this ioctl path.",
  "fix_evidence": "findings/poc/DF-4576/fix.diff (git-apply-able vs sys/dev/drm/amd/amdgpu/amdgpu_gem.c, insertion between the bo_va selection and the operation switch); guest env.txt showing why no baseline/patched run is possible"
}