DF-1259 / mfi_stp_oob.c
/* * DF-1259 trigger PoC — mfi_stp_cmd unbounded SGE loop corrupts mfi_softc. * * Bug (sys/dev/raid/mfi/mfi.c:2725 mfi_stp_cmd): * uint8_t i; (loop var) * for (i = 0; i < ioc->mfi_sge_count; i++) { (~:2747) * bus_dma_tag_create(..., &sc->mfi_kbuff_arr_dmat[i]); // sized [2] * bus_dmamem_alloc(sc->mfi_kbuff_arr_dmat[i], ...&sc->kbuff_arr[i]); * bus_dmamap_load(..., &sc->mfi_kbuff_arr_busaddr[i]); // sized [2] * kern_sge[i].phys_addr = ...; // mfi_sgl sized [2] * cm->cm_frame->stp.sgl.sg64[i].addr = ...; // sg64 sized [2] * copyin(ioc->mfi_sgl[i].iov_base, sc->kbuff_arr[i], ioc->mfi_sgl[i].iov_len); * } * mfivar.h:196-198 mfi_kbuff_arr_dmat[2] / _dmamap[2] / _busaddr[2] * mfireg.h:591-598 struct mfi_stp_frame { ...; sg32[2]; sg64[2]; } * The native MFI_CMD path has NO MAX_IOCTL_SGE cap before calling * mfi_stp_cmd. mfi_sge_count >= 3 -> index 2 writes OOB past the [2] * arrays into the adjacent mfi_softc fields (mfi_comms, frame structs). * (uint8_t i additionally wraps at 256, secondary.) * * Reachability on the audit guest: * As with DF-1258, the /dev/mfi%d node only exists once mfi attaches to an * LSI MegaRAID SAS controller (absent on this QEMU guest). The STP command * path is additionally gated on a user frame with header.cmd == MFI_CMD_STP. * This program reports the device-absence to make the result unambiguous. * * Build: cc -o mfi_stp_oob mfi_stp_oob.c * Run: ./mfi_stp_oob */ #include <sys/types.h> #include <sys/ioctl.h> #include <fcntl.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <unistd.h> int main(void) { int fd = open("/dev/mfi0", O_RDWR); if (fd < 0) { printf("[DF-1259] open(\"/dev/mfi0\") failed: %s (errno=%d)\n", strerror(errno), errno); if (errno == ENOENT || errno == ENXIO) printf("[DF-1259] RESULT: /dev/mfi0 absent -> mfi not attached.\n" "[DF-1259] The mfi_stp_cmd OOB write into mfi_softc is NOT\n" "[DF-1259] reachable on this guest (no LSI MegaRAID HW).\n" "[DF-1259] Bug confirmed in source at mfi.c:2747; latent on\n" "[DF-1259] hardware-equipped hosts.\n"); return 0; } close(fd); return 0; } |