--- 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;