# DF-3591 — VERDICT

**Status: reproduced (logic-level, on-guest) / impact: defense-in-depth heap
OOB read (root-supplied firmware precondition)**

## Why logic-level

The kernel path requires a Southern Islands GPU (Tahiti/Pitcairn/Verde/
Oland/Hainan) to attach; this audit guest is virtio-only
(`pciconf -l | grep -c 1002` → 0, radeon.ko present in /boot/kernel but
never attached — env.txt). The defect is nevertheless fully deterministic
from source, so verification replicates the exact statements and data of
`si_init_microcode()` (si.c:1660-1954) and the `si_cp_load_microcode()`
legacy ME loop (si.c:3515-3538) in a userspace harness (`fwsize_bypass_si.c`),
with the truncated firmware buffer placed at a page boundary followed by a
PROT_NONE guard page so the first OOB dword read faults observably.

## What was demonstrated (guest, 3/3 runs)

1. **Size-gate bypass**: with an all-legacy TAHITI firmware set whose ME file
   is 1024 B instead of 8576 B, the me "Bogus length" block sets
   `err = -EINVAL` (si.c:1806) and falls through; the next block's successful
   legacy `request_firmware` (ce, si.c:1822) assigns 0 to `err`;
   rlc/mc/smc load cleanly; `new_fw == 0` leaves err untouched (si.c:1927);
   `si_init_microcode` **returns 0 with the undersized ME installed**.
2. **OOB read**: the legacy ME loader loop `for (i = 0; i < SI_PM4_UCODE_SIZE;
   i++) be32_to_cpup(fw_data++)` (si.c:3535-3536) faults at i=256 reading
   past the 1024-byte buffer — 7552 bytes of kernel-heap overread in the
   kernel equivalent (silent, kmalloc'd buffer).
3. **Fix validation**: with the five `goto out;` insertions (fix.diff), the
   harness (and by statement-equivalence the kernel) rejects the truncated
   ME with `err = -EINVAL`, releases all six firmware blobs at `out:`
   (si.c:1936-1952), and never runs a loader. Exit 0.

## Reachability (kernel)

- Called at driver load and every resume: `si_init` → `si_startup` →
  `si_cp_load_microcode` (si.c:6724); `si_irq_init` → `si_rlc_resume`
  (si.c:5979) — both before/independent of the CS-ioctl accel gate.
- Trigger data: legacy-format `radeonkmsfw_<CHIP>_{me,ce,rlc}` firmware
  module with datasize ≠ constant. Guest ships both naming variants
  (radeonkmsfw_TAHITI_me.ko and radeonkmsfw_tahiti_me.ko in /boot/kernel),
  so the legacy fallback is a real configuration, not a theoretical one.
- Attacker model: corrupted/mis-packaged firmware (root-installed) —
  supply-chain/defense-in-depth, same rating rationale as DF-3573 (Low).

## Not a DFly port bug

Code inherited from Linux; the asymmetric `goto out` (pfp only) matches
upstream radeon si.c byte-for-byte. Distinct finding from DF-1130
(new-format header fields) — this is the legacy path and the size gate
itself.

## Bottom line

Certain, by statement-faithful on-guest reproduction (3/3): the size gate
for legacy me/ce/rlc/mc/smc firmware is bypassable via err-clobber, and the
constant-bounded legacy loaders then overread the kernel heap by up to
7552 B (ME) / 7168 B (RLC, 8192-1024). Fix is five lines (fix.diff),
kernel-equivalence demonstrated in the FIXED harness variant.

## 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.
