From: Alan Stern Date: Tue, 18 May 2021 20:18:35 +0000 (-0400) Subject: USB: usbfs: Don't WARN about excessively large memory allocations X-Git-Tag: v5.4.124~125 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2c835fede13e03f2743a333e4370b5ed2db91e83;p=thirdparty%2Fkernel%2Fstable.git USB: usbfs: Don't WARN about excessively large memory allocations commit 4f2629ea67e7225c3fd292c7fe4f5b3c9d6392de upstream. Syzbot found that the kernel generates a WARNing if the user tries to submit a bulk transfer through usbfs with a buffer that is way too large. This isn't a bug in the kernel; it's merely an invalid request from the user and the usbfs code does handle it correctly. In theory the same thing can happen with async transfers, or with the packet descriptor table for isochronous transfers. To prevent the MM subsystem from complaining about these bad allocation requests, add the __GFP_NOWARN flag to the kmalloc calls for these buffers. CC: Andrew Morton CC: Reported-and-tested-by: syzbot+882a85c0c8ec4a3e2281@syzkaller.appspotmail.com Signed-off-by: Alan Stern Link: https://lore.kernel.org/r/20210518201835.GA1140918@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 35e89460b9ca8..d037deb958841 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1218,7 +1218,12 @@ static int proc_bulk(struct usb_dev_state *ps, void __user *arg) ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb)); if (ret) return ret; - tbuf = kmalloc(len1, GFP_KERNEL); + + /* + * len1 can be almost arbitrarily large. Don't WARN if it's + * too big, just fail the request. + */ + tbuf = kmalloc(len1, GFP_KERNEL | __GFP_NOWARN); if (!tbuf) { ret = -ENOMEM; goto done; @@ -1691,7 +1696,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb if (num_sgs) { as->urb->sg = kmalloc_array(num_sgs, sizeof(struct scatterlist), - GFP_KERNEL); + GFP_KERNEL | __GFP_NOWARN); if (!as->urb->sg) { ret = -ENOMEM; goto error; @@ -1726,7 +1731,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb (uurb_start - as->usbm->vm_start); } else { as->urb->transfer_buffer = kmalloc(uurb->buffer_length, - GFP_KERNEL); + GFP_KERNEL | __GFP_NOWARN); if (!as->urb->transfer_buffer) { ret = -ENOMEM; goto error;