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

Heap buffer overflow in arcmsr_Read_iop_rqbuffer_data_D: 128-byte kmalloc overwritten by firmware-controlled data_len

Summary

arcmsr_Read_iop_rqbuffer_data_D at :1446-1471: kmalloc(128) at :1449; iop_len=prbuffer->data_len from MMIO firmware-controlled; caller only bounds by ARCMSR_MAX_QBUFFER-1=4095. Loop writes iop_len bytes into 128-byte buf1 -> up to ~3967 bytes heap overflow. Then reads iop_len bytes from buf1 OOB. Compromised/malicious Areca controller or device->host IOP message. Fix: clamp iop_len to sizeof(prbuffer->data)=124.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1184 Β· 11 files
FileTypeDescriptionSize
harness.c trigger-source replicates arcmsr_Read_iop_rqbuffer_data_D copy loop with firmware data_len up to 4095 4.0 KB view raw
README.md readme finding summary, why-harness, build/run/expected 1.4 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 13 B view raw
run.log run-log decisive run: data_len=400/4095 overflow the 128-byte object 569 B view raw
fix.diff suggested-fix clamp iop_len to sizeof(prbuffer->data) before the kmalloc/copy 640 B view raw
fix_build.log build-log single-fix GENERIC kernel build with this fix applied (shared, rc=0) 5.6 MB ↓ download
env.txt environment uname, cc version 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-1184 β€” arcmsr_Read_iop_rqbuffer_data_D: 128-byte kmalloc overflowed by firmware data_len

Finding

arcmsr_Read_iop_rqbuffer_data_D() (arcmsr.c:1437-1477) for Type B/C/D adapters: - :1446 reads iop_len = (u_int32_t)prbuffer->data_len β€” a 32-bit length field whose source is MMIO/DMA from the Areca IOP firmware. - :1449 allocates buf1 = kmalloc(128, M_DEVBUF, ...) β€” only 128 bytes. - :1454-1458 copies iop_len bytes (4 at a time) into buf1.

The caller arcmsr_iop2drv_data_wrote_handle() (:1511-1526) only bounds data_len against ARCMSR_MAX_QBUFFER-1 = 4095 (:1519-1521), never against 128. So a malicious/compromised Areca controller (or PCI-passthrough device) supplying data_len in (128, 4095] overflows the 128-byte heap object by up to ~3967 bytes. struct QBUFFER.data is itself only 124 bytes (arcmsr.h:1059-1062), so even a legitimate-looking data_len ≀ 4095 is unbounded relative to the kmalloc.

Why harness

arcmsr IS in X86_64_GENERIC but the driver only attaches to Areca RAID PCI controllers (vendor 0x17d3); none are present on the QEMU guest, so the ISR path that calls this function is never reached. Harness replays the function with crafted data_len against the real 128-byte allocation.

Build & run

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

Expected

Harness shows the heap buffer overrunning at data_len > 128 (up to 4095) and the resulting OOB write into adjacent slab memory.

Fix verification

not_testable

compile+harness validated

see evidence pack

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

REPRODUCED (harness). arcmsr_Read_iop_rqbuffer firmware data_len up to 4095 vs 128B kmalloc -> 3967B overflow. arcmsr in GENERIC. No Areca controller.