# DF-1174 — VERDICT

**Verdict: REPRODUCED (source+harness, module-build-validated).** Not `uid=0` —
this is a **divide-by-zero DoS** in optional legacy ATA RAID metadata parsing.

## Bug confirmation

`ata_raid_attach()` at `sys/dev/disk/nata/ata-raid.c:144` runs (lines 154-160):

```c
if (rdp->type == AR_T_RAID0 || rdp->type == AR_T_RAID01 || rdp->type == AR_T_RAID5) {
    rdp->total_sectors = rounddown(rdp->total_sectors,
        rdp->interleave * rdp->width);
    ...
}
```

`rounddown(x, y)` is `((x)/(y))*(y)` (`sys/sys/param.h:400`). If
`interleave == 0` or `width == 0` (their product), the kernel executes an
integer divide-by-zero → #DE trap → **kernel panic**.

Both fields are populated **directly from disk metadata with no zero check**
across six RAID metadata parsers in the same file:

| Parser  | line  | field set |
|---------|-------|-----------|
| HPTv2   | `:1868` | `width = meta->array_width` |
| HPTv3   | `:2039/2045/2051` | `width = meta->configs[0].total_disks` |
| Intel   | `:2229` | `interleave = map->stripe_sectors` |
| ITE     | `:2528` | `interleave = meta->stripe_sectors` |
| nVidia  | `:3107-3108` | `interleave = meta->stripe_sectors; width = meta->array_width` |
| SII     | `:3562` | `interleave = meta->stripe_sectors` |

A second div-by-zero exists at `:1028` (`ata_raid_status`):
```c
status->progress = 100 * rdp->rebuild_lba / rdp->total_sectors;
```
triggered via `IOCATARAIDSTATUS` when `total_sectors == 0` from crafted metadata.

## Reproducibility on the audit guest

- `nataraid` is `optional` (`sys/conf/files:143`); not in `X86_64_GENERIC`.
  The module ships at `/boot/kernel/nataraid.ko` (loadable, but the legacy
  `nata` controller stack is opt-in and not loaded on the audit guest).
- The QEMU guest uses **virtio-blk** (`vtblk0`), not ATA, so the `ata-raid`
  metadata parsers are never invoked on guest disks. Live triggering would
  require rebooting QEMU with an added IDE/SATA disk image containing crafted
  metadata — outside the "guest already up" envelope.

A userspace harness (`harness.c`) reconstructs `rounddown()` and replays the
`ata_raid_attach` line 157-158 division and the `ata_raid_status` line 1028
division for several crafted-metadata cases. All produce `SIGFPE` (integer
divide-by-zero), the userspace analogue of the kernel #DE panic:

```
[case 1] nVidia meta stripe_sectors=0, array_width=2 -> rounddown(1000000, 0*2)
    BUG: integer divide-by-zero -> SIGFPE 8
[case 2] Intel meta stripe_sectors=64, array_width=0 -> rounddown(1000000, 64*0)
    BUG: integer divide-by-zero -> SIGFPE 8
[case 3] ITE meta stripe_sectors=0, array_width=0 -> rounddown(1000000, 0*0)
    BUG: integer divide-by-zero -> SIGFPE 8
[case 4] IOCATARAIDSTATUS: total_sectors=0 (crafted metadata)
    BUG: integer divide-by-zero -> SIGFPE 8
```

## Module build validation

The fix.diff was applied in-guest to `/usr/src` and `make` in
`/usr/src/sys/dev/disk/nata/nataraid` produced a clean `nataraid.ko` (`RC=0`,
no warnings, full `-Werror` kernel CFLAGS). The patched source compiles. After
validation the source was reverted (`patch -p1 -R`).

## Exploit chain

`none` — divide-by-zero is a pure DoS, not a memory-corruption primitive.

## Fix

`fix.diff`:
1. In `ata_raid_attach`, before the `rounddown`, validate
   `interleave != 0 && width != 0`; log and bail out otherwise.
2. In `ata_raid_status` (`IOCATARAIDSTATUS`), guard the `total_sectors`
   division with a non-zero check.

`git apply --check` passes against the audit tree, and the patched source
compiles cleanly into `nataraid.ko` on the guest.

## Threat model

The metadata is parsed from the first/last sectors of a physical disk during
the `nata` controller's attach probe. An attacker who can supply a disk with
crafted RAID metadata (USB/external disk, malicious VM disk image, mounted
image) triggers an automatic kernel panic at the next driver probe. No
privilege required beyond the ability to write to a disk that the kernel
subsequently probes.

Severity Medium: requires the legacy `nata` stack (`sys/dev/disk/nata/`,
opt-in; DragonFlyBSD's default ATA stack is `sys/dev/disk/ata`). High (DoS)
for systems that load `nata`/`nataraid`.
