# DF-1175 — Intel/nVidia RAID metadata parser OOB read

## Finding

Two checksum loops in `sys/dev/disk/nata/ata-raid.c` use a disk-controlled
`u_int32_t config_size` field as their iteration bound, with only a small
fixed-size `kmalloc` buffer to read into. A crafted metadata block with a
large `config_size` causes the loop to read far past the allocation into
unmapped kernel memory, producing a page-fault panic (DoS) — and for small
over-reads, an info leak of slab-trailing kernel heap bytes.

### Intel parser (`ata_raid_intel_read_meta`, line 2120)

```c
/* ata-raid.c:2132 */  meta = kmalloc(1536, M_AR, M_WAITOK | M_ZERO);
...
/* ata-raid.c:2145 */  if (strncmp(meta->intel_id, INTEL_MAGIC, ...)) goto out;
...
/* ata-raid.c:2151-2154 */
for (checksum = 0, ptr = (u_int32_t *)meta, count = 0;
     count < (meta->config_size / sizeof(u_int32_t)); count++)
    checksum += *ptr++;
```

`config_size` is a `u_int32_t` from disk (`ata-raid.h:307`). The buffer is
**1536 bytes** but the loop will read up to `config_size` bytes
(`config_size/4` u32 words). A `config_size` of 0x10000 → 64000-byte OOB read.

### nVidia parser (`ata_raid_nvidia_read_meta`, line 3018)

```c
/* ata-raid.c:3028 */  meta = kmalloc(sizeof(struct nvidia_raid_conf), ...);
...
/* ata-raid.c:3039 */  if (strncmp(meta->nvidia_id, NV_MAGIC, ...)) goto out;
...
/* ata-raid.c:3046-3048 */
for (checksum = 0, ptr = (u_int32_t*)meta, count = 0;
     count < meta->config_size; count++)
    checksum += *ptr++;
```

`config_size` is a `u_int32_t` from disk (`ata-raid.h:592`). The buffer is
**512 bytes** (verified `sizeof(struct nvidia_raid_conf) == 512` in-guest),
but the loop reads `config_size` u32 words = `4 * config_size` bytes. A
`config_size` of 0x400 → 3584-byte OOB read.

### Reachability without a valid checksum

In both parsers, the **magic-string check runs BEFORE the loop** (Intel:2145,
nVidia:3039), but the **checksum verification runs AFTER** (Intel:2156,
nVidia:3049). An attacker only needs to satisfy the 8/24-byte magic; the loop
faults before the checksum is compared, so a self-consistent checksum is **not**
required.

## Reproducibility on the audit guest

Same constraints as DF-1174: `nataraid` is `optional` (`sys/conf/files:143`),
not in `X86_64_GENERIC`; the module ships at `/boot/kernel/nataraid.ko`; the
QEMU guest uses virtio-blk (not ATA), so the parsers never run on guest disks.
Live triggering would require rebooting QEMU with an added IDE disk image
containing crafted metadata.

A userspace harness (`harness.c`) reconstructs both loops with the exact
kmalloc sizes (1536 / 512) and a matching magic, and drives them with an
oversized `config_size`. Run on the guest (`./build.sh && ./run.sh`):

```
=== Case 1: Intel parser (ata-raid.c:2132-2154) ===
  meta = kmalloc(1536); magic OK; config_size = 0x10000 (65536)
  loop will run 16384 iterations, reading 65536 bytes (buffer = 1536 bytes -> 64000-byte OOB read)
  magic check: PASS (matches INTEL_MAGIC)
  BUG: OOB read faulted (signal 11) -- kernel equivalent: page fault past kmalloc(1536) ...

=== Case 2: nVidia parser (ata-raid.c:3028-3048) ===
  meta = kmalloc(sizeof(nvidia_raid_conf)=512); magic OK; config_size = 0x400 (1024)
  loop will run 1024 iterations, reading 4096 bytes (buffer = 512 bytes -> 3584-byte OOB read)
  magic check: PASS (matches NV_MAGIC)
  BUG: OOB read faulted (signal 11) -- kernel equivalent: page fault past kmalloc(512) ...
```

## Threat model

Same as DF-1174: an attacker who can supply a disk with crafted RAID
metadata triggers an automatic kernel panic (or info leak) at the next driver
probe. No privilege required beyond disk-write capability.

Severity Medium: requires the legacy `nata` stack (opt-in); not in GENERIC.
High (panic + small info leak) for systems that load `nata`/`nataraid`.

## Recommended fix

Cap the loop iteration count to the actual buffer size in both parsers. See
`fix.diff`.
