# DF-4278 evidence pack — R300_ZB_ZPASS_ADDR unvalidated reloc offset → GPU OOB write

- **Finding:** `sys/dev/drm/radeon/r300.c:1073-1082` (`case R300_ZB_ZPASS_ADDR`)
- **Class:** CS-checker bypass → GPU-side out-of-bounds write (cross-BO corruption)
- **Reach:** unprivileged local user with DRM render access → `DRM_IOCTL_RADEON_CS`
- **Verdict:** `untested` — hardware-gated (no r300-class GPU on the audit guest; see `env.txt`)

## What this pack contains

| file | what |
|---|---|
| `zpass_oob.c` | pure-ioctl trigger: 4-dword CS setting ZB_ZPASS_ADDR = bo_gpu_offset + 0xF0000000 |
| `build.sh` | `cc -O2 -o zpass_oob zpass_oob.c` (needs a DragonFly system with radeon headers) |
| `run.sh` | runs the trigger, expects `/dev/dri/card0` backed by r300..rv570 hw |
| `env.txt` | guest uname + proof no ATI/radeon device exists on the audit guest |
| `fix.diff` | git-apply-able one-hunk fix adding the missing bo-size validation |
| `manifest.json` / `verdict.json` | machine-readable verdict (status `untested`) |

## How to reproduce (on real hardware)

1. Boot DragonFly with an r300/r350/rv350/rv370/rv380/rv515/rv530/rv570/rv580 GPU
   (PCI vendor 0x1002) and `radeon` KMS active (`kldload radeonkms` / kernel driver).
2. `./build.sh && ./run.sh`
3. **Vulnerable kernel:** exit 0, "CS accepted" — the checker patched
   `ib[1] = 0xF0000000 + gpu_offset` with no bound check; any subsequent draw
   with the occlusion count enabled increments memory at that GPU VA.
4. **Patched kernel (fix.diff):** exit 2, `-EINVAL`.

## Why this is a real gap (static proof, path:line)

The checker's own discipline for every other GPU-address register:

| register | tracked? | validated where |
|---|---|---|
| `R300_RB3D_COLOROFFSET0..3` (r300.c:654) | `track->cb[i]` | r100.c:2264 `pitch*cpp*maxy + offset <= bo_size` |
| `R300_ZB_DEPTHOFFSET` (r300.c:671) | `track->zb` | r100.c:2283 |
| `R300_RB3D_AARESOLVE_OFFSET` (r300.c:1115) | `track->aa` | r100.c:2303 |
| `R300_TX_OFFSET_0..15` (r300.c:684) | `track->textures[i]` | r100.c texture check (`size > bo_size`) |
| **`R300_ZB_ZPASS_ADDR` (r300.c:1073)** | **nothing** | **nowhere** |

The r100 twin (`RADEON_RB3D_ZPASS_ADDR`, r100.c:1778) has the identical gap,
which shows the omission is systemic, not an intentional exception.
