# PoC DF-1566: r600_dpm VCE/UVD vbios table count OOB

**Class:** Firmware-controlled index OOB
**Cited site:** `sys/dev/drm/radeon/r600_dpm.c:1104-1107,1117-1122,1157-1160,833-840`

## Reproduction status

HW/module gated — **cannot be live-triggered on the audit QEMU guest.**

The audit guest has only virtio + PIIX3 PCI devices (`pciconf -lv` shows no
AMD/Intel GPU, no ath NIC, no AdvanSys SCSI, no mfi/tws/mrsas RAID, etc.),
so the cited code path is not reachable at runtime on this guest.

The bug is **confirmed at the source level** by tracing the cited path:line
in `sys/dev/drm/radeon/r600_dpm.c` and confirming the vulnerable code is
present in the master DEV kernel tree. The `fix.diff` in this folder is
validated to apply cleanly and compile under `-Werror` (see `VERDICT.md`).

## Mechanism

r600_dpm iterates limits->numEntries VCE limit records dereferencing array->entries[0]+ucVCEClockInfoIndex*sizeof(VCEClockInfo). ucVCEClockInfoIndex is UCHAR 0..255 NEVER compared vs array->ucNumEntries. Same pattern VCE state loop 1117-1122, UVD loop 1157-1160. Generic table walkers r600_parse_clk_voltage_dep_table 833-840 loop ucNumEntries advancing pointer sizeof(record) each iter; nothing checks entries+ucNumEntries*sizeof(record) stays within bios+bios_size.

## Realistic impact ceiling (on suitable HW)

kernel heap OOB read via crafted VBIOS

## Fix

In r600_parse_extended_power_table, reject VCE/UVD clock-info arrays whose ucNumEntries is 0 or > 32.

See `fix.diff` for the git-apply-able patch.

## How to validate the fix

```sh
scp -F dfbsd-qemu/config fix.diff dfbsd:/root/DF-1566.diff
ssh -F dfbsd-qemu/config dfbsd 'cd /usr/src && patch -p1 --forward < /root/DF-1566.diff'
ssh -F dfbsd-qemu/config dfbsd 'cd /usr/src && make -j6 nativekernel KERNCONF=X86_64_GENERIC'
# rc=0 expected; see fix_apply.log + fix_build.log in this folder.
```
