# DF-5431 — VERDICT

## 1. Reproduced? YES — real kernel-boot panic

run.log:87-89 (kernel v6.5.0.1712.g89e6a #1 Mon Jun 29 clean-install build):

```
ACPI MADT: IOAPIC addr 0xfec00000, apic id 0, gsi base 0
ACPI MADT: IOAPIC addr 0xfec88000, apic id 1, gsi base 0
panic: ioapic_add: overlapped gsi, base 0 npin 1, hit base 0, npin 24
```

Boot completed the entire LAPIC/SMP stage (`ACPI CPUS = 2`, AP started) and
panicked in `ioapic_config` at SI_BOOT2_IOAPIC.

## 2. Why it is real (path:line)

* Probe side accepts the table: `madt_ioapic_probe_callback`
  (acpi_madt.c:615-633) checks only `Address != 0` (:619-622) and
  `Id != APICID_MAX` (:623-628); `madt_ioapic_probe` (:652-662) adds only
  `ioapic_cnt != 0` and "some entry has GlobalIrqBase 0". The crafted table
  satisfies all of these.
* Enumerate side: `madt_ioapic_enum_callback` (acpi_madt.c:728-738) calls
  `ioapic_map`/`ioapic_read`/`ioapic_add` with the raw firmware fields.
  `ioapic_add()` panics on GSI overlap (ioapic.c:233-243) and duplicate
  address (ioapic.c:244-245); `ioapic_config` panics above 16 IOAPICs
  (ioapic.c:136-138). All three are `panic()`, present in production
  kernels — this does NOT depend on INVARIANTS (unlike DF-5430).

Two more members of the same class demonstrated by inspection (not booted):
two identical IO_APIC addresses → "duplicated addr" panic; 17 IO_APIC
entries pass probe (count never capped) → "more than 16 I/O APIC" panic.

Related secondary robustness gap noted (not separately booted):
`GlobalIrqBase` is a raw UINT32 truncated to `int gsi_base` in
`ioapic_add(void *, int, int)` — bases ≥ 2^31 overflow `gsi_end`
(ioapic.c:231), which can defeat the overlap check arithmetic.

## 3. Threat model

Same as DF-5430: firmware/bootloader-controlled ACPI tables
(`hint.acpi.0.rsdp` vector demonstrated); no unprivileged in-guest path.
Deterministic boot-time panic = DoS, unconditional on kernel build.
Low severity, matching the accepted DF-1034/DF-5339 bar.

## 4. Exploit chain

None — controlled panic() before any memory unsafety.

## 5. Fix

`fix.diff` adds probe-side topology sanity within acpi_madt.c: duplicate
IOAPIC address, duplicate GSI base (two IOAPICs sharing a base always
overlap, since every IOAPIC has ≥1 pin), and a 16-entry cap — each returns
EINVAL so the enumerator is rejected gracefully and ioapic_config falls
back. Full npin-aware overlap detection needs MMIO reads at probe time and
belongs with ioapic.c's panic→rejection conversion (noted in the finding).
`git apply --check` passes. Not kernel-build-validated this run (single
mandatory build slot spent on DF-5432; this is a Low boot panic — DF-5339
precedent).

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