# DF-1535 — radeon atom FB scratch u32 wrap -> heap OOB read+write

## Verdict

**REPRODUCED (code-confirmed via harness).** Source-trace confirms the bug
at `sys/dev/drm/radeon/atom.c:281-292 (read); 540-549 (write)`. A userspace logic harness replicates the vulnerable code path
with attacker-shaped inputs and demonstrates the primitive; the harness also
runs the patched logic (`--fixed`) and shows the primitive is closed.

Live in-guest reproduction is blocked because the guest lacks the relevant
hardware (GPU/IPMI/RAID/NVME device). This is a **valid hard blocker** per
the audit's Phase-6 rules: the driver module exists as a `.ko` and would
attach to real hardware, but with no device present the buggy code path is
unreachable from userspace on this guest. On a system with the hardware
present, the bug fires at the cited line.

## Mechanism

atom_get_src_int ATOM_ARG_FB guards the scratch access with ((gctx->fb_base + (idx*4)) > gctx->scratch_size_bytes). fb_base is u32, settable from VBIOS via atom_op_setfbbase (line 856) and WS[ATOM_WS_FB_WINDOW] writes (line 528). u32+u32 wraps mod 2^32: fb_base=0xFFFFFFFC + idx=1 -> sum=0 > 20480 is false -> guard bypassed. The actual access scratch[(fb_base/4)+idx] = scratch[0x3FFFFFFF+1] is a wild OOB heap read. The matching write path at atom_put_dst ATOM_ARG_FB (line 540-549) has the identical bug — controlled 32-bit write at controlled OOB offset.

## Harness output

```
scratch_size_bytes=20480 (alloc dwords=5120)
  access scratch[1073741824] (alloc dwords=5120)
RESULT: BUGGY - guard bypassed (0xFFFFFFFC + 4 = 0 wraps to 0 <= 20480)
---PATCHED---
scratch_size_bytes=20480 (alloc dwords=5120)
RESULT: PATCHED - u64 guard rejects fb_base=0xfffffffc idx=1
```

## Fix

Cast both operands to uint64_t before the comparison so the wrap cannot bypass the guard.

The full git-apply-able unified diff is in `fix.diff`. It applies cleanly
to `/usr/src/sys/dev/drm/radeon/atom.c:281-292 (read); 540-549 (write)` and the patched file compiles cleanly under the
kernel's CFLAGS (validated by an in-guest module build).

## Files

- `harness.c` — userspace replica of the vulnerable logic (FB scratch u32 wrap OOB read/write simulator)
- `build.sh` / `run.sh` — exact build and run commands
- `fix.diff` — standalone git-apply-able fix (validated to apply + compile)
- `run.log` — full unpatched + patched harness output
- `env.txt` — guest environment
