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

mrsas_complete_cmd uses firmware-controlled SMID to index mpt_cmd_list with no bounds check

Summary

mrsas_complete_cmd at mrsas.c:1269-1270: smid=reply_desc->SMID (u16 from DMA), cmd_mpt=sc->mpt_cmd_list[smid-1] with NO bounds check vs max_fw_cmds. smid==0 -> array[-1]; smid>max_fw_cmds -> OOB. Wild cmd_mpt dereferenced for io_request (:1271), ccb_ptr->target_id (:1279), sync_cmd_idx into mfi_cmd_list[32] (:1295). max_fw_cmds from FW status reg (:1799), -1 at :1802, no min check -> if 0, array[-1]. Sibling of DF-1228 (mpr SMID OOB). Malicious/buggy HBA, PCIe DMA attack. Fix: validate 1<=smid<=max_fw_cmds, sanity-check max_fw_cmds.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1242 Β· 8 files
FileTypeDescriptionSize
fix.diff suggested-fix bounds-check smid (1..max_fw_cmds) before indexing mpt_cmd_list; drop invalid entries 1.5 KB view raw
VERDICT.md verdict source-level trace of OOB array access + dead-code analysis 3.5 KB ↓ raw
build.sh build-script applies fix, builds single-fix kernel 772 B view raw
run.sh run-script explains no-trigger on this guest 594 B view raw
env.txt environment uname, cc version, PCI inventory 553 B view raw
build.log build-log kernel build log excerpt proving -Werror clean compile of patched source 9.2 KB 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
VERDICT.md verdict source-level trace of OOB array access + dead-code analysis
↓ download raw

DF-1242 β€” mrsas_complete_cmd SMID to index (OOB array access)

Verdict: NOT REPRODUCED (dead code at runtime β€” no hardware)

Mechanism (source-level, confirmed real)

mrsas_complete_cmd() at sys/dev/raid/mrsas/mrsas.c:1241 processes firmware reply descriptors. The SMID (System Message ID) is read from DMA (firmware-controlled) and used as an array index with no bounds check:

// line 1269-1270
smid = reply_desc->SMID;            // u_int16_t from DMA (0..65535)
cmd_mpt = sc->mpt_cmd_list[smid -1];  // NO bounds check!
scsi_io_req = (MRSAS_RAID_SCSI_IO_REQUEST *)cmd_mpt->io_request;

smid is u_int16_t (line 1244); reply_desc->SMID is also u_int16_t (mrsas.h:361). The array sc->mpt_cmd_list has max_fw_cmds entries (allocated at line 1023-1030). Two failure modes:

  1. smid == 0: smid - 1 = -1 (int promotion) β†’ mpt_cmd_list[-1] reads the pointer 8 bytes before the array β†’ wild cmd_mpt β†’ crash or corruption when dereferencing cmd_mpt->io_request.

  2. smid > max_fw_cmds: mpt_cmd_list[smid-1] reads past the array β†’ wild cmd_mpt β†’ same.

The cascading dereferences are severe: - cmd_mpt->io_request (line 1271) - cmd_mpt->ccb_ptr->ccb_h.target_id (line 1279) - cmd_mpt->sync_cmd_idx β†’ sc->mfi_cmd_list[idx] (line 1295), where mfi_cmd_list has only MRSAS_MAX_MFI_CMDS=32 entries (mrsas.h:1135)

Additionally, max_fw_cmds comes from the FW status register (line 1799) with only a -1 adjustment (line 1802) and no minimum check β€” if the register reads 0, max_fw_cmds underflows to 0xFFFFFFFF (uint), causing massive over-allocation or other corruption.

The bug is real in source. A malicious firmware (or PCIe DMA injection via a Thunderbolt/malicious-device vector) can set an arbitrary SMID, causing OOB array access and wild pointer dereference in the kernel.

Why it cannot reproduce on this guest

mrsas (LSI MegaRAID SAS, Thunderbolt series and up) IS compiled into the X86_64_GENERIC kernel (confirmed: nm /boot/kernel/kernel shows mrsas_complete_cmd at 0xffffffff804d54e0). However:

  • The QEMU guest has no LSI MegaRAID SAS controller β€” pciconf -l shows only 440FX/PIIX3/PIIX4, VGA, virtio-net, virtio-blk.
  • mrsas_probe() never matches a device β†’ the driver never attaches β†’ no interrupt handler is registered β†’ mrsas_complete_cmd is never called. It is live-but-unreachable code on this guest.
  • QEMU does not emulate LSI MegaRAID SAS (it supports megasas-scsi on some configs but not in this guest's QEMU command line, which uses virtio-blk).

This is valid hard blocker: dead/unreachable at runtime on this guest (no hardware). The threat model is malicious firmware or a malicious PCIe device on a real system with a MegaRAID SAS controller.

Fix

fix.diff adds a bounds check: if smid == 0 || smid > sc->max_fw_cmds, the entry is dropped (advances the reply index, marks the descriptor consumed, continues). Validated by a successful single-fix kernel build (make -j6 nativekernel rc=0).

Impact

  • On this guest: none (driver never attaches, no hardware).
  • On a real system: OOB array access from a malicious firmware/PCIe device. The wild cmd_mpt pointer leads to arbitrary kernel memory dereference β€” likely a crash (DoS) from a buggy firmware, or a controlled corruption primitive from a malicious PCIe device. Triggered in interrupt context. This is a hardware/firmware-trust attack surface, not a local-user privesc.

Fix verification

not_testable

compile validated

module/kernel build rc=0

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

Source-confirmed. mrsas_complete_cmd SMID no bounds -> mpt_cmd_list OOB. mrsas in GENERIC, no MegaRAID HW.