DF-4864 / verdict.json
{ "finding_id": "DF-4864", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "Deterministic 32-byte kernel heap OOB write per GPU-VM create on AMD Raven APUs (all revisions): amdgpu_vm_clear_bo() allocates a 64-byte/16-dword SA sub-allocation (amdgpu_vm.c:855) but the ATS root-PD clear emits two 10-dword set_pte_pde packets (amdgpu_vm.c:867-874 -> sdma_v4_0.c:1190-1200) plus 4 SDMA pad dwords = 24 dwords into 16. Trigger is CHIP_RAVEN-only (pte_support_ats, amdgpu_vm.c:3172): rev0/1 root PD = 512 entries split 256/256 (gmc_v9_0.c:941), rev>=2 = 257 entries split 256/1 (gmc_v9_0.c:945). The kernel-side path cannot run on the audit guest (QEMU Bochs 0x1234:1111 VGA, no AMD device, no /dev/dri, no drm modules) so it is not runtime-reproduced; the arithmetic is proven from unambiguous source constants and the byte-exact write pattern (10->20->24 dwords, 32 canary bytes destroyed; non-ATS case fits exactly at 16) is demonstrated by the verbatim-code harness in run.log. The guard WARN_ON(length_dw > 64) at amdgpu_vm.c:878 compares dwords to the byte size and never trips. Overrun lands in the adjacent SA hole / neighbouring IB, or past the 1MB SA pool mapping when pool-packed (groomable via user-sized GFX CS IBs).", "exploit_chain": "On real Raven hardware: unpriv /dev/drm client -> VM-create ioctl -> amdgpu_vm_init -> amdgpu_vm_clear_bo(root PD) -> 24 dwords written into 16-dword SA sub-allocation -> 32-byte overwrite of neighbouring SA data (cross-context GPU command corruption), or past the SA pools kernel mapping when the pool is groomed full (spray GFX CS IBs, amdgpu_cs.c:1033) -> kernel heap corruption with semi-controlled content (value_hi/count of PTE packet + NOPs). No uid0 chain developed: required ASIC absent from the audit guest.", "evidence": "run.log lines [Raven-root-512] *** OOB WRITE: 8 dwords (32 bytes) ... and [non-ATS-single] fits exactly; VERDICT.md arithmetic section; fix_build.log final amdgpu.ko link line (patched module compiles -Werror clean); env.txt (guest has no AMD GPU).", "kernel_refs": [ "sys/dev/drm/amd/amdgpu/amdgpu_vm.c:855", "sys/dev/drm/amd/amdgpu/amdgpu_vm.c:861-876", "sys/dev/drm/amd/amdgpu/amdgpu_vm.c:878", "sys/dev/drm/amd/amdgpu/amdgpu_vm.h:293", "sys/dev/drm/amd/amdgpu/sdma_v4_0.c:1184-1200", "sys/dev/drm/amd/amdgpu/sdma_v4_0.c:1208-1222", "sys/dev/drm/amd/amdgpu/amdgpu_ib.c:61-81", "sys/dev/drm/amd/amdgpu/amdgpu_sa.c:151-173", "sys/dev/drm/amd/amdgpu/gmc_v9_0.c:941-949", "sys/dev/drm/amd/amdgpu/amdgpu_vm.c:3172" ], "poc_changes": "No seed PoC existed (pass-2 discovery); harness authored from scratch with emit/pad code copied verbatim from sdma_v4_0.c.", "attempts": 3, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 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": 62, "guest_dirty": 0, "build_cmd": "sh build.sh (cc -O2 -Wall -o df4864_trigger df4864_trigger.c, guest unpriv user)", "run_cmd": "sh run.sh (guest unpriv user)", "code_hash": "1c969a40e74a12dca42c1ee001a19fc589b25aa743bb2b54061f319fbabc9324", "notes": "Hardware-gated: needs AMD Raven APU (asic CHIP_RAVEN, any rev). This is the amdgpu twin of the radeon ring-pad sizing family (cf. radeon DF-4820/4821 context) and matches the pass-2 pad-accounting hint (g) for amdgpu_ring.c. fix.diff applied to guest /usr/src, amdgpu.ko module rebuilt clean (-Werror), source reverted afterwards; runtime fix A/B impossible on guest -> not_testable.", "recommended_fix": "Size the clear-IB for the worst case (two set_pte_pde packets + SDMA pad): amdgpu_job_alloc_with_ib(adev, 128, &job) and fix the dword/byte confusion in the WARN (length_dw > 32).", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff compiles clean against the guests /usr/src (full amdgpu.ko module build under -Werror, fix_build.log); runtime baseline-vs-patched comparison impossible on this guest (no AMD GPU). 128 bytes covers the proven worst case (20 emit + 7 pad = 27 dwords).", "fix_evidence": "findings/poc/DF-4864/fix_build.log (patch applied: hunks 852/882; final cc -r -o amdgpu.ko ... amdgpu_vm.o link); fix.diff (git-apply-clean against sys/)." } |