From: Greg Kroah-Hartman Date: Tue, 14 Jul 2026 16:50:57 +0000 (+0200) Subject: 5.10-stable patches X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a1b30ad317d9d1c8290a49062a6ba208fa12936;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: net-usb-kalmia-bound-rx-frame-length-in-kalmia_rx_fixup.patch usb-cdc_acm-add-quirk-for-uniden-bc125at-scanner.patch usb-core-add-usb_quirk_no_lpm-for-via-labs-usb-2.0-hub.patch usb-dwc3-meson-g12a-fix-refcount-leak-in-dwc3_meson_g12a_resume.patch usb-gadget-composite-fix-dead-empty-check-in-the-usb_dt_otg-handler.patch usb-idmouse-fix-use-after-free-on-disconnect-race.patch usb-iowarrior-fix-use-after-free-on-disconnect.patch usb-ldusb-fix-use-after-free-on-disconnect-race.patch usb-legousbtower-fix-use-after-free-on-disconnect-race.patch usb-misc-uss720-unregister-parport-on-probe-failure.patch usb-mtu3-unmap-request-dma-on-queue-failure.patch usb-quirks-add-no_lpm-for-the-samsung-t5-evo-portable-ssd.patch usb-serial-digi_acceleport-fix-broken-rx-after-throttle.patch usb-serial-digi_acceleport-fix-hard-lockup-on-disconnect.patch usb-serial-option-add-telit-cinterion-fe990d50-compositions.patch usb-sl811-hcd-disable-controller-wakeup-on-remove.patch usb-storage-include-us_fl_no_same-in-quirks-mask.patch usb-typec-tcpm-validate-svid-index-in-svdm_consume_modes.patch usb-typec-ucsi-invert-displayport-role-assignment.patch usb-typec-ucsi-pass-full-dp-config-payload-in-set_new_cam-for-dp-alt-mode.patch usb-ulpi-fix-memory-leak-on-registration-failure.patch usb-usb-storage-ene_ub6250-restore-media-ready-check.patch usbip-tools-support-superspeedplus-devices.patch usbip-vudc-fix-null-deref-in-vep_dequeue.patch --- diff --git a/queue-5.10/net-usb-kalmia-bound-rx-frame-length-in-kalmia_rx_fixup.patch b/queue-5.10/net-usb-kalmia-bound-rx-frame-length-in-kalmia_rx_fixup.patch new file mode 100644 index 0000000000..077cf54ef8 --- /dev/null +++ b/queue-5.10/net-usb-kalmia-bound-rx-frame-length-in-kalmia_rx_fixup.patch @@ -0,0 +1,53 @@ +From 47b6bcef6e679593d2e86e04ee72c46a4e2f7139 Mon Sep 17 00:00:00 2001 +From: Maoyi Xie +Date: Mon, 22 Jun 2026 16:01:57 +0800 +Subject: net: usb: kalmia: bound RX frame length in kalmia_rx_fixup() + +From: Maoyi Xie + +commit 47b6bcef6e679593d2e86e04ee72c46a4e2f7139 upstream. + +kalmia_rx_fixup() computes usb_packet_length = skb->len - (2 * +KALMIA_HEADER_LENGTH) as a u16, guarded only by a pre-loop check that +skb->len is at least KALMIA_HEADER_LENGTH, which is 6. A device can +deliver a short bulk-IN frame with skb->len in the 6 to 11 range, or +leave a short trailing remainder on a later loop iteration. Either case +underflows usb_packet_length to about 65530. + +That bypasses the usb_packet_length < ether_packet_length truncation path. +The device-supplied ether_packet_length, a le16 up to 65535 read from +header_start[2], then drives a memcmp() and the following skb_trim() and +skb_pull() past the end of the rx buffer. The rx buffer is hard_mtu * 10, +which is 14000 bytes. That is an out of bounds read. + +Require both the start and end framing headers to be present before +subtracting them, on every loop iteration. + +Fixes: d40261236e8e ("net/usb: Add Samsung Kalmia driver for Samsung GT-B3730") +Cc: stable@vger.kernel.org +Signed-off-by: Maoyi Xie +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/178211531778.2216480.12637613349790980750@maoyixie.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/kalmia.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/net/usb/kalmia.c ++++ b/drivers/net/usb/kalmia.c +@@ -276,6 +276,14 @@ kalmia_rx_fixup(struct usbnet *dev, stru + "Received header: %6phC. Package length: %i\n", + header_start, skb->len - KALMIA_HEADER_LENGTH); + ++ /* both framing headers must be present before we subtract ++ * them, otherwise usb_packet_length underflows and the ++ * device-supplied ether_packet_length drives an out of bounds ++ * access below ++ */ ++ if (skb->len < 2 * KALMIA_HEADER_LENGTH) ++ return 0; ++ + /* subtract start header and end header */ + usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH); + ether_packet_length = get_unaligned_le16(&header_start[2]); diff --git a/queue-5.10/series b/queue-5.10/series index 19101acf1d..95ef10120a 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -93,3 +93,27 @@ hid-lg-g15-cancel-pending-work-on-remove-to-fix-a-use-after-free.patch hid-sensor-hub-add-sensor_hub_input_attr_read_values-for-multi-byte-reads.patch hfs-hfsplus-zero-initialize-buffer-in-hfs_bnode_read.patch nilfs2-reject-clean_segments-ioctl-with-out-of-range-segment-numbers.patch +net-usb-kalmia-bound-rx-frame-length-in-kalmia_rx_fixup.patch +usb-cdc_acm-add-quirk-for-uniden-bc125at-scanner.patch +usb-core-add-usb_quirk_no_lpm-for-via-labs-usb-2.0-hub.patch +usb-dwc3-meson-g12a-fix-refcount-leak-in-dwc3_meson_g12a_resume.patch +usb-gadget-composite-fix-dead-empty-check-in-the-usb_dt_otg-handler.patch +usb-idmouse-fix-use-after-free-on-disconnect-race.patch +usb-ldusb-fix-use-after-free-on-disconnect-race.patch +usb-iowarrior-fix-use-after-free-on-disconnect.patch +usb-quirks-add-no_lpm-for-the-samsung-t5-evo-portable-ssd.patch +usb-legousbtower-fix-use-after-free-on-disconnect-race.patch +usb-sl811-hcd-disable-controller-wakeup-on-remove.patch +usb-storage-include-us_fl_no_same-in-quirks-mask.patch +usb-misc-uss720-unregister-parport-on-probe-failure.patch +usb-mtu3-unmap-request-dma-on-queue-failure.patch +usb-serial-option-add-telit-cinterion-fe990d50-compositions.patch +usb-serial-digi_acceleport-fix-broken-rx-after-throttle.patch +usb-serial-digi_acceleport-fix-hard-lockup-on-disconnect.patch +usb-ulpi-fix-memory-leak-on-registration-failure.patch +usb-usb-storage-ene_ub6250-restore-media-ready-check.patch +usbip-tools-support-superspeedplus-devices.patch +usbip-vudc-fix-null-deref-in-vep_dequeue.patch +usb-typec-tcpm-validate-svid-index-in-svdm_consume_modes.patch +usb-typec-ucsi-invert-displayport-role-assignment.patch +usb-typec-ucsi-pass-full-dp-config-payload-in-set_new_cam-for-dp-alt-mode.patch diff --git a/queue-5.10/usb-cdc_acm-add-quirk-for-uniden-bc125at-scanner.patch b/queue-5.10/usb-cdc_acm-add-quirk-for-uniden-bc125at-scanner.patch new file mode 100644 index 0000000000..d8ed5a2546 --- /dev/null +++ b/queue-5.10/usb-cdc_acm-add-quirk-for-uniden-bc125at-scanner.patch @@ -0,0 +1,124 @@ +From 6eba58568f6cc3ff8515a00b05e258d8cfb72b72 Mon Sep 17 00:00:00 2001 +From: Jared Baldridge +Date: Sat, 30 May 2026 18:19:48 -0400 +Subject: usb: cdc_acm: Add quirk for Uniden BC125AT scanner + +From: Jared Baldridge + +commit 6eba58568f6cc3ff8515a00b05e258d8cfb72b72 upstream. + +Uniden BC125AT radio scanner has a USB interface which fails to work +with the cdc_acm driver: + usb 1-1: new full-speed USB device number 2 using uhci_hcd + cdc_acm 1-1:1.0: Zero length descriptor references + cdc_acm 1-1:1.0: probe with driver cdc_acm failed with error -22 + usbcore: registered new interface driver cdc_acm + +Adding the NO_UNION_NORMAL quirk for the device fixes the issue: + + usb 1-1: new full-speed USB device number 2 using uhci_hcd + cdc_acm 1-1:1.0: ttyACM0: USB ACM device + usbcore: registered new interface driver cdc_acm + +`lsusb -v` of the device: + + Bus 001 Device 002: ID 1965:0017 Uniden Corporation BC125AT + Negotiated speed: Full Speed (12Mbps) + Device Descriptor: + bLength 18 + bDescriptorType 1 + bcdUSB 2.00 + bDeviceClass 2 Communications + bDeviceSubClass 0 [unknown] + bDeviceProtocol 0 + bMaxPacketSize0 64 + idVendor 0x1965 Uniden Corporation + idProduct 0x0017 BC125AT + bcdDevice 0.01 + iManufacturer 1 Uniden America Corp. + iProduct 2 BC125AT + iSerial 3 0001 + bNumConfigurations 1 + Configuration Descriptor: + bLength 9 + bDescriptorType 2 + wTotalLength 0x0030 + bNumInterfaces 2 + bConfigurationValue 1 + iConfiguration 0 + bmAttributes 0x80 + (Bus Powered) + MaxPower 500mA + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 0 + bAlternateSetting 0 + bNumEndpoints 1 + bInterfaceClass 2 Communications + bInterfaceSubClass 2 Abstract (modem) + bInterfaceProtocol 0 + iInterface 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x87 EP 7 IN + bmAttributes 3 + Transfer Type Interrupt + Synch Type None + Usage Type Data + wMaxPacketSize 0x0008 1x 8 bytes + bInterval 10 + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 1 + bAlternateSetting 0 + bNumEndpoints 2 + bInterfaceClass 10 CDC Data + bInterfaceSubClass 0 [unknown] + bInterfaceProtocol 0 + iInterface 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x81 EP 1 IN + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0040 1x 64 bytes + bInterval 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x02 EP 2 OUT + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0040 1x 64 bytes + bInterval 0 + Device Status: 0x0000 + (Bus Powered) + +Signed-off-by: Jared Baldridge +Cc: stable +Link: https://patch.msgid.link/20260530221959.612526-1-jrb@expunge.us +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/class/cdc-acm.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1788,6 +1788,9 @@ static const struct usb_device_id acm_id + { USB_DEVICE(0x1901, 0x0006), /* GE Healthcare Patient Monitor UI Controller */ + .driver_info = DISABLE_ECHO, /* DISABLE ECHO in termios flag */ + }, ++ { USB_DEVICE(0x1965, 0x0017), /* Uniden BC125AT */ ++ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ ++ }, + { USB_DEVICE(0x1965, 0x0018), /* Uniden UBC125XLT */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, diff --git a/queue-5.10/usb-core-add-usb_quirk_no_lpm-for-via-labs-usb-2.0-hub.patch b/queue-5.10/usb-core-add-usb_quirk_no_lpm-for-via-labs-usb-2.0-hub.patch new file mode 100644 index 0000000000..4d5a80048f --- /dev/null +++ b/queue-5.10/usb-core-add-usb_quirk_no_lpm-for-via-labs-usb-2.0-hub.patch @@ -0,0 +1,49 @@ +From bd728c3d9b1cc0bb0fda6a7055c5c8b55d7477b2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rodrigo=20Lugathe=20da=20Concei=C3=A7=C3=A3o=20Alves?= + +Date: Wed, 3 Jun 2026 08:36:26 -0300 +Subject: USB: core: add USB_QUIRK_NO_LPM for VIA Labs USB 2.0 hub +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rodrigo Lugathe da Conceição Alves + +commit bd728c3d9b1cc0bb0fda6a7055c5c8b55d7477b2 upstream. + +The VIA Labs, Inc. USB 2.0 hub controller (2109:2817), +found in a KVM switch, fails to enumerate high-power devices during +cold boot and system restart. + +Applying the kernel parameter + usbcore.quirks=2109:2817:k +resolves the issue. + +Enumeration failure log: + usb 1-1.2.3: device descriptor read/64, error -32 + usb 1-1.2.3: Device not responding to setup address. + usb 1-1.2.3: device not accepting address 11, error -71 + usb 1-1.2-port3: unable to enumerate USB device + +Add USB_QUIRK_NO_LPM for this device. + +Signed-off-by: Rodrigo Lugathe da Conceição Alves +Cc: stable +Link: https://patch.msgid.link/20260603113626.395612-1-lugathe2@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/quirks.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -561,6 +561,9 @@ static const struct usb_device_id usb_qu + /* VLI disk */ + { USB_DEVICE(0x2109, 0x0711), .driver_info = USB_QUIRK_NO_LPM }, + ++ /* VIA Labs, Inc. USB2.0 Hub */ ++ { USB_DEVICE(0x2109, 0x2817), .driver_info = USB_QUIRK_NO_LPM }, ++ + /* Raydium Touchscreen */ + { USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM }, + diff --git a/queue-5.10/usb-dwc3-meson-g12a-fix-refcount-leak-in-dwc3_meson_g12a_resume.patch b/queue-5.10/usb-dwc3-meson-g12a-fix-refcount-leak-in-dwc3_meson_g12a_resume.patch new file mode 100644 index 0000000000..0ecf57ec11 --- /dev/null +++ b/queue-5.10/usb-dwc3-meson-g12a-fix-refcount-leak-in-dwc3_meson_g12a_resume.patch @@ -0,0 +1,77 @@ +From 692c354bef03b77b30e57e61934da502c8a12d45 Mon Sep 17 00:00:00 2001 +From: WenTao Liang +Date: Thu, 11 Jun 2026 21:11:21 +0800 +Subject: usb: dwc3: meson-g12a: fix refcount leak in dwc3_meson_g12a_resume() + +From: WenTao Liang + +commit 692c354bef03b77b30e57e61934da502c8a12d45 upstream. + +If dwc3_meson_g12a_resume() succeeds in calling +reset_control_reset(), an internal triggered_count reference is +acquired. If any later step fails (usb_init, phy_init, +phy_power_on, regulator_enable, or usb_post_init), the function +returns the error without rearming the reset control. This leaks +the reference and leaves the reset control in a triggered state, +causing future reset_control_reset() calls to incorrectly return +early as if already reset. + +Add an error path that calls reset_control_rearm() to balance +the reference before returning the error. + +Cc: stable +Fixes: 5b0ba0caaf3a ("usb: dwc3: meson-g12a: refactor usb init") +Signed-off-by: WenTao Liang +Link: https://patch.msgid.link/20260611131121.81784-1-vulab@iscas.ac.cn +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/dwc3-meson-g12a.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/drivers/usb/dwc3/dwc3-meson-g12a.c ++++ b/drivers/usb/dwc3/dwc3-meson-g12a.c +@@ -912,35 +912,39 @@ static int __maybe_unused dwc3_meson_g12 + + ret = priv->drvdata->usb_init(priv); + if (ret) +- return ret; ++ goto err_rearm; + + /* Init PHYs */ + for (i = 0 ; i < PHY_COUNT ; ++i) { + ret = phy_init(priv->phys[i]); + if (ret) +- return ret; ++ goto err_rearm; + } + + /* Set PHY Power */ + for (i = 0 ; i < PHY_COUNT ; ++i) { + ret = phy_power_on(priv->phys[i]); + if (ret) +- return ret; ++ goto err_rearm; + } + + if (priv->vbus && priv->otg_phy_mode == PHY_MODE_USB_HOST) { + ret = regulator_enable(priv->vbus); + if (ret) +- return ret; ++ goto err_rearm; + } + + if (priv->drvdata->usb_post_init) { + ret = priv->drvdata->usb_post_init(priv); + if (ret) +- return ret; ++ goto err_rearm; + } + + return 0; ++ ++err_rearm: ++ reset_control_rearm(priv->reset); ++ return ret; + } + + static const struct dev_pm_ops dwc3_meson_g12a_dev_pm_ops = { diff --git a/queue-5.10/usb-gadget-composite-fix-dead-empty-check-in-the-usb_dt_otg-handler.patch b/queue-5.10/usb-gadget-composite-fix-dead-empty-check-in-the-usb_dt_otg-handler.patch new file mode 100644 index 0000000000..ee6a42dc70 --- /dev/null +++ b/queue-5.10/usb-gadget-composite-fix-dead-empty-check-in-the-usb_dt_otg-handler.patch @@ -0,0 +1,61 @@ +From f8f680609c2b3ab795ffcd6f21585b6dfc46d395 Mon Sep 17 00:00:00 2001 +From: Maoyi Xie +Date: Wed, 27 May 2026 23:08:32 +0800 +Subject: usb: gadget: composite: fix dead empty check in the USB_DT_OTG handler + +From: Maoyi Xie + +commit f8f680609c2b3ab795ffcd6f21585b6dfc46d395 upstream. + +The OTG branch of composite_setup() falls back to the first +configuration when none is selected: + + if (cdev->config) + config = cdev->config; + else + config = list_first_entry(&cdev->configs, + struct usb_configuration, list); + if (!config) + goto done; + ... + memcpy(req->buf, config->descriptors[0], value); + +list_first_entry() never returns NULL. On an empty list it returns +container_of() of the list head. So the "if (!config)" check is dead. + +When cdev->configs is empty, config points at the head inside struct +usb_composite_dev. config->descriptors[0] reads whatever sits at that +offset. The memcpy copies up to w_length bytes of it into the response +buffer. + +cdev->configs can be empty in two cases. One is a teardown race on +gadget unbind with a control transfer in flight. The other is a driver +that sets is_otg before it adds a config. A reproducer that holds +cdev->configs empty triggers a KASAN fault in this branch. + +Use list_first_entry_or_null() so the existing check does its job. + +Fixes: 53e6242db8d6 ("usb: gadget: composite: add USB_DT_OTG request handling") +Cc: stable +Signed-off-by: Maoyi Xie +Link: https://patch.msgid.link/20260527150832.2943293-1-maoyixie.tju@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/composite.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -1747,9 +1747,10 @@ composite_setup(struct usb_gadget *gadge + if (cdev->config) + config = cdev->config; + else +- config = list_first_entry( ++ config = list_first_entry_or_null( + &cdev->configs, +- struct usb_configuration, list); ++ struct usb_configuration, ++ list); + if (!config) + goto done; + diff --git a/queue-5.10/usb-idmouse-fix-use-after-free-on-disconnect-race.patch b/queue-5.10/usb-idmouse-fix-use-after-free-on-disconnect-race.patch new file mode 100644 index 0000000000..5d37cb6902 --- /dev/null +++ b/queue-5.10/usb-idmouse-fix-use-after-free-on-disconnect-race.patch @@ -0,0 +1,151 @@ +From ff002c153f9722caece3983cc23dc4d9d4652cb4 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 22 Jun 2026 17:26:10 +0200 +Subject: USB: idmouse: fix use-after-free on disconnect race + +From: Johan Hovold + +commit ff002c153f9722caece3983cc23dc4d9d4652cb4 upstream. + +mutex_unlock() may access the mutex structure after releasing the lock +and therefore cannot be used to manage lifetime of objects directly +(unlike spinlocks and refcounts). [1][2] + +Use a kref to release the driver data to avoid use-after-free in +mutex_unlock() when release() races with disconnect(). + +[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is + non-atomic") +[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most + other sleeping locks, can still use the lock object + after it's unlocked") + +Fixes: 54d2bc068fd2 ("USB: fix locking in idmouse") +Cc: stable@vger.kernel.org # 2.6.24 +Cc: Oliver Neukum +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20260622152612.116422-3-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/idmouse.c | 45 ++++++++++++++++++++++----------------------- + 1 file changed, 22 insertions(+), 23 deletions(-) + +--- a/drivers/usb/misc/idmouse.c ++++ b/drivers/usb/misc/idmouse.c +@@ -63,6 +63,7 @@ MODULE_DEVICE_TABLE(usb, idmouse_table); + + /* structure to hold all of our device specific stuff */ + struct usb_idmouse { ++ struct kref kref; + + struct usb_device *udev; /* save off the usb device pointer */ + struct usb_interface *interface; /* the interface for this device */ +@@ -209,8 +210,10 @@ static int idmouse_resume(struct usb_int + return 0; + } + +-static inline void idmouse_delete(struct usb_idmouse *dev) ++static inline void idmouse_delete(struct kref *kref) + { ++ struct usb_idmouse *dev = container_of(kref, struct usb_idmouse, kref); ++ + kfree(dev->bulk_in_buffer); + kfree(dev); + } +@@ -254,6 +257,8 @@ static int idmouse_open(struct inode *in + /* increment our usage count for the driver */ + ++dev->open; + ++ kref_get(&dev->kref); ++ + /* save our object in the file's private structure */ + file->private_data = dev; + +@@ -277,16 +282,11 @@ static int idmouse_release(struct inode + + /* lock our device */ + mutex_lock(&dev->lock); +- + --dev->open; ++ mutex_unlock(&dev->lock); ++ ++ kref_put(&dev->kref, idmouse_delete); + +- if (!dev->present) { +- /* the device was unplugged before the file was released */ +- mutex_unlock(&dev->lock); +- idmouse_delete(dev); +- } else { +- mutex_unlock(&dev->lock); +- } + return 0; + } + +@@ -334,6 +334,7 @@ static int idmouse_probe(struct usb_inte + if (dev == NULL) + return -ENOMEM; + ++ kref_init(&dev->kref); + mutex_init(&dev->lock); + dev->udev = udev; + dev->interface = interface; +@@ -342,8 +343,7 @@ static int idmouse_probe(struct usb_inte + result = usb_find_bulk_in_endpoint(iface_desc, &endpoint); + if (result) { + dev_err(&interface->dev, "Unable to find bulk-in endpoint.\n"); +- idmouse_delete(dev); +- return result; ++ goto err_put_kref; + } + + dev->orig_bi_size = usb_endpoint_maxp(endpoint); +@@ -351,8 +351,8 @@ static int idmouse_probe(struct usb_inte + dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; + dev->bulk_in_buffer = kmalloc(IMGSIZE + dev->bulk_in_size, GFP_KERNEL); + if (!dev->bulk_in_buffer) { +- idmouse_delete(dev); +- return -ENOMEM; ++ result = -ENOMEM; ++ goto err_put_kref; + } + + /* allow device read, write and ioctl */ +@@ -364,14 +364,18 @@ static int idmouse_probe(struct usb_inte + if (result) { + /* something prevented us from registering this device */ + dev_err(&interface->dev, "Unable to allocate minor number.\n"); +- idmouse_delete(dev); +- return result; ++ goto err_put_kref; + } + + /* be noisy */ + dev_info(&interface->dev,"%s now attached\n",DRIVER_DESC); + + return 0; ++ ++err_put_kref: ++ kref_put(&dev->kref, idmouse_delete); ++ ++ return result; + } + + static void idmouse_disconnect(struct usb_interface *interface) +@@ -387,14 +391,9 @@ static void idmouse_disconnect(struct us + /* prevent device read, write and ioctl */ + dev->present = 0; + +- /* if the device is opened, idmouse_release will clean this up */ +- if (!dev->open) { +- mutex_unlock(&dev->lock); +- idmouse_delete(dev); +- } else { +- /* unlock */ +- mutex_unlock(&dev->lock); +- } ++ mutex_unlock(&dev->lock); ++ ++ kref_put(&dev->kref, idmouse_delete); + + dev_info(&interface->dev, "disconnected\n"); + } diff --git a/queue-5.10/usb-iowarrior-fix-use-after-free-on-disconnect.patch b/queue-5.10/usb-iowarrior-fix-use-after-free-on-disconnect.patch new file mode 100644 index 0000000000..8c8e143830 --- /dev/null +++ b/queue-5.10/usb-iowarrior-fix-use-after-free-on-disconnect.patch @@ -0,0 +1,44 @@ +From bc0e4f16c44e50daa0b1ea729934baa3b4815dee Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Sat, 23 May 2026 19:05:23 +0200 +Subject: USB: iowarrior: fix use-after-free on disconnect + +From: Johan Hovold + +commit bc0e4f16c44e50daa0b1ea729934baa3b4815dee upstream. + +Submitted write URBs are not stopped on close() and therefore need to be +stopped unconditionally on disconnect() to avoid use-after-free in the +completion handler. + +Fixes: b5f8d46867ca ("USB: iowarrior: fix use-after-free after driver unbind") +Fixes: 946b960d13c1 ("USB: add driver for iowarrior devices.") +Reported-by: syzbot+ad2aac2febc3bedf0962@syzkaller.appspotmail.com +Link: https://lore.kernel.org/all/6a0ce39b.170a0220.39a13.0007.GAE@google.com/ +Cc: stable +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20260523170523.1074563-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/iowarrior.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/misc/iowarrior.c ++++ b/drivers/usb/misc/iowarrior.c +@@ -923,13 +923,15 @@ static void iowarrior_disconnect(struct + /* prevent device read, write and ioctl */ + dev->present = 0; + ++ /* write urbs are not stopped on close() so kill unconditionally */ ++ usb_kill_anchored_urbs(&dev->submitted); ++ + if (dev->opened) { + /* There is a process that holds a filedescriptor to the device , + so we only shutdown read-/write-ops going on. + Deleting the device is postponed until close() was called. + */ + usb_kill_urb(dev->int_in_urb); +- usb_kill_anchored_urbs(&dev->submitted); + wake_up_interruptible(&dev->read_wait); + wake_up_interruptible(&dev->write_wait); + mutex_unlock(&dev->mutex); diff --git a/queue-5.10/usb-ldusb-fix-use-after-free-on-disconnect-race.patch b/queue-5.10/usb-ldusb-fix-use-after-free-on-disconnect-race.patch new file mode 100644 index 0000000000..cbe4d25623 --- /dev/null +++ b/queue-5.10/usb-ldusb-fix-use-after-free-on-disconnect-race.patch @@ -0,0 +1,135 @@ +From 19bdfc7b3c179331eafa423d87e1336f43bbfeb8 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 22 Jun 2026 17:26:11 +0200 +Subject: USB: ldusb: fix use-after-free on disconnect race + +From: Johan Hovold + +commit 19bdfc7b3c179331eafa423d87e1336f43bbfeb8 upstream. + +mutex_unlock() may access the mutex structure after releasing the lock +and therefore cannot be used to manage lifetime of objects directly +(unlike spinlocks and refcounts). [1][2] + +Use a kref to release the driver data to avoid use-after-free in +mutex_unlock() when release() races with disconnect(). + +[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is + non-atomic") +[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most + other sleeping locks, can still use the lock object + after it's unlocked") + +Fixes: ce0d7d3f575f ("usb: ldusb: ld_usb semaphore to mutex") +Cc: stable +Cc: Daniel Walker +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20260622152612.116422-4-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/ldusb.c | 38 ++++++++++++++++++-------------------- + 1 file changed, 18 insertions(+), 20 deletions(-) + +--- a/drivers/usb/misc/ldusb.c ++++ b/drivers/usb/misc/ldusb.c +@@ -151,6 +151,7 @@ MODULE_PARM_DESC(min_interrupt_out_inter + + /* Structure to hold all of our device specific stuff */ + struct ld_usb { ++ struct kref kref; + struct mutex mutex; /* locks this structure */ + struct usb_interface *intf; /* save off the usb interface pointer */ + unsigned long disconnected:1; +@@ -202,8 +203,10 @@ static void ld_usb_abort_transfers(struc + /* + * ld_usb_delete + */ +-static void ld_usb_delete(struct ld_usb *dev) ++static void ld_usb_delete(struct kref *kref) + { ++ struct ld_usb *dev = container_of(kref, struct ld_usb, kref); ++ + /* free data structures */ + usb_free_urb(dev->interrupt_in_urb); + usb_free_urb(dev->interrupt_out_urb); +@@ -356,6 +359,8 @@ static int ld_usb_open(struct inode *ino + goto unlock_exit; + } + ++ kref_get(&dev->kref); ++ + /* save device in the file's private structure */ + file->private_data = dev; + +@@ -382,17 +387,8 @@ static int ld_usb_release(struct inode * + + mutex_lock(&dev->mutex); + +- if (dev->open_count != 1) { +- retval = -ENODEV; ++ if (dev->disconnected) + goto unlock_exit; +- } +- if (dev->disconnected) { +- /* the device was unplugged before the file was released */ +- mutex_unlock(&dev->mutex); +- /* unlock here as ld_usb_delete frees dev */ +- ld_usb_delete(dev); +- goto exit; +- } + + /* wait until write transfer is finished */ + if (dev->interrupt_out_busy) +@@ -402,7 +398,7 @@ static int ld_usb_release(struct inode * + + unlock_exit: + mutex_unlock(&dev->mutex); +- ++ kref_put(&dev->kref, ld_usb_delete); + exit: + return retval; + } +@@ -661,6 +657,8 @@ static int ld_usb_probe(struct usb_inter + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + goto exit; ++ ++ kref_init(&dev->kref); + mutex_init(&dev->mutex); + spin_lock_init(&dev->rbsl); + dev->intf = intf; +@@ -740,7 +738,7 @@ exit: + return retval; + + error: +- ld_usb_delete(dev); ++ kref_put(&dev->kref, ld_usb_delete); + + return retval; + } +@@ -768,18 +766,18 @@ static void ld_usb_disconnect(struct usb + + mutex_lock(&dev->mutex); + +- /* if the device is not opened, then we clean up right now */ +- if (!dev->open_count) { +- mutex_unlock(&dev->mutex); +- ld_usb_delete(dev); +- } else { +- dev->disconnected = 1; ++ dev->disconnected = 1; ++ ++ if (dev->open_count) { + /* wake up pollers */ + wake_up_interruptible_all(&dev->read_wait); + wake_up_interruptible_all(&dev->write_wait); +- mutex_unlock(&dev->mutex); + } + ++ mutex_unlock(&dev->mutex); ++ ++ kref_put(&dev->kref, ld_usb_delete); ++ + dev_info(&intf->dev, "LD USB Device #%d now disconnected\n", + (minor - USB_LD_MINOR_BASE)); + } diff --git a/queue-5.10/usb-legousbtower-fix-use-after-free-on-disconnect-race.patch b/queue-5.10/usb-legousbtower-fix-use-after-free-on-disconnect-race.patch new file mode 100644 index 0000000000..2a6f432614 --- /dev/null +++ b/queue-5.10/usb-legousbtower-fix-use-after-free-on-disconnect-race.patch @@ -0,0 +1,141 @@ +From 62fc8eb1b1481051f7bab4aa93d79809053dd09f Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 22 Jun 2026 17:26:12 +0200 +Subject: USB: legousbtower: fix use-after-free on disconnect race + +From: Johan Hovold + +commit 62fc8eb1b1481051f7bab4aa93d79809053dd09f upstream. + +mutex_unlock() may access the mutex structure after releasing the lock +and therefore cannot be used to manage lifetime of objects directly +(unlike spinlocks and refcounts). [1][2] + +Use a kref to release the driver data to avoid use-after-free in +mutex_unlock() when release() races with disconnect(). + +[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is + non-atomic") +[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most + other sleeping locks, can still use the lock object + after it's unlocked") + +Fixes: 18bcbcfe9ca2 ("USB: misc: legousbtower: semaphore to mutex") +Cc: stable +Cc: Daniel Walker +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20260622152612.116422-5-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/legousbtower.c | 37 +++++++++++++++++++------------------ + 1 file changed, 19 insertions(+), 18 deletions(-) + +--- a/drivers/usb/misc/legousbtower.c ++++ b/drivers/usb/misc/legousbtower.c +@@ -185,6 +185,7 @@ MODULE_DEVICE_TABLE(usb, tower_table); + + /* Structure to hold all of our device specific stuff */ + struct lego_usb_tower { ++ struct kref kref; + struct mutex lock; /* locks this structure */ + struct usb_device *udev; /* save off the usb device pointer */ + unsigned char minor; /* the starting minor number for this device */ +@@ -220,7 +221,6 @@ struct lego_usb_tower { + /* local function prototypes */ + static ssize_t tower_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos); + static ssize_t tower_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos); +-static inline void tower_delete(struct lego_usb_tower *dev); + static int tower_open(struct inode *inode, struct file *file); + static int tower_release(struct inode *inode, struct file *file); + static __poll_t tower_poll(struct file *file, poll_table *wait); +@@ -286,8 +286,10 @@ static inline void lego_usb_tower_debug_ + /* + * tower_delete + */ +-static inline void tower_delete(struct lego_usb_tower *dev) ++static inline void tower_delete(struct kref *kref) + { ++ struct lego_usb_tower *dev = container_of(kref, struct lego_usb_tower, kref); ++ + /* free data structures */ + usb_free_urb(dev->interrupt_in_urb); + usb_free_urb(dev->interrupt_out_urb); +@@ -381,6 +383,8 @@ static int tower_open(struct inode *inod + + dev->open_count = 1; + ++ kref_get(&dev->kref); ++ + unlock_exit: + mutex_unlock(&dev->lock); + +@@ -404,14 +408,8 @@ static int tower_release(struct inode *i + + mutex_lock(&dev->lock); + +- if (dev->disconnected) { +- /* the device was unplugged before the file was released */ +- +- /* unlock here as tower_delete frees dev */ +- mutex_unlock(&dev->lock); +- tower_delete(dev); +- goto exit; +- } ++ if (dev->disconnected) ++ goto out_unlock; + + /* wait until write transfer is finished */ + if (dev->interrupt_out_busy) { +@@ -425,7 +423,9 @@ static int tower_release(struct inode *i + + dev->open_count = 0; + ++out_unlock: + mutex_unlock(&dev->lock); ++ kref_put(&dev->kref, tower_delete); + exit: + return retval; + } +@@ -752,6 +752,7 @@ static int tower_probe(struct usb_interf + if (!dev) + goto exit; + ++ kref_init(&dev->kref); + mutex_init(&dev->lock); + dev->udev = usb_get_dev(udev); + spin_lock_init(&dev->read_buffer_lock); +@@ -828,7 +829,7 @@ exit: + return retval; + + error: +- tower_delete(dev); ++ kref_put(&dev->kref, tower_delete); + return retval; + } + +@@ -856,18 +857,18 @@ static void tower_disconnect(struct usb_ + + mutex_lock(&dev->lock); + +- /* if the device is not opened, then we clean up right now */ +- if (!dev->open_count) { +- mutex_unlock(&dev->lock); +- tower_delete(dev); +- } else { +- dev->disconnected = 1; ++ dev->disconnected = 1; ++ ++ if (dev->open_count) { + /* wake up pollers */ + wake_up_interruptible_all(&dev->read_wait); + wake_up_interruptible_all(&dev->write_wait); +- mutex_unlock(&dev->lock); + } + ++ mutex_unlock(&dev->lock); ++ ++ kref_put(&dev->kref, tower_delete); ++ + dev_info(&interface->dev, "LEGO USB Tower #%d now disconnected\n", + (minor - LEGO_USB_TOWER_MINOR_BASE)); + } diff --git a/queue-5.10/usb-misc-uss720-unregister-parport-on-probe-failure.patch b/queue-5.10/usb-misc-uss720-unregister-parport-on-probe-failure.patch new file mode 100644 index 0000000000..86724bc683 --- /dev/null +++ b/queue-5.10/usb-misc-uss720-unregister-parport-on-probe-failure.patch @@ -0,0 +1,54 @@ +From b4ecbdc4f8830f5586c4a5cfc384c00f20f8f8b3 Mon Sep 17 00:00:00 2001 +From: Myeonghun Pak +Date: Tue, 7 Jul 2026 00:10:49 +0900 +Subject: USB: misc: uss720: unregister parport on probe failure + +From: Myeonghun Pak + +commit b4ecbdc4f8830f5586c4a5cfc384c00f20f8f8b3 upstream. + +uss720_probe() registers a parport before reading the 1284 register used +to detect unsupported Belkin F5U002 adapters. If get_1284_register() +fails, the error path drops the driver private data and the USB device +reference, but leaves the parport device registered. + +Leaving the port registered is more than a private allocation leak: +parport_register_port() has already reserved a parport number and +registered the parport bus device, while pp->private_data still points at +the private data that the common error path is about to release. + +Undo the pre-announce registration in the get_1284_register() failure +branch before jumping to the common private-data cleanup path. Clear +priv->pp first, matching the disconnect path and avoiding a stale pointer +in the private data. + +This issue was identified during our ongoing static-analysis research while +reviewing kernel code. + +Fixes: 3295f1b866bf ("usb: misc: uss720: check for incompatible versions of the Belkin F5U002") +Cc: stable +Co-developed-by: Ijae Kim +Signed-off-by: Ijae Kim +Signed-off-by: Myeonghun Pak +Reviewed-by: Alex Henrie +Link: https://patch.msgid.link/20260706151049.63470-1-mhun512@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/uss720.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/usb/misc/uss720.c ++++ b/drivers/usb/misc/uss720.c +@@ -732,8 +732,11 @@ static int uss720_probe(struct usb_inter + * here. */ + ret = get_1284_register(pp, 0, ®, GFP_KERNEL); + dev_dbg(&intf->dev, "reg: %7ph\n", priv->reg); +- if (ret < 0) ++ if (ret < 0) { ++ priv->pp = NULL; ++ parport_del_port(pp); + goto probe_abort; ++ } + + ret = usb_find_last_int_in_endpoint(interface, &epd); + if (!ret) { diff --git a/queue-5.10/usb-mtu3-unmap-request-dma-on-queue-failure.patch b/queue-5.10/usb-mtu3-unmap-request-dma-on-queue-failure.patch new file mode 100644 index 0000000000..ed4a33bb51 --- /dev/null +++ b/queue-5.10/usb-mtu3-unmap-request-dma-on-queue-failure.patch @@ -0,0 +1,38 @@ +From 0bddda5a11665c210339de76d27ebbd1a2e0b43c Mon Sep 17 00:00:00 2001 +From: Haoxiang Li +Date: Tue, 23 Jun 2026 17:33:25 +0800 +Subject: usb: mtu3: unmap request DMA on queue failure + +From: Haoxiang Li + +commit 0bddda5a11665c210339de76d27ebbd1a2e0b43c upstream. + +mtu3_gadget_queue() maps the request before checking whether +the QMU GPD ring can accept another transfer. the request is +returned with -EAGAIN before it is linked on the endpoint +request list if mtu3_prepare_transfer() fails. + +Normal completion and dequeue paths unmap requests from +mtu3_req_complete(), but this error path never reaches that +helper, so the DMA mapping is left active. Unmap the request +before returning from the failed queue path. + +Fixes: df2069acb005 ("usb: Add MediaTek USB3 DRD driver") +Cc: stable +Signed-off-by: Haoxiang Li +Link: https://patch.msgid.link/20260623093325.2105323-1-haoxiang_li2024@163.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/mtu3/mtu3_gadget.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/mtu3/mtu3_gadget.c ++++ b/drivers/usb/mtu3/mtu3_gadget.c +@@ -305,6 +305,7 @@ static int mtu3_gadget_queue(struct usb_ + + if (mtu3_prepare_transfer(mep)) { + ret = -EAGAIN; ++ usb_gadget_unmap_request(&mtu->g, req, mep->is_in); + goto error; + } + diff --git a/queue-5.10/usb-quirks-add-no_lpm-for-the-samsung-t5-evo-portable-ssd.patch b/queue-5.10/usb-quirks-add-no_lpm-for-the-samsung-t5-evo-portable-ssd.patch new file mode 100644 index 0000000000..b169a99e61 --- /dev/null +++ b/queue-5.10/usb-quirks-add-no_lpm-for-the-samsung-t5-evo-portable-ssd.patch @@ -0,0 +1,43 @@ +From fc591787785b9709a0bb65a7df3ba2537d611c47 Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +Date: Tue, 2 Jun 2026 14:45:08 -0600 +Subject: USB: quirks: add NO_LPM for the Samsung T5 EVO Portable SSD + +From: Erich E. Hoover + +commit fc591787785b9709a0bb65a7df3ba2537d611c47 upstream. + +The Samsung T5 EVO Portable SSD (04e8:6200) exhibit two forms of +link instability when USB Link Power Management is enabled: + + 1. The units fail to initialize properly on first detection, + resulting in a lockup in the drive where it must be power cycled + or the kernel will not recognize the presence of the device. + + 2. If used for sustained operations (small amounts of continuous + data are transferred to the unit) then the unit will "hiccup" + after roughly 8 hours of use and will disconnect and reconnect. + This has a certain probability of triggering the first issue, + but also causes mount points to become invalid since the device + gets issued a new letter. + +Signed-off-by: Erich E. Hoover +Cc: stable +Link: https://patch.msgid.link/20260602204508.48856-1-erich.e.hoover@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/quirks.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -292,6 +292,9 @@ static const struct usb_device_id usb_qu + /* CarrolTouch 4500U */ + { USB_DEVICE(0x04e7, 0x0030), .driver_info = USB_QUIRK_RESET_RESUME }, + ++ /* Samsung T5 EVO Portable SSD */ ++ { USB_DEVICE(0x04e8, 0x6200), .driver_info = USB_QUIRK_NO_LPM }, ++ + /* Samsung Android phone modem - ID conflict with SPH-I500 */ + { USB_DEVICE(0x04e8, 0x6601), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, diff --git a/queue-5.10/usb-serial-digi_acceleport-fix-broken-rx-after-throttle.patch b/queue-5.10/usb-serial-digi_acceleport-fix-broken-rx-after-throttle.patch new file mode 100644 index 0000000000..aa4e2e0dcf --- /dev/null +++ b/queue-5.10/usb-serial-digi_acceleport-fix-broken-rx-after-throttle.patch @@ -0,0 +1,56 @@ +From 83a3dfc018943b05b6daf3a6f891833e1aabfa1f Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 23 Jun 2026 17:08:15 +0200 +Subject: USB: serial: digi_acceleport: fix broken rx after throttle + +From: Johan Hovold + +commit 83a3dfc018943b05b6daf3a6f891833e1aabfa1f upstream. + +If the port is closed while throttled, the read urb is never resubmitted +and the port will not receive any further data until the device is +reconnected (or the driver is rebound). + +Clear the throttle flags and submit the urb if needed when opening the +port. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/digi_acceleport.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/usb/serial/digi_acceleport.c ++++ b/drivers/usb/serial/digi_acceleport.c +@@ -1070,6 +1070,7 @@ static int digi_open(struct tty_struct * + unsigned char buf[32]; + struct digi_port *priv = usb_get_serial_port_data(port); + struct ktermios not_termios; ++ int throttled; + + /* be sure the device is started up */ + if (digi_startup_device(port->serial) != 0) +@@ -1097,6 +1098,21 @@ static int digi_open(struct tty_struct * + not_termios.c_iflag = ~tty->termios.c_iflag; + digi_set_termios(tty, port, ¬_termios); + } ++ ++ spin_lock_irq(&priv->dp_port_lock); ++ throttled = priv->dp_throttle_restart; ++ priv->dp_throttled = 0; ++ priv->dp_throttle_restart = 0; ++ spin_unlock_irq(&priv->dp_port_lock); ++ ++ if (throttled) { ++ ret = usb_submit_urb(port->read_urb, GFP_KERNEL); ++ if (ret) { ++ dev_err(&port->dev, "failed to submit read urb: %d\n", ret); ++ return ret; ++ } ++ } ++ + return 0; + } + diff --git a/queue-5.10/usb-serial-digi_acceleport-fix-hard-lockup-on-disconnect.patch b/queue-5.10/usb-serial-digi_acceleport-fix-hard-lockup-on-disconnect.patch new file mode 100644 index 0000000000..259b34985b --- /dev/null +++ b/queue-5.10/usb-serial-digi_acceleport-fix-hard-lockup-on-disconnect.patch @@ -0,0 +1,52 @@ +From 5c1ea24b53bf3bfb859f0a05573997487975da23 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 23 Jun 2026 17:11:10 +0200 +Subject: USB: serial: digi_acceleport: fix hard lockup on disconnect + +From: Johan Hovold + +commit 5c1ea24b53bf3bfb859f0a05573997487975da23 upstream. + +If submitting the OOB write urb fails persistently (e.g if the device is +being disconnected) the driver would loop indefinitely with interrupts +disabled. + +Check for urb submission errors when sending OOB commands to avoid +hanging if, for example, open(), set_termios() or close() races with a +physical disconnect. + +This is issue was flagged by Sashiko when reviewing an unrelated change +to the driver. + +Link: https://sashiko.dev/#/patchset/20260610132232.356139-1-johan%40kernel.org?part=1 +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/digi_acceleport.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/usb/serial/digi_acceleport.c ++++ b/drivers/usb/serial/digi_acceleport.c +@@ -394,12 +394,14 @@ static int digi_write_oob_command(struct + len &= ~3; + memcpy(oob_port->write_urb->transfer_buffer, buf, len); + oob_port->write_urb->transfer_buffer_length = len; ++ + ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC); +- if (ret == 0) { +- oob_priv->dp_write_urb_in_use = 1; +- count -= len; +- buf += len; +- } ++ if (ret) ++ break; ++ ++ oob_priv->dp_write_urb_in_use = 1; ++ count -= len; ++ buf += len; + } + spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags); + if (ret) diff --git a/queue-5.10/usb-serial-option-add-telit-cinterion-fe990d50-compositions.patch b/queue-5.10/usb-serial-option-add-telit-cinterion-fe990d50-compositions.patch new file mode 100644 index 0000000000..ab7ffe2cdd --- /dev/null +++ b/queue-5.10/usb-serial-option-add-telit-cinterion-fe990d50-compositions.patch @@ -0,0 +1,207 @@ +From b33ab1dd80f5c1742f49eb6ec7b337c5ffcf3d32 Mon Sep 17 00:00:00 2001 +From: Fabio Porcedda +Date: Fri, 12 Jun 2026 13:39:16 +0200 +Subject: USB: serial: option: add Telit Cinterion FE990D50 compositions + +From: Fabio Porcedda + +commit b33ab1dd80f5c1742f49eb6ec7b337c5ffcf3d32 upstream. + +Add support for Telit Cinterion FE990D50 compositions: + +0x990: RNDIS + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) + + tty (diag) + ADPL + adb +T: Bus=01 Lev=01 Prnt=01 Port=06 Cnt=03 Dev#= 3 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=1bc7 ProdID=0990 Rev=06.06 +S: Manufacturer=Telit Cinterion +S: Product=FE990 +S: SerialNumber=90b6a3ed +C: #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host +E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms +I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) +E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none) +E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) +E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +0x991: rmnet + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) + + tty (diag) + ADPL + adb +T: Bus=01 Lev=01 Prnt=01 Port=06 Cnt=03 Dev#= 9 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=1bc7 ProdID=0991 Rev=06.06 +S: Manufacturer=Telit Cinterion +S: Product=FE990 +S: SerialNumber=90b6a3ed +C: #Ifs= 9 Cfg#= 1 Atr=e0 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=(none) +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms +I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 6 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) +E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none) +E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 8 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) +E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +0x992: MBIM + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) + + tty (diag) + ADPL + adb +T: Bus=01 Lev=01 Prnt=01 Port=06 Cnt=03 Dev#= 12 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=1bc7 ProdID=0992 Rev=06.06 +S: Manufacturer=Telit Cinterion +S: Product=FE990 +S: SerialNumber=90b6a3ed +C: #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim +E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) +E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none) +E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) +E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +0x993: ECM + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) + + tty (diag) + ADPL + adb +T: Bus=01 Lev=01 Prnt=01 Port=06 Cnt=03 Dev#= 15 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=1bc7 ProdID=0993 Rev=06.06 +S: Manufacturer=Telit Cinterion +S: Product=FE990 +S: SerialNumber=90b6a3ed +C: #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether +E: Ad=82(I) Atr=03(Int.) MxPS= 16 Ivl=32ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) +E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none) +E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) +E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Cc: stable@vger.kernel.org +Signed-off-by: Fabio Porcedda +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1326,6 +1326,22 @@ static const struct usb_device_id option + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0990, 0xff, 0xff, 0x30), /* Telit FE990D50 (RNDIS) */ ++ .driver_info = NCTRL(6) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0990, 0xff, 0xff, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0990, 0xff, 0xff, 0x60) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0991, 0xff, 0xff, 0x30), /* Telit FE990D50 (rmnet) */ ++ .driver_info = NCTRL(5) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0991, 0xff, 0xff, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0991, 0xff, 0xff, 0x60) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0992, 0xff, 0xff, 0x30), /* Telit FE990D50 (MBIM) */ ++ .driver_info = NCTRL(6) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0992, 0xff, 0xff, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0992, 0xff, 0xff, 0x60) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0993, 0xff, 0xff, 0x30), /* Telit FE990D50 (ECM) */ ++ .driver_info = NCTRL(6) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0993, 0xff, 0xff, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0993, 0xff, 0xff, 0x60) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1031, 0xff), /* Telit LE910C1-EUX */ + .driver_info = NCTRL(0) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff), /* Telit LE910C1-EUX (ECM) */ diff --git a/queue-5.10/usb-sl811-hcd-disable-controller-wakeup-on-remove.patch b/queue-5.10/usb-sl811-hcd-disable-controller-wakeup-on-remove.patch new file mode 100644 index 0000000000..7f9fa1c0ca --- /dev/null +++ b/queue-5.10/usb-sl811-hcd-disable-controller-wakeup-on-remove.patch @@ -0,0 +1,41 @@ +From 4e8ba83ac4d311992e6a4c21de5dd705010df06e Mon Sep 17 00:00:00 2001 +From: Myeonghun Pak +Date: Wed, 1 Jul 2026 21:16:25 +0900 +Subject: usb: sl811-hcd: disable controller wakeup on remove + +From: Myeonghun Pak + +commit 4e8ba83ac4d311992e6a4c21de5dd705010df06e upstream. + +sl811h_probe() enables the HCD controller device as a wakeup source after +usb_add_hcd() succeeds, but sl811h_remove() removes the HCD and releases +the driver resources without disabling that wakeup source. + +Disable controller wakeup after usb_remove_hcd() and before usb_put_hcd() +so the wakeup source object is detached while the controller device pointer +is still available. + +This issue was identified during our ongoing static-analysis research while +reviewing kernel code. + +Fixes: 3c9740a117d4 ("usb: hcd: move controller wakeup setting initialization to individual driver") +Cc: stable +Co-developed-by: Ijae Kim +Signed-off-by: Ijae Kim +Signed-off-by: Myeonghun Pak +Link: https://patch.msgid.link/20260701121625.96815-1-mhun512@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/sl811-hcd.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/host/sl811-hcd.c ++++ b/drivers/usb/host/sl811-hcd.c +@@ -1591,6 +1591,7 @@ sl811h_remove(struct platform_device *de + + remove_debug_file(sl811); + usb_remove_hcd(hcd); ++ device_wakeup_disable(hcd->self.controller); + + /* some platforms may use IORESOURCE_IO */ + res = platform_get_resource(dev, IORESOURCE_MEM, 1); diff --git a/queue-5.10/usb-storage-include-us_fl_no_same-in-quirks-mask.patch b/queue-5.10/usb-storage-include-us_fl_no_same-in-quirks-mask.patch new file mode 100644 index 0000000000..fd5f880f6c --- /dev/null +++ b/queue-5.10/usb-storage-include-us_fl_no_same-in-quirks-mask.patch @@ -0,0 +1,45 @@ +From 2c00e09e3f9f06f8434f5ea2ee6179ce46692ee6 Mon Sep 17 00:00:00 2001 +From: Xu Rao +Date: Tue, 2 Jun 2026 13:38:42 +0800 +Subject: USB: storage: include US_FL_NO_SAME in quirks mask + +From: Xu Rao + +commit 2c00e09e3f9f06f8434f5ea2ee6179ce46692ee6 upstream. + +usb_stor_adjust_quirks() parses the usb-storage.quirks module +parameter into a new flag set and then applies it with the quirk +mask to override built-in flags. + +The mask is meant to cover the flags that can be overridden by +the module parameter. The 'k' quirk character sets US_FL_NO_SAME, +but US_FL_NO_SAME is not included in the mask. + +As a result, the module parameter can set US_FL_NO_SAME, but it +cannot clear a built-in US_FL_NO_SAME flag by providing an override +entry that omits 'k'. + +Add US_FL_NO_SAME to the mask so that the module parameter can +override it in the same way as the other supported flags. + +Fixes: 8010622c86ca ("USB: UAS: introduce a quirk to set no_write_same") +Cc: stable +Signed-off-by: Xu Rao +Reviewed-by: Alan Stern +Link: https://patch.msgid.link/3BCE5880F9A45C2E+20260602053842.2920137-1-raoxu@uniontech.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/storage/usb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/storage/usb.c ++++ b/drivers/usb/storage/usb.c +@@ -488,7 +488,7 @@ void usb_stor_adjust_quirks(struct usb_d + US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE | + US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES | + US_FL_MAX_SECTORS_240 | US_FL_NO_REPORT_LUNS | +- US_FL_ALWAYS_SYNC); ++ US_FL_ALWAYS_SYNC | US_FL_NO_SAME); + + p = quirks; + while (*p) { diff --git a/queue-5.10/usb-typec-tcpm-validate-svid-index-in-svdm_consume_modes.patch b/queue-5.10/usb-typec-tcpm-validate-svid-index-in-svdm_consume_modes.patch new file mode 100644 index 0000000000..a00e5f5d97 --- /dev/null +++ b/queue-5.10/usb-typec-tcpm-validate-svid-index-in-svdm_consume_modes.patch @@ -0,0 +1,57 @@ +From 7b681dd5fbf60b24a13c14661e5b7735759fb491 Mon Sep 17 00:00:00 2001 +From: Badhri Jagan Sridharan +Date: Mon, 22 Jun 2026 22:08:03 +0000 +Subject: usb: typec: tcpm: Validate SVID index in svdm_consume_modes() + +From: Badhri Jagan Sridharan + +commit 7b681dd5fbf60b24a13c14661e5b7735759fb491 upstream. + +In svdm_consume_modes(), the SVID value is read from pmdata->svids using +pmdata->svid_index as an array index without bounds validation: + + paltmode->svid = pmdata->svids[pmdata->svid_index]; + +If pmdata->svid_index is driven beyond SVID_DISCOVERY_MAX (16), it results +in an out-of-bounds read of the pmdata->svids array. Because pd_mode_data +is embedded inside struct tcpm_port, indexing past svids reads into +adjacent fields. In particular: +- At index 16, it reads the altmodes count. +- At index 18 and beyond, it reads into altmode_desc[], which contains + partner-supplied SVDM Discovery Modes VDOs. + +By injecting a chosen SVID into altmode_desc[0].vdo and driving svid_index +to 20, the partner can force paltmode->svid to be loaded with an arbitrary, +partner- chosen SVID, which is then registered via +typec_partner_register_altmode(). + +Fix this by validating that pmdata->svid_index is non-negative and strictly +less than pmdata->nsvids before accessing the pmdata->svids array inside +svdm_consume_modes(). + +Assisted-by: Antigravity:gemini-3.5-flash +Fixes: 4ab8c18d4d67 ("usb: typec: Register a device for every mode") +Cc: stable +Signed-off-by: Badhri Jagan Sridharan +Reviewed-by: RD Babiera +Acked-by: Heikki Krogerus +Link: https://patch.msgid.link/20260622220803.305750-1-badhri@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/tcpm/tcpm.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/usb/typec/tcpm/tcpm.c ++++ b/drivers/usb/typec/tcpm/tcpm.c +@@ -1157,6 +1157,11 @@ static void svdm_consume_modes(struct tc + return; + } + ++ if (pmdata->svid_index < 0 || pmdata->svid_index >= pmdata->nsvids) { ++ tcpm_log(port, "Invalid SVID index %d", pmdata->svid_index); ++ return; ++ } ++ + for (i = 1; i < cnt; i++) { + paltmode = &pmdata->altmode_desc[pmdata->altmodes]; + memset(paltmode, 0, sizeof(*paltmode)); diff --git a/queue-5.10/usb-typec-ucsi-invert-displayport-role-assignment.patch b/queue-5.10/usb-typec-ucsi-invert-displayport-role-assignment.patch new file mode 100644 index 0000000000..e2c0be59b0 --- /dev/null +++ b/queue-5.10/usb-typec-ucsi-invert-displayport-role-assignment.patch @@ -0,0 +1,48 @@ +From d092d7edf8faefa3e27b9fc7f0e7904b06c833a2 Mon Sep 17 00:00:00 2001 +From: Andrei Kuchynski +Date: Mon, 1 Jun 2026 14:28:37 +0000 +Subject: usb: typec: ucsi: Invert DisplayPort role assignment + +From: Andrei Kuchynski + +commit d092d7edf8faefa3e27b9fc7f0e7904b06c833a2 upstream. + +The existing implementation assigned these flags backwards, configuring +the partner's DisplayPort role to match the port's role instead of +complementing it. +This prevents proper configuration during DP altmode activation, often +causing `pin_assignment` to remain 0 in `dp_altmode_configure()` and +resulting in VDM negotiation failures: + + [ 583.328246] typec port1.1: VDM 0xff01a150 failed + +Additionally, the fix ensures that the `pin_assignment` sysfs attribute +displays the correct values. + +Cc: stable +Fixes: af8622f6a585 ("usb: typec: ucsi: Support for DisplayPort alt mode") +Signed-off-by: Andrei Kuchynski +Reviewed-by: Heikki Krogerus +Link: https://patch.msgid.link/20260601142837.3240207-1-akuchynski@chromium.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/displayport.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/typec/ucsi/displayport.c ++++ b/drivers/usb/typec/ucsi/displayport.c +@@ -150,12 +150,12 @@ static int ucsi_displayport_status_updat + * that Multi-function is preferred. + */ + if (DP_CAP_CAPABILITY(cap) & DP_CAP_UFP_D) { +- dp->data.status |= DP_STATUS_CON_UFP_D; ++ dp->data.status |= DP_STATUS_CON_DFP_D; + + if (DP_CAP_UFP_D_PIN_ASSIGN(cap) & BIT(DP_PIN_ASSIGN_D)) + dp->data.status |= DP_STATUS_PREFER_MULTI_FUNC; + } else { +- dp->data.status |= DP_STATUS_CON_DFP_D; ++ dp->data.status |= DP_STATUS_CON_UFP_D; + + if (DP_CAP_DFP_D_PIN_ASSIGN(cap) & BIT(DP_PIN_ASSIGN_D)) + dp->data.status |= DP_STATUS_PREFER_MULTI_FUNC; diff --git a/queue-5.10/usb-typec-ucsi-pass-full-dp-config-payload-in-set_new_cam-for-dp-alt-mode.patch b/queue-5.10/usb-typec-ucsi-pass-full-dp-config-payload-in-set_new_cam-for-dp-alt-mode.patch new file mode 100644 index 0000000000..c97b9131ef --- /dev/null +++ b/queue-5.10/usb-typec-ucsi-pass-full-dp-config-payload-in-set_new_cam-for-dp-alt-mode.patch @@ -0,0 +1,48 @@ +From 735a461d060d4eeb2f9732aba1295bc32a3982e2 Mon Sep 17 00:00:00 2001 +From: Madhu M +Date: Fri, 19 Jun 2026 21:03:11 +0530 +Subject: usb: typec: ucsi: Pass full DP config payload in SET_NEW_CAM for DP alt mode + +From: Madhu M + +commit 735a461d060d4eeb2f9732aba1295bc32a3982e2 upstream. + +In the UCSI Specification Revision 3.1 RC1, bits 32-63 of the SET_NEW_CAM +command hold the 32-bit Alternate Mode Specific (AMSpecific) field. + +For DisplayPort Alternate Mode, this field must contain the full +32-bit DisplayPort configuration VDO payload that the OPM wants the +connector to operate in, rather than just the pin assignment value. +This AMSpecific value follows the DisplayPort Configurations defined +in the DisplayPort Alt Mode on USB Type-C Specification v2.1a, +Table 5-13: SOP DisplayPort Configurations. + +Fixes: af8622f6a585 ("usb: typec: ucsi: Support for DisplayPort alt mode") +Cc: stable +Signed-off-by: Madhu M +Reviewed-by: Jameson Thies +Reviewed-by: Andrei Kuchynski +Reviewed-by: Heikki Krogerus +Link: https://patch.msgid.link/20260619153311.3526083-1-madhu.m@intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/displayport.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/usb/typec/ucsi/displayport.c ++++ b/drivers/usb/typec/ucsi/displayport.c +@@ -169,13 +169,12 @@ static int ucsi_displayport_status_updat + + static int ucsi_displayport_configure(struct ucsi_dp *dp) + { +- u32 pins = DP_CONF_GET_PIN_ASSIGN(dp->data.conf); + u64 command; + + if (!dp->override) + return 0; + +- command = UCSI_CMD_SET_NEW_CAM(dp->con->num, 1, dp->offset, pins); ++ command = UCSI_CMD_SET_NEW_CAM(dp->con->num, 1, dp->offset, dp->data.conf); + + return ucsi_send_command(dp->con->ucsi, command, NULL, 0); + } diff --git a/queue-5.10/usb-ulpi-fix-memory-leak-on-registration-failure.patch b/queue-5.10/usb-ulpi-fix-memory-leak-on-registration-failure.patch new file mode 100644 index 0000000000..b9db8dde5d --- /dev/null +++ b/queue-5.10/usb-ulpi-fix-memory-leak-on-registration-failure.patch @@ -0,0 +1,76 @@ +From 8af6812795869a66e9b26044f455b13deecdb69c Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 8 Jun 2026 16:58:03 +0200 +Subject: USB: ulpi: fix memory leak on registration failure + +From: Johan Hovold + +commit 8af6812795869a66e9b26044f455b13deecdb69c upstream. + +The allocated device name is never freed on early ULPI device +registration failures. + +Fix this by initialising the device structure earlier and releasing the +initial reference whenever registration fails. + +Fixes: 289fcff4bcdb ("usb: add bus type for USB ULPI") +Cc: stable +Cc: Heikki Krogerus +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20260608145803.69360-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/common/ulpi.c | 23 ++++++++++------------- + 1 file changed, 10 insertions(+), 13 deletions(-) + +--- a/drivers/usb/common/ulpi.c ++++ b/drivers/usb/common/ulpi.c +@@ -241,28 +241,24 @@ static int ulpi_register(struct device * + ulpi->dev.parent = dev; /* needed early for ops */ + ulpi->dev.bus = &ulpi_bus; + ulpi->dev.type = &ulpi_dev_type; ++ ++ device_initialize(&ulpi->dev); ++ + dev_set_name(&ulpi->dev, "%s.ulpi", dev_name(dev)); + + ACPI_COMPANION_SET(&ulpi->dev, ACPI_COMPANION(dev)); + + ret = ulpi_of_register(ulpi); +- if (ret) { +- kfree(ulpi); ++ if (ret) + return ret; +- } + + ret = ulpi_read_id(ulpi); +- if (ret) { +- of_node_put(ulpi->dev.of_node); +- kfree(ulpi); ++ if (ret) + return ret; +- } + +- ret = device_register(&ulpi->dev); +- if (ret) { +- put_device(&ulpi->dev); ++ ret = device_add(&ulpi->dev); ++ if (ret) + return ret; +- } + + dev_dbg(&ulpi->dev, "registered ULPI PHY: vendor %04x, product %04x\n", + ulpi->id.vendor, ulpi->id.product); +@@ -291,9 +287,10 @@ struct ulpi *ulpi_register_interface(str + ulpi->ops = ops; + + ret = ulpi_register(dev, ulpi); +- if (ret) ++ if (ret) { ++ put_device(&ulpi->dev); + return ERR_PTR(ret); +- ++ } + + return ulpi; + } diff --git a/queue-5.10/usb-usb-storage-ene_ub6250-restore-media-ready-check.patch b/queue-5.10/usb-usb-storage-ene_ub6250-restore-media-ready-check.patch new file mode 100644 index 0000000000..571af4abb4 --- /dev/null +++ b/queue-5.10/usb-usb-storage-ene_ub6250-restore-media-ready-check.patch @@ -0,0 +1,47 @@ +From 5fc3f333c001f1e308bbcdeecdec0d054d24338b Mon Sep 17 00:00:00 2001 +From: Xu Rao +Date: Fri, 26 Jun 2026 15:06:07 +0800 +Subject: USB: usb-storage: ene_ub6250: restore media-ready check + +From: Xu Rao + +commit 5fc3f333c001f1e308bbcdeecdec0d054d24338b upstream. + +Commit 1892bf90677a ("USB: usb-storage: Fix use of bitfields for +hardware data in ene_ub6250.c") converted the media status fields from +bitfields to bit masks. + +The original ene_transport() test called ene_init() only when neither +media type was ready: + + !(sd_ready || ms_ready) + +The converted test became: + + !sd_ready || ms_ready + +This is not equivalent. Restore the original semantics by testing that +both ready bits are clear before calling ene_init(). + +Fixes: 1892bf90677a ("USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c") +Cc: stable +Signed-off-by: Xu Rao +Reviewed-by: Alan Stern +Link: https://patch.msgid.link/F42641386E32404F+20260626070607.4119527-1-raoxu@uniontech.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/storage/ene_ub6250.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/storage/ene_ub6250.c ++++ b/drivers/usb/storage/ene_ub6250.c +@@ -2305,7 +2305,8 @@ static int ene_transport(struct scsi_cmn + + /*US_DEBUG(usb_stor_show_command(us, srb)); */ + scsi_set_resid(srb, 0); +- if (unlikely(!(info->SD_Status & SD_Ready) || (info->MS_Status & MS_Ready))) ++ if (unlikely(!(info->SD_Status & SD_Ready) && ++ !(info->MS_Status & MS_Ready))) + result = ene_init(us); + if (result == USB_STOR_XFER_GOOD) { + result = USB_STOR_TRANSPORT_ERROR; diff --git a/queue-5.10/usbip-tools-support-superspeedplus-devices.patch b/queue-5.10/usbip-tools-support-superspeedplus-devices.patch new file mode 100644 index 0000000000..ad79d8b088 --- /dev/null +++ b/queue-5.10/usbip-tools-support-superspeedplus-devices.patch @@ -0,0 +1,68 @@ +From 195e667c8719480c320cd48ac0fbf1cb81d6ffe0 Mon Sep 17 00:00:00 2001 +From: Yichong Chen +Date: Wed, 17 Jun 2026 10:06:13 +0800 +Subject: usbip: tools: support SuperSpeedPlus devices + +From: Yichong Chen + +commit 195e667c8719480c320cd48ac0fbf1cb81d6ffe0 upstream. + +USB devices running at SuperSpeedPlus report "10000" or "20000" in +their sysfs speed attribute. usbip currently maps only "5000" to +USB_SPEED_SUPER, so a SuperSpeedPlus device is imported as +USB_SPEED_UNKNOWN. + +The attach request is then rejected by vhci_hcd: + + vhci_hcd: Failed attach request for unsupported USB speed: UNKNOWN + +Map the SuperSpeedPlus sysfs speed values to USB_SPEED_SUPER_PLUS, use +the SuperSpeed VHCI hub for SuperSpeedPlus devices, and recognize the +gadget current_speed string used by the kernel. + +Fixes: b2316645ca5e ("usb: show speed "10000" in sysfs for USB 3.1 SuperSpeedPlus devices") +Cc: stable +Signed-off-by: Yichong Chen +Reviewed-by: Shuah Khan +Link: https://patch.msgid.link/00C828F338E43447+20260617020613.199086-1-chenyichong@uniontech.com +Signed-off-by: Greg Kroah-Hartman +--- + tools/usb/usbip/libsrc/usbip_common.c | 2 ++ + tools/usb/usbip/libsrc/usbip_device_driver.c | 4 ++++ + tools/usb/usbip/libsrc/vhci_driver.c | 1 + + 3 files changed, 7 insertions(+) + +--- a/tools/usb/usbip/libsrc/usbip_common.c ++++ b/tools/usb/usbip/libsrc/usbip_common.c +@@ -29,6 +29,8 @@ static const struct speed_string speed_s + { USB_SPEED_HIGH, "480", "High Speed(480Mbps)" }, + { USB_SPEED_WIRELESS, "53.3-480", "Wireless"}, + { USB_SPEED_SUPER, "5000", "Super Speed(5000Mbps)" }, ++ { USB_SPEED_SUPER_PLUS, "10000", "Super Speed Plus(10000Mbps)" }, ++ { USB_SPEED_SUPER_PLUS, "20000", "Super Speed Plus(20000Mbps)" }, + { 0, NULL, NULL } + }; + +--- a/tools/usb/usbip/libsrc/usbip_device_driver.c ++++ b/tools/usb/usbip/libsrc/usbip_device_driver.c +@@ -57,6 +57,10 @@ static struct { + .speed = USB_SPEED_SUPER, + .name = "super-speed", + }, ++ { ++ .speed = USB_SPEED_SUPER_PLUS, ++ .name = "super-speed-plus", ++ }, + }; + + static +--- a/tools/usb/usbip/libsrc/vhci_driver.c ++++ b/tools/usb/usbip/libsrc/vhci_driver.c +@@ -338,6 +338,7 @@ int usbip_vhci_get_free_port(uint32_t sp + + switch (speed) { + case USB_SPEED_SUPER: ++ case USB_SPEED_SUPER_PLUS: + if (vhci_driver->idev[i].hub != HUB_SPEED_SUPER) + continue; + break; diff --git a/queue-5.10/usbip-vudc-fix-null-deref-in-vep_dequeue.patch b/queue-5.10/usbip-vudc-fix-null-deref-in-vep_dequeue.patch new file mode 100644 index 0000000000..988893de7b --- /dev/null +++ b/queue-5.10/usbip-vudc-fix-null-deref-in-vep_dequeue.patch @@ -0,0 +1,76 @@ +From c5371e0b91b24159a3ebaa61e70b0980bcf03c0a Mon Sep 17 00:00:00 2001 +From: Sam Day +Date: Fri, 26 Jun 2026 14:29:10 +1000 +Subject: usbip: vudc: fix NULL deref in vep_dequeue() + +From: Sam Day + +commit c5371e0b91b24159a3ebaa61e70b0980bcf03c0a upstream. + +vep_alloc_request() wasn't initializing vrequest->udc, so cancellations +on the FunctionFS AIO path were arriving in vep_dequeue without a valid +UDC reference. + +Since vrequest->udc is never actually properly used anywhere, we opt to +remove it, and update vep_dequeue to obtain a reference to the udc with +ep_to_vudc(), consistent with the other vep_ ops. + +AFAICT this bug has existed for ~10 years. Seems that nobody has really +stressed the FunctionFS AIO path on usbip's vudc. + +I tested this fix in a QEMU aarch64 guest driving FunctionFS endpoints +via AIO. Before the fix, running `usbip attach` from the host would +cause the guest to oops with the following backtrace: + +Call trace: + vep_dequeue+0x1c/0xe4 (P) + usb_ep_dequeue+0x14/0x20 + ffs_aio_cancel+0x24/0x34 + __arm64_sys_io_cancel+0xb0/0x124 + do_el0_svc+0x68/0x100 + el0_svc+0x18/0x5c + el0t_64_sync_handler+0x98/0xdc + el0t_64_sync+0x154/0x158 + +Assisted-by: opencode:openai/gpt-5.5 +Cc: stable +Fixes: b6a0ca111867 ("usbip: vudc: Add UDC specific ops") +Reviewed-by: Igor Kotrasinski +Signed-off-by: Sam Day +Link: https://patch.msgid.link/20260626-usbip-vudc-deque-fix-v3-1-98c2dc4d6a48@samcday.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/usbip/vudc.h | 1 - + drivers/usb/usbip/vudc_dev.c | 4 +--- + 2 files changed, 1 insertion(+), 4 deletions(-) + +--- a/drivers/usb/usbip/vudc.h ++++ b/drivers/usb/usbip/vudc.h +@@ -38,7 +38,6 @@ struct vep { + + struct vrequest { + struct usb_request req; +- struct vudc *udc; + struct list_head req_entry; /* Request queue */ + }; + +--- a/drivers/usb/usbip/vudc_dev.c ++++ b/drivers/usb/usbip/vudc_dev.c +@@ -333,7 +333,6 @@ static int vep_queue(struct usb_ep *_ep, + static int vep_dequeue(struct usb_ep *_ep, struct usb_request *_req) + { + struct vep *ep; +- struct vrequest *req; + struct vudc *udc; + struct vrequest *lst; + unsigned long flags; +@@ -343,8 +342,7 @@ static int vep_dequeue(struct usb_ep *_e + return ret; + + ep = to_vep(_ep); +- req = to_vrequest(_req); +- udc = req->udc; ++ udc = ep_to_vudc(ep); + + if (!udc->driver) + return -ESHUTDOWN;