# DF-2495 — inflated `rdp->total_disks` (LSI v2 `disk_count`) drives a 1912-byte kernel-heap OOB write out of `ata_raid_status()` (IOCATARAIDSTATUS); `ata_raid_create()` likewise loops `config->total_disks` unchecked

**File:** `sys/dev/disk/nata/ata-raid.c:1013-1025, 1051-1151, 2856` · **Severity:** High (filed) · **Bucket:** memcorrupt · **Confidence:** certain
**Status: reproduced on the QEMU guest** (production parse + production
`ata_raid_status()` through the rig; the real-kernel `/dev/ata` ioctl arm also
executed — see run.log and VERDICT.md for the honest impact ceiling: `/dev/ata`
is 0600 root-only on this tree, so the ioctl trigger is root-gated).

## Build (guest, root)

```
cd /root/dfrig && ./build.sh      # dfrig_ata.ko (production ata-raid.c compiled in)
cc -O2 -Wall -o df2495_status df2495_status.c
```

## Run

```
sh run.sh                         # rig test 3 + real-kernel arm (test 7 + ioctl)
```

## Expected (see run.log)

* rig test 3: production parse sets `rdp->total_disks=255` from crafted
  `configs[0].raid.disk_count`; production `ata_raid_status()` then writes
  `status->disks[0..254]` — 2064 bytes into/through a 152-byte buffer
  (the exact size the generic ioctl layer kmallocs for IOCATARAIDSTATUS):
  **1912 bytes past the allocation**, smashing 12/24 marker guard chunks
  with the production `{state=0, lun=-1}` pattern.
* real-kernel arm: rig test 7 installs the inflated array into the REAL
  `ata_raid_arrays[0]`; `./df2495_status 0` (root, real syscall) returns
  `total_disks=255` — the real kernel wrote the same 1912 OOB bytes.

## Fix

`fix.diff`: reject `disk_count > MAX_DISKS` at the LSI v2 parse, bound
`rdp->total_disks` in `ata_raid_status()`, and reject out-of-range
`config->total_disks` in `ata_raid_create()`.
Validated on a rebuilt kernel (fix_build.log / fix_run.log).
