β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-4889

iir_pci_attach drives the i960 MPR register layout at fixed offsets 0x2c-0x3fc0 with no BAR0 size validation β€” short BAR0 => MMIO reads/writes past the resource mapping (panic or up to ~12KB wild zero-write) before the magic read-back can reject the card

Summary

BAR0 mapped then immediately driven at fixed offsets (magic at +0x1000, a 0x2FC0-byte zero-fill of 0x1000-0x3FC0, queue regs, doorbells) with no rman_get_size check against GDT_PCINEW_SZ (0x4000) - a short BAR makes every access past the mapping: page fault, or wild kernel-memory zero-write if the neighbor page is mapped (the magic write lands BEFORE the read-back check, so the zero-fill runs before the card is rejected). Crafted/broken PCIe device trigger band (same as DF-4172). Size-check fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4889 Β· 5 files
FileTypeDescriptionSize
README.md β€” 1.1 KB ↓ raw
VERDICT.md β€” 2.9 KB ↓ raw
fix.diff β€” 687 B view raw
verdict.json β€” 2.4 KB view raw
env.txt β€” 636 B view raw

DF-4889

iir_pci_attach maps BAR0 and immediately drives the i960 MPR register layout at fixed offsets 0x002c..0x3FC0 (magic write/read at 0x1000 at iir_pci.c:223-231, 0x2FC0-byte region clear at iir_pci.c:232-233) without ever checking rman_get_size(io) >= GDT_PCINEW_SZ (0x4000). A card with the probed IDs (0x8086:0x0600 / ICP 0x1119 range) but a short BAR0 β†’ MMIO reads/writes past the resource mapping: panic, or a bulk zero-write of up to ~12KB into kernel memory following the mapping β€” before the magic read-back check can reject the card.

Hardware-gated finding β€” PoC not runnable on the audit guest (no such controller; pciconf -lv shows no 0x8086:0x0600 / 0x1119 device β€” see env.txt). Driver is compiled into the guest kernel (kldstat -v β†’ 100 pci/iir), so the code path is live wherever the card exists.

Status: untested per the DF-4175 hardware-gated convention; the missing check is certain by inspection. Source citations in the pass-2 result block; full narrative in VERDICT.md; fix in fix.diff (size check right after bus_alloc_resource_any).

VERDICT.md
↓ download raw

DF-4889 β€” iir_pci_attach uses fixed DPMEM offsets up to 0x3FC0 with no BAR0 size validation

Status: untested (hardware-gated β€” no matching controller on the audit guest; code gap certain by inspection). Severity: Low. Class: improper input validation β†’ out-of-bounds MMIO access (CWE-125/CWE-787, device-memory variant).

Root cause (sys/dev/raid/iir/iir_pci.c)

iir_pci_attach maps BAR0 with bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE) (iir_pci.c:186-192) and immediately drives the i960 "MPR" register layout at fixed offsets, never comparing the mapped extent (rman_get_size(io)) against the layout size GDT_PCINEW_SZ (0x4000, iir.h:101):

  • first access: bus_space_write_4(..., GDT_MPR_IC, GDT_MPR_MAGIC) at offset 0x1000 (iir_pci.c:223-224) followed by a read-back (iir_pci.c:225-226);
  • interface-area clear: bus_space_set_region_4(..., GDT_I960_SZ, 0, GDT_MPR_SZ >> 2) β€” 0xBF0 words covering 0x1000..0x3FC0 (iir_pci.c:232-233);
  • status/command doorbells at 0x2c/0x34, queue regs up to GDT_MPR_IC + GDT_S_INFO + 12 β‰ˆ 0x1013 (iir_pci.c:236-301).

A card that enumerates with the probed IDs (Intel 0x8086:0x0600, or ICP vortex 0x1119:0x0100-0x02ff / 0x0300 β€” iir_pci.c:160-171) but declares BAR0 smaller than 0x4000 (a broken card, or a deliberately crafted PCIe device) causes every access past the mapped extent to land on the virtual page(s) after the resource mapping: unmapped β†’ kernel page-fault panic; or mapped for another purpose β†’ wild kernel-memory reads/writes at fixed offsets past the mapping (the 0x1000..0x3FC0 region clear at iir_pci.c:232-233 is a bulk write of zeros over up to 12KB past a short BAR).

The magic read-back at iir_pci.c:225-231 catches most broken cards if the first write/read at 0x1000 happens to fault or read back garbage β€” but with a short BAR whose following virtual page is writable kernel memory, the write at :223 already corrupted that page before the check, and the read-back may return exactly the magic just written, passing the check and proceeding to the 0x2FC0-byte zero-clear.

Threat model

Attacker must control PCIe-enumerated hardware (evil device, DMA-attached card, or a misbehaving/counterfeit RAID card) β€” a physical/supply-chain trigger, hence Low. No path from an unprivileged user. Same trigger band as sibling hardware-gated raid findings (DF-4172 etc.).

Fix

See fix.diff: require rman_get_size(io) >= GDT_PCINEW_SZ right after mapping (and, with DF-4888's fix, the BAR is properly released when the check fails).

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.

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

fix.diff authored post-verification against the read-only sys/ tree; not build-validated (no controller hardware)

findings/poc/DF-4889/fix.diff
↓ fix.diffper-fix-DF-4889

Confirmed kernel references

Detail

Evidence (decisive lines)

findings/poc/DF-4889/VERDICT.md (offset math incl. 0x1000..0x3FC0 region clear); findings/poc/DF-4889/fix.diff; guest hardware-absence proof in findings/poc/DF-4889/env.txt

PoC changes

no runnable PoC (hardware absent); evidence pack documents the offset math and fix

Verified recommended fix

Reject attach when rman_get_size(io) < GDT_PCINEW_SZ immediately after mapping BAR0 (see fix.diff)

Verdict

Source-verified, hardware-gated: iir_pci_attach never validates rman_get_size(io) against the MPR layout size GDT_PCINEW_SZ (0x4000) yet touches fixed offsets 0x2c..0x3fc0 - the very first access (GDT_MPR_MAGIC write/read at offset 0x1000, iir_pci.c:223-231) and the GDT_MPR_SZ region clear at iir_pci.c:232-233 run past a short BAR. The write at :223 precedes the read-back check, so a writable page following a short mapping is corrupted before the card is rejected. Not runnable on the audit guest: no matching controller in pciconf (env.txt); driver compiled into the kernel (kldstat -v: '100 pci/iir').