DragonFlyBSD Kernel Audit
DF-1918 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/raid/mrsas/mrsas_ioctl.c b/sys/dev/raid/mrsas/mrsas_ioctl.c
--- a/sys/dev/raid/mrsas/mrsas_ioctl.c
+++ b/sys/dev/raid/mrsas/mrsas_ioctl.c
@@ -265,6 +265,22 @@
 
     ioctl_sense_size = user_ioc->sense_len;
     if (user_ioc->sense_len) {
+        /*
+         * DF-1918: user_ioc->sense_off is an attacker-controlled u32 from
+         * userspace (mrsas_ioctl.h:85) and was previously used verbatim
+         * as the in-frame offset at which the 8-byte ioctl_sense_phys_addr
+         * is stored (mrsas_ioctl.c:291-293).  With no validation the
+         * store could land past the 1024-byte cmd->frame DMA allocation
+         * (MRSAS_MFI_FRAME_SIZE).  Reject any sense_off that would push
+         * the 8-byte store past the end of the frame.
+         */
+        if (user_ioc->sense_off >
+            MRSAS_MFI_FRAME_SIZE - sizeof(unsigned long)) {
+            device_printf(sc->mrsas_dev,
+                "In %s() sense_off=0x%x overflows frame\n",
+                __func__, user_ioc->sense_off);
+            return (EINVAL);
+        }
         if (bus_dma_tag_create( sc->mrsas_parent_tag,   // parent
                                 1, 0,                   // algnmnt, boundary
                                 BUS_SPACE_MAXADDR_32BIT,// lowaddr