⬢ DragonFlyBSD Kernel Audit
DF-3952 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/mlx/mlx.c
+++ b/sys/dev/raid/mlx/mlx.c
@@ -1870,8 +1870,17 @@
 
     /* if we need a buffer for data transfer, allocate one and copy in its initial contents */
     if (mu->mu_datasize > 0) {
-	if (mu->mu_datasize > MAXPHYS)
-	    return (EINVAL);
+	if (mu->mu_datasize > MAXPHYS)
+	    return (EINVAL);
+	/*
+	 * The s/g budget comes from the firmware (me_max_sg); the DMA tag
+	 * allows MLX_NSEG segments regardless, and exceeding the firmware
+	 * budget panics in mlx_setup_dmamap().  Keep the passthrough buffer
+	 * within what the controller can actually map.
+	 */
+	if (sc->mlx_enq2 != NULL &&
+	    mu->mu_datasize > (sc->mlx_enq2->me_max_sg - 1) * PAGE_SIZE)
+	    return (EINVAL);
 	if (((kbuf = kmalloc(mu->mu_datasize, M_DEVBUF, M_WAITOK)) == NULL) ||
 	    (error = copyin(mu->mu_buf, kbuf, mu->mu_datasize)))
 	    goto out;