From: Greg Kroah-Hartman Date: Sun, 20 Mar 2022 10:27:20 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v4.9.308~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0fb06af4f541b78d8686619118cdf4c45d4b78e4;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: usb-gadget-fix-use-after-free-bug-by-not-setting-udc-dev.driver.patch usb-gadget-rndis-prevent-integer-overflow-in-rndis_set_response.patch usb-usbtmc-fix-bug-in-pipe-direction-for-control-transfers.patch --- diff --git a/queue-5.4/series b/queue-5.4/series index efe01276036..f91b91334e4 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -9,3 +9,6 @@ drm-panel-simple-fix-innolux-g070y2-l01-bpp-settings.patch net-handle-arphrd_pimreg-in-dev_is_mac_header_xmit.patch net-dsa-add-missing-of_node_put-in-dsa_port_parse_of.patch arm64-fix-clang-warning-about-tramp_valias.patch +usb-gadget-rndis-prevent-integer-overflow-in-rndis_set_response.patch +usb-gadget-fix-use-after-free-bug-by-not-setting-udc-dev.driver.patch +usb-usbtmc-fix-bug-in-pipe-direction-for-control-transfers.patch diff --git a/queue-5.4/usb-gadget-fix-use-after-free-bug-by-not-setting-udc-dev.driver.patch b/queue-5.4/usb-gadget-fix-use-after-free-bug-by-not-setting-udc-dev.driver.patch new file mode 100644 index 00000000000..7c95ba36bc0 --- /dev/null +++ b/queue-5.4/usb-gadget-fix-use-after-free-bug-by-not-setting-udc-dev.driver.patch @@ -0,0 +1,86 @@ +From 16b1941eac2bd499f065a6739a40ce0011a3d740 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Sat, 5 Mar 2022 21:47:22 -0500 +Subject: usb: gadget: Fix use-after-free bug by not setting udc->dev.driver + +From: Alan Stern + +commit 16b1941eac2bd499f065a6739a40ce0011a3d740 upstream. + +The syzbot fuzzer found a use-after-free bug: + +BUG: KASAN: use-after-free in dev_uevent+0x712/0x780 drivers/base/core.c:2320 +Read of size 8 at addr ffff88802b934098 by task udevd/3689 + +CPU: 2 PID: 3689 Comm: udevd Not tainted 5.17.0-rc4-syzkaller-00229-g4f12b742eb2b #0 +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.14.0-2 04/01/2014 +Call Trace: + + __dump_stack lib/dump_stack.c:88 [inline] + dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 + print_address_description.constprop.0.cold+0x8d/0x303 mm/kasan/report.c:255 + __kasan_report mm/kasan/report.c:442 [inline] + kasan_report.cold+0x83/0xdf mm/kasan/report.c:459 + dev_uevent+0x712/0x780 drivers/base/core.c:2320 + uevent_show+0x1b8/0x380 drivers/base/core.c:2391 + dev_attr_show+0x4b/0x90 drivers/base/core.c:2094 + +Although the bug manifested in the driver core, the real cause was a +race with the gadget core. dev_uevent() does: + + if (dev->driver) + add_uevent_var(env, "DRIVER=%s", dev->driver->name); + +and between the test and the dereference of dev->driver, the gadget +core sets dev->driver to NULL. + +The race wouldn't occur if the gadget core registered its devices on +a real bus, using the standard synchronization techniques of the +driver core. However, it's not necessary to make such a large change +in order to fix this bug; all we need to do is make sure that +udc->dev.driver is always NULL. + +In fact, there is no reason for udc->dev.driver ever to be set to +anything, let alone to the value it currently gets: the address of the +gadget's driver. After all, a gadget driver only knows how to manage +a gadget, not how to manage a UDC. + +This patch simply removes the statements in the gadget core that touch +udc->dev.driver. + +Fixes: 2ccea03a8f7e ("usb: gadget: introduce UDC Class") +CC: +Reported-and-tested-by: syzbot+348b571beb5eeb70a582@syzkaller.appspotmail.com +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/r/YiQgukfFFbBnwJ/9@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/core.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/usb/gadget/udc/core.c ++++ b/drivers/usb/gadget/udc/core.c +@@ -1303,7 +1303,6 @@ static void usb_gadget_remove_driver(str + usb_gadget_udc_stop(udc); + + udc->driver = NULL; +- udc->dev.driver = NULL; + udc->gadget->dev.driver = NULL; + } + +@@ -1352,7 +1351,6 @@ static int udc_bind_to_driver(struct usb + driver->function); + + udc->driver = driver; +- udc->dev.driver = &driver->driver; + udc->gadget->dev.driver = &driver->driver; + + usb_gadget_udc_set_speed(udc, driver->max_speed); +@@ -1374,7 +1372,6 @@ err1: + dev_err(&udc->dev, "failed to start %s: %d\n", + udc->driver->function, ret); + udc->driver = NULL; +- udc->dev.driver = NULL; + udc->gadget->dev.driver = NULL; + return ret; + } diff --git a/queue-5.4/usb-gadget-rndis-prevent-integer-overflow-in-rndis_set_response.patch b/queue-5.4/usb-gadget-rndis-prevent-integer-overflow-in-rndis_set_response.patch new file mode 100644 index 00000000000..001e879c856 --- /dev/null +++ b/queue-5.4/usb-gadget-rndis-prevent-integer-overflow-in-rndis_set_response.patch @@ -0,0 +1,31 @@ +From 65f3324f4b6fed78b8761c3b74615ecf0ffa81fa Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 1 Mar 2022 11:04:24 +0300 +Subject: usb: gadget: rndis: prevent integer overflow in rndis_set_response() + +From: Dan Carpenter + +commit 65f3324f4b6fed78b8761c3b74615ecf0ffa81fa upstream. + +If "BufOffset" is very large the "BufOffset + 8" operation can have an +integer overflow. + +Cc: stable@kernel.org +Fixes: 38ea1eac7d88 ("usb: gadget: rndis: check size of RNDIS_MSG_SET command") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/20220301080424.GA17208@kili +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/rndis.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/gadget/function/rndis.c ++++ b/drivers/usb/gadget/function/rndis.c +@@ -640,6 +640,7 @@ static int rndis_set_response(struct rnd + BufLength = le32_to_cpu(buf->InformationBufferLength); + BufOffset = le32_to_cpu(buf->InformationBufferOffset); + if ((BufLength > RNDIS_MAX_TOTAL_SIZE) || ++ (BufOffset > RNDIS_MAX_TOTAL_SIZE) || + (BufOffset + 8 >= RNDIS_MAX_TOTAL_SIZE)) + return -EINVAL; + diff --git a/queue-5.4/usb-usbtmc-fix-bug-in-pipe-direction-for-control-transfers.patch b/queue-5.4/usb-usbtmc-fix-bug-in-pipe-direction-for-control-transfers.patch new file mode 100644 index 00000000000..aefc79a3b3e --- /dev/null +++ b/queue-5.4/usb-usbtmc-fix-bug-in-pipe-direction-for-control-transfers.patch @@ -0,0 +1,86 @@ +From e9b667a82cdcfe21d590344447d65daed52b353b Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 3 Mar 2022 16:00:17 -0500 +Subject: usb: usbtmc: Fix bug in pipe direction for control transfers + +From: Alan Stern + +commit e9b667a82cdcfe21d590344447d65daed52b353b upstream. + +The syzbot fuzzer reported a minor bug in the usbtmc driver: + +usb 5-1: BOGUS control dir, pipe 80001e80 doesn't match bRequestType 0 +WARNING: CPU: 0 PID: 3813 at drivers/usb/core/urb.c:412 +usb_submit_urb+0x13a5/0x1970 drivers/usb/core/urb.c:410 +Modules linked in: +CPU: 0 PID: 3813 Comm: syz-executor122 Not tainted +5.17.0-rc5-syzkaller-00306-g2293be58d6a1 #0 +... +Call Trace: + + usb_start_wait_urb+0x113/0x530 drivers/usb/core/message.c:58 + usb_internal_control_msg drivers/usb/core/message.c:102 [inline] + usb_control_msg+0x2a5/0x4b0 drivers/usb/core/message.c:153 + usbtmc_ioctl_request drivers/usb/class/usbtmc.c:1947 [inline] + +The problem is that usbtmc_ioctl_request() uses usb_rcvctrlpipe() for +all of its transfers, whether they are in or out. It's easy to fix. + +CC: +Reported-and-tested-by: syzbot+a48e3d1a875240cab5de@syzkaller.appspotmail.com +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/r/YiEsYTPEE6lOCOA5@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/class/usbtmc.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/drivers/usb/class/usbtmc.c ++++ b/drivers/usb/class/usbtmc.c +@@ -1889,6 +1889,7 @@ static int usbtmc_ioctl_request(struct u + struct usbtmc_ctrlrequest request; + u8 *buffer = NULL; + int rv; ++ unsigned int is_in, pipe; + unsigned long res; + + res = copy_from_user(&request, arg, sizeof(struct usbtmc_ctrlrequest)); +@@ -1898,12 +1899,14 @@ static int usbtmc_ioctl_request(struct u + if (request.req.wLength > USBTMC_BUFSIZE) + return -EMSGSIZE; + ++ is_in = request.req.bRequestType & USB_DIR_IN; ++ + if (request.req.wLength) { + buffer = kmalloc(request.req.wLength, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + +- if ((request.req.bRequestType & USB_DIR_IN) == 0) { ++ if (!is_in) { + /* Send control data to device */ + res = copy_from_user(buffer, request.data, + request.req.wLength); +@@ -1914,8 +1917,12 @@ static int usbtmc_ioctl_request(struct u + } + } + ++ if (is_in) ++ pipe = usb_rcvctrlpipe(data->usb_dev, 0); ++ else ++ pipe = usb_sndctrlpipe(data->usb_dev, 0); + rv = usb_control_msg(data->usb_dev, +- usb_rcvctrlpipe(data->usb_dev, 0), ++ pipe, + request.req.bRequest, + request.req.bRequestType, + request.req.wValue, +@@ -1927,7 +1934,7 @@ static int usbtmc_ioctl_request(struct u + goto exit; + } + +- if (rv && (request.req.bRequestType & USB_DIR_IN)) { ++ if (rv && is_in) { + /* Read control data from device */ + res = copy_to_user(request.data, buffer, rv); + if (res)