β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-1173

Multiple metadata parsers: OOB write on ar_softc.disks[] via unvalidated disk_number

Summary

HPTv2 (:1806/:1861), HPTv3 (:2040/:2073/:2103), nVidia (:3121), SII (:3588/:3592), LSI v2 (:2866): disk_number (u8 from disk metadata, 0-255) used directly as index into raid->disks[MAX_DISKS=16] with NO bounds check. disk_number>=16 -> OOB heap write on ar_softc overwriting lock/disk/devstat/cdev/pid. HPTv3 RAID01 path sums two u8 values (up to 765). Attacker: crafted disk metadata. Fix: validate disk_number<MAX_DISKS in every parser.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1173 Β· 11 files
FileTypeDescriptionSize
harness.c trigger-source replicates nVidia/HPTv2-RAID01 indexing of disks[disk_number] with crafted u8 disk_number 6.1 KB view raw
README.md readme finding summary, why-harness, build/run/expected 2.3 KB ↓ raw
build.sh build-script cc -O2 -Wall -o harness harness.c 107 B view raw
run.sh run-script ./harness 60 B view raw
build.log build-log final build (gcc -Warray-bounds warnings on the intentional OOB) 695 B view raw
run.log run-log decisive harness run: disks[200]/disks[500] OOB confirmed 1.5 KB view raw
fix.diff suggested-fix bounds-check disk_number<MAX_DISKS in HPTv2/HPTv3/LSIv2/nVidia/SII parsers 2.1 KB view raw
fix_build.log build-log single-fix GENERIC kernel build with this fix applied (rc=0) 5.6 MB ↓ download
env.txt environment uname, cc version, atapci listing 286 B view raw
../fix_build_combined.log build-log Combined 41-finding kernel build (rc=0, -Werror clean) 5.6 MB ↓ download
../fix_build_summary.txt build-summary Summary of the combined 41-finding kernel build 826 B view raw
README.md readme finding summary, why-harness, build/run/expected
↓ download raw

DF-1173 β€” nataraid metadata parsers: OOB write on ar_softc.disks[]

Finding

Multiple ATA-RAID metadata parsers use a firmware/disk-controlled disk_number (u8, 0-255, or a sum of two u8s up to ~510) as a direct index into raid->disks[MAX_DISKS=16] with no bounds check:

  • HPTv2 RAID0/SPAN ata-raid.c:1806 β†’ write at :1861
  • HPTv2 RAID01 ata-raid.c:1838 (disk_number + array_width, up to ~510)
  • HPTv3 ata-raid.c:2040/2046/2052/2058/2073 β†’ write at :2103
  • LSI v2 ata-raid.c:2866 β†’ write at :3001
  • nVidia ata-raid.c:3121 (uses meta->disk_number directly)
  • SII ata-raid.c:3588/3592 (derived from u8 fields)

struct ar_softc (ata-raid.h:108) places disks[16] immediately before toggle, rebuild_lba, lock, disk, devstat, cdev, pid β€” so an out-of-range disk_number overwrites a struct lock (deadlock/corruption), a cdev_t pointer (arbitrary-kernel-address deref), and a struct proc * (UAF), i.e. kernel memory corruption.

Why harness (not live trigger)

nataraid IS compiled into X86_64_GENERIC, but: 1. The metadata parsers are gated by PCI vendor ID in ata_raid_read_metadata() (ata-raid.c:1414-1480): the nVidia parser only runs on PCI vendor ATA_NVIDIA_ID, HPT on ATA_HIGHPOINT_ID, SII on ATA_SILICON_IMAGE_ID, LSI on ATA_LSI_ID. The QEMU guest's only ATA controller is the Intel PIIX3 (chip 0x70108086), which routes to the Intel parser, not any cited vendor parser. 2. The guest has no ATA hard disk (ad*) β€” only a DVD-ROM (acd0) β€” and nataraid created no RAID arrays (/dev/ar* absent). 3. Even on matching hardware the trigger requires a crafted disk image whose metadata sector (NVIDIA_LBA = total_secs - 2, etc.) is attacker-written (e.g. a USB/external image chown'd to the attacker).

So the primitive is demonstrated at the function level with a userspace harness that replicates the exact indexing the kernel performs.

Build & run

./build.sh && ./run.sh

Expected (bug present)

The harness reports the OOB index and which kernel fields (lock/cdev/pid offsets) fall under the write, and exits non-zero. The OOB write is real; on matching hardware with a crafted disk it corrupts the slab object past disks[15].

Fix verification

not_testable

compile+harness validated

see evidence pack

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

REPRODUCED (harness). nataraid 5 metadata parsers disk_number u8 unvalidated vs disks[MAX_DISKS=16] -> 9600B OOB. nataraid in GENERIC. No ATA RAID controller on guest.