DF-4832 / verdict.json
{ "finding_id": "DF-4832", "status": "untested", "reproduced": 0, "impact": "none", "confidence": "speculative", "verdict": "uvd_v1_0_resume programs the UVD VCPU LMI cache windows starting 128 bytes into vcpu_bo (addr=(gpu_addr>>3)+16, uvd_v1_0.c:121) but keeps full-size regions (ALIGN(datasize), HEAP, STACK+SESSION*N, uvd_v1_0.c:122-135), while radeon_uvd.c:184-186 sizes the bo at ALIGN(datasize+8)+HEAP+STACK+SESSION*N. For datasize%4096 in [1,4088] (4088/4096 = 99.8% of sizes, incl. every realistic legacy blob; these ASICs always use legacy headerless fw) the STACK/SESSION window ends exactly bo_end+128B, in the VRAM object allocated after vcpu_bo. Affects the whole R600 class (r600.c:3080) and RV770 (uvd_v2_2.c:106). Arithmetic proven exhaustively by check_arith.py (arith.log: min=max=128B overrun; control uvd_v2_2 fits for ALL residues). End-to-end not runnable: guest has no AMD ASIC (bochs chip=0x11111234, no drm modules, env.txt) and the window-tail write is fw-behavior-dependent -- speculative, mirroring accepted twins DF-4524 (vce_v3_0) and DF-4742 (vce_v2_0). GPU-scope only: LMI windows map VRAM, not host memory; ceiling is 128B cross-object GPU read/write between adjacent GEM bos during video decode (CS-reachable by unpriv users on real hw). No kernel host-memory impact.", "exploit_chain": "", "evidence": "arith.log (exhaustive mod-4096 sweep: overrun min=max=128B, 4088/4096 residues; uvd_v2_2 control clean for all residues; post-fix span==bo_size for all ds in [0,0x2FFFF]); VERDICT.md (full derivation + negative-check list); env.txt (guest GPU absent)", "kernel_refs": [ "sys/dev/drm/radeon/uvd_v1_0.c:121", "sys/dev/drm/radeon/uvd_v1_0.c:122", "sys/dev/drm/radeon/uvd_v1_0.c:126", "sys/dev/drm/radeon/uvd_v1_0.c:132", "sys/dev/drm/radeon/radeon_uvd.c:184", "sys/dev/drm/radeon/radeon.h:1675", "sys/dev/drm/radeon/r600.c:3080", "sys/dev/drm/radeon/uvd_v2_2.c:106" ], "poc_changes": "n/a (no seed; arithmetic harness written fresh, DF-4742 style)", "attempts": 0, "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": 0, "guest_dirty": 0, "build_cmd": "python3 check_arith.py", "run_cmd": "not runnable (no radeon ASIC on guest; needs R600-class/RV770 + UVD fw + CS decode session)", "code_hash": "b8498e7f1eab3e90f1aa389f3340db73c8f2d0fb29888cc07fcf528d527bcfd7", "notes": "hw-gated (R600/RV610/RV630/RV670/RV620/RV635/RS780/RS880/RV770 UVD); radeon UVD v1 twin of DF-4524/DF-4742. Cross-note for orchestrator: uvd_v4_2.c:47 (+0x200 skip w/ ALIGN(datasize+4), fw_header_present) shows the same 512B-class overhang shape in the harness -- pass-1 clean, out of this files scope. Sibling radeon_uvd.c CS/handle issues are DF-1655/1656/1657/4500/4501 (not re-filed). AGP batch-mate drm_agpsupport.c audited clean pass 2 (root-only ioctls, backend re-validation); no pack.", "recommended_fix": "Shrink the fw window by the 128B entry skip in uvd_v1_0_resume (size = (RADEON_GPU_PAGE_ALIGN(datasize+8) >> 3) - 16) so the window chain ends at the bo boundary, or clamp windows to bo size v4_0-style", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "Fix not kernel-validated: no radeon GPU on this guest, no baseline to flip. fix.diff is arithmetic-exact: post-fix span == bo_size for every ds in [0,0x2FFFF] (arith.log tail).", "fix_evidence": "fix.diff (applies clean via git apply --check; window chain ends exactly at bo end)" } |