From: Greg Kroah-Hartman Date: Thu, 13 Jan 2022 10:51:38 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v5.16.1~42 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ee91f6fb0bd6377df6c671e7abfbb8281ad55afd;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: bluetooth-bfusb-fix-division-by-zero-in-send-path.patch series usb-core-fix-bug-in-resuming-hub-s-handling-of-wakeup-requests.patch usb-fix-slab-out-of-bounds-write-bug-in-usb_hcd_poll_rh_status.patch --- diff --git a/queue-4.4/bluetooth-bfusb-fix-division-by-zero-in-send-path.patch b/queue-4.4/bluetooth-bfusb-fix-division-by-zero-in-send-path.patch new file mode 100644 index 00000000000..2cbfe4e6b4a --- /dev/null +++ b/queue-4.4/bluetooth-bfusb-fix-division-by-zero-in-send-path.patch @@ -0,0 +1,38 @@ +From b5e6fa7a12572c82f1e7f2f51fbb02a322291291 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 25 Oct 2021 13:39:44 +0200 +Subject: Bluetooth: bfusb: fix division by zero in send path + +From: Johan Hovold + +commit b5e6fa7a12572c82f1e7f2f51fbb02a322291291 upstream. + +Add the missing bulk-out endpoint sanity check to probe() to avoid +division by zero in bfusb_send_frame() in case a malicious device has +broken descriptors (or when doing descriptor fuzz testing). + +Note that USB core will reject URBs submitted for endpoints with zero +wMaxPacketSize but that drivers doing packet-size calculations still +need to handle this (cf. commit 2548288b4fb0 ("USB: Fix: Don't skip +endpoint descriptors with maxpacket=0")). + +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bluetooth/bfusb.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/bluetooth/bfusb.c ++++ b/drivers/bluetooth/bfusb.c +@@ -645,6 +645,9 @@ static int bfusb_probe(struct usb_interf + data->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress; + data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize); + ++ if (!data->bulk_pkt_size) ++ goto done; ++ + rwlock_init(&data->lock); + + data->reassembly = NULL; diff --git a/queue-4.4/series b/queue-4.4/series new file mode 100644 index 00000000000..94b4c20f64b --- /dev/null +++ b/queue-4.4/series @@ -0,0 +1,3 @@ +bluetooth-bfusb-fix-division-by-zero-in-send-path.patch +usb-core-fix-bug-in-resuming-hub-s-handling-of-wakeup-requests.patch +usb-fix-slab-out-of-bounds-write-bug-in-usb_hcd_poll_rh_status.patch diff --git a/queue-4.4/usb-core-fix-bug-in-resuming-hub-s-handling-of-wakeup-requests.patch b/queue-4.4/usb-core-fix-bug-in-resuming-hub-s-handling-of-wakeup-requests.patch new file mode 100644 index 00000000000..f20113a0f3e --- /dev/null +++ b/queue-4.4/usb-core-fix-bug-in-resuming-hub-s-handling-of-wakeup-requests.patch @@ -0,0 +1,69 @@ +From 0f663729bb4afc92a9986b66131ebd5b8a9254d1 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Sat, 1 Jan 2022 14:52:14 -0500 +Subject: USB: core: Fix bug in resuming hub's handling of wakeup requests + +From: Alan Stern + +commit 0f663729bb4afc92a9986b66131ebd5b8a9254d1 upstream. + +Bugzilla #213839 reports a 7-port hub that doesn't work properly when +devices are plugged into some of the ports; the kernel goes into an +unending disconnect/reinitialize loop as shown in the bug report. + +This "7-port hub" comprises two four-port hubs with one plugged into +the other; the failures occur when a device is plugged into one of the +downstream hub's ports. (These hubs have other problems too. For +example, they bill themselves as USB-2.0 compliant but they only run +at full speed.) + +It turns out that the failures are caused by bugs in both the kernel +and the hub. The hub's bug is that it reports a different +bmAttributes value in its configuration descriptor following a remote +wakeup (0xe0 before, 0xc0 after -- the wakeup-support bit has +changed). + +The kernel's bug is inside the hub driver's resume handler. When +hub_activate() sees that one of the hub's downstream ports got a +wakeup request from a child device, it notes this fact by setting the +corresponding bit in the hub->change_bits variable. But this variable +is meant for connection changes, not wakeup events; setting it causes +the driver to believe the downstream port has been disconnected and +then connected again (in addition to having received a wakeup +request). + +Because of this, the hub driver then tries to check whether the device +currently plugged into the downstream port is the same as the device +that had been attached there before. Normally this check succeeds and +wakeup handling continues with no harm done (which is why the bug +remained undetected until now). But with these dodgy hubs, the check +fails because the config descriptor has changed. This causes the hub +driver to reinitialize the child device, leading to the +disconnect/reinitialize loop described in the bug report. + +The proper way to note reception of a downstream wakeup request is +to set a bit in the hub->event_bits variable instead of +hub->change_bits. That way the hub driver will realize that something +has happened to the port but will not think the port and child device +have been disconnected. This patch makes that change. + +Cc: +Tested-by: Jonathan McDowell +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/r/YdCw7nSfWYPKWQoD@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hub.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1169,7 +1169,7 @@ static void hub_activate(struct usb_hub + */ + if (portchange || (hub_is_superspeed(hub->hdev) && + port_resumed)) +- set_bit(port1, hub->change_bits); ++ set_bit(port1, hub->event_bits); + + } else if (udev->persist_enabled) { + #ifdef CONFIG_PM diff --git a/queue-4.4/usb-fix-slab-out-of-bounds-write-bug-in-usb_hcd_poll_rh_status.patch b/queue-4.4/usb-fix-slab-out-of-bounds-write-bug-in-usb_hcd_poll_rh_status.patch new file mode 100644 index 00000000000..1538940a0ed --- /dev/null +++ b/queue-4.4/usb-fix-slab-out-of-bounds-write-bug-in-usb_hcd_poll_rh_status.patch @@ -0,0 +1,65 @@ +From 1d7d4c07932e04355d6e6528d44a2f2c9e354346 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 31 Dec 2021 21:07:12 -0500 +Subject: USB: Fix "slab-out-of-bounds Write" bug in usb_hcd_poll_rh_status + +From: Alan Stern + +commit 1d7d4c07932e04355d6e6528d44a2f2c9e354346 upstream. + +When the USB core code for getting root-hub status reports was +originally written, it was assumed that the hub driver would be its +only caller. But this isn't true now; user programs can use usbfs to +communicate with root hubs and get status reports. When they do this, +they may use a transfer_buffer that is smaller than the data returned +by the HCD, which will lead to a buffer overflow error when +usb_hcd_poll_rh_status() tries to store the status data. This was +discovered by syzbot: + +BUG: KASAN: slab-out-of-bounds in memcpy include/linux/fortify-string.h:225 [inline] +BUG: KASAN: slab-out-of-bounds in usb_hcd_poll_rh_status+0x5f4/0x780 drivers/usb/core/hcd.c:776 +Write of size 2 at addr ffff88801da403c0 by task syz-executor133/4062 + +This patch fixes the bug by reducing the amount of status data if it +won't fit in the transfer_buffer. If some data gets discarded then +the URB's completion status is set to -EOVERFLOW rather than 0, to let +the user know what happened. + +Reported-and-tested-by: syzbot+3ae6a2b06f131ab9849f@syzkaller.appspotmail.com +Signed-off-by: Alan Stern +Cc: +Link: https://lore.kernel.org/r/Yc+3UIQJ2STbxNua@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hcd.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -731,6 +731,7 @@ void usb_hcd_poll_rh_status(struct usb_h + { + struct urb *urb; + int length; ++ int status; + unsigned long flags; + char buffer[6]; /* Any root hubs with > 31 ports? */ + +@@ -748,11 +749,17 @@ void usb_hcd_poll_rh_status(struct usb_h + if (urb) { + clear_bit(HCD_FLAG_POLL_PENDING, &hcd->flags); + hcd->status_urb = NULL; ++ if (urb->transfer_buffer_length >= length) { ++ status = 0; ++ } else { ++ status = -EOVERFLOW; ++ length = urb->transfer_buffer_length; ++ } + urb->actual_length = length; + memcpy(urb->transfer_buffer, buffer, length); + + usb_hcd_unlink_urb_from_ep(hcd, urb); +- usb_hcd_giveback_urb(hcd, urb, 0); ++ usb_hcd_giveback_urb(hcd, urb, status); + } else { + length = 0; + set_bit(HCD_FLAG_POLL_PENDING, &hcd->flags);