DF-4871 VERDICT — r600_copy_dma ignores sync_resv/sync_rings failures

## Bottom line

Not reproduced on the audit guest: triggering requires real r6xx-class
Radeon hardware (the DMA copy engine) in a state where cross-ring
synchronization fails while a bo migration is in flight — the guest has no
Radeon hardware (env.txt). The defect is evident from source and from the
divergence with the checked sibling path; impact ceiling is silent
GPU-side data corruption of the migrated buffer object's own contents
(I:L, no kernel memory corruption).

## Why the code path is real (line-by-line trace)

1. Unprivileged GEM clients cause bo moves constantly (VRAM↔GTT migration,
   eviction under memory pressure): radeon_ttm.c `radeon_bo_move` →
   `radeon_move_blit` → radeon_ttm.c:302 `radeon_copy(rdev, ..., bo->resv)`
   → asic `copy.copy` = `r600_copy_dma` (registered e.g. radeon_asic.c for
   R600..NI DMA rings). `resv` is always the embedded `&bo->tbo.resv`
   (never NULL on this path — the Linux NULL-resv crash class does not
   apply here).
2. r600_dma.c:466 `radeon_sync_resv(rdev, &sync, resv, false);` — return
   value discarded. radeon_sync.c:106/119: on a non-radeon fence it does
   `dma_fence_wait()`; an interrupted wait returns an error and the sync is
   incomplete — ignored here.
3. r600_dma.c:467 `radeon_sync_rings(rdev, &sync, ring->idx);` — return
   value discarded. Failure modes (radeon_sync.c):
   - :153-156 `-EINVAL` "Syncing to a disabled ring!" — reachable when a
     source ring was disabled by an earlier failed ib test
     (radeon_ib.c:271 `ring->ready = false`) or GPU reset while fences on
     it are still pending;
   - :160-163 / :180-183 / :190-193 manual `radeon_fence_wait()` fallback
     errors;
   - :165-174 semaphore create / ring alloc failures.
   On the `-EINVAL` path the loop aborts *before* waiting on the remaining
   sync_to[] fences.
4. r600_dma.c:469-481, 490: the copy packets are emitted and
   `radeon_ring_unlock_commit()` fires regardless → the DMA copy is not
   ordered after the pending write on the other ring → the destination bo
   receives stale/partial source data, with a successfully-signaled fence.
   Silent, undetectable-from-userspace data corruption of the client's own
   buffer.
5. Contrast: radeon_ib.c:149-154 — the only other caller of
   `radeon_sync_rings()` — treats failure as fatal (unlock_undo + return).
   Upstream Linux additionally checks `radeon_sync_resv()` in this exact
   function (`if (r) goto error_free;`) and moved it before the ring lock.

## Why it is not the known DF-1942/DF-1943

DF-1942 = size_in_dw wrap (copy length math); DF-1943 = insufficient ring
dword reservation (`num_loops * 4 + 8`). This finding is the ignored error
returns of the two sync calls — orthogonal defect, orthogonal fix (which
DF-1943's reservation bump does not repair).

## Exploit chain

None: no kernel memory is corrupted; corruption is confined to the bo's own
GPU contents. A determined unprivileged user on degraded hardware could
corrupt its own buffers' contents (not another user's — the missing sync is
only w.r.t. fences on the *same* resv).

## Fix validation

Not possible on this guest (no hardware). fix.diff authored from the trace
above: check both returns; unwind (unlock_undo + sync_free) on failure;
move `radeon_sync_resv()` before `radeon_ring_lock()` so its sleeping fence
waits don't run under the global ring mutex — mirroring upstream.
fix_status: not_testable.

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