]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Mar 2026 15:53:58 +0000 (16:53 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Mar 2026 15:53:58 +0000 (16:53 +0100)
added patches:
usb-cdc-acm-restore-cap_brk-functionnality-to-ch343.patch
usb-class-cdc-wdm-fix-reordering-issue-in-read-code-path.patch
usb-core-don-t-power-off-roothub-phys-if-phy_set_mode-fails.patch
usb-core-limit-the-length-of-unkillable-synchronous-timeouts.patch
usb-core-quirks-add-huawei-me906s-device-to-wakeup-quirk.patch
usb-image-mdc800-kill-download-urb-on-timeout.patch
usb-mdc800-handle-signal-and-read-racing.patch
usb-misc-uss720-properly-clean-up-reference-in-uss720_probe.patch
usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch
usb-usbcore-introduce-usb_bulk_msg_killable.patch
usb-usbtmc-use-usb_bulk_msg_killable-with-user-specified-timeouts.patch
usb-xhci-fix-memory-leak-in-xhci_disable_slot.patch
usb-yurex-fix-race-in-probe.patch

14 files changed:
queue-5.15/series
queue-5.15/usb-cdc-acm-restore-cap_brk-functionnality-to-ch343.patch [new file with mode: 0644]
queue-5.15/usb-class-cdc-wdm-fix-reordering-issue-in-read-code-path.patch [new file with mode: 0644]
queue-5.15/usb-core-don-t-power-off-roothub-phys-if-phy_set_mode-fails.patch [new file with mode: 0644]
queue-5.15/usb-core-limit-the-length-of-unkillable-synchronous-timeouts.patch [new file with mode: 0644]
queue-5.15/usb-core-quirks-add-huawei-me906s-device-to-wakeup-quirk.patch [new file with mode: 0644]
queue-5.15/usb-image-mdc800-kill-download-urb-on-timeout.patch [new file with mode: 0644]
queue-5.15/usb-mdc800-handle-signal-and-read-racing.patch [new file with mode: 0644]
queue-5.15/usb-misc-uss720-properly-clean-up-reference-in-uss720_probe.patch [new file with mode: 0644]
queue-5.15/usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch [new file with mode: 0644]
queue-5.15/usb-usbcore-introduce-usb_bulk_msg_killable.patch [new file with mode: 0644]
queue-5.15/usb-usbtmc-use-usb_bulk_msg_killable-with-user-specified-timeouts.patch [new file with mode: 0644]
queue-5.15/usb-xhci-fix-memory-leak-in-xhci_disable_slot.patch [new file with mode: 0644]
queue-5.15/usb-yurex-fix-race-in-probe.patch [new file with mode: 0644]

index ee212ef55d75aefdb1302db8e80f9e1c1a56bfc0..36ee1a9e3c0900fa1f2bcac5067af95cf38bf0cf 100644 (file)
@@ -131,3 +131,16 @@ revert-arm64-dts-qcom-sdm845-oneplus-mark-l14a-regul.patch
 cgroup-fix-race-between-task-migration-and-iteration.patch
 net-usb-lan78xx-fix-silent-drop-of-packets-with-checksum-errors.patch
 net-usb-lan78xx-skip-ltm-configuration-for-lan7850.patch
+usb-core-quirks-add-huawei-me906s-device-to-wakeup-quirk.patch
+usb-xhci-fix-memory-leak-in-xhci_disable_slot.patch
+usb-yurex-fix-race-in-probe.patch
+usb-misc-uss720-properly-clean-up-reference-in-uss720_probe.patch
+usb-core-don-t-power-off-roothub-phys-if-phy_set_mode-fails.patch
+usb-cdc-acm-restore-cap_brk-functionnality-to-ch343.patch
+usb-usbcore-introduce-usb_bulk_msg_killable.patch
+usb-usbtmc-use-usb_bulk_msg_killable-with-user-specified-timeouts.patch
+usb-core-limit-the-length-of-unkillable-synchronous-timeouts.patch
+usb-class-cdc-wdm-fix-reordering-issue-in-read-code-path.patch
+usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch
+usb-mdc800-handle-signal-and-read-racing.patch
+usb-image-mdc800-kill-download-urb-on-timeout.patch
diff --git a/queue-5.15/usb-cdc-acm-restore-cap_brk-functionnality-to-ch343.patch b/queue-5.15/usb-cdc-acm-restore-cap_brk-functionnality-to-ch343.patch
new file mode 100644 (file)
index 0000000..dd72a42
--- /dev/null
@@ -0,0 +1,62 @@
+From 14ae24cba291bddfdc296bbcbfd00cd09d0498ef Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <maz@kernel.org>
+Date: Sun, 1 Mar 2026 12:44:40 +0000
+Subject: usb: cdc-acm: Restore CAP_BRK functionnality to CH343
+
+From: Marc Zyngier <maz@kernel.org>
+
+commit 14ae24cba291bddfdc296bbcbfd00cd09d0498ef upstream.
+
+The CH343 USB/serial adapter is as buggy as it is popular (very).
+One of its quirks is that despite being capable of signalling a
+BREAK condition, it doesn't advertise it.
+
+This used to work nonetheless until 66aad7d8d3ec5 ("usb: cdc-acm:
+return correct error code on unsupported break") applied some
+reasonable restrictions, preventing breaks from being emitted on
+devices that do not advertise CAP_BRK.
+
+Add a quirk for this particular device, so that breaks can still
+be produced on some of my machines attached to my console server.
+
+Fixes: 66aad7d8d3ec5 ("usb: cdc-acm: return correct error code on unsupported break")
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Cc: stable <stable@kernel.org>
+Cc: Oliver Neukum <oneukum@suse.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Link: https://patch.msgid.link/20260301124440.1192752-1-maz@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/class/cdc-acm.c |    5 +++++
+ drivers/usb/class/cdc-acm.h |    1 +
+ 2 files changed, 6 insertions(+)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1359,6 +1359,8 @@ made_compressed_probe:
+               acm->ctrl_caps = h.usb_cdc_acm_descriptor->bmCapabilities;
+       if (quirks & NO_CAP_LINE)
+               acm->ctrl_caps &= ~USB_CDC_CAP_LINE;
++      if (quirks & MISSING_CAP_BRK)
++              acm->ctrl_caps |= USB_CDC_CAP_BRK;
+       acm->ctrlsize = ctrlsize;
+       acm->readsize = readsize;
+       acm->rx_buflimit = num_rx_buf;
+@@ -1988,6 +1990,9 @@ static const struct usb_device_id acm_id
+       .driver_info = IGNORE_DEVICE,
+       },
++      /* CH343 supports CAP_BRK, but doesn't advertise it */
++      { USB_DEVICE(0x1a86, 0x55d3), .driver_info = MISSING_CAP_BRK, },
++
+       /* control interfaces without any protocol set */
+       { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
+               USB_CDC_PROTO_NONE) },
+--- a/drivers/usb/class/cdc-acm.h
++++ b/drivers/usb/class/cdc-acm.h
+@@ -141,3 +141,4 @@ struct acm {
+ #define CLEAR_HALT_CONDITIONS         BIT(5)
+ #define SEND_ZERO_PACKET              BIT(6)
+ #define DISABLE_ECHO                  BIT(7)
++#define MISSING_CAP_BRK                       BIT(8)
diff --git a/queue-5.15/usb-class-cdc-wdm-fix-reordering-issue-in-read-code-path.patch b/queue-5.15/usb-class-cdc-wdm-fix-reordering-issue-in-read-code-path.patch
new file mode 100644 (file)
index 0000000..63c6ae2
--- /dev/null
@@ -0,0 +1,50 @@
+From 8df672bfe3ec2268c2636584202755898e547173 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Wed, 4 Mar 2026 14:01:12 +0100
+Subject: usb: class: cdc-wdm: fix reordering issue in read code path
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 8df672bfe3ec2268c2636584202755898e547173 upstream.
+
+Quoting the bug report:
+
+Due to compiler optimization or CPU out-of-order execution, the
+desc->length update can be reordered before the memmove. If this
+happens, wdm_read() can see the new length and call copy_to_user() on
+uninitialized memory. This also violates LKMM data race rules [1].
+
+Fix it by using WRITE_ONCE and memory barriers.
+
+Fixes: afba937e540c9 ("USB: CDC WDM driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Closes: https://lore.kernel.org/linux-usb/CALbr=LbrUZn_cfp7CfR-7Z5wDTHF96qeuM=3fO2m-q4cDrnC4A@mail.gmail.com/
+Reported-by: Gui-Dong Han <hanguidong02@gmail.com>
+Reviewed-by: Gui-Dong Han <hanguidong02@gmail.com>
+Link: https://patch.msgid.link/20260304130116.1721682-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/class/cdc-wdm.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -225,7 +225,8 @@ static void wdm_in_callback(struct urb *
+               /* we may already be in overflow */
+               if (!test_bit(WDM_OVERFLOW, &desc->flags)) {
+                       memmove(desc->ubuf + desc->length, desc->inbuf, length);
+-                      desc->length += length;
++                      smp_wmb(); /* against wdm_read() */
++                      WRITE_ONCE(desc->length, desc->length + length);
+               }
+       }
+ skip_error:
+@@ -533,6 +534,7 @@ static ssize_t wdm_read
+               return -ERESTARTSYS;
+       cntr = READ_ONCE(desc->length);
++      smp_rmb(); /* against wdm_in_callback() */
+       if (cntr == 0) {
+               desc->read = 0;
+ retry:
diff --git a/queue-5.15/usb-core-don-t-power-off-roothub-phys-if-phy_set_mode-fails.patch b/queue-5.15/usb-core-don-t-power-off-roothub-phys-if-phy_set_mode-fails.patch
new file mode 100644 (file)
index 0000000..960ad08
--- /dev/null
@@ -0,0 +1,50 @@
+From e293015ba76eb96ce4ebed7e3b2cb1a7d319f3e9 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <j4g8y7@gmail.com>
+Date: Wed, 18 Feb 2026 21:21:07 +0100
+Subject: usb: core: don't power off roothub PHYs if phy_set_mode() fails
+
+From: Gabor Juhos <j4g8y7@gmail.com>
+
+commit e293015ba76eb96ce4ebed7e3b2cb1a7d319f3e9 upstream.
+
+Remove the error path from the usb_phy_roothub_set_mode() function.
+The code is clearly wrong, because phy_set_mode() calls can't be
+balanced with phy_power_off() calls.
+
+Additionally, the usb_phy_roothub_set_mode() function is called only
+from usb_add_hcd() before it powers on the PHYs, so powering off those
+makes no sense anyway.
+
+Presumably, the code is copy-pasted from the phy_power_on() function
+without adjusting the error handling.
+
+Cc: stable@vger.kernel.org # v5.1+
+Fixes: b97a31348379 ("usb: core: comply to PHY framework")
+Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://patch.msgid.link/20260218-usb-phy-poweroff-fix-v1-1-66e6831e860e@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/phy.c |    8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+--- a/drivers/usb/core/phy.c
++++ b/drivers/usb/core/phy.c
+@@ -138,16 +138,10 @@ int usb_phy_roothub_set_mode(struct usb_
+       list_for_each_entry(roothub_entry, head, list) {
+               err = phy_set_mode(roothub_entry->phy, mode);
+               if (err)
+-                      goto err_out;
++                      return err;
+       }
+       return 0;
+-
+-err_out:
+-      list_for_each_entry_continue_reverse(roothub_entry, head, list)
+-              phy_power_off(roothub_entry->phy);
+-
+-      return err;
+ }
+ EXPORT_SYMBOL_GPL(usb_phy_roothub_set_mode);
diff --git a/queue-5.15/usb-core-limit-the-length-of-unkillable-synchronous-timeouts.patch b/queue-5.15/usb-core-limit-the-length-of-unkillable-synchronous-timeouts.patch
new file mode 100644 (file)
index 0000000..56eb60b
--- /dev/null
@@ -0,0 +1,134 @@
+From 1015c27a5e1a63efae2b18a9901494474b4d1dc3 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 17 Feb 2026 22:10:32 -0500
+Subject: USB: core: Limit the length of unkillable synchronous timeouts
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 1015c27a5e1a63efae2b18a9901494474b4d1dc3 upstream.
+
+The usb_control_msg(), usb_bulk_msg(), and usb_interrupt_msg() APIs in
+usbcore allow unlimited timeout durations.  And since they use
+uninterruptible waits, this leaves open the possibility of hanging a
+task for an indefinitely long time, with no way to kill it short of
+unplugging the target device.
+
+To prevent this sort of problem, enforce a maximum limit on the length
+of these unkillable timeouts.  The limit chosen here, somewhat
+arbitrarily, is 60 seconds.  On many systems (although not all) this
+is short enough to avoid triggering the kernel's hung-task detector.
+
+In addition, clear up the ambiguity of negative timeout values by
+treating them the same as 0, i.e., using the maximum allowed timeout.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/linux-usb/3acfe838-6334-4f6d-be7c-4bb01704b33d@rowland.harvard.edu/
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+CC: stable@vger.kernel.org
+Link: https://patch.msgid.link/15fc9773-a007-47b0-a703-df89a8cf83dd@rowland.harvard.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/message.c |   27 +++++++++++++--------------
+ include/linux/usb.h        |    3 +++
+ 2 files changed, 16 insertions(+), 14 deletions(-)
+
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -44,6 +44,8 @@ static void usb_api_blocking_completion(
+  * Starts urb and waits for completion or timeout.
+  * Whether or not the wait is killable depends on the flag passed in.
+  * For example, compare usb_bulk_msg() and usb_bulk_msg_killable().
++ *
++ * For non-killable waits, we enforce a maximum limit on the timeout value.
+  */
+ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length,
+               bool killable)
+@@ -60,7 +62,9 @@ static int usb_start_wait_urb(struct urb
+       if (unlikely(retval))
+               goto out;
+-      expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
++      if (!killable && (timeout <= 0 || timeout > USB_MAX_SYNCHRONOUS_TIMEOUT))
++              timeout = USB_MAX_SYNCHRONOUS_TIMEOUT;
++      expire = (timeout > 0) ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
+       if (killable)
+               rc = wait_for_completion_killable_timeout(&ctx.done, expire);
+       else
+@@ -126,8 +130,7 @@ static int usb_internal_control_msg(stru
+  * @index: USB message index value
+  * @data: pointer to the data to send
+  * @size: length in bytes of the data to send
+- * @timeout: time in msecs to wait for the message to complete before timing
+- *    out (if 0 the wait is forever)
++ * @timeout: time in msecs to wait for the message to complete before timing out
+  *
+  * Context: task context, might sleep.
+  *
+@@ -182,8 +185,7 @@ EXPORT_SYMBOL_GPL(usb_control_msg);
+  * @index: USB message index value
+  * @driver_data: pointer to the data to send
+  * @size: length in bytes of the data to send
+- * @timeout: time in msecs to wait for the message to complete before timing
+- *    out (if 0 the wait is forever)
++ * @timeout: time in msecs to wait for the message to complete before timing out
+  * @memflags: the flags for memory allocation for buffers
+  *
+  * Context: !in_interrupt ()
+@@ -241,8 +243,7 @@ EXPORT_SYMBOL_GPL(usb_control_msg_send);
+  * @index: USB message index value
+  * @driver_data: pointer to the data to be filled in by the message
+  * @size: length in bytes of the data to be received
+- * @timeout: time in msecs to wait for the message to complete before timing
+- *    out (if 0 the wait is forever)
++ * @timeout: time in msecs to wait for the message to complete before timing out
+  * @memflags: the flags for memory allocation for buffers
+  *
+  * Context: !in_interrupt ()
+@@ -313,8 +314,7 @@ EXPORT_SYMBOL_GPL(usb_control_msg_recv);
+  * @len: length in bytes of the data to send
+  * @actual_length: pointer to a location to put the actual length transferred
+  *    in bytes
+- * @timeout: time in msecs to wait for the message to complete before
+- *    timing out (if 0 the wait is forever)
++ * @timeout: time in msecs to wait for the message to complete before timing out
+  *
+  * Context: task context, might sleep.
+  *
+@@ -346,8 +346,7 @@ EXPORT_SYMBOL_GPL(usb_interrupt_msg);
+  * @len: length in bytes of the data to send
+  * @actual_length: pointer to a location to put the actual length transferred
+  *    in bytes
+- * @timeout: time in msecs to wait for the message to complete before
+- *    timing out (if 0 the wait is forever)
++ * @timeout: time in msecs to wait for the message to complete before timing out
+  *
+  * Context: task context, might sleep.
+  *
+@@ -407,12 +406,12 @@ EXPORT_SYMBOL_GPL(usb_bulk_msg);
+  * @actual_length: pointer to a location to put the actual length transferred
+  *    in bytes
+  * @timeout: time in msecs to wait for the message to complete before
+- *    timing out (if 0 the wait is forever)
++ *    timing out (if <= 0, the wait is as long as possible)
+  *
+  * Context: task context, might sleep.
+  *
+- * This function is just like usb_blk_msg() except that it waits in a
+- * killable state.
++ * This function is just like usb_blk_msg(), except that it waits in a
++ * killable state and there is no limit on the timeout length.
+  *
+  * Return:
+  * If successful, 0. Otherwise a negative error number. The number of actual
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -1805,6 +1805,9 @@ void usb_buffer_unmap_sg(const struct us
+  *                         SYNCHRONOUS CALL SUPPORT                  *
+  *-------------------------------------------------------------------*/
++/* Maximum value allowed for timeout in synchronous routines below */
++#define USB_MAX_SYNCHRONOUS_TIMEOUT           60000   /* ms */
++
+ extern int usb_control_msg(struct usb_device *dev, unsigned int pipe,
+       __u8 request, __u8 requesttype, __u16 value, __u16 index,
+       void *data, __u16 size, int timeout);
diff --git a/queue-5.15/usb-core-quirks-add-huawei-me906s-device-to-wakeup-quirk.patch b/queue-5.15/usb-core-quirks-add-huawei-me906s-device-to-wakeup-quirk.patch
new file mode 100644 (file)
index 0000000..f65e138
--- /dev/null
@@ -0,0 +1,36 @@
+From 0326ff28d56b4fa202de36ffc8462a354f383a64 Mon Sep 17 00:00:00 2001
+From: Christoffer Sandberg <cs@tuxedo.de>
+Date: Fri, 6 Mar 2026 18:28:14 +0100
+Subject: usb/core/quirks: Add Huawei ME906S-device to wakeup quirk
+
+From: Christoffer Sandberg <cs@tuxedo.de>
+
+commit 0326ff28d56b4fa202de36ffc8462a354f383a64 upstream.
+
+Similar to other Huawei LTE modules using this quirk, this version with
+another vid/pid suffers from spurious wakeups.
+
+Setting the quirk fixes the issue for this device as well.
+
+Cc: stable <stable@kernel.org>
+Signed-off-by: Christoffer Sandberg <cs@tuxedo.de>
+Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
+Link: https://patch.msgid.link/20260306172817.2098898-1-wse@tuxedocomputers.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/quirks.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -205,6 +205,10 @@ static const struct usb_device_id usb_qu
+       /* HP v222w 16GB Mini USB Drive */
+       { USB_DEVICE(0x03f0, 0x3f40), .driver_info = USB_QUIRK_DELAY_INIT },
++      /* Huawei 4G LTE module ME906S  */
++      { USB_DEVICE(0x03f0, 0xa31d), .driver_info =
++                      USB_QUIRK_DISCONNECT_SUSPEND },
++
+       /* Creative SB Audigy 2 NX */
+       { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
diff --git a/queue-5.15/usb-image-mdc800-kill-download-urb-on-timeout.patch b/queue-5.15/usb-image-mdc800-kill-download-urb-on-timeout.patch
new file mode 100644 (file)
index 0000000..aa05bc0
--- /dev/null
@@ -0,0 +1,49 @@
+From 1be3b77de4eb89af8ae2fd6610546be778e25589 Mon Sep 17 00:00:00 2001
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Date: Mon, 9 Feb 2026 15:19:37 +0000
+Subject: usb: image: mdc800: kill download URB on timeout
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+commit 1be3b77de4eb89af8ae2fd6610546be778e25589 upstream.
+
+mdc800_device_read() submits download_urb and waits for completion.
+If the timeout fires and the device has not responded, the function
+returns without killing the URB, leaving it active.
+
+A subsequent read() resubmits the same URB while it is still
+in-flight, triggering the WARN in usb_submit_urb():
+
+  "URB submitted while active"
+
+Check the return value of wait_event_timeout() and kill the URB if
+it indicates timeout, ensuring the URB is complete before its status
+is inspected or the URB is resubmitted.
+
+Similar to
+- commit 372c93131998 ("USB: yurex: fix control-URB timeout handling")
+- commit b98d5000c505 ("media: rc: iguanair: handle timeouts")
+
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Cc: stable <stable@kernel.org>
+Link: https://patch.msgid.link/20260209151937.2247202-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/image/mdc800.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/image/mdc800.c
++++ b/drivers/usb/image/mdc800.c
+@@ -731,9 +731,11 @@ static ssize_t mdc800_device_read (struc
+                                       mutex_unlock(&mdc800->io_lock);
+                                       return len-left;
+                               }
+-                              wait_event_timeout(mdc800->download_wait,
++                              retval = wait_event_timeout(mdc800->download_wait,
+                                    mdc800->downloaded,
+                                    msecs_to_jiffies(TO_DOWNLOAD_GET_READY));
++                              if (!retval)
++                                      usb_kill_urb(mdc800->download_urb);
+                               mdc800->downloaded = 0;
+                               if (mdc800->download_urb->status != 0)
+                               {
diff --git a/queue-5.15/usb-mdc800-handle-signal-and-read-racing.patch b/queue-5.15/usb-mdc800-handle-signal-and-read-racing.patch
new file mode 100644 (file)
index 0000000..359c0a7
--- /dev/null
@@ -0,0 +1,32 @@
+From 2d6d260e9a3576256fe9ef6d1f7930c9ec348723 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Mon, 9 Feb 2026 15:20:48 +0100
+Subject: usb: mdc800: handle signal and read racing
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 2d6d260e9a3576256fe9ef6d1f7930c9ec348723 upstream.
+
+If a signal arrives after a read has partially completed,
+we need to return the number of bytes read. -EINTR is correct
+only if that number is zero.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Cc: stable <stable@kernel.org>
+Link: https://patch.msgid.link/20260209142048.1503791-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/image/mdc800.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/image/mdc800.c
++++ b/drivers/usb/image/mdc800.c
+@@ -708,7 +708,7 @@ static ssize_t mdc800_device_read (struc
+               if (signal_pending (current)) 
+               {
+                       mutex_unlock(&mdc800->io_lock);
+-                      return -EINTR;
++                      return len == left ? -EINTR : len-left;
+               }
+               sts=left > (mdc800->out_count-mdc800->out_ptr)?mdc800->out_count-mdc800->out_ptr:left;
diff --git a/queue-5.15/usb-misc-uss720-properly-clean-up-reference-in-uss720_probe.patch b/queue-5.15/usb-misc-uss720-properly-clean-up-reference-in-uss720_probe.patch
new file mode 100644 (file)
index 0000000..f7378c1
--- /dev/null
@@ -0,0 +1,33 @@
+From 45dba8011efac11a2f360383221b541f5ea53ce5 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Mon, 23 Feb 2026 13:19:43 +0100
+Subject: usb: misc: uss720: properly clean up reference in uss720_probe()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+commit 45dba8011efac11a2f360383221b541f5ea53ce5 upstream.
+
+If get_1284_register() fails, the usb device reference count is
+incorrect and needs to be properly dropped before returning.  That will
+happen when the kref is dropped in the call to destroy_priv(), so jump
+to that error path instead of returning directly.
+
+Cc: stable <stable@kernel.org>
+Assisted-by: gkh_clanker_2000
+Link: https://patch.msgid.link/2026022342-smokiness-stove-d792@gregkh
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/uss720.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/uss720.c
++++ b/drivers/usb/misc/uss720.c
+@@ -733,7 +733,7 @@ static int uss720_probe(struct usb_inter
+       ret = get_1284_register(pp, 0, &reg, GFP_KERNEL);
+       dev_dbg(&intf->dev, "reg: %7ph\n", priv->reg);
+       if (ret < 0)
+-              return ret;
++              goto probe_abort;
+       ret = usb_find_last_int_in_endpoint(interface, &epd);
+       if (!ret) {
diff --git a/queue-5.15/usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch b/queue-5.15/usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch
new file mode 100644 (file)
index 0000000..10c4b7c
--- /dev/null
@@ -0,0 +1,46 @@
+From 3cbc242b88c607f55da3d0d0d336b49bf1e20412 Mon Sep 17 00:00:00 2001
+From: Fan Wu <fanwu01@zju.edu.cn>
+Date: Tue, 3 Mar 2026 07:33:44 +0000
+Subject: usb: renesas_usbhs: fix use-after-free in ISR during device removal
+
+From: Fan Wu <fanwu01@zju.edu.cn>
+
+commit 3cbc242b88c607f55da3d0d0d336b49bf1e20412 upstream.
+
+In usbhs_remove(), the driver frees resources (including the pipe array)
+while the interrupt handler (usbhs_interrupt) is still registered. If an
+interrupt fires after usbhs_pipe_remove() but before the driver is fully
+unbound, the ISR may access freed memory, causing a use-after-free.
+
+Fix this by calling devm_free_irq() before freeing resources. This ensures
+the interrupt handler is both disabled and synchronized (waits for any
+running ISR to complete) before usbhs_pipe_remove() is called.
+
+Fixes: f1407d5c6624 ("usb: renesas_usbhs: Add Renesas USBHS common code")
+Cc: stable <stable@kernel.org>
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
+Link: https://patch.msgid.link/20260303073344.34577-1-fanwu01@zju.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/renesas_usbhs/common.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/usb/renesas_usbhs/common.c
++++ b/drivers/usb/renesas_usbhs/common.c
+@@ -804,6 +804,15 @@ static void usbhs_remove(struct platform
+       usbhs_platform_call(priv, hardware_exit, pdev);
+       reset_control_assert(priv->rsts);
++
++      /*
++       * Explicitly free the IRQ to ensure the interrupt handler is
++       * disabled and synchronized before freeing resources.
++       * devm_free_irq() calls free_irq() which waits for any running
++       * ISR to complete, preventing UAF.
++       */
++      devm_free_irq(&pdev->dev, priv->irq, priv);
++
+       usbhs_mod_remove(priv);
+       usbhs_fifo_remove(priv);
+       usbhs_pipe_remove(priv);
diff --git a/queue-5.15/usb-usbcore-introduce-usb_bulk_msg_killable.patch b/queue-5.15/usb-usbcore-introduce-usb_bulk_msg_killable.patch
new file mode 100644 (file)
index 0000000..e8ac81c
--- /dev/null
@@ -0,0 +1,166 @@
+From 416909962e7cdf29fd01ac523c953f37708df93d Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 17 Feb 2026 22:07:47 -0500
+Subject: USB: usbcore: Introduce usb_bulk_msg_killable()
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 416909962e7cdf29fd01ac523c953f37708df93d upstream.
+
+The synchronous message API in usbcore (usb_control_msg(),
+usb_bulk_msg(), and so on) uses uninterruptible waits.  However,
+drivers may call these routines in the context of a user thread, which
+means it ought to be possible to at least kill them.
+
+For this reason, introduce a new usb_bulk_msg_killable() function
+which behaves the same as usb_bulk_msg() except for using
+wait_for_completion_killable_timeout() instead of
+wait_for_completion_timeout().  The same can be done later for
+usb_control_msg() later on, if it turns out to be needed.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Suggested-by: Oliver Neukum <oneukum@suse.com>
+Link: https://lore.kernel.org/linux-usb/3acfe838-6334-4f6d-be7c-4bb01704b33d@rowland.harvard.edu/
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+CC: stable@vger.kernel.org
+Link: https://patch.msgid.link/248628b4-cc83-4e81-a620-3ce4e0376d41@rowland.harvard.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/message.c |   79 +++++++++++++++++++++++++++++++++++++++------
+ include/linux/usb.h        |    5 +-
+ 2 files changed, 72 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -41,16 +41,17 @@ static void usb_api_blocking_completion(
+ /*
+- * Starts urb and waits for completion or timeout. Note that this call
+- * is NOT interruptible. Many device driver i/o requests should be
+- * interruptible and therefore these drivers should implement their
+- * own interruptible routines.
++ * Starts urb and waits for completion or timeout.
++ * Whether or not the wait is killable depends on the flag passed in.
++ * For example, compare usb_bulk_msg() and usb_bulk_msg_killable().
+  */
+-static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
++static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length,
++              bool killable)
+ {
+       struct api_context ctx;
+       unsigned long expire;
+       int retval;
++      long rc;
+       init_completion(&ctx.done);
+       urb->context = &ctx;
+@@ -60,12 +61,21 @@ static int usb_start_wait_urb(struct urb
+               goto out;
+       expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
+-      if (!wait_for_completion_timeout(&ctx.done, expire)) {
++      if (killable)
++              rc = wait_for_completion_killable_timeout(&ctx.done, expire);
++      else
++              rc = wait_for_completion_timeout(&ctx.done, expire);
++      if (rc <= 0) {
+               usb_kill_urb(urb);
+-              retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status);
++              if (ctx.status != -ENOENT)
++                      retval = ctx.status;
++              else if (rc == 0)
++                      retval = -ETIMEDOUT;
++              else
++                      retval = rc;
+               dev_dbg(&urb->dev->dev,
+-                      "%s timed out on ep%d%s len=%u/%u\n",
++                      "%s timed out or killed on ep%d%s len=%u/%u\n",
+                       current->comm,
+                       usb_endpoint_num(&urb->ep->desc),
+                       usb_urb_dir_in(urb) ? "in" : "out",
+@@ -99,7 +109,7 @@ static int usb_internal_control_msg(stru
+       usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
+                            len, usb_api_blocking_completion, NULL);
+-      retv = usb_start_wait_urb(urb, timeout, &length);
++      retv = usb_start_wait_urb(urb, timeout, &length, false);
+       if (retv < 0)
+               return retv;
+       else
+@@ -384,10 +394,59 @@ int usb_bulk_msg(struct usb_device *usb_
+               usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
+                               usb_api_blocking_completion, NULL);
+-      return usb_start_wait_urb(urb, timeout, actual_length);
++      return usb_start_wait_urb(urb, timeout, actual_length, false);
+ }
+ EXPORT_SYMBOL_GPL(usb_bulk_msg);
++/**
++ * usb_bulk_msg_killable - Builds a bulk urb, sends it off and waits for completion in a killable state
++ * @usb_dev: pointer to the usb device to send the message to
++ * @pipe: endpoint "pipe" to send the message to
++ * @data: pointer to the data to send
++ * @len: length in bytes of the data to send
++ * @actual_length: pointer to a location to put the actual length transferred
++ *    in bytes
++ * @timeout: time in msecs to wait for the message to complete before
++ *    timing out (if 0 the wait is forever)
++ *
++ * Context: task context, might sleep.
++ *
++ * This function is just like usb_blk_msg() except that it waits in a
++ * killable state.
++ *
++ * Return:
++ * If successful, 0. Otherwise a negative error number. The number of actual
++ * bytes transferred will be stored in the @actual_length parameter.
++ *
++ */
++int usb_bulk_msg_killable(struct usb_device *usb_dev, unsigned int pipe,
++               void *data, int len, int *actual_length, int timeout)
++{
++      struct urb *urb;
++      struct usb_host_endpoint *ep;
++
++      ep = usb_pipe_endpoint(usb_dev, pipe);
++      if (!ep || len < 0)
++              return -EINVAL;
++
++      urb = usb_alloc_urb(0, GFP_KERNEL);
++      if (!urb)
++              return -ENOMEM;
++
++      if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
++                      USB_ENDPOINT_XFER_INT) {
++              pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
++              usb_fill_int_urb(urb, usb_dev, pipe, data, len,
++                              usb_api_blocking_completion, NULL,
++                              ep->desc.bInterval);
++      } else
++              usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
++                              usb_api_blocking_completion, NULL);
++
++      return usb_start_wait_urb(urb, timeout, actual_length, true);
++}
++EXPORT_SYMBOL_GPL(usb_bulk_msg_killable);
++
+ /*-------------------------------------------------------------------*/
+ static void sg_clean(struct usb_sg_request *io)
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -1811,8 +1811,9 @@ extern int usb_control_msg(struct usb_de
+ extern int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,
+       void *data, int len, int *actual_length, int timeout);
+ extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
+-      void *data, int len, int *actual_length,
+-      int timeout);
++      void *data, int len, int *actual_length, int timeout);
++extern int usb_bulk_msg_killable(struct usb_device *usb_dev, unsigned int pipe,
++      void *data, int len, int *actual_length, int timeout);
+ /* wrappers around usb_control_msg() for the most common standard requests */
+ int usb_control_msg_send(struct usb_device *dev, __u8 endpoint, __u8 request,
diff --git a/queue-5.15/usb-usbtmc-use-usb_bulk_msg_killable-with-user-specified-timeouts.patch b/queue-5.15/usb-usbtmc-use-usb_bulk_msg_killable-with-user-specified-timeouts.patch
new file mode 100644 (file)
index 0000000..a113a1b
--- /dev/null
@@ -0,0 +1,57 @@
+From 7784caa413a89487dd14dd5c41db8753483b2acb Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 17 Feb 2026 22:09:22 -0500
+Subject: USB: usbtmc: Use usb_bulk_msg_killable() with user-specified timeouts
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 7784caa413a89487dd14dd5c41db8753483b2acb upstream.
+
+The usbtmc driver accepts timeout values specified by the user in an
+ioctl command, and uses these timeouts for some usb_bulk_msg() calls.
+Since the user can specify arbitrarily long timeouts and
+usb_bulk_msg() uses unkillable waits, call usb_bulk_msg_killable()
+instead to avoid the possibility of the user hanging a kernel thread
+indefinitely.
+
+Reported-by: syzbot+25ba18e2c5040447585d@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/linux-usb/8e1c7ac5-e076-44b0-84b8-1b34b20f0ae1@suse.com/T/#t
+Tested-by: syzbot+25ba18e2c5040447585d@syzkaller.appspotmail.com
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Fixes: 048c6d88a021 ("usb: usbtmc: Add ioctls to set/get usb timeout")
+CC: stable@vger.kernel.org
+Link: https://patch.msgid.link/81c6fc24-0607-40f1-8c20-5270dab2fad5@rowland.harvard.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/class/usbtmc.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/class/usbtmc.c
++++ b/drivers/usb/class/usbtmc.c
+@@ -727,7 +727,7 @@ static int usbtmc488_ioctl_trigger(struc
+       buffer[1] = data->bTag;
+       buffer[2] = ~data->bTag;
+-      retval = usb_bulk_msg(data->usb_dev,
++      retval = usb_bulk_msg_killable(data->usb_dev,
+                             usb_sndbulkpipe(data->usb_dev,
+                                             data->bulk_out),
+                             buffer, USBTMC_HEADER_SIZE,
+@@ -1347,7 +1347,7 @@ static int send_request_dev_dep_msg_in(s
+       buffer[11] = 0; /* Reserved */
+       /* Send bulk URB */
+-      retval = usb_bulk_msg(data->usb_dev,
++      retval = usb_bulk_msg_killable(data->usb_dev,
+                             usb_sndbulkpipe(data->usb_dev,
+                                             data->bulk_out),
+                             buffer, USBTMC_HEADER_SIZE,
+@@ -1419,7 +1419,7 @@ static ssize_t usbtmc_read(struct file *
+       actual = 0;
+       /* Send bulk URB */
+-      retval = usb_bulk_msg(data->usb_dev,
++      retval = usb_bulk_msg_killable(data->usb_dev,
+                             usb_rcvbulkpipe(data->usb_dev,
+                                             data->bulk_in),
+                             buffer, bufsize, &actual,
diff --git a/queue-5.15/usb-xhci-fix-memory-leak-in-xhci_disable_slot.patch b/queue-5.15/usb-xhci-fix-memory-leak-in-xhci_disable_slot.patch
new file mode 100644 (file)
index 0000000..a5f5d5c
--- /dev/null
@@ -0,0 +1,66 @@
+From c1c8550e70401159184130a1afc6261db01fc0ce Mon Sep 17 00:00:00 2001
+From: Zilin Guan <zilin@seu.edu.cn>
+Date: Thu, 5 Mar 2026 00:36:37 +0200
+Subject: usb: xhci: Fix memory leak in xhci_disable_slot()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+commit c1c8550e70401159184130a1afc6261db01fc0ce upstream.
+
+xhci_alloc_command() allocates a command structure and, when the
+second argument is true, also allocates a completion structure.
+Currently, the error handling path in xhci_disable_slot() only frees
+the command structure using kfree(), causing the completion structure
+to leak.
+
+Use xhci_free_command() instead of kfree(). xhci_free_command() correctly
+frees both the command structure and the associated completion structure.
+Since the command structure is allocated with zero-initialization,
+command->in_ctx is NULL and will not be erroneously freed by
+xhci_free_command().
+
+This bug was found using an experimental static analysis tool we are
+developing. The tool is based on the LLVM framework and is specifically
+designed to detect memory management issues. It is currently under
+active development and not yet publicly available, but we plan to
+open-source it after our research is published.
+
+The bug was originally detected on v6.13-rc1 using our static analysis
+tool, and we have verified that the issue persists in the latest mainline
+kernel.
+
+We performed build testing on x86_64 with allyesconfig using GCC=11.4.0.
+Since triggering these error paths in xhci_disable_slot() requires specific
+hardware conditions or abnormal state, we were unable to construct a test
+case to reliably trigger these specific error paths at runtime.
+
+Fixes: 7faac1953ed1 ("xhci: avoid race between disable slot command and host runtime suspend")
+CC: stable@vger.kernel.org
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://patch.msgid.link/20260304223639.3882398-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -4056,7 +4056,7 @@ int xhci_disable_slot(struct xhci_hcd *x
+       if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) ||
+                       (xhci->xhc_state & XHCI_STATE_HALTED)) {
+               spin_unlock_irqrestore(&xhci->lock, flags);
+-              kfree(command);
++              xhci_free_command(xhci, command);
+               return -ENODEV;
+       }
+@@ -4064,7 +4064,7 @@ int xhci_disable_slot(struct xhci_hcd *x
+                               slot_id);
+       if (ret) {
+               spin_unlock_irqrestore(&xhci->lock, flags);
+-              kfree(command);
++              xhci_free_command(xhci, command);
+               return ret;
+       }
+       xhci_ring_cmd_db(xhci);
diff --git a/queue-5.15/usb-yurex-fix-race-in-probe.patch b/queue-5.15/usb-yurex-fix-race-in-probe.patch
new file mode 100644 (file)
index 0000000..150a704
--- /dev/null
@@ -0,0 +1,41 @@
+From 7a875c09899ba0404844abfd8f0d54cdc481c151 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Mon, 9 Feb 2026 15:37:20 +0100
+Subject: usb: yurex: fix race in probe
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 7a875c09899ba0404844abfd8f0d54cdc481c151 upstream.
+
+The bbu member of the descriptor must be set to the value
+standing for uninitialized values before the URB whose
+completion handler sets bbu is submitted. Otherwise there is
+a window during which probing can overwrite already retrieved
+data.
+
+Cc: stable <stable@kernel.org>
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Link: https://patch.msgid.link/20260209143720.1507500-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/yurex.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/yurex.c
++++ b/drivers/usb/misc/yurex.c
+@@ -272,6 +272,7 @@ static int yurex_probe(struct usb_interf
+                        dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt,
+                        dev, 1);
+       dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++      dev->bbu = -1;
+       if (usb_submit_urb(dev->urb, GFP_KERNEL)) {
+               retval = -EIO;
+               dev_err(&interface->dev, "Could not submitting URB\n");
+@@ -280,7 +281,6 @@ static int yurex_probe(struct usb_interf
+       /* save our data pointer in this interface device */
+       usb_set_intfdata(interface, dev);
+-      dev->bbu = -1;
+       /* we can register the device now, as it is ready */
+       retval = usb_register_dev(interface, &yurex_class);