Commit 1e0bcecb authored by Alan Stern's avatar Alan Stern Committed by Yu Liao
Browse files

USB: usbfs: Don't WARN about excessively large memory allocations

stable inclusion
from stable-v4.19.193
commit 2ab21d6e1411999b5fb43434f421f00bf50002eb
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9BHQL
CVE: CVE-2021-47170

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=2ab21d6e1411999b5fb43434f421f00bf50002eb



--------------------------------

commit 4f2629ea 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 <akpm@linux-foundation.org>
CC: <stable@vger.kernel.org>
Reported-and-tested-by: default avatar <syzbot+882a85c0c8ec4a3e2281@syzkaller.appspotmail.com>
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/r/20210518201835.GA1140918@rowland.harvard.edu


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarYu Liao <liaoyu15@huawei.com>
parent 6726609c
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -1189,7 +1189,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;
@@ -1630,7 +1635,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;
@@ -1665,7 +1670,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;