# DF-3914 — VERDICT

**Status:** not_reproduced (kernel path hardware-gated on this guest) /
OOB-write primitive proven at object level.
**Confidence:** certain (source-level; the missing bound is unconditional).

## What was verified and how

1. **Root cause, line by line** (`sys/dev/raid/mpr/mpr_mapping.c`):
   - `:2843` `et_entry->num_slots = le16toh(event_data->NumSlots);` — sole
     validation of the firmware-supplied slot count is `!= 0` at `:2760`.
   - `:1241-1243` (SAS) and `:1392-1394` (PCIe): direct-attached branch sets
     `et_entry->start_index = sc->num_rsvd_entries` with **no** relation
     established between `num_slots` and the table size.
   - `:1292-1299` (SAS) / `:1443-1450` (PCIe): reservation loop writes
     `num_slots` entries from `map_idx` — the unguarded sink.
   - `:2140-2141` allocation is `max_devices * sizeof(dev_mapping_table)`
     (32 B/entry); `:2565` `max_devices = MaxTargets + MaxVolumes` (u16).
   - Bounded contrast: the expander branch goes through
     `_mapping_find_enc_map_space()` `:979-993`, which only reports space
     found *within* `end_of_table <= max_devices`; the DA branch bypasses it.
   - `grep -n num_slots` over the whole file confirms **no** clamp between
     `:2843` and the two loops.

2. **Distinctness from the known findings** (pass-2 mandate):
   - DF-1282 = `_mapping_process_dpm_pg0` `mapping_table[dev_idx]` write from
     DPM page0 ingestion (`:2327/:2358`), including the `dev_idx+num_slots`
     loop at `:2328`. DF-3914 is the **event-driven** reservation path — the
     overflow source is `NumSlots` from an Enclosure Status Change event, not
     a DPM `DeviceIndex`, and it fires on a *live* topo event with a clean DPM.
   - DF-1283 = `start_index + slot - start_slot` unsigned underflow in
     `_mapping_add_new_device`/`_mapping_add_new_pcie_device` (`:1637/:1894`).
     DF-3914 is in `_mapping_get_dev_info`/`_mapping_get_pcie_dev_info`, no
     slot subtraction involved.

3. **Hardware gate** (why the kernel path is not runtime-reachable here):
   guest `pciconf -l` (env.txt) lists only i440FX/PIIX/virtio-vga/virtio-net/
   virtio-blk devices — no `vendor 0x1000` SAS controller, so `mpr_attach()`
   never executes. Same gate already proven for DF-1282/DF-3800.

4. **Object-level proof** (guest, `run.log` + `run.2.log`): harness replicates
   `struct dev_mapping_table` (32 B, `mprvar.h:113`), allocates
   `max_devices=264` entries plus a 4096-entry canary guard, then runs the
   verbatim `:1292-1299` loop with `NumSlots=2048`, `num_rsvd=1`:
   1785 entries (57,120 bytes) past the 8,448-byte allocation receive
   `physical_id = 0x5141524153534141` at stride 32 — i.e. a
   firmware-controlled 8-byte value per 32-byte slot, exactly what the kernel
   loop writes past its slab object. Second run reproduced identically.

## Exploit chain (why this matters beyond a panic)

The written `physical_id` is the enclosure's 64-bit SAS address — fully chosen
by the (malicious) firmware/enclosure. A ~2 MB linear overflow with a
controlled qword every 32 bytes across adjacent kmalloc zones is a classic
slab-corruption primitive: overflow into a neighboring object with function
pointer / list pointers (e.g. neighboring driver structures) → control flow.
Not developed further: hardware-gated (no HBA to carry the malicious event),
same trust boundary as DF-1282/DF-1283.

## Fix validation

`fix.diff` adds the missing bound on both DA paths, mirroring the existing
"no space" handling (mark add entries processed; stop mapping this event).
- Applied cleanly (`patch -p1`) to the guest `/usr/src` copy together with
  DF-3915's diff (`git apply --check` passes on the pristine tree too).
- `make nativekernel KERNCONF=X86_64_GENERIC`: `mpr_mapping.c` recompiled
  with `-Werror` in both the static-kernel and KLD_MODULE passes — no
  diagnostics (`fix_build.log`).
- `fix_status: not_testable` for *runtime* validation: the fixed path needs an
  mpr(4) controller emitting the malicious enclosure event; no such hardware
  on the guest.

## Bottom line

Real, source-certain, firmware-fed heap OOB write (CWE-787) with a controlled
8-byte-in-32 stride, distinct from DF-1282/DF-1283; primitive proven at object
level on the audit guest; kernel path hardware-gated; fix compiles clean.

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