# DF-2498 VERDICT — reproduced (heap OOB write past disks[15] and past the allocation; ~3MB OOB read)

## Bottom line

CONFIRMED, both halves of the finding. In
`ata_raid_intel_read_meta()` (`sys/dev/disk/nata/ata-raid.c`) the
mapping pointer, the array disk count and every disk-table index come
straight from crafted on-disk metadata with no bounds checks:

1. **OOB WRITE (primary)** — `raid->total_disks = map->total_disks`
   (:2230) taken verbatim (crafted 60; `MAX_DISKS` is 16) makes the
   fill loop (:2243-2263) write `raid->disks[16..59]`:
   44 entries past `disks[]` **in-object** (smashing
   toggle/rebuild_lba/lock/disk/devstat/cdev/pid of the live
   `struct ar_softc`, read back showing the crafted
   serial/sectors/flags pattern) and **11/11 entries
   (`disks[49..59]`) past the end of the 2424-byte kmalloc object**
   (crafted `0x00C0FFEE` sector markers read back at victim
   +2488..+2992; an adjacent 0x11-filled guard chunk of the same size
   class was smashed across 324/2424 bytes with the same pattern —
   the writes demonstrably crossed into a neighbor allocation). The
   serial-match loop (:2266-2283) adds further OOB `.dev/.flags`
   writes for the same entries. With `map->total_disks=255` (also
   unvalidated) the write range extends to ~+13.3KB past the object
   (arithmetic shown in the rig output); 60 already crosses the
   allocation.
2. **OOB READ (~3.0 MB)** — `disk_idx = map->disk_idx[disk] & 0xffff`
   (:2244) with `disk_idx=0xffff` makes `meta->disk[disk_idx]` read
   at `meta + 216 + 48*65535` = **meta+3145996**, ~3.0MB past the
   1536-byte metadata allocation (:2247-2262 bcopy 16 serial bytes +
   sectors + flags from there). Proven executed via a mixed-index
   craft (in-bounds marker honored, wild sibling reads performed);
   the bytes at that distance happened to be zeroed heap, so nothing
   faulted — the kernel direct-maps the kmem region, making the
   "panic" variant heap-layout-dependent rather than deterministic.
   The `meta->total_disks > ~21 → map pointer past the allocation`
   clause of the finding is the same missing check (covered by the
   fix); on the guest a `map`-past-buffer read lands in mapped KVA.

No userland leak path was demonstrated (the copied serials are not
exposed by IOCATARAIDSTATUS), so the demonstrated impact is silent
kernel-heap corruption — same profile as DF-2494 in this parser
family. The primitive is strong: attacker-chosen 16-byte patterns
written at 48-byte stride up to ~13KB past a heap object, plus
arbitrary-offset (16-bit index × 48) heap reads into the array state.

## Threat model

Crafted Intel MatrixRAID metadata ("Intel Raid ISM Cfg Sig. ", valid
checksum — computed by the rig exactly as the parser requires) on a
disk attached to an nata channel; parsed at boot/attach with no
privileges. The rig drives the identical production parser with the
identical crafted image (only `ata_queue_request` interposed to serve
the sector).

## Fix validation (single-fix kernel)

`fix.diff` adds three validations to the parser: `meta->total_disks`
in `[1, MAX_DISKS]` before computing `map`; `map->total_disks` in
`[1, MAX_DISKS]` before use (frees the slot and exits like the
unknown-type path); `disk_idx >= meta->total_disks` skipped. On the
fixed kernel (`fix_validation.log`): the crafted `map->total_disks=60`
parse is rejected (`ataraid: Intel invalid map total_disks 60`, rc=0,
array NULL, guards untouched); the `0xffff` disk_idx entries are
skipped (disks[1..15] remain zero, no wild read, no fault); the
in-bounds marker still works. Guest stayed up through the whole
battery.

## Kernel references

- `sys/dev/disk/nata/ata-raid.c:2165` — `map = &meta->disk[meta->total_disks]` (u_int8_t, unvalidated)
- `sys/dev/disk/nata/ata-raid.c:2190,2203` — `raid->width = map->total_disks`
- `sys/dev/disk/nata/ata-raid.c:2230` — `raid->total_disks = map->total_disks` (up to 255 vs MAX_DISKS 16)
- `sys/dev/disk/nata/ata-raid.c:2243-2263` — OOB write loop + `meta->disk[disk_idx]` wild read
- `sys/dev/disk/nata/ata-raid.c:2266-2283` — serial-match loop adding OOB `.dev/.flags` writes
- `sys/dev/disk/nata/ata-raid.h:295-354` — `struct intel_raid_conf` (1536-byte kmalloc, 48-byte disk entries), `struct intel_raid_mapping`

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