# DF-1250 — radeon hardcoded-EDID parser over-reads rdev->bios

## Verdict (one line)
**CONFIRMED REAL (source trace + harness primitive), NOT reproduced on audit guest (no AMD/ATI radeon GPU).**

## Finding
`sys/dev/drm/radeon/radeon_combios.c:radeon_combios_check_hardcoded_edid()`
computes the EDID copy size from an attacker-controlled BIOS byte
`raw[0x7e]` and `memcpy`s that many bytes out of the BIOS allocation
**before** any validity check, so a malicious Video BIOS whose image is
small (as little as 512 bytes via `radeon_read_platform_bios`) but whose
`raw[0x7e] = 0xff` causes a ~32 KB over-read of adjacent kernel heap.

## Mechanism (path:line)
1. `radeon_combios.c:373` — `raw = rdev->bios + edid_info;`
2. `radeon_combios.c:374` — `size = EDID_LENGTH * (raw[0x7e] + 1);`
   `raw[0x7e]` ∈ [0,255] ⇒ `size` ∈ [128, 32768].
3. `radeon_combios.c:375` — `edid = kmalloc(size, ...);`
4. `radeon_combios.c:379` — `memcpy(edid, raw, size);`  ← over-read here.
5. `radeon_combios.c:381` — `if (!drm_edid_is_valid(edid))` is checked
   **only after** the `memcpy`, so the leak is unconditional.
6. The BIOS allocation can be as small as 512 bytes:
   `sys/dev/drm/radeon/radeon_bios.c:radeon_read_platform_bios` does
   `size = bios[2] * 512` (`radeon_bios.c:146`) and `kmemdup(bios, size,...)`
   (`radeon_bios.c:153`). `raw[0x7e]=0xff` ⇒ `size=32768` ⇒ ~32 KB of
   adjacent heap leaked.

## Why not reproduced on the audit guest
`radeon` is a loadable DRM module, **not in GENERIC**, and the guest has no
AMD/ATI GPU. The hardcoded-EDID table is parsed during GPU attach from the
card's Video BIOS, which is not present. The realistic trigger is a
malicious GPU Video BIOS (e.g. a hotplug PCIe card with a crafted ROM) — a
legitimate "malicious peripheral firmware" threat, not exercisable here.

## Primitive proof (harness)
`harness.c` models a 512-byte BIOS slab, sets `raw[0x7e]=0xff`, computes
`size` exactly as the kernel does, and reports the over-read:
```
bios allocation = 512 bytes
raw[0x7e] = 0xff
computed size (radeon_combios.c:374) = 32768 bytes
over-read past BIOS allocation: 32320 bytes of adjacent kernel heap
PRIMITIVE CONFIRMED: memcpy(edid, raw, 32768) reads 32320 bytes past a 512-byte BIOS slab.
```

## Fix
`fix.diff` (3 files):
- `radeon.h`: add `uint32_t bios_length;` (allocation size of `*bios`).
- `radeon_bios.c`: set `rdev->bios_length = size;` at every BIOS alloc
  site (5 sites).
- `radeon_combios.c`: before dereferencing `raw[0x7e]` and before the
  `memcpy`, verify `edid_info + 0x7f` and `edid_info + size` are within
  `rdev->bios_length`; otherwise return false.
**Validated: builds cleanly into `radeon.ko` with `-Werror`.** (DF-1251's
fix shares the same `bios_length` infrastructure.)

## Reproduce
```
ssh dfbsd-maxx; cd poc/DF-1250 && cc -O2 -Wall -o harness harness.c && ./harness
```
