From: Greg Kroah-Hartman Date: Tue, 14 Jul 2026 16:52:14 +0000 (+0200) Subject: 7.1-stable patches X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d2dc10543022db1748fa7c70557bbfb1da18e93e;p=thirdparty%2Fkernel%2Fstable-queue.git 7.1-stable patches added patches: net-usb-kalmia-bound-rx-frame-length-in-kalmia_rx_fixup.patch revert-usb-typec-mux-avoid-duplicated-mux-switches.patch usb-cdc_acm-add-quirk-for-uniden-bc125at-scanner.patch usb-cdnsp-fix-stream-context-array-leak-in-cdnsp_alloc_stream_info.patch usb-core-add-usb_quirk_no_lpm-for-via-labs-usb-2.0-hub.patch usb-dwc3-fix-dwc3_readl-and-dwc3_writel-calls-in-dwc3_ulpi_setup.patch usb-dwc3-meson-g12a-fix-refcount-leak-in-dwc3_meson_g12a_resume.patch usb-free-iso-schedules-on-failed-submit.patch usb-gadget-composite-fix-dead-empty-check-in-the-usb_dt_otg-handler.patch usb-gadget-f_fs-fix-dma-fence-leak.patch usb-gadget-f_fs-initialize-epfile-in-early-to-fix-endpoint-direction-checks.patch usb-gadget-f_fs-initialize-reset_work-at-allocation-time.patch usb-gadget-f_fs-tie-read_buffer-lifetime-to-ffs_epfile.patch usb-gadget-f_printer-take-kref-only-for-successful-open.patch usb-gadget-udc-fix-use-after-free-in-gadget_match_driver.patch usb-idmouse-fix-use-after-free-on-disconnect-race.patch usb-iowarrior-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-usbio-bound-bulk-in-response-length-to-the-received-transfer.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-digi_acceleport-fix-write-buffer-corruption.patch usb-serial-keyspan_pda-fix-information-leak.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-anx7411-use-devm_pm_runtime_enable.patch usb-typec-class-drop-pd-lookup-reference.patch usb-typec-ps883x-fix-dp-usb3-configuration.patch usb-typec-tcpm-fix-vdm-type-for-enter-mode-commands.patch usb-typec-tcpm-validate-svid-index-in-svdm_consume_modes.patch usb-typec-ucsi-cancel-pending-work-on-system-suspend.patch usb-typec-ucsi-ccg-fix-use-after-free-of-ucsi-on-remove.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-7.1/net-usb-kalmia-bound-rx-frame-length-in-kalmia_rx_fixup.patch b/queue-7.1/net-usb-kalmia-bound-rx-frame-length-in-kalmia_rx_fixup.patch new file mode 100644 index 0000000000..077cf54ef8 --- /dev/null +++ b/queue-7.1/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-7.1/revert-usb-typec-mux-avoid-duplicated-mux-switches.patch b/queue-7.1/revert-usb-typec-mux-avoid-duplicated-mux-switches.patch new file mode 100644 index 0000000000..d3f1b009bd --- /dev/null +++ b/queue-7.1/revert-usb-typec-mux-avoid-duplicated-mux-switches.patch @@ -0,0 +1,75 @@ +From f576c75f95a52c71b30167d7efb6d47148f9c279 Mon Sep 17 00:00:00 2001 +From: Jens Glathe +Date: Sat, 30 May 2026 10:20:22 +0200 +Subject: Revert "usb: typec: mux: avoid duplicated mux switches" + +From: Jens Glathe + +commit f576c75f95a52c71b30167d7efb6d47148f9c279 upstream. + +This reverts commit b145c3f29d62f71cc9d2d714e2d4ae4c8d3f863d. + +The deduplication logic appears to cause issues with separate +SBU muxes. The mode-switch call on these (like gpio-sbu-mux) +never appeared, so no successful mode-switch happened. The more +high-end Parade PS883X redrivers are not affected due to being +retimer-switch. The revert fixes dp altmode mode-switch for both. + +Tested on: + Lenovo Thinkbook 16 G7 QOY + Lenovo Ideapad 5 2in1 14Q8X9 + Microsoft Windows Dev Kit 2023 (Blackrock) + Lenovo Thinkpad T14s G6 + +Fixes: b145c3f29d62 ("usb: typec: mux: avoid duplicated mux switches") +Cc: stable +Signed-off-by: Jens Glathe +Reviewed-by: Heikki Krogerus +Link: https://patch.msgid.link/20260530-typc-mux-modeset-v1-1-64b0281e2cd6@oldschoolsolutions.biz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/mux.c | 13 +------------ + 1 file changed, 1 insertion(+), 12 deletions(-) + +diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c +index db5e4a4c0a99..9b908c46bd7d 100644 +--- a/drivers/usb/typec/mux.c ++++ b/drivers/usb/typec/mux.c +@@ -275,9 +275,7 @@ static int mux_fwnode_match(struct device *dev, const void *fwnode) + static void *typec_mux_match(const struct fwnode_handle *fwnode, + const char *id, void *data) + { +- struct typec_mux_dev **mux_devs = data; + struct device *dev; +- int i; + + /* + * Device graph (OF graph) does not give any means to identify the +@@ -293,14 +291,6 @@ static void *typec_mux_match(const struct fwnode_handle *fwnode, + dev = class_find_device(&typec_mux_class, NULL, fwnode, + mux_fwnode_match); + +- /* Skip duplicates */ +- for (i = 0; i < TYPEC_MUX_MAX_DEVS; i++) +- if (to_typec_mux_dev(dev) == mux_devs[i]) { +- put_device(dev); +- return NULL; +- } +- +- + return dev ? to_typec_mux_dev(dev) : ERR_PTR(-EPROBE_DEFER); + } + +@@ -326,8 +316,7 @@ struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode) + return ERR_PTR(-ENOMEM); + + count = fwnode_connection_find_matches(fwnode, "mode-switch", +- (void **)mux_devs, +- typec_mux_match, ++ NULL, typec_mux_match, + (void **)mux_devs, + ARRAY_SIZE(mux_devs)); + if (count <= 0) { +-- +2.55.0 + diff --git a/queue-7.1/series b/queue-7.1/series index 1c46716882..4d6b162880 100644 --- a/queue-7.1/series +++ b/queue-7.1/series @@ -293,3 +293,47 @@ bpf-restore-sysctl-new-value-from-1-to-0.patch bpf-validate-btf-repeated-field-counts-before-expansion.patch bpf-keep-dynamic-inner-array-lookups-nullable.patch bpf-allow-lpm-map-access-from-sleepable-bpf-programs.patch +net-usb-kalmia-bound-rx-frame-length-in-kalmia_rx_fixup.patch +revert-usb-typec-mux-avoid-duplicated-mux-switches.patch +usb-cdc_acm-add-quirk-for-uniden-bc125at-scanner.patch +usb-cdnsp-fix-stream-context-array-leak-in-cdnsp_alloc_stream_info.patch +usb-core-add-usb_quirk_no_lpm-for-via-labs-usb-2.0-hub.patch +usb-dwc3-fix-dwc3_readl-and-dwc3_writel-calls-in-dwc3_ulpi_setup.patch +usb-dwc3-meson-g12a-fix-refcount-leak-in-dwc3_meson_g12a_resume.patch +usb-free-iso-schedules-on-failed-submit.patch +usb-gadget-composite-fix-dead-empty-check-in-the-usb_dt_otg-handler.patch +usb-gadget-udc-fix-use-after-free-in-gadget_match_driver.patch +usb-gadget-f_printer-take-kref-only-for-successful-open.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-iowarrior-fix-use-after-free-on-disconnect-race.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-usbio-bound-bulk-in-response-length-to-the-received-transfer.patch +usb-misc-uss720-unregister-parport-on-probe-failure.patch +usb-mtu3-unmap-request-dma-on-queue-failure.patch +usb-serial-keyspan_pda-fix-information-leak.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-serial-digi_acceleport-fix-write-buffer-corruption.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-anx7411-use-devm_pm_runtime_enable.patch +usb-typec-class-drop-pd-lookup-reference.patch +usb-typec-ps883x-fix-dp-usb3-configuration.patch +usb-typec-tcpm-fix-vdm-type-for-enter-mode-commands.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-typec-ucsi-ccg-fix-use-after-free-of-ucsi-on-remove.patch +usb-typec-ucsi-cancel-pending-work-on-system-suspend.patch +usb-gadget-f_fs-initialize-reset_work-at-allocation-time.patch +usb-gadget-f_fs-fix-dma-fence-leak.patch +usb-gadget-f_fs-initialize-epfile-in-early-to-fix-endpoint-direction-checks.patch +usb-gadget-f_fs-tie-read_buffer-lifetime-to-ffs_epfile.patch diff --git a/queue-7.1/usb-cdc_acm-add-quirk-for-uniden-bc125at-scanner.patch b/queue-7.1/usb-cdc_acm-add-quirk-for-uniden-bc125at-scanner.patch new file mode 100644 index 0000000000..2a26206b72 --- /dev/null +++ b/queue-7.1/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 +@@ -1810,6 +1810,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-7.1/usb-cdnsp-fix-stream-context-array-leak-in-cdnsp_alloc_stream_info.patch b/queue-7.1/usb-cdnsp-fix-stream-context-array-leak-in-cdnsp_alloc_stream_info.patch new file mode 100644 index 0000000000..e59c8c74cf --- /dev/null +++ b/queue-7.1/usb-cdnsp-fix-stream-context-array-leak-in-cdnsp_alloc_stream_info.patch @@ -0,0 +1,38 @@ +From 3348f444a4ce43dd5c2d1aa41634cb6eff33aa64 Mon Sep 17 00:00:00 2001 +From: Haoxiang Li +Date: Mon, 22 Jun 2026 13:26:27 +0800 +Subject: usb: cdnsp: fix stream context array leak in cdnsp_alloc_stream_info() + +From: Haoxiang Li + +commit 3348f444a4ce43dd5c2d1aa41634cb6eff33aa64 upstream. + +cdnsp_alloc_stream_info() allocates stream_info->stream_ctx_array with +cdnsp_alloc_stream_ctx(). If a later stream ring allocation or stream +mapping update fails, the error path frees the allocated stream rings +and stream_rings array, but leaves stream_ctx_array allocated. + +Free the stream context array before falling through to the stream_rings +cleanup path. + +Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") +Cc: stable +Signed-off-by: Haoxiang Li +Acked-by: Peter Chen +Link: https://patch.msgid.link/20260622052627.696373-1-haoxiang_li2024@163.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/cdns3/cdnsp-mem.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/cdns3/cdnsp-mem.c ++++ b/drivers/usb/cdns3/cdnsp-mem.c +@@ -631,6 +631,8 @@ cleanup_rings: + } + } + ++ cdnsp_free_stream_ctx(pdev, pep); ++ + cleanup_stream_rings: + kfree(pep->stream_info.stream_rings); + diff --git a/queue-7.1/usb-core-add-usb_quirk_no_lpm-for-via-labs-usb-2.0-hub.patch b/queue-7.1/usb-core-add-usb_quirk_no_lpm-for-via-labs-usb-2.0-hub.patch new file mode 100644 index 0000000000..6221e0fb98 --- /dev/null +++ b/queue-7.1/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 +@@ -576,6 +576,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-7.1/usb-dwc3-fix-dwc3_readl-and-dwc3_writel-calls-in-dwc3_ulpi_setup.patch b/queue-7.1/usb-dwc3-fix-dwc3_readl-and-dwc3_writel-calls-in-dwc3_ulpi_setup.patch new file mode 100644 index 0000000000..dab36618db --- /dev/null +++ b/queue-7.1/usb-dwc3-fix-dwc3_readl-and-dwc3_writel-calls-in-dwc3_ulpi_setup.patch @@ -0,0 +1,46 @@ +From e0f844d9d74200d311c6438a0f04270834ba5365 Mon Sep 17 00:00:00 2001 +From: Ben Dooks +Date: Fri, 3 Jul 2026 17:20:33 +0100 +Subject: usb: dwc3: fix dwc3_readl() and dwc3_writel() calls in dwc3_ulpi_setup() + +From: Ben Dooks + +commit e0f844d9d74200d311c6438a0f04270834ba5365 upstream. + +The dwc3_ulpi_setup() calls the register read and write calls with +dwc3->regs when both these calls take the dwc3 structure directly. + +Chnage these two calls to fix the following sparse warning, and +possibly a nasty bug in the dwc3_ulpi_setup() code: + +drivers/usb/dwc3/core.c:796:45: warning: incorrect type in argument 1 (different address spaces) +drivers/usb/dwc3/core.c:796:45: expected struct dwc3 *dwc +drivers/usb/dwc3/core.c:796:45: got void [noderef] __iomem *regs +drivers/usb/dwc3/core.c:798:40: warning: incorrect type in argument 1 (different address spaces) +drivers/usb/dwc3/core.c:798:40: expected struct dwc3 *dwc +drivers/usb/dwc3/core.c:798:40: got void [noderef] __iomem *regs + +Cc: stable +Fixes: 9accc68b1cf0 ("usb: dwc3: Add dwc pointer to dwc3_readl/writel") +Acked-by: Thinh Nguyen +Signed-off-by: Ben Dooks +Link: https://patch.msgid.link/20260703162033.2847599-1-ben.dooks@codethink.co.uk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -793,9 +793,9 @@ static void dwc3_ulpi_setup(struct dwc3 + + if (dwc->enable_usb2_transceiver_delay) { + for (index = 0; index < dwc->num_usb2_ports; index++) { +- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(index)); ++ reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(index)); + reg |= DWC3_GUSB2PHYCFG_XCVRDLY; +- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(index), reg); ++ dwc3_writel(dwc, DWC3_GUSB2PHYCFG(index), reg); + } + } + } diff --git a/queue-7.1/usb-dwc3-meson-g12a-fix-refcount-leak-in-dwc3_meson_g12a_resume.patch b/queue-7.1/usb-dwc3-meson-g12a-fix-refcount-leak-in-dwc3_meson_g12a_resume.patch new file mode 100644 index 0000000000..e5dd1f44d0 --- /dev/null +++ b/queue-7.1/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 +@@ -907,35 +907,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-7.1/usb-free-iso-schedules-on-failed-submit.patch b/queue-7.1/usb-free-iso-schedules-on-failed-submit.patch new file mode 100644 index 0000000000..801a97f36c --- /dev/null +++ b/queue-7.1/usb-free-iso-schedules-on-failed-submit.patch @@ -0,0 +1,105 @@ +From b9399d25fbb34a05bbe76eeedd730f62ff2670e9 Mon Sep 17 00:00:00 2001 +From: Dawei Feng +Date: Tue, 30 Jun 2026 15:14:19 +0800 +Subject: usb: free iso schedules on failed submit + +From: Dawei Feng + +commit b9399d25fbb34a05bbe76eeedd730f62ff2670e9 upstream. + +EHCI and FOTG210 isochronous submits build an ehci_iso_sched before +linking the URB to the endpoint queue, and keep the staged schedule in +urb->hcpriv until iso_stream_schedule() and the link helpers consume it. +If the controller is no longer accessible, or usb_hcd_link_urb_to_ep() +fails, submit jumps to done_not_linked before that handoff happens and +leaks the staged schedule still attached to urb->hcpriv. + +Free the staged schedule from done_not_linked when submit fails before +the URB is linked and clear urb->hcpriv after the free. + +The bug was first flagged by an experimental analysis tool we are +developing for kernel memory-management bugs while analyzing +v6.13-rc1. The tool is still under development and is not yet publicly +available. Manual inspection confirms that the bug is still +present in v7.1.1. + +An x86_64 allyesconfig build showed no new warnings. As we do not have an +EHCI host controller with a USB isochronous device to test with, no +runtime testing was able to be performed. + +Fixes: 8de98402652c ("[PATCH] USB: Fix USB suspend/resume crasher (#2)") +Fixes: e9df41c5c589 ("USB: make HCDs responsible for managing endpoint queues") +Fixes: 7d50195f6c50 ("usb: host: Faraday fotg210-hcd driver") +Cc: stable +Signed-off-by: Dawei Feng +Reviewed-by: Alan Stern +Link: https://patch.msgid.link/20260630071419.349161-1-dawei.feng@seu.edu.cn +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/fotg210/fotg210-hcd.c | 6 ++++-- + drivers/usb/host/ehci-sched.c | 11 +++++++++-- + 2 files changed, 13 insertions(+), 4 deletions(-) + +--- a/drivers/usb/fotg210/fotg210-hcd.c ++++ b/drivers/usb/fotg210/fotg210-hcd.c +@@ -4267,8 +4267,6 @@ static int iso_stream_schedule(struct fo + return 0; + + fail: +- iso_sched_free(stream, sched); +- urb->hcpriv = NULL; + return status; + } + +@@ -4562,6 +4560,10 @@ static int itd_submit(struct fotg210_hcd + else + usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb); + done_not_linked: ++ if (status < 0) { ++ iso_sched_free(stream, urb->hcpriv); ++ urb->hcpriv = NULL; ++ } + spin_unlock_irqrestore(&fotg210->lock, flags); + done: + return status; +--- a/drivers/usb/host/ehci-sched.c ++++ b/drivers/usb/host/ehci-sched.c +@@ -1623,6 +1623,7 @@ iso_stream_schedule( + status = 1; /* and give it back immediately */ + iso_sched_free(stream, sched); + sched = NULL; ++ urb->hcpriv = NULL; + } + } + urb->error_count = skip / period; +@@ -1653,8 +1654,6 @@ iso_stream_schedule( + return status; + + fail: +- iso_sched_free(stream, sched); +- urb->hcpriv = NULL; + return status; + } + +@@ -1966,6 +1965,10 @@ static int itd_submit(struct ehci_hcd *e + usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); + } + done_not_linked: ++ if (status < 0) { ++ iso_sched_free(stream, urb->hcpriv); ++ urb->hcpriv = NULL; ++ } + spin_unlock_irqrestore(&ehci->lock, flags); + done: + return status; +@@ -2343,6 +2346,10 @@ static int sitd_submit(struct ehci_hcd * + usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); + } + done_not_linked: ++ if (status < 0) { ++ iso_sched_free(stream, urb->hcpriv); ++ urb->hcpriv = NULL; ++ } + spin_unlock_irqrestore(&ehci->lock, flags); + done: + return status; diff --git a/queue-7.1/usb-gadget-composite-fix-dead-empty-check-in-the-usb_dt_otg-handler.patch b/queue-7.1/usb-gadget-composite-fix-dead-empty-check-in-the-usb_dt_otg-handler.patch new file mode 100644 index 0000000000..e19f0ef6a3 --- /dev/null +++ b/queue-7.1/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 +@@ -1863,9 +1863,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-7.1/usb-gadget-f_fs-fix-dma-fence-leak.patch b/queue-7.1/usb-gadget-f_fs-fix-dma-fence-leak.patch new file mode 100644 index 0000000000..ba0b7be84c --- /dev/null +++ b/queue-7.1/usb-gadget-f_fs-fix-dma-fence-leak.patch @@ -0,0 +1,52 @@ +From baa6b6068a3f2bf2ed525a1cb37975905dadc658 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Tue, 9 Jun 2026 17:29:05 +0200 +Subject: usb: gadget: f_fs: Fix DMA fence leak +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Paul Cercueil + +commit baa6b6068a3f2bf2ed525a1cb37975905dadc658 upstream. + +In ffs_dmabuf_transfer(), a ffs_dma_fence object is kmalloc'd, with the +underlying dma_fence later initialized by dma_fence_init(), which sets +its kref counter to 1. Then, dma_resv_add_fence() gets a second +reference, and a pointer to the ffs_dma_fence is passed as the +usb_request's "context" field. + +The dma-resv mechanism will manage the second reference, but the first +reference is never properly released; the ffs_dmabuf_cleanup() function +decreases the reference count, but only to balance with the reference +grab in ffs_dmabuf_signal_done(). + +The code will then slowly leak memory as more ffs_dma_fence objects are +created without being ever freed. + +Address this issue by transferring ownership of the fence to the DMA +reservation object, by calling dma_fence_put() right after +dma_resv_add_fence(). The ffs_dma_fence then gets properly discarded +after being signalled. + +Fixes: 7b07a2a7ca02 ("usb: gadget: functionfs: Add DMABUF import interface") +Cc: stable +Signed-off-by: Paul Cercueil +Tested-by: Nuno Sá +Reviewed-by: Nuno Sá +Link: https://patch.msgid.link/20260609152905.729328-1-paul@crapouillou.net +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_fs.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -1705,6 +1705,7 @@ static int ffs_dmabuf_transfer(struct fi + resv_dir = epfile->in ? DMA_RESV_USAGE_READ : DMA_RESV_USAGE_WRITE; + + dma_resv_add_fence(dmabuf->resv, &fence->base, resv_dir); ++ dma_fence_put(&fence->base); + dma_resv_unlock(dmabuf->resv); + + /* Now that the dma_fence is in place, queue the transfer. */ diff --git a/queue-7.1/usb-gadget-f_fs-initialize-epfile-in-early-to-fix-endpoint-direction-checks.patch b/queue-7.1/usb-gadget-f_fs-initialize-epfile-in-early-to-fix-endpoint-direction-checks.patch new file mode 100644 index 0000000000..ae49d6653b --- /dev/null +++ b/queue-7.1/usb-gadget-f_fs-initialize-epfile-in-early-to-fix-endpoint-direction-checks.patch @@ -0,0 +1,47 @@ +From 82cfd4739011bdc7e87b5d585703427e89ddfaa5 Mon Sep 17 00:00:00 2001 +From: Neill Kapron +Date: Fri, 19 Jun 2026 04:06:03 +0000 +Subject: usb: gadget: f_fs: Initialize epfile->in early to fix endpoint direction checks + +From: Neill Kapron + +commit 82cfd4739011bdc7e87b5d585703427e89ddfaa5 upstream. + +When parsing endpoint descriptors, ffs_data_got_descs() generates the +eps_addrmap which contains the endpoint direction. However, epfile->in +was previously only populated in ffs_func_eps_enable() which executes +upon USB host connection. As a result, early userspace ioctls like +FUNCTIONFS_DMABUF_ATTACH that run before the host connects would see +epfile->in as 0, leading to incorrect DMA directions. + +By moving the initialization to ffs_epfiles_create(), epfile->in is +accurate before userspace opens the endpoint files. + +Fixes: 7b07a2a7ca02 ("usb: gadget: functionfs: Add DMABUF import interface") +Cc: stable +Assisted-by: Antigravity:gemini-3.1-pro +Signed-off-by: Neill Kapron +Link: https://patch.msgid.link/20260619040609.4010746-2-nkapron@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_fs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -2367,6 +2367,7 @@ static int ffs_epfiles_create(struct ffs + sprintf(epfile->name, "ep%02x", ffs->eps_addrmap[i]); + else + sprintf(epfile->name, "ep%u", i); ++ epfile->in = (ffs->eps_addrmap[i] & USB_ENDPOINT_DIR_MASK) ? 1 : 0; + err = ffs_sb_create_file(ffs->sb, epfile->name, + epfile, &ffs_epfile_operations); + if (err) { +@@ -2456,7 +2457,6 @@ static int ffs_func_eps_enable(struct ff + ret = usb_ep_enable(ep->ep); + if (!ret) { + epfile->ep = ep; +- epfile->in = usb_endpoint_dir_in(ep->ep->desc); + epfile->isoc = usb_endpoint_xfer_isoc(ep->ep->desc); + } else { + break; diff --git a/queue-7.1/usb-gadget-f_fs-initialize-reset_work-at-allocation-time.patch b/queue-7.1/usb-gadget-f_fs-initialize-reset_work-at-allocation-time.patch new file mode 100644 index 0000000000..ec2c82fb78 --- /dev/null +++ b/queue-7.1/usb-gadget-f_fs-initialize-reset_work-at-allocation-time.patch @@ -0,0 +1,99 @@ +From 3137b243c93982fe3460335e12f9247739766e10 Mon Sep 17 00:00:00 2001 +From: Tyler Baker +Date: Tue, 9 Jun 2026 15:36:34 -0400 +Subject: usb: gadget: f_fs: initialize reset_work at allocation time +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Tyler Baker + +commit 3137b243c93982fe3460335e12f9247739766e10 upstream. + +ffs_fs_kill_sb() unconditionally calls cancel_work_sync() on +ffs->reset_work when a functionfs instance is unmounted: + + ffs_data_reset(ffs); + cancel_work_sync(&ffs->reset_work); + +However ffs->reset_work is only ever initialized via INIT_WORK() in +ffs_func_set_alt() and ffs_func_disable(), and only on the +FFS_DEACTIVATED path. That state is reached solely by ffs_data_closed() +when the instance is mounted with the "no_disconnect" option, so for the +common case (no "no_disconnect", or mounted and unmounted without ever +being deactivated) reset_work is never initialized. + +ffs_data_new() allocates the ffs_data with kzalloc_obj() and does not +initialize reset_work, and ffs_data_reset()/ffs_data_clear() do not touch +it either, so reset_work.func is left NULL. cancel_work_sync() on such a +work then trips the WARN_ON(!work->func) guard in __flush_work(): + + WARNING: kernel/workqueue.c:4301 at __flush_work+0x330/0x360, CPU#3: umount + Call trace: + __flush_work + cancel_work_sync + ffs_fs_kill_sb [usb_f_fs] + deactivate_locked_super + deactivate_super + cleanup_mnt + __cleanup_mnt + task_work_run + exit_to_user_mode_loop + el0_svc + +On older kernels cancel_work_sync() on a zero-initialized work struct was +a silent no-op, which hid the missing initialization. + +Initialize reset_work once in ffs_data_new() so it is always valid for +the lifetime of the ffs_data, and drop the now-redundant INIT_WORK() +calls from the two deactivation paths. + +Fixes: 18d6b32fca38 ("usb: gadget: f_fs: add "no_disconnect" mode") +Cc: stable +Signed-off-by: Tyler Baker +Cc: Loic Poulain +Cc: Dmitry Baryshkov +Cc: Srinivas Kandagatla +Tested-by: Loic Poulain +Reviewed-by: Peter Chen +Acked-by: Michał Nazarewicz +Link: https://patch.msgid.link/20260609193635.2284430-1-tyler.baker@oss.qualcomm.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_fs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -288,6 +288,7 @@ static int ffs_acquire_dev(const char *d + static void ffs_release_dev(struct ffs_dev *ffs_dev); + static int ffs_ready(struct ffs_data *ffs); + static void ffs_closed(struct ffs_data *ffs); ++static void ffs_reset_work(struct work_struct *work); + + /* Misc helper functions ****************************************************/ + +@@ -2221,6 +2222,7 @@ static struct ffs_data *ffs_data_new(con + init_waitqueue_head(&ffs->ev.waitq); + init_waitqueue_head(&ffs->wait); + init_completion(&ffs->ep0req_completion); ++ INIT_WORK(&ffs->reset_work, ffs_reset_work); + + /* XXX REVISIT need to update it in some places, or do we? */ + ffs->ev.can_stall = 1; +@@ -3775,7 +3777,6 @@ static int ffs_func_set_alt(struct usb_f + if (ffs->state == FFS_DEACTIVATED) { + ffs->state = FFS_CLOSING; + spin_unlock_irqrestore(&ffs->eps_lock, flags); +- INIT_WORK(&ffs->reset_work, ffs_reset_work); + schedule_work(&ffs->reset_work); + return -ENODEV; + } +@@ -3806,7 +3807,6 @@ static void ffs_func_disable(struct usb_ + if (ffs->state == FFS_DEACTIVATED) { + ffs->state = FFS_CLOSING; + spin_unlock_irqrestore(&ffs->eps_lock, flags); +- INIT_WORK(&ffs->reset_work, ffs_reset_work); + schedule_work(&ffs->reset_work); + return; + } diff --git a/queue-7.1/usb-gadget-f_fs-tie-read_buffer-lifetime-to-ffs_epfile.patch b/queue-7.1/usb-gadget-f_fs-tie-read_buffer-lifetime-to-ffs_epfile.patch new file mode 100644 index 0000000000..c74e78c192 --- /dev/null +++ b/queue-7.1/usb-gadget-f_fs-tie-read_buffer-lifetime-to-ffs_epfile.patch @@ -0,0 +1,52 @@ +From 8bdcf96eb135aebacac319667f87db034fb38406 Mon Sep 17 00:00:00 2001 +From: Neill Kapron +Date: Fri, 19 Jun 2026 04:06:04 +0000 +Subject: usb: gadget: f_fs: Tie read_buffer lifetime to ffs_epfile +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Neill Kapron + +commit 8bdcf96eb135aebacac319667f87db034fb38406 upstream. + +Currently, ffs_epfile_release unconditionally frees the endpoint's +read_buffer when a file descriptor is closed. If userspace explicitly +opens the endpoint multiple times and closes one, the read_buffer is +destroyed. This can lead to silent data loss if other file descriptors +are still actively reading from the endpoint. + +By tying the lifetime of the read_buffer to the ffs_epfile structure itself +(which is destroyed when the functionfs instance is torn down in +ffs_epfiles_destroy), we eliminate the brittle dependency on open/release +calls while correctly matching the conceptual lifetime of unread data on +the hardware endpoint. + +Fixes: 9353afbbfa7b ("usb: gadget: f_fs: buffer data from ‘oversized’ OUT requests") +Cc: stable +Assisted-by: Antigravity:gemini-3.1-pro +Signed-off-by: Neill Kapron +Link: https://patch.msgid.link/20260619040609.4010746-3-nkapron@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_fs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -1375,7 +1375,6 @@ ffs_epfile_release(struct inode *inode, + + mutex_unlock(&epfile->dmabufs_mutex); + +- __ffs_epfile_read_buffer_free(epfile); + ffs_data_closed(epfile->ffs); + + return 0; +@@ -2393,6 +2392,7 @@ static void ffs_epfiles_destroy(struct s + + for (; count; --count, ++epfile) { + BUG_ON(mutex_is_locked(&epfile->mutex)); ++ __ffs_epfile_read_buffer_free(epfile); + simple_remove_by_name(root, epfile->name, clear_one); + } + diff --git a/queue-7.1/usb-gadget-f_printer-take-kref-only-for-successful-open.patch b/queue-7.1/usb-gadget-f_printer-take-kref-only-for-successful-open.patch new file mode 100644 index 0000000000..223c66f154 --- /dev/null +++ b/queue-7.1/usb-gadget-f_printer-take-kref-only-for-successful-open.patch @@ -0,0 +1,41 @@ +From 30adce93d5c4a5a1ec29d9249e3fdfcc391d406b Mon Sep 17 00:00:00 2001 +From: Xu Rao +Date: Fri, 26 Jun 2026 14:46:17 +0800 +Subject: usb: gadget: f_printer: take kref only for successful open + +From: Xu Rao + +commit 30adce93d5c4a5a1ec29d9249e3fdfcc391d406b upstream. + +printer_open() returns -EBUSY when the character device is already +open, but it increments dev->kref regardless of the return value. VFS +does not call ->release() for a failed open, so every rejected second +open permanently leaks one reference. + +Move kref_get() into the successful-open branch. + +Fixes: e8d5f92b8d30 ("usb: gadget: function: printer: fix use-after-free in __lock_acquire") +Cc: stable +Signed-off-by: Xu Rao +Link: https://patch.msgid.link/80295742B820DA9B+20260626064617.4090626-1-raoxu@uniontech.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_printer.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/usb/gadget/function/f_printer.c ++++ b/drivers/usb/gadget/function/f_printer.c +@@ -363,12 +363,11 @@ printer_open(struct inode *inode, struct + ret = 0; + /* Change the printer status to show that it's on-line. */ + dev->printer_status |= PRINTER_SELECTED; ++ kref_get(&dev->kref); + } + + spin_unlock_irqrestore(&dev->lock, flags); + +- kref_get(&dev->kref); +- + return ret; + } + diff --git a/queue-7.1/usb-gadget-udc-fix-use-after-free-in-gadget_match_driver.patch b/queue-7.1/usb-gadget-udc-fix-use-after-free-in-gadget_match_driver.patch new file mode 100644 index 0000000000..f23770f48a --- /dev/null +++ b/queue-7.1/usb-gadget-udc-fix-use-after-free-in-gadget_match_driver.patch @@ -0,0 +1,113 @@ +From 67e511d2989eb1c8c588b599ce2fcc6bb8e6f7ea Mon Sep 17 00:00:00 2001 +From: Jimmy Hu +Date: Thu, 25 Jun 2026 15:37:04 +0800 +Subject: usb: gadget: udc: Fix use-after-free in gadget_match_driver + +From: Jimmy Hu + +commit 67e511d2989eb1c8c588b599ce2fcc6bb8e6f7ea upstream. + +The udc structure acts as the management structure for the gadget, +but their lifecycles are decoupled. A race condition exists where +usb_del_gadget() frees the udc memory (e.g., via mode-switch work) +while gadget_match_driver() concurrently accesses the freed udc memory +(e.g., via configfs), causing a Use-After-Free (UAF) that triggers a +NULL pointer dereference when the freed memory is zeroed: + +[39430.908615][ T1171] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 +[39430.911397][ T1171] pc : __pi_strcmp+0x20/0x140 +[39430.911441][ T1171] lr : gadget_match_driver+0x34/0x60 +... +[39430.911890][ T1171] usb_gadget_register_driver_owner+0x50/0xf8 +[39430.911910][ T1171] gadget_dev_desc_UDC_store+0xf4/0x140 +[39430.931308][ T1171] configfs_write_iter+0xec/0x134 + +[39430.957058][ T1171] Workqueue: events_freezable __dwc3_set_mode +[39430.957287][ T1171] dwc3_gadget_exit+0x34/0x8c +[39430.957304][ T1171] __dwc3_set_mode+0xc0/0x664 + +Fix this by ensuring the udc structure remains allocated until the +gadget is released. To achieve this, introduce a new +usb_gadget_release() routine to the core. When the gadget is added, +usb_add_gadget() stores the gadget's release routine in the udc +structure and takes a reference to the udc. When the gadget is +released, usb_gadget_release() drops the reference to the udc and +then calls the gadget's release routine. + +Suggested-by: Alan Stern +Cc: stable +Signed-off-by: Jimmy Hu +Reviewed-by: Alan Stern +Link: https://patch.msgid.link/20260625073705.803880-1-hhhuuu@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/core.c | 29 ++++++++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/core.c ++++ b/drivers/usb/gadget/udc/core.c +@@ -31,8 +31,9 @@ static const struct bus_type gadget_bus_ + /** + * struct usb_udc - describes one usb device controller + * @driver: the gadget driver pointer. For use by the class code +- * @dev: the child device to the actual controller + * @gadget: the gadget. For use by the class code ++ * @gadget_release: the gadget's release routine ++ * @dev: the child device to the actual controller + * @list: for use by the udc class driver + * @vbus: for udcs who care about vbus status, this value is real vbus status; + * for udcs who do not care about vbus status, this value is always true +@@ -53,6 +54,7 @@ static const struct bus_type gadget_bus_ + struct usb_udc { + struct usb_gadget_driver *driver; + struct usb_gadget *gadget; ++ void (*gadget_release)(struct device *dev); + struct device dev; + struct list_head list; + bool vbus; +@@ -1357,6 +1359,17 @@ static void usb_udc_nop_release(struct d + dev_vdbg(dev, "%s\n", __func__); + } + ++static void usb_gadget_release(struct device *dev) ++{ ++ struct usb_gadget *gadget = dev_to_usb_gadget(dev); ++ struct usb_udc *udc = gadget->udc; ++ /* Cache the gadget's release routine to prevent UAF */ ++ void (*release)(struct device *dev) = udc->gadget_release; ++ ++ put_device(&udc->dev); ++ release(dev); ++} ++ + /** + * usb_initialize_gadget - initialize a gadget and its embedded struct device + * @parent: the parent device to this udc. Usually the controller driver's +@@ -1413,6 +1426,14 @@ int usb_add_gadget(struct usb_gadget *ga + mutex_init(&udc->connect_lock); + + udc->started = false; ++ /* ++ * Align decoupled lifecycles: take a UDC reference to ensure it ++ * remains allocated until the gadget is released, requiring an ++ * override of the gadget's release routine to drop it. ++ */ ++ udc->gadget_release = gadget->dev.release; ++ gadget->dev.release = usb_gadget_release; ++ get_device(&udc->dev); + + mutex_lock(&udc_lock); + list_add_tail(&udc->list, &udc_list); +@@ -1457,6 +1478,12 @@ int usb_add_gadget(struct usb_gadget *ga + mutex_lock(&udc_lock); + list_del(&udc->list); + mutex_unlock(&udc_lock); ++ /* ++ * Revert the override and drop the UDC reference to prevent ++ * leaking the UDC if the gadget was statically allocated. ++ */ ++ gadget->dev.release = udc->gadget_release; ++ put_device(&udc->dev); + + err_put_udc: + put_device(&udc->dev); diff --git a/queue-7.1/usb-idmouse-fix-use-after-free-on-disconnect-race.patch b/queue-7.1/usb-idmouse-fix-use-after-free-on-disconnect-race.patch new file mode 100644 index 0000000000..5d37cb6902 --- /dev/null +++ b/queue-7.1/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-7.1/usb-iowarrior-fix-use-after-free-on-disconnect-race.patch b/queue-7.1/usb-iowarrior-fix-use-after-free-on-disconnect-race.patch new file mode 100644 index 0000000000..097c92ee67 --- /dev/null +++ b/queue-7.1/usb-iowarrior-fix-use-after-free-on-disconnect-race.patch @@ -0,0 +1,154 @@ +From c602254ba4c10f60a73cd99d147874f86a3f485c Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 22 Jun 2026 17:26:09 +0200 +Subject: USB: iowarrior: fix use-after-free on disconnect race + +From: Johan Hovold + +commit c602254ba4c10f60a73cd99d147874f86a3f485c 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: 946b960d13c1 ("USB: add driver for iowarrior devices.") +Cc: stable +Reported-by: Yue Sun +Link: https://lore.kernel.org/r/20260618080204.38322-1-samsun1006219@gmail.com +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20260622152612.116422-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/iowarrior.c | 57 ++++++++++++++++++------------------------- + 1 file changed, 24 insertions(+), 33 deletions(-) + +--- a/drivers/usb/misc/iowarrior.c ++++ b/drivers/usb/misc/iowarrior.c +@@ -72,6 +72,7 @@ static struct usb_driver iowarrior_drive + + /* Structure to hold all of our device specific stuff */ + struct iowarrior { ++ struct kref kref; + struct mutex mutex; /* locks this structure */ + struct usb_device *udev; /* save off the usb device pointer */ + struct usb_interface *interface; /* the interface for this device */ +@@ -240,8 +241,10 @@ static void iowarrior_write_callback(str + /* + * iowarrior_delete + */ +-static inline void iowarrior_delete(struct iowarrior *dev) ++static inline void iowarrior_delete(struct kref *kref) + { ++ struct iowarrior *dev = container_of(kref, struct iowarrior, kref); ++ + kfree(dev->int_in_buffer); + usb_free_urb(dev->int_in_urb); + kfree(dev->read_queue); +@@ -637,6 +640,9 @@ static int iowarrior_open(struct inode * + } + /* increment our usage count for the driver */ + ++dev->opened; ++ ++ kref_get(&dev->kref); ++ + /* save our object in the file's private structure */ + file->private_data = dev; + retval = 0; +@@ -652,7 +658,6 @@ out: + static int iowarrior_release(struct inode *inode, struct file *file) + { + struct iowarrior *dev; +- int retval = 0; + + dev = file->private_data; + if (!dev) +@@ -660,29 +665,18 @@ static int iowarrior_release(struct inod + + /* lock our device */ + mutex_lock(&dev->mutex); ++ dev->opened = 0; /* we're closing now */ + +- if (dev->opened <= 0) { +- retval = -ENODEV; /* close called more than once */ +- mutex_unlock(&dev->mutex); +- } else { +- dev->opened = 0; /* we're closing now */ +- retval = 0; +- if (dev->present) { +- /* +- The device is still connected so we only shutdown +- pending read-/write-ops. +- */ +- usb_kill_urb(dev->int_in_urb); +- wake_up_interruptible(&dev->read_wait); +- wake_up_interruptible(&dev->write_wait); +- mutex_unlock(&dev->mutex); +- } else { +- /* The device was unplugged, cleanup resources */ +- mutex_unlock(&dev->mutex); +- iowarrior_delete(dev); +- } ++ if (dev->present) { ++ usb_kill_urb(dev->int_in_urb); ++ wake_up_interruptible(&dev->read_wait); ++ wake_up_interruptible(&dev->write_wait); + } +- return retval; ++ mutex_unlock(&dev->mutex); ++ ++ kref_put(&dev->kref, iowarrior_delete); ++ ++ return 0; + } + + static __poll_t iowarrior_poll(struct file *file, poll_table * wait) +@@ -767,6 +761,7 @@ static int iowarrior_probe(struct usb_in + if (!dev) + return retval; + ++ kref_init(&dev->kref); + mutex_init(&dev->mutex); + + atomic_set(&dev->intr_idx, 0); +@@ -885,7 +880,8 @@ static int iowarrior_probe(struct usb_in + return retval; + + error: +- iowarrior_delete(dev); ++ kref_put(&dev->kref, iowarrior_delete); ++ + return retval; + } + +@@ -909,19 +905,14 @@ static void iowarrior_disconnect(struct + 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); + wake_up_interruptible(&dev->read_wait); + wake_up_interruptible(&dev->write_wait); +- mutex_unlock(&dev->mutex); +- } else { +- /* no process is using the device, cleanup now */ +- mutex_unlock(&dev->mutex); +- iowarrior_delete(dev); + } ++ ++ mutex_unlock(&dev->mutex); ++ ++ kref_put(&dev->kref, iowarrior_delete); + } + + /* usb specific object needed to register this driver with the usb subsystem */ diff --git a/queue-7.1/usb-iowarrior-fix-use-after-free-on-disconnect.patch b/queue-7.1/usb-iowarrior-fix-use-after-free-on-disconnect.patch new file mode 100644 index 0000000000..1426431a09 --- /dev/null +++ b/queue-7.1/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 +@@ -905,13 +905,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-7.1/usb-ldusb-fix-use-after-free-on-disconnect-race.patch b/queue-7.1/usb-ldusb-fix-use-after-free-on-disconnect-race.patch new file mode 100644 index 0000000000..16ea3b8aa9 --- /dev/null +++ b/queue-7.1/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 +@@ -150,6 +150,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; +@@ -201,8 +202,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); +@@ -355,6 +358,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; + +@@ -381,17 +386,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) +@@ -401,7 +397,7 @@ static int ld_usb_release(struct inode * + + unlock_exit: + mutex_unlock(&dev->mutex); +- ++ kref_put(&dev->kref, ld_usb_delete); + exit: + return retval; + } +@@ -659,6 +655,8 @@ static int ld_usb_probe(struct usb_inter + dev = kzalloc_obj(*dev); + 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-7.1/usb-legousbtower-fix-use-after-free-on-disconnect-race.patch b/queue-7.1/usb-legousbtower-fix-use-after-free-on-disconnect-race.patch new file mode 100644 index 0000000000..2a6f432614 --- /dev/null +++ b/queue-7.1/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-7.1/usb-misc-usbio-bound-bulk-in-response-length-to-the-received-transfer.patch b/queue-7.1/usb-misc-usbio-bound-bulk-in-response-length-to-the-received-transfer.patch new file mode 100644 index 0000000000..f61e422545 --- /dev/null +++ b/queue-7.1/usb-misc-usbio-bound-bulk-in-response-length-to-the-received-transfer.patch @@ -0,0 +1,71 @@ +From 8c6314489550fa81d41723a0ff33f655b5b6c7b6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?HE=20WEI=20=28=E3=82=AE=E3=82=AB=E3=82=AF=29?= + +Date: Wed, 24 Jun 2026 18:09:52 +0900 +Subject: usb: misc: usbio: bound bulk IN response length to the received transfer +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: HE WEI (ギカク) + +commit 8c6314489550fa81d41723a0ff33f655b5b6c7b6 upstream. + +usbio_bulk_msg() copies bpkt_len = le16_to_cpu(bpkt->len) bytes out of +the bulk IN buffer (usbio->rxbuf, allocated with size usbio->rxbuf_len) +into the caller's buffer. bpkt_len is fully controlled by the device +and is only checked against ibuf_len; ibuf_len in turn is checked +against usbio->txbuf_len, not against rxbuf_len: + + if ((obuf_len > (usbio->txbuf_len - sizeof(*bpkt))) || + (ibuf_len > (usbio->txbuf_len - sizeof(*bpkt)))) + return -EMSGSIZE; + +txbuf_len and rxbuf_len are taken independently from the bulk OUT and +bulk IN endpoint wMaxPacketSize in usbio_probe(). A malicious or +malfunctioning device that advertises a large bulk OUT endpoint and a +small bulk IN endpoint (e.g. by claiming one of the quirk-free IDs such +as the Lattice NX33U, 0x2ac1:0x20cb) therefore makes ibuf_len, and +hence the device-supplied bpkt_len, exceed rxbuf_len. memcpy() then +reads up to txbuf_len - rxbuf_len bytes past the end of the rxbuf slab +object. The over-read bytes are handed back to the i2c layer and on to +user space through i2c-dev, disclosing adjacent slab memory; with KASAN +this is reported as a slab-out-of-bounds read. + +The number of bytes actually received is already known: act equals the +URB actual_length and is bounded by rxbuf_len. Reject any response +that claims more payload than was received, mirroring the existing +"act < sizeof(*bpkt)" check just above. + +The control path (usbio_ctrl_msg()) is not affected: it uses a single +buffer (ctrlbuf) for both directions, so its analogous copy can never +leave the allocation. + +Found by code review. The out-of-bounds read was confirmed under +AddressSanitizer with a faithful userspace model of usbio_bulk_msg()'s +receive path (an rxbuf_len-sized buffer, the same act/ibuf_len/bpkt_len +checks and the memcpy). A USB raw-gadget + dummy_hcd reproducer is +also available. + +Fixes: 121a0f839dbb ("usb: misc: Add Intel USBIO bridge driver") +Cc: stable +Signed-off-by: HE WEI (ギカク) +Link: https://patch.msgid.link/20260624090952.86439-1-skyexpoc@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/usbio.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/misc/usbio.c ++++ b/drivers/usb/misc/usbio.c +@@ -344,6 +344,10 @@ read: + if (ibuf_len < bpkt_len) + return -ENOSPC; + ++ /* The device must not claim more payload than it actually sent. */ ++ if (bpkt_len > act - sizeof(*bpkt)) ++ return -EPROTO; ++ + memcpy(ibuf, bpkt->data, bpkt_len); + + return bpkt_len; diff --git a/queue-7.1/usb-misc-uss720-unregister-parport-on-probe-failure.patch b/queue-7.1/usb-misc-uss720-unregister-parport-on-probe-failure.patch new file mode 100644 index 0000000000..86724bc683 --- /dev/null +++ b/queue-7.1/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-7.1/usb-mtu3-unmap-request-dma-on-queue-failure.patch b/queue-7.1/usb-mtu3-unmap-request-dma-on-queue-failure.patch new file mode 100644 index 0000000000..ed4a33bb51 --- /dev/null +++ b/queue-7.1/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-7.1/usb-quirks-add-no_lpm-for-the-samsung-t5-evo-portable-ssd.patch b/queue-7.1/usb-quirks-add-no_lpm-for-the-samsung-t5-evo-portable-ssd.patch new file mode 100644 index 0000000000..2078fc4554 --- /dev/null +++ b/queue-7.1/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 +@@ -296,6 +296,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-7.1/usb-serial-digi_acceleport-fix-broken-rx-after-throttle.patch b/queue-7.1/usb-serial-digi_acceleport-fix-broken-rx-after-throttle.patch new file mode 100644 index 0000000000..991c9faebb --- /dev/null +++ b/queue-7.1/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 +@@ -1071,6 +1071,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) +@@ -1098,6 +1099,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-7.1/usb-serial-digi_acceleport-fix-hard-lockup-on-disconnect.patch b/queue-7.1/usb-serial-digi_acceleport-fix-hard-lockup-on-disconnect.patch new file mode 100644 index 0000000000..259b34985b --- /dev/null +++ b/queue-7.1/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-7.1/usb-serial-digi_acceleport-fix-write-buffer-corruption.patch b/queue-7.1/usb-serial-digi_acceleport-fix-write-buffer-corruption.patch new file mode 100644 index 0000000000..9091d578af --- /dev/null +++ b/queue-7.1/usb-serial-digi_acceleport-fix-write-buffer-corruption.patch @@ -0,0 +1,74 @@ +From 24ca1fea8f2753bf33e1d458ec1ae5d9b7796a65 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 23 Jun 2026 17:12:29 +0200 +Subject: USB: serial: digi_acceleport: fix write buffer corruption + +From: Johan Hovold + +commit 24ca1fea8f2753bf33e1d458ec1ae5d9b7796a65 upstream. + +The digi_write_inb_command() is supposed to wait for the write urb to +become available or return an error, but instead it updates the transfer +buffer and tries to resubmit the urb on timeout. + +To make things worse, for commands like break control where no timeout +is used, the driver would corrupt the urb immediately due to a broken +jiffies comparison (on 32-bit machines this takes five minutes of uptime +to trigger due to INITIAL_JIFFIES). + +Fix this by adding the missing return on timeout and waiting +indefinitely when no timeout has been specified as intended. + +This issue was (sort of) flagged by Sashiko when reviewing an unrelated +change to the driver. + +Link: https://sashiko.dev/#/patchset/20260610132232.356139-1-johan%40kernel.org?part=11 +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 | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/drivers/usb/serial/digi_acceleport.c ++++ b/drivers/usb/serial/digi_acceleport.c +@@ -431,20 +431,22 @@ static int digi_write_inb_command(struct + int len; + struct digi_port *priv = usb_get_serial_port_data(port); + unsigned char *data = port->write_urb->transfer_buffer; ++ unsigned long expire; + unsigned long flags; + + dev_dbg(&port->dev, "digi_write_inb_command: TOP: port=%d, count=%d\n", + priv->dp_port_num, count); + + if (timeout) +- timeout += jiffies; +- else +- timeout = ULONG_MAX; ++ expire = jiffies + timeout; + + spin_lock_irqsave(&priv->dp_port_lock, flags); + while (count > 0 && ret == 0) { +- while (priv->dp_write_urb_in_use && +- time_before(jiffies, timeout)) { ++ while (priv->dp_write_urb_in_use) { ++ if (timeout && time_after(jiffies, expire)) { ++ ret = -ETIMEDOUT; ++ break; ++ } + cond_wait_interruptible_timeout_irqrestore( + &priv->write_wait, DIGI_RETRY_TIMEOUT, + &priv->dp_port_lock, flags); +@@ -453,6 +455,9 @@ static int digi_write_inb_command(struct + spin_lock_irqsave(&priv->dp_port_lock, flags); + } + ++ if (ret) ++ break; ++ + /* len must be a multiple of 4 and small enough to */ + /* guarantee the write will send buffered data first, */ + /* so commands are in order with data and not split */ diff --git a/queue-7.1/usb-serial-keyspan_pda-fix-information-leak.patch b/queue-7.1/usb-serial-keyspan_pda-fix-information-leak.patch new file mode 100644 index 0000000000..babe213aaf --- /dev/null +++ b/queue-7.1/usb-serial-keyspan_pda-fix-information-leak.patch @@ -0,0 +1,38 @@ +From 6bfc8d01ac4068eced509f8fc74d0cd205e4dcec Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 29 Jun 2026 14:45:26 +0200 +Subject: USB: serial: keyspan_pda: fix information leak + +From: Johan Hovold + +commit 6bfc8d01ac4068eced509f8fc74d0cd205e4dcec upstream. + +The write() callback is supposed to return the number of characters +accepted or a negative errno. Since the addition of write fifo support +the keyspan_pda implementation will however return the number characters +submitted to the device if the write urb is not already in use. If this +number is larger than the number of characters passed to write(), the +line discipline continues writing data from beyond the tty write buffer. + +Fix the information leak by making sure that keyspan_pda_write_start() +returns zero on success as intended. + +Fixes: 034e38e8f687 ("USB: serial: keyspan_pda: add write-fifo support") +Cc: stable@vger.kernel.org # 5.11 +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/keyspan_pda.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/serial/keyspan_pda.c ++++ b/drivers/usb/serial/keyspan_pda.c +@@ -518,7 +518,7 @@ static int keyspan_pda_write_start(struc + if (count == room) + schedule_work(&priv->unthrottle_work); + +- return count; ++ return 0; + } + + static void keyspan_pda_write_bulk_callback(struct urb *urb) diff --git a/queue-7.1/usb-serial-option-add-telit-cinterion-fe990d50-compositions.patch b/queue-7.1/usb-serial-option-add-telit-cinterion-fe990d50-compositions.patch new file mode 100644 index 0000000000..ab7ffe2cdd --- /dev/null +++ b/queue-7.1/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-7.1/usb-sl811-hcd-disable-controller-wakeup-on-remove.patch b/queue-7.1/usb-sl811-hcd-disable-controller-wakeup-on-remove.patch new file mode 100644 index 0000000000..7f9fa1c0ca --- /dev/null +++ b/queue-7.1/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-7.1/usb-storage-include-us_fl_no_same-in-quirks-mask.patch b/queue-7.1/usb-storage-include-us_fl_no_same-in-quirks-mask.patch new file mode 100644 index 0000000000..601820a7ab --- /dev/null +++ b/queue-7.1/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 +@@ -570,7 +570,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-7.1/usb-typec-anx7411-use-devm_pm_runtime_enable.patch b/queue-7.1/usb-typec-anx7411-use-devm_pm_runtime_enable.patch new file mode 100644 index 0000000000..bfb3703fdb --- /dev/null +++ b/queue-7.1/usb-typec-anx7411-use-devm_pm_runtime_enable.patch @@ -0,0 +1,45 @@ +From 0ef7cc27da8b9e315a4a5a665c68c44206f5e559 Mon Sep 17 00:00:00 2001 +From: Myeonghun Pak +Date: Wed, 1 Jul 2026 20:40:06 +0900 +Subject: usb: typec: anx7411: use devm_pm_runtime_enable() + +From: Myeonghun Pak + +commit 0ef7cc27da8b9e315a4a5a665c68c44206f5e559 upstream. + +anx7411_i2c_probe() enables runtime PM before returning successfully, but +anx7411_i2c_remove() tears down the Type-C partner state, workqueue, dummy +I2C device, mux, switch and port without disabling runtime PM. + +Use devm_pm_runtime_enable() so runtime PM is disabled automatically on +driver detach. Since devres action registration can fail, route that +failure through the existing probe unwind path. + +This issue was identified during our ongoing static-analysis research while +reviewing kernel code. + +Fixes: fe6d8a9c8e64 ("usb: typec: anx7411: Add Analogix PD ANX7411 support") +Cc: stable +Co-developed-by: Ijae Kim +Signed-off-by: Ijae Kim +Signed-off-by: Myeonghun Pak +Reviewed-by: Heikki Krogerus +Link: https://patch.msgid.link/20260701114006.75738-1-mhun512@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/anx7411.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/typec/anx7411.c ++++ b/drivers/usb/typec/anx7411.c +@@ -1537,7 +1537,9 @@ static int anx7411_i2c_probe(struct i2c_ + if (anx7411_typec_check_connection(plat)) + dev_err(dev, "check status\n"); + +- pm_runtime_enable(dev); ++ ret = devm_pm_runtime_enable(dev); ++ if (ret) ++ goto free_wq; + + return 0; + diff --git a/queue-7.1/usb-typec-class-drop-pd-lookup-reference.patch b/queue-7.1/usb-typec-class-drop-pd-lookup-reference.patch new file mode 100644 index 0000000000..bf2d3462d4 --- /dev/null +++ b/queue-7.1/usb-typec-class-drop-pd-lookup-reference.patch @@ -0,0 +1,36 @@ +From 43ae2f90b70cda374c487c1639a01d0f14e5d583 Mon Sep 17 00:00:00 2001 +From: Shuangpeng Bai +Date: Thu, 2 Jul 2026 15:13:29 -0400 +Subject: usb: typec: class: drop PD lookup reference + +From: Shuangpeng Bai + +commit 43ae2f90b70cda374c487c1639a01d0f14e5d583 upstream. + +usb_power_delivery_find() wraps class_find_device_by_name(). That helper +returns a device reference that must be released by the caller. + +select_usb_power_delivery_store() only needs this reference while calling +the pd_set callback. Drop it once the callback returns. Otherwise the sysfs +write can pin the selected USB Power Delivery object and prevent it from +being released on unregister. + +Fixes: a7cff92f0635 ("usb: typec: USB Power Delivery helpers for ports and partners") +Cc: stable +Signed-off-by: Shuangpeng Bai +Link: https://patch.msgid.link/20260702191329.2648043-1-shuangpeng.kernel@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/class.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/typec/class.c ++++ b/drivers/usb/typec/class.c +@@ -1619,6 +1619,7 @@ static ssize_t select_usb_power_delivery + return -EINVAL; + + ret = port->ops->pd_set(port, pd); ++ put_device(&pd->dev); + if (ret) + return ret; + diff --git a/queue-7.1/usb-typec-ps883x-fix-dp-usb3-configuration.patch b/queue-7.1/usb-typec-ps883x-fix-dp-usb3-configuration.patch new file mode 100644 index 0000000000..811e5f5a56 --- /dev/null +++ b/queue-7.1/usb-typec-ps883x-fix-dp-usb3-configuration.patch @@ -0,0 +1,53 @@ +From b229b22b0a945d52dee887c856991ad08744d08e Mon Sep 17 00:00:00 2001 +From: Stephan Gerhold +Date: Mon, 1 Jun 2026 15:55:02 +0200 +Subject: usb: typec: ps883x: Fix DP+USB3 configuration + +From: Stephan Gerhold + +commit b229b22b0a945d52dee887c856991ad08744d08e upstream. + +Commit 6bebd9b77726 ("usb: typec: ps883x: Rework ps883x_set()") introduced +two regressions: + + 1. The CONN_STATUS_0_USB_3_1_CONNECTED bit is mistakenly written to the + wrong configuration register (cfg1 instead of cfg0). This breaks USB3 + when using USB3+DP adapters. + + 2. The switch-case fallthrough block is inverted: Currently, + TYPEC_DP_STATE_C (DP-only) inherits the USB3 configuration, while + TYPEC_DP_STATE_D (DP+USB3) is missing the necessary DP sink flags. + +Fix these by writing the USB3 bit to the correct register and swapping the +case statement order so both states get their correct bits assigned. + +Cc: stable +Fixes: 6bebd9b77726 ("usb: typec: ps883x: Rework ps883x_set()") +Signed-off-by: Stephan Gerhold +Reviewed-by: Heikki Krogerus +Tested-by: Jens Glathe +Reviewed-by: Konrad Dybcio +Link: https://patch.msgid.link/20260601-ps883x-usb3dp-fixes-v1-1-d19bec3a6d26@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/mux/ps883x.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/usb/typec/mux/ps883x.c ++++ b/drivers/usb/typec/mux/ps883x.c +@@ -118,12 +118,12 @@ static int ps883x_set(struct ps883x_reti + CONN_STATUS_1_DP_HPD_LEVEL; + + switch (state->mode) { ++ case TYPEC_DP_STATE_D: ++ cfg0 |= CONN_STATUS_0_USB_3_1_CONNECTED; ++ fallthrough; + case TYPEC_DP_STATE_C: + cfg1 |= CONN_STATUS_1_DP_SINK_REQUESTED | + CONN_STATUS_1_DP_PIN_ASSIGNMENT_C_D; +- fallthrough; +- case TYPEC_DP_STATE_D: +- cfg1 |= CONN_STATUS_0_USB_3_1_CONNECTED; + break; + default: /* MODE_E */ + break; diff --git a/queue-7.1/usb-typec-tcpm-fix-vdm-type-for-enter-mode-commands.patch b/queue-7.1/usb-typec-tcpm-fix-vdm-type-for-enter-mode-commands.patch new file mode 100644 index 0000000000..7e7360b0a5 --- /dev/null +++ b/queue-7.1/usb-typec-tcpm-fix-vdm-type-for-enter-mode-commands.patch @@ -0,0 +1,43 @@ +From 9cff680e47632b7723cb19f9c5e63669063c3417 Mon Sep 17 00:00:00 2001 +From: Andy Yan +Date: Thu, 4 Jun 2026 18:50:24 +0800 +Subject: usb: typec: tcpm: Fix VDM type for Enter Mode commands + +From: Andy Yan + +commit 9cff680e47632b7723cb19f9c5e63669063c3417 upstream. + +VDO() second parameter is VDM type (bit 15): 1 for SVDM, 0 for UVDM. +Using 'vdo ? 2 : 1' corrupts SVID low bit when vdo is non-NULL +(2 << 15 = BIT(16)). Enter Mode is always SVDM, hardcode to 1. + +Fixes: 8face9aa57c8 ("usb: typec: Add parameter for the VDO to typec_altmode_enter()") +Cc: stable +Signed-off-by: Andy Yan +Reviewed-by: Heikki Krogerus +Link: https://patch.msgid.link/20260604105059.18750-1-andyshrk@163.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/tcpm/tcpm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/typec/tcpm/tcpm.c ++++ b/drivers/usb/typec/tcpm/tcpm.c +@@ -3088,7 +3088,7 @@ static int tcpm_altmode_enter(struct typ + if (svdm_version < 0) + return svdm_version; + +- header = VDO(altmode->svid, vdo ? 2 : 1, svdm_version, CMD_ENTER_MODE); ++ header = VDO(altmode->svid, 1, svdm_version, CMD_ENTER_MODE); + header |= VDO_OPOS(altmode->mode); + + return tcpm_queue_vdm_unlocked(port, header, vdo, vdo ? 1 : 0, TCPC_TX_SOP); +@@ -3136,7 +3136,7 @@ static int tcpm_cable_altmode_enter(stru + if (svdm_version < 0) + return svdm_version; + +- header = VDO(altmode->svid, vdo ? 2 : 1, svdm_version, CMD_ENTER_MODE); ++ header = VDO(altmode->svid, 1, svdm_version, CMD_ENTER_MODE); + header |= VDO_OPOS(altmode->mode); + + return tcpm_queue_vdm_unlocked(port, header, vdo, vdo ? 1 : 0, TCPC_TX_SOP_PRIME); diff --git a/queue-7.1/usb-typec-tcpm-validate-svid-index-in-svdm_consume_modes.patch b/queue-7.1/usb-typec-tcpm-validate-svid-index-in-svdm_consume_modes.patch new file mode 100644 index 0000000000..1bd9c7446c --- /dev/null +++ b/queue-7.1/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 +@@ -2000,6 +2000,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++) { + if (pmdata->altmodes >= ALTMODE_DISCOVERY_MAX) { + /* Already logged in svdm_consume_svids() */ diff --git a/queue-7.1/usb-typec-ucsi-cancel-pending-work-on-system-suspend.patch b/queue-7.1/usb-typec-ucsi-cancel-pending-work-on-system-suspend.patch new file mode 100644 index 0000000000..36c1f0924c --- /dev/null +++ b/queue-7.1/usb-typec-ucsi-cancel-pending-work-on-system-suspend.patch @@ -0,0 +1,116 @@ +From 7c4a234bd31a64a8dbd0140dc812da592c5e0787 Mon Sep 17 00:00:00 2001 +From: Paul Menzel +Date: Fri, 3 Jul 2026 13:07:37 +0200 +Subject: usb: typec: ucsi: cancel pending work on system suspend + +From: Paul Menzel + +commit 7c4a234bd31a64a8dbd0140dc812da592c5e0787 upstream. + +On a Dell XPS 13 9360 (BIOS 2.21.0), entering system suspend (deep/S3) +races a pending UCSI connector-change worker against the ACPI EC teardown. +The worker evaluates the UCSI _DSM (GET_CONNECTOR_STATUS), whose AML +accesses the Embedded Controller. By that point the ACPI EC has already +been stopped for suspend, so the EC address space handler rejects the +access with AE_BAD_PARAMETER, aborting the AML and failing the connector +query: + + [22314.689495] ACPI: EC: interrupt blocked + [22314.711981] ACPI: PM: Preparing to enter system sleep state S3 + [22314.743260] ACPI: EC: event blocked + [22314.743265] ACPI: EC: EC stopped + [22314.743267] ACPI: PM: Saving platform NVS memory + [22314.744241] ACPI Error: AE_BAD_PARAMETER, Returned by Handler for [EmbeddedControl] (20260408/evregion-303) + [22314.744432] ACPI Error: Aborting method \_SB.PCI0.LPCB.ECDV.ECW1 due to previous error (AE_BAD_PARAMETER) (20260408/psparse-543) + [22314.744673] ACPI Error: Aborting method \ECWB due to previous error (AE_BAD_PARAMETER) (20260408/psparse-543) + [22314.745201] ACPI Error: Aborting method \_SB.UBTC._DSM due to previous error (AE_BAD_PARAMETER) (20260408/psparse-543) + [22314.745394] ACPI: \_SB_.UBTC: failed to evaluate _DSM c298836f-a47c-e411-ad36-631042b5008f rev:1 func:1 (0x1001) + [22314.745414] ucsi_acpi USBC000:00: ucsi_acpi_dsm: failed to evaluate _DSM 1 + [22314.745424] ucsi_acpi USBC000:00: ucsi_handle_connector_change: GET_CONNECTOR_STATUS failed (-5) + +ucsi_acpi implements a resume callback but no suspend callback, so nothing +cancels the connector-change work before the firmware/EC is torn down. + +Add a `ucsi_suspend()` core helper that cancels the pending init and +connector-change work, and wire it into ucsi_acpi's PM ops. The connector +state is re-read on resume by `ucsi_resume()`, so cancelling the work loses +nothing. + +Fixes: 4e3a50293c2b ("usb: typec: ucsi: acpi: Implement resume callback") +Cc: stable +Signed-off-by: Paul Menzel +Assisted-by: Claude Opus 4.8 +Reviewed-by: Heikki Krogerus +Link: https://patch.msgid.link/20260703110738.8457-2-pmenzel@molgen.mpg.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/ucsi.c | 20 ++++++++++++++++++++ + drivers/usb/typec/ucsi/ucsi.h | 1 + + drivers/usb/typec/ucsi/ucsi_acpi.c | 10 +++++++++- + 3 files changed, 30 insertions(+), 1 deletion(-) + +--- a/drivers/usb/typec/ucsi/ucsi.c ++++ b/drivers/usb/typec/ucsi/ucsi.c +@@ -1978,6 +1978,26 @@ static void ucsi_resume_work(struct work + } + } + ++int ucsi_suspend(struct ucsi *ucsi) ++{ ++ int i; ++ ++ /* ++ * Cancel pending work so it cannot access the firmware after the ACPI ++ * EC is stopped for suspend; state is re-read on resume. ++ */ ++ cancel_delayed_work_sync(&ucsi->work); ++ ++ if (!ucsi->connector) ++ return 0; ++ ++ for (i = 0; i < ucsi->cap.num_connectors; i++) ++ cancel_work_sync(&ucsi->connector[i].work); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(ucsi_suspend); ++ + int ucsi_resume(struct ucsi *ucsi) + { + if (ucsi->connector) +--- a/drivers/usb/typec/ucsi/ucsi.h ++++ b/drivers/usb/typec/ucsi/ucsi.h +@@ -566,6 +566,7 @@ int ucsi_send_command(struct ucsi *ucsi, + void *retval, size_t size); + + void ucsi_altmode_update_active(struct ucsi_connector *con); ++int ucsi_suspend(struct ucsi *ucsi); + int ucsi_resume(struct ucsi *ucsi); + + void ucsi_notify_common(struct ucsi *ucsi, u32 cci); +--- a/drivers/usb/typec/ucsi/ucsi_acpi.c ++++ b/drivers/usb/typec/ucsi/ucsi_acpi.c +@@ -245,6 +245,13 @@ static void ucsi_acpi_remove(struct plat + ucsi_acpi_notify); + } + ++static int ucsi_acpi_suspend(struct device *dev) ++{ ++ struct ucsi_acpi *ua = dev_get_drvdata(dev); ++ ++ return ucsi_suspend(ua->ucsi); ++} ++ + static int ucsi_acpi_resume(struct device *dev) + { + struct ucsi_acpi *ua = dev_get_drvdata(dev); +@@ -252,7 +259,8 @@ static int ucsi_acpi_resume(struct devic + return ucsi_resume(ua->ucsi); + } + +-static DEFINE_SIMPLE_DEV_PM_OPS(ucsi_acpi_pm_ops, NULL, ucsi_acpi_resume); ++static DEFINE_SIMPLE_DEV_PM_OPS(ucsi_acpi_pm_ops, ucsi_acpi_suspend, ++ ucsi_acpi_resume); + + static const struct acpi_device_id ucsi_acpi_match[] = { + { "PNP0CA0", 0 }, diff --git a/queue-7.1/usb-typec-ucsi-ccg-fix-use-after-free-of-ucsi-on-remove.patch b/queue-7.1/usb-typec-ucsi-ccg-fix-use-after-free-of-ucsi-on-remove.patch new file mode 100644 index 0000000000..3bbfa03e82 --- /dev/null +++ b/queue-7.1/usb-typec-ucsi-ccg-fix-use-after-free-of-ucsi-on-remove.patch @@ -0,0 +1,51 @@ +From 1f0bdc2884b67de337215079bba166df0cdf4ac5 Mon Sep 17 00:00:00 2001 +From: Fan Wu +Date: Tue, 16 Jun 2026 13:20:11 +0000 +Subject: usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove + +From: Fan Wu + +commit 1f0bdc2884b67de337215079bba166df0cdf4ac5 upstream. + +The threaded IRQ handler ccg_irq_handler() calls ucsi_notify_common(), +which on a connector-change event calls ucsi_connector_change() and +schedules connector work. In ucsi_ccg_remove(), ucsi_destroy() frees +uc->ucsi (kfree) before free_irq() is called, so a handler invocation +already in flight may access the freed object after ucsi_destroy(). + + CPU 0 (remove) | CPU 1 (threaded IRQ) + ucsi_destroy(uc->ucsi) | ccg_irq_handler() + kfree(ucsi) // FREE | ucsi_notify_common(uc->ucsi) // USE + +Move free_irq() before ucsi_destroy() in the remove path. It is kept +after ucsi_unregister(): ucsi_unregister() cancels connector work whose +handler issues GET_CONNECTOR_STATUS through ucsi_send_command_common(), +which waits for a completion that is signalled from the IRQ handler, so +the IRQ must stay active until that work has been cancelled. + +The probe error path already orders free_irq() before ucsi_destroy(). + +This bug was found by static analysis. + +Fixes: e32fd989ac1c ("usb: typec: ucsi: ccg: Move to the new API") +Cc: stable +Signed-off-by: Fan Wu +Reviewed-by: Heikki Krogerus +Link: https://patch.msgid.link/20260616132011.103279-1-fanwu01@zju.edu.cn +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/ucsi_ccg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/typec/ucsi/ucsi_ccg.c ++++ b/drivers/usb/typec/ucsi/ucsi_ccg.c +@@ -1519,8 +1519,8 @@ static void ucsi_ccg_remove(struct i2c_c + cancel_work_sync(&uc->work); + pm_runtime_disable(uc->dev); + ucsi_unregister(uc->ucsi); +- ucsi_destroy(uc->ucsi); + free_irq(uc->irq, uc); ++ ucsi_destroy(uc->ucsi); + } + + static const struct of_device_id ucsi_ccg_of_match_table[] = { diff --git a/queue-7.1/usb-typec-ucsi-invert-displayport-role-assignment.patch b/queue-7.1/usb-typec-ucsi-invert-displayport-role-assignment.patch new file mode 100644 index 0000000000..86b89d50bc --- /dev/null +++ b/queue-7.1/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 +@@ -166,12 +166,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-7.1/usb-typec-ucsi-pass-full-dp-config-payload-in-set_new_cam-for-dp-alt-mode.patch b/queue-7.1/usb-typec-ucsi-pass-full-dp-config-payload-in-set_new_cam-for-dp-alt-mode.patch new file mode 100644 index 0000000000..bcbcf5f0d1 --- /dev/null +++ b/queue-7.1/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 +@@ -185,13 +185,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-7.1/usb-ulpi-fix-memory-leak-on-registration-failure.patch b/queue-7.1/usb-ulpi-fix-memory-leak-on-registration-failure.patch new file mode 100644 index 0000000000..ae396f58a6 --- /dev/null +++ b/queue-7.1/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 +@@ -281,28 +281,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; +- } + + root = debugfs_create_dir(dev_name(&ulpi->dev), ulpi_root); + debugfs_create_file("regs", 0444, root, ulpi, &ulpi_regs_fops); +@@ -334,9 +330,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-7.1/usb-usb-storage-ene_ub6250-restore-media-ready-check.patch b/queue-7.1/usb-usb-storage-ene_ub6250-restore-media-ready-check.patch new file mode 100644 index 0000000000..571af4abb4 --- /dev/null +++ b/queue-7.1/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-7.1/usbip-tools-support-superspeedplus-devices.patch b/queue-7.1/usbip-tools-support-superspeedplus-devices.patch new file mode 100644 index 0000000000..ad79d8b088 --- /dev/null +++ b/queue-7.1/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-7.1/usbip-vudc-fix-null-deref-in-vep_dequeue.patch b/queue-7.1/usbip-vudc-fix-null-deref-in-vep_dequeue.patch new file mode 100644 index 0000000000..988893de7b --- /dev/null +++ b/queue-7.1/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;