⬢ DragonFlyBSD Kernel Audit
DF-3932 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/mly/mly.c
+++ b/sys/dev/raid/mly/mly.c
@@ -2886,9 +2886,20 @@ mly_user_command(struct mly_softc *sc, struct mly_user_command *uc)
     struct mly_command	*mc;
     int			error;
 
+    /*
+     * DataTransferLength is a signed int from userland.  Negating
+     * INT_MIN yields INT_MIN again (int wrap), which sign-extends
+     * into size_t as 0xffffffff80000000 -- a "positive" size_t that
+     * kmalloc(M_INTWAIT) turns into
+     * panic("kmem_slab_alloc(): kernel_map ran out of space!").
+     * Cap the transfer at MAXBSIZE, the buffer DMA tag's maxsize
+     * (larger transfers cannot be bus_dmamap_load()ed anyway).
+     */
+    if (uc->DataTransferLength == INT_MIN ||
+        uc->DataTransferLength > MAXBSIZE ||
+        uc->DataTransferLength < -MAXBSIZE)
+	return(EINVAL);
+
     /* allocate a command */
     if (mly_alloc_command(sc, &mc)) {
	error = ENOMEM;