# VERDICT -- DF-1391

## Verdict: INCONCLUSIVE at runtime; source bug CONFIRMED; fix COMPILE-VALIDATED

**Citations confirmed:**
  - sys/dev/drm/radeon/rv6xx_dpm.c:1889
  - sys/dev/drm/radeon/rv6xx_dpm.c:1896
  - sys/dev/drm/radeon/rv6xx_dpm.c:1901
  - sys/dev/drm/radeon/rv6xx_dpm.c:1916
  - sys/dev/drm/radeon/rv6xx_dpm.c:1918

### Is the bug real? -- YES (source trace)

rv6xx_parse_power_table() computes power_state/non_clock_info/clock_info from
    VBIOS u16/u8 fields (usStateArrayOffset, usNonClockInfoArrayOffset,
usClockInfoArrayOffset, ucStateEntrySize, ucNonClockSize, ucClockInfoSize,
ucNonClockStateIndex, idx[j]) with NO bounds check vs the BIOS allocation.
atom_context has no bios_size field, so the parser cannot detect OOB. Crafted
VBIOS -> OOB heap read. Sibling of DF-1333 (rv770 same pattern).

### Can it be reproduced on this guest? -- NO (hardware-gated)

No AMD GPU in PCI list; radeon.ko not loaded.

The radeon driver is a loadable module only (NOT in `X86_64_GENERIC`), is not loaded, and cannot be `kldload`'d by an unprivileged user (kldload is root-only). Even loaded, it would not attach without the hardware.
Therefore the vulnerable code is unreachable at runtime here. Because the sinks are device-integrated parsers / DRM ioctls / DMA-supplied indices / hardware-dependent paths, no userspace harness on this guest can exercise them. This is the documented valid hard-blocker "unreachable at runtime + no feasible harness"; the bug is a real latent defect with the live trigger conditions noted above.

### No escalation chain (and why that is correct here)
There is no memory-corruption primitive to escalate on this guest: the corruption sinks live entirely inside the not-attached driver behind hardware that is absent. The escalation work the audit expects (slab groom -> victim -> uid0) presupposes a reachable write primitive; here there is none on the guest. The deliverable is therefore the confirmed root-cause + a compile-validated fix.

### Fix (fix.diff) -- authored and COMPILE-VALIDATED
Three-file change: (1) added `uint32_t bios_size` to struct radeon_device
(radeon.h); (2) populated it at every rdev->bios allocation site in
radeon_bios.c (5 sites); (3) added bounds checks against rdev->bios_size at
every pointer arithmetic in rv6xx_parse_power_table (state, non_clock_info,
idx array, clock_info) with an `inval:` error path. (supersedes the finding
proposal which suggested adding bios_size to atom_context; this is equivalent
but keeps the change inside the radeon driver.)

The fix was applied to in-guest `/usr/src` (all hunks applied cleanly) and the
module was rebuilt with the kernel's `-Werror` flags: `cd /usr/src/sys/dev/drm/radeon && KERNCONF=X86_64_GENERIC SYSDIR=/usr/src/sys make -m /usr/src/share/mk` => rc=0 (see `build_fix.log`). No warnings or errors in the patched translation unit. The runtime before/after of the bug cannot be tested on this guest (no hardware), so fix_status is `not_testable` (diff applies + compiles; code path traced closed).

### Why not `not_reproduced` (false-positive)?
This is NOT a false positive. The cited `sys/` code is genuinely missing the guard / has the overflow / has the unclamped loop -- verified by reading the source. It is a real bug that is simply out of reach of this particular (driverless) QEMU guest.
