# DF-3854 — VERDICT

## Status: `inconclusive` (deref order proven by trace + harness SIGSEGV; kernel run hardware-gated, no radeon GPU on audit guest)

## Full narrative

### The bug

`radeon_combios_external_tmds_setup()` IGP branch
(`sys/dev/drm/radeon/radeon_combios.c:2888-2891`):

```c
if (rdev->flags & RADEON_IS_IGP) {
        offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE);
        rev = RBIOS8(offset);          /* <-- deref BEFORE the check */
        if (offset) {
                rev = RBIOS8(offset);
```

`combios_get_table_offset()` returns 0 when `rdev->bios == NULL`
(`radeon_combios.c:131`). `RBIOS8(0)` is `rdev->bios[0]` (radeon.h:2686).
So when the BIOS is absent the function reads address 0 before testing the
offset it just got. The read at :2890 is dead code (re-read at :2892 inside
the guard) — a pure check-order slip, present verbatim upstream
(Linux v5.10 radeon_combios.c:2900) — inherited, not a port regression.

### Why `bios == NULL` is a live state on exactly these chips

`r100_init()` (`sys/dev/drm/radeon/r100.c:4056-4059`):

```c
if (!radeon_get_bios(rdev)) {
        if (ASIC_IS_AVIVO(rdev))    /* only AVIVO aborts */
                return -EINVAL;
}
... radeon_combios_init(rdev);      /* combios-era chips continue with bios==NULL */
```

RS100–RS480 IGP chipsets are pre-AVIVO, combios-only. A board whose ROM
cannot be read (BAR unavailable, shadow disabled, VFCT absent — occurs on
real hardware) leaves `rdev->bios == NULL` and the driver loads in
table-fallback mode.

### Reaching the encoder

With no BIOS, connector info comes from
`radeon_get_legacy_connector_info_from_table()` (radeon_combios.c:1447+),
selected by the `radeon.connector_table=` module parameter or the PPC
PowerMac tables (:1455-1520). CT_POWERBOOK_EXTERNAL / CT_MINI_EXTERNAL /
CT_MAC_X800 / CT_MAC_G5_9600 create DFP2 (external TMDS) encoders. The first
mode set on such an encoder runs `radeon_legacy_tmds_ext_mode_set()` →
`radeon_combios_external_tmds_setup()` (`radeon_legacy_encoders.c:985`) →
NULL deref → kernel page fault at address 0 → panic.

Impact ceiling: local boot/mode-set denial of service on misconfigured IGP
hardware; requires root-set module param on x86 (or a PowerMac with a dead
ROM). Severity Low.

### Fix

`fix.diff` removes the premature read (one line). Apply-verified
(`fix_apply.log`); runtime fix validation not possible (no hardware):
`fix_status = not_testable`.

## kernel_refs
- sys/dev/drm/radeon/radeon_combios.c:2888-2891 (bug)
- sys/dev/drm/radeon/radeon_combios.c:124-132 (offset 0 on NULL bios)
- sys/dev/drm/radeon/radeon.h:2686 (RBIOS8)
- sys/dev/drm/radeon/r100.c:4056-4059 (bios==NULL continues, pre-AVIVO)
- sys/dev/drm/radeon/radeon_legacy_encoders.c:985 (caller)

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
