From 3703a9c98426dfc5c73da88a094d124f58888ab7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 4 Jun 2026 13:00:25 +0200 Subject: [PATCH] 5.15-stable patches added patches: comedi-comedi_test-fix-check-for-valid-scan_begin_src-in-waveform_ai_cmdtest.patch comedi-comedi_test-fix-limiting-of-convert_arg-in-waveform_ai_cmdtest.patch drm-hyperv-validate-vmbus-packet-size-in-receive-callback.patch input-atmel_mxt_ts-fix-boundary-check-in-mxt_prepare_cfg_mem.patch input-synaptics-add-len2058-to-smbus-passlist-for-thinkpad-e490.patch scsi-fcoe-reject-fip-descriptors-with-zero-fip_dlen-in-cvl-walker.patch scsi-scsi_transport_fc-widen-fpin-pname-walker-counter-to-u32.patch serial-dz-fix-bootconsole-message-clobbering-at-chip-reset.patch serial-fsl_lpuart-fix-rx-buffer-and-dma-map-leaks-in-start_rx_dma.patch serial-sh-sci-fix-memory-region-release-in-error-path.patch serial-zs-fix-bootconsole-handover-lockup.patch serial-zs-fix-swapped-ri-dsr-modem-line-transition-counting.patch serial-zs-switch-to-using-channel-reset.patch thunderbolt-property-reject-dir_len-4-to-prevent-size_t-underflow.patch thunderbolt-property-reject-u32-wrap-in-tb_property_entry_valid.patch tty-serial-pch_uart-add-check-for-dma_alloc_coherent.patch usb-chipidea-core-convert-ci_role_switch-to-local-variable.patch usb-core-fix-up-interrupt-in-endpoints-with-bogus-wbytesperinterval.patch usb-gadget-dummy_hcd-reject-hub-port-requests-for-non-existent-ports.patch usb-gadget-f_fs-copy-only-received-bytes-on-short-ep0-read.patch usb-gadget-net2280-fix-double-free-in-probe-error-path.patch usb-quirks-add-no_lpm-for-lenovo-thinkpad-usb-c-dock-gen2-hub-controllers.patch usb-serial-belkin_sa-validate-interrupt-status-length.patch usb-serial-cypress_m8-validate-interrupt-packet-headers.patch usb-serial-keyspan-fix-missing-indat-transfer-sanity-check.patch usb-serial-mct_u232-fix-missing-interrupt-in-transfer-sanity-check.patch usb-serial-mxuport-fix-memory-corruption-with-small-endpoint.patch usb-serial-option-add-meig-srm813q.patch usb-serial-option-add-missing-rsvd-5-flag-for-rolling-rw135r-gl.patch usb-storage-add-quirks-for-pny-elite-portable-ssd.patch usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch usb-usbtmc-check-urb-actual_length-for-interrupt-in-notifications.patch usb-usbtmc-reject-interrupt-endpoints-with-small-wmaxpacketsize.patch usbip-vudc-fix-use-after-free-bug-in-vudc_remove-due-to-race-condition.patch --- ...can_begin_src-in-waveform_ai_cmdtest.patch | 37 ++++ ...f-convert_arg-in-waveform_ai_cmdtest.patch | 69 +++++++ ...mbus-packet-size-in-receive-callback.patch | 187 ++++++++++++++++++ ...oundary-check-in-mxt_prepare_cfg_mem.patch | 53 +++++ ...-to-smbus-passlist-for-thinkpad-e490.patch | 45 +++++ ...ors-with-zero-fip_dlen-in-cvl-walker.patch | 53 +++++ ...den-fpin-pname-walker-counter-to-u32.patch | 163 +++++++++++++++ ...ole-message-clobbering-at-chip-reset.patch | 71 +++++++ ...er-and-dma-map-leaks-in-start_rx_dma.patch | 90 +++++++++ ...-memory-region-release-in-error-path.patch | 40 ++++ ...l-zs-fix-bootconsole-handover-lockup.patch | 100 ++++++++++ ...i-dsr-modem-line-transition-counting.patch | 36 ++++ ...ial-zs-switch-to-using-channel-reset.patch | 89 +++++++++ queue-5.15/series | 34 ++++ ...ir_len-4-to-prevent-size_t-underflow.patch | 75 +++++++ ...-u32-wrap-in-tb_property_entry_valid.patch | 65 ++++++ ...art-add-check-for-dma_alloc_coherent.patch | 68 +++++++ ...ert-ci_role_switch-to-local-variable.patch | 77 ++++++++ ...dpoints-with-bogus-wbytesperinterval.patch | 65 ++++++ ...port-requests-for-non-existent-ports.patch | 50 +++++ ...nly-received-bytes-on-short-ep0-read.patch | 79 ++++++++ ...-fix-double-free-in-probe-error-path.patch | 48 +++++ ...kpad-usb-c-dock-gen2-hub-controllers.patch | 40 ++++ ..._sa-validate-interrupt-status-length.patch | 50 +++++ ...m8-validate-interrupt-packet-headers.patch | 86 ++++++++ ...-missing-indat-transfer-sanity-check.patch | 34 ++++ ...g-interrupt-in-transfer-sanity-check.patch | 36 ++++ ...emory-corruption-with-small-endpoint.patch | 40 ++++ .../usb-serial-option-add-meig-srm813q.patch | 94 +++++++++ ...ng-rsvd-5-flag-for-rolling-rw135r-gl.patch | 132 +++++++++++++ ...dd-quirks-for-pny-elite-portable-ssd.patch | 69 +++++++ ...n-power-role-change-if-not-connected.patch | 39 ++++ ...ength-for-interrupt-in-notifications.patch | 49 +++++ ...-endpoints-with-small-wmaxpacketsize.patch | 41 ++++ ...in-vudc_remove-due-to-race-condition.patch | 77 ++++++++ 35 files changed, 2381 insertions(+) create mode 100644 queue-5.15/comedi-comedi_test-fix-check-for-valid-scan_begin_src-in-waveform_ai_cmdtest.patch create mode 100644 queue-5.15/comedi-comedi_test-fix-limiting-of-convert_arg-in-waveform_ai_cmdtest.patch create mode 100644 queue-5.15/drm-hyperv-validate-vmbus-packet-size-in-receive-callback.patch create mode 100644 queue-5.15/input-atmel_mxt_ts-fix-boundary-check-in-mxt_prepare_cfg_mem.patch create mode 100644 queue-5.15/input-synaptics-add-len2058-to-smbus-passlist-for-thinkpad-e490.patch create mode 100644 queue-5.15/scsi-fcoe-reject-fip-descriptors-with-zero-fip_dlen-in-cvl-walker.patch create mode 100644 queue-5.15/scsi-scsi_transport_fc-widen-fpin-pname-walker-counter-to-u32.patch create mode 100644 queue-5.15/serial-dz-fix-bootconsole-message-clobbering-at-chip-reset.patch create mode 100644 queue-5.15/serial-fsl_lpuart-fix-rx-buffer-and-dma-map-leaks-in-start_rx_dma.patch create mode 100644 queue-5.15/serial-sh-sci-fix-memory-region-release-in-error-path.patch create mode 100644 queue-5.15/serial-zs-fix-bootconsole-handover-lockup.patch create mode 100644 queue-5.15/serial-zs-fix-swapped-ri-dsr-modem-line-transition-counting.patch create mode 100644 queue-5.15/serial-zs-switch-to-using-channel-reset.patch create mode 100644 queue-5.15/thunderbolt-property-reject-dir_len-4-to-prevent-size_t-underflow.patch create mode 100644 queue-5.15/thunderbolt-property-reject-u32-wrap-in-tb_property_entry_valid.patch create mode 100644 queue-5.15/tty-serial-pch_uart-add-check-for-dma_alloc_coherent.patch create mode 100644 queue-5.15/usb-chipidea-core-convert-ci_role_switch-to-local-variable.patch create mode 100644 queue-5.15/usb-core-fix-up-interrupt-in-endpoints-with-bogus-wbytesperinterval.patch create mode 100644 queue-5.15/usb-gadget-dummy_hcd-reject-hub-port-requests-for-non-existent-ports.patch create mode 100644 queue-5.15/usb-gadget-f_fs-copy-only-received-bytes-on-short-ep0-read.patch create mode 100644 queue-5.15/usb-gadget-net2280-fix-double-free-in-probe-error-path.patch create mode 100644 queue-5.15/usb-quirks-add-no_lpm-for-lenovo-thinkpad-usb-c-dock-gen2-hub-controllers.patch create mode 100644 queue-5.15/usb-serial-belkin_sa-validate-interrupt-status-length.patch create mode 100644 queue-5.15/usb-serial-cypress_m8-validate-interrupt-packet-headers.patch create mode 100644 queue-5.15/usb-serial-keyspan-fix-missing-indat-transfer-sanity-check.patch create mode 100644 queue-5.15/usb-serial-mct_u232-fix-missing-interrupt-in-transfer-sanity-check.patch create mode 100644 queue-5.15/usb-serial-mxuport-fix-memory-corruption-with-small-endpoint.patch create mode 100644 queue-5.15/usb-serial-option-add-meig-srm813q.patch create mode 100644 queue-5.15/usb-serial-option-add-missing-rsvd-5-flag-for-rolling-rw135r-gl.patch create mode 100644 queue-5.15/usb-storage-add-quirks-for-pny-elite-portable-ssd.patch create mode 100644 queue-5.15/usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch create mode 100644 queue-5.15/usb-usbtmc-check-urb-actual_length-for-interrupt-in-notifications.patch create mode 100644 queue-5.15/usb-usbtmc-reject-interrupt-endpoints-with-small-wmaxpacketsize.patch create mode 100644 queue-5.15/usbip-vudc-fix-use-after-free-bug-in-vudc_remove-due-to-race-condition.patch diff --git a/queue-5.15/comedi-comedi_test-fix-check-for-valid-scan_begin_src-in-waveform_ai_cmdtest.patch b/queue-5.15/comedi-comedi_test-fix-check-for-valid-scan_begin_src-in-waveform_ai_cmdtest.patch new file mode 100644 index 0000000000..913f3c0c81 --- /dev/null +++ b/queue-5.15/comedi-comedi_test-fix-check-for-valid-scan_begin_src-in-waveform_ai_cmdtest.patch @@ -0,0 +1,37 @@ +From 542f5248cb481073203e0dadab5bcbd28aeae308 Mon Sep 17 00:00:00 2001 +From: Ian Abbott +Date: Wed, 22 Apr 2026 17:21:19 +0100 +Subject: comedi: comedi_test: fix check for valid scan_begin_src in waveform_ai_cmdtest() + +From: Ian Abbott + +commit 542f5248cb481073203e0dadab5bcbd28aeae308 upstream. + +Commit 783ddaebd397 ("staging: comedi: comedi_test: support +scan_begin_src == TRIG_FOLLOW") neglected to add a test that +`scan_begin_src` has only one bit set. The allowed values are +`TRIG_FOLLOW` and `TRIG_TIMER`, but the code incorrectly also allows +`TRIG_FOLLOW | TRIG_TIMER`. Add a call to +`comedi_check_trigger_is_unique()` to check that only one trigger source +bit is set. + +Fixes: 783ddaebd397 ("staging: comedi: comedi_test: support scan_begin_src == TRIG_FOLLOW") +Cc: stable +Signed-off-by: Ian Abbott +Link: https://patch.msgid.link/20260422162138.36003-1-abbotti@mev.co.uk +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/comedi/drivers/comedi_test.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/comedi/drivers/comedi_test.c ++++ b/drivers/comedi/drivers/comedi_test.c +@@ -273,6 +273,7 @@ static int waveform_ai_cmdtest(struct co + /* Step 2a : make sure trigger sources are unique */ + + err |= comedi_check_trigger_is_unique(cmd->convert_src); ++ err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); + err |= comedi_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ diff --git a/queue-5.15/comedi-comedi_test-fix-limiting-of-convert_arg-in-waveform_ai_cmdtest.patch b/queue-5.15/comedi-comedi_test-fix-limiting-of-convert_arg-in-waveform_ai_cmdtest.patch new file mode 100644 index 0000000000..d73e9878d9 --- /dev/null +++ b/queue-5.15/comedi-comedi_test-fix-limiting-of-convert_arg-in-waveform_ai_cmdtest.patch @@ -0,0 +1,69 @@ +From 8a3bee801d420be8a7a0bae4a26547b353b8fe22 Mon Sep 17 00:00:00 2001 +From: Ian Abbott +Date: Wed, 22 Apr 2026 15:46:37 +0100 +Subject: comedi: comedi_test: Fix limiting of convert_arg in waveform_ai_cmdtest() + +From: Ian Abbott + +commit 8a3bee801d420be8a7a0bae4a26547b353b8fe22 upstream. + +The function checks and possibly modifies the description of an +asynchronous command to be run on the analog input subdevice of a comedi +device attached to the "comedi_test" driver, returning 0 if no +modifications were required, or a positive value that indicates which +step of the checking process it failed on. Step 4 fixes up various +argument values for various trigger sources. + +There are two bugs in the fixing up of the `convert_arg` value to keep +the `scan_begin_arg` value within the range of `unsigned int` when +`scan_begin_src` and `convert_src` both have the value `TRIG_TIMER`, +which indicates that the corresponding `_arg` values hold a time period +in nanoseconds. The code also uses `scan_end_arg` which hold the number +of "conversions" within each "scan". The goal is to end up with the +scan period being less than or equal to the convert period multiplied by +the number of conversions per scan. It intends to do that by clamping +the `convert_arg` value to a maximum value of `UINT_MAX / scan_end_arg` +rounded down to a multiple of 1000 (`NSEC_PER_USEC`). + +(The rounding from nanoseconds to microseconds is because the driver is +modelling a device that uses a 1 MHz clock for timing. This is partly +because that is a more typical timing base for real hardware devices +driven by comedi, and partly because the driver used to use `struct +timeval` internally.) + +The first bug is that the code checks if `scan_begin_arg == TRIG_TIMER` +when it should be checking if `scan_begin_src == TRIG_TIMER`. The +bugged check will always fail because if `scan_begin_src == TRIG_TIMER`, +then `scan_begin_arg` will be at least 1000 (`NSEC_PER_USEC`), otherwise +`scan_begin_src == TRIG_FOLLOW` and `scan_begin_arg` will be 0. (N.B +`TRIG_TIMER` is defined as `0x10`.) The second bug is that is rounding +the maximum value down to a multiple of 1000000000 (`NSEC_PER_SEC`) +instead of 1000 (`NSEC_PER_USEC`), however this bug is not reached due +to the first bug. This patch fixes both bugs. + +Fixes: 783ddaebd397 ("staging: comedi: comedi_test: support scan_begin_src == TRIG_FOLLOW") +Fixes: 5afdcad2f818 ("staging: comedi: comedi_test: limit maximum convert_arg") +Cc: stable +Signed-off-by: Ian Abbott +Link: https://patch.msgid.link/20260422144637.27692-1-abbotti@mev.co.uk +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/comedi/drivers/comedi_test.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/comedi/drivers/comedi_test.c ++++ b/drivers/comedi/drivers/comedi_test.c +@@ -324,10 +324,10 @@ static int waveform_ai_cmdtest(struct co + arg = min(arg, + rounddown(UINT_MAX, (unsigned int)NSEC_PER_USEC)); + arg = NSEC_PER_USEC * DIV_ROUND_CLOSEST(arg, NSEC_PER_USEC); +- if (cmd->scan_begin_arg == TRIG_TIMER) { ++ if (cmd->scan_begin_src == TRIG_TIMER) { + /* limit convert_arg to keep scan_begin_arg in range */ + limit = UINT_MAX / cmd->scan_end_arg; +- limit = rounddown(limit, (unsigned int)NSEC_PER_SEC); ++ limit = rounddown(limit, (unsigned int)NSEC_PER_USEC); + arg = min(arg, limit); + } + err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg); diff --git a/queue-5.15/drm-hyperv-validate-vmbus-packet-size-in-receive-callback.patch b/queue-5.15/drm-hyperv-validate-vmbus-packet-size-in-receive-callback.patch new file mode 100644 index 0000000000..4a00fa9504 --- /dev/null +++ b/queue-5.15/drm-hyperv-validate-vmbus-packet-size-in-receive-callback.patch @@ -0,0 +1,187 @@ +From 7f87763f47a3c22fb50265a00619ef10f2394b18 Mon Sep 17 00:00:00 2001 +From: Berkant Koc +Date: Sat, 23 May 2026 15:27:47 +0200 +Subject: drm/hyperv: validate VMBus packet size in receive callback + +From: Berkant Koc + +commit 7f87763f47a3c22fb50265a00619ef10f2394b18 upstream. + +hyperv_receive_sub() reads msg->vid_hdr.type and dispatches into one +of four message-type branches without knowing how many bytes the host +wrote into hv->recv_buf. The completion path then runs +memcpy(hv->init_buf, msg, VMBUS_MAX_PACKET_SIZE), so the consumer that +wakes on wait_for_completion_timeout() can read up to 16 KiB of +residue from a prior message as if it were the response payload. + +Pass bytes_recvd into hyperv_receive_sub() and reject any packet that +does not cover the pipe + synthvid header. A single switch on +msg->vid_hdr.type then computes the type-specific payload size: the +three completion-driving types (SYNTHVID_VERSION_RESPONSE, +SYNTHVID_RESOLUTION_RESPONSE, SYNTHVID_VRAM_LOCATION_ACK) fall through +to a shared exit that requires that size before memcpy/complete, while +SYNTHVID_FEATURE_CHANGE validates its own payload and returns before +reading is_dirt_needed. Unknown types are dropped. + +SYNTHVID_RESOLUTION_RESPONSE is variable length: the host fills +resolution_count entries, not the full SYNTHVID_MAX_RESOLUTION_COUNT +array. Validate the fixed prefix first so resolution_count can be +read, bound it against the array, then require only the count-sized +array, so the shorter responses the host actually sends are accepted. + +Only run the sub-handler when vmbus_recvpacket() returned success. The +memcpy length is bytes_recvd, which is bounded by VMBUS_MAX_PACKET_SIZE +only on a successful receive; on -ENOBUFS vmbus_recvpacket() instead +reports the required length, which can exceed hv->recv_buf, so copying +bytes_recvd would read and write past the 16 KiB buffers. Gating on the +success return keeps the copy bounded. The nonzero-return path is itself +a malformed-message case and is now logged rather than silently skipped; +channel recovery is not attempted. + +Rejected packets are reported via drm_err_ratelimited() rather than +silently dropped, matching the CoCo-hardened pattern in +hv_kvp_onchannelcallback(). + +Fixes: 76c56a5affeb ("drm/hyperv: Add DRM driver for hyperv synthetic video device") +Cc: stable@vger.kernel.org # 5.14+ +Signed-off-by: Berkant Koc +Assisted-by: Claude:claude-opus-4-7 berkoc-pipeline +Reviewed-by: Michael Kelley +Tested-by: Michael Kelley +Signed-off-by: Hamza Mahfooz +Link: https://patch.msgid.link/8200dbc199c7a9b75ac7e8af6c748d2189b5ebd5.1779542874.git.me@berkoc.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/hyperv/hyperv_drm_proto.c | 100 ++++++++++++++++++++++++++---- + 1 file changed, 87 insertions(+), 13 deletions(-) + +--- a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c ++++ b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c +@@ -422,30 +422,92 @@ static int hyperv_get_supported_resoluti + return 0; + } + +-static void hyperv_receive_sub(struct hv_device *hdev) ++static void hyperv_receive_sub(struct hv_device *hdev, u32 bytes_recvd) + { + struct hyperv_drm_device *hv = hv_get_drvdata(hdev); + struct synthvid_msg *msg; ++ size_t hdr_size; ++ size_t need; + + if (!hv) + return; + +- msg = (struct synthvid_msg *)hv->recv_buf; +- +- /* Complete the wait event */ +- if (msg->vid_hdr.type == SYNTHVID_VERSION_RESPONSE || +- msg->vid_hdr.type == SYNTHVID_RESOLUTION_RESPONSE || +- msg->vid_hdr.type == SYNTHVID_VRAM_LOCATION_ACK) { +- memcpy(hv->init_buf, msg, VMBUS_MAX_PACKET_SIZE); +- complete(&hv->wait); ++ hdr_size = sizeof(struct pipe_msg_hdr) + ++ sizeof(struct synthvid_msg_hdr); ++ if (bytes_recvd < hdr_size) { ++ drm_err_ratelimited(&hv->dev, ++ "synthvid packet too small for header: %u\n", ++ bytes_recvd); + return; + } + +- if (msg->vid_hdr.type == SYNTHVID_FEATURE_CHANGE) { ++ msg = (struct synthvid_msg *)hv->recv_buf; ++ need = hdr_size; ++ ++ switch (msg->vid_hdr.type) { ++ case SYNTHVID_VERSION_RESPONSE: ++ need += sizeof(struct synthvid_version_resp); ++ break; ++ case SYNTHVID_RESOLUTION_RESPONSE: ++ /* ++ * The resolution response is variable length: the host ++ * fills resolution_count entries, not the full ++ * SYNTHVID_MAX_RESOLUTION_COUNT array. Require the fixed ++ * prefix first so resolution_count can be read, then ++ * demand exactly the count-sized array. ++ */ ++ need += offsetof(struct synthvid_supported_resolution_resp, ++ supported_resolution); ++ if (bytes_recvd < need) ++ break; ++ if (msg->resolution_resp.resolution_count > ++ SYNTHVID_MAX_RESOLUTION_COUNT) { ++ drm_err_ratelimited(&hv->dev, ++ "synthvid resolution count too large: %u\n", ++ msg->resolution_resp.resolution_count); ++ return; ++ } ++ need += msg->resolution_resp.resolution_count * ++ sizeof(struct hvd_screen_info); ++ break; ++ case SYNTHVID_VRAM_LOCATION_ACK: ++ need += sizeof(struct synthvid_vram_location_ack); ++ break; ++ case SYNTHVID_FEATURE_CHANGE: ++ /* ++ * Not a completion-driving message: validate its own payload ++ * and consume it here rather than falling through to the ++ * memcpy/complete shared by the wait-event responses. ++ */ ++ if (bytes_recvd < need + ++ sizeof(struct synthvid_feature_change)) { ++ drm_err_ratelimited(&hv->dev, ++ "synthvid feature change packet too small: %u\n", ++ bytes_recvd); ++ return; ++ } + hv->dirt_needed = msg->feature_chg.is_dirt_needed; + if (hv->dirt_needed) + hyperv_hide_hw_ptr(hv->hdev); ++ return; ++ default: ++ return; ++ } ++ ++ /* ++ * Shared completion path for the wait-event responses ++ * (VERSION_RESPONSE, RESOLUTION_RESPONSE, VRAM_LOCATION_ACK): ++ * require the type-specific payload before handing the buffer to ++ * the waiter. ++ */ ++ if (bytes_recvd < need) { ++ drm_err_ratelimited(&hv->dev, ++ "synthvid packet too small for type %u: %u < %zu\n", ++ msg->vid_hdr.type, bytes_recvd, need); ++ return; + } ++ memcpy(hv->init_buf, msg, bytes_recvd); ++ complete(&hv->wait); + } + + static void hyperv_receive(void *ctx) +@@ -466,9 +528,21 @@ static void hyperv_receive(void *ctx) + ret = vmbus_recvpacket(hdev->channel, recv_buf, + VMBUS_MAX_PACKET_SIZE, + &bytes_recvd, &req_id); +- if (bytes_recvd > 0 && +- recv_buf->pipe_hdr.type == PIPE_MSG_DATA) +- hyperv_receive_sub(hdev); ++ if (ret) { ++ /* ++ * A nonzero return (e.g. -ENOBUFS for an oversized ++ * packet) is itself a malformed message: bytes_recvd ++ * then reports the required length rather than a copied ++ * payload, so it must not be forwarded to the ++ * sub-handler. Channel recovery is not attempted. ++ */ ++ drm_err_ratelimited(&hv->dev, ++ "vmbus_recvpacket failed: %d (need %u)\n", ++ ret, bytes_recvd); ++ } else if (bytes_recvd > 0 && ++ recv_buf->pipe_hdr.type == PIPE_MSG_DATA) { ++ hyperv_receive_sub(hdev, bytes_recvd); ++ } + } while (bytes_recvd > 0 && ret == 0); + } + diff --git a/queue-5.15/input-atmel_mxt_ts-fix-boundary-check-in-mxt_prepare_cfg_mem.patch b/queue-5.15/input-atmel_mxt_ts-fix-boundary-check-in-mxt_prepare_cfg_mem.patch new file mode 100644 index 0000000000..1ad1daaab4 --- /dev/null +++ b/queue-5.15/input-atmel_mxt_ts-fix-boundary-check-in-mxt_prepare_cfg_mem.patch @@ -0,0 +1,53 @@ +From baa0210fb6a9dc3882509a9411b6d284d88fe30e Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Mon, 4 May 2026 11:54:45 -0700 +Subject: Input: atmel_mxt_ts - fix boundary check in mxt_prepare_cfg_mem + +From: Dmitry Torokhov + +commit baa0210fb6a9dc3882509a9411b6d284d88fe30e upstream. + +When a configuration file provides an object size that is larger than the +driver's known mxt_obj_size(object), the driver intends to discard the +extra bytes. + +The loop iterates using for (i = 0; i < size; i++). Inside the loop, the +condition to skip processing extra bytes is: + + if (i > mxt_obj_size(object)) + continue; + +Since i is a 0-based index, the valid indices for the object are 0 through +mxt_obj_size(object) - 1. + +When i == mxt_obj_size(object), the condition evaluates to false, and the +code processes the byte instead of discarding it. + +This causes the code to calculate byte_offset = reg + i - cfg->start_ofs +and writes the byte there, overwriting exactly one byte of the adjacent +instance or object. + +Update the boundary check to skip extra bytes correctly by using >=. + +Fixes: 50a77c658b80 ("Input: atmel_mxt_ts - download device config using firmware loader") +Cc: stable@vger.kernel.org +Assisted-by: Gemini:gemini-3.1-pro +Reviewed-by: Ricardo Ribalda +Link: https://patch.msgid.link/20260504185448.4055973-1-dmitry.torokhov@gmail.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/touchscreen/atmel_mxt_ts.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/input/touchscreen/atmel_mxt_ts.c ++++ b/drivers/input/touchscreen/atmel_mxt_ts.c +@@ -1443,7 +1443,7 @@ static int mxt_prepare_cfg_mem(struct mx + } + cfg->raw_pos += offset; + +- if (i > mxt_obj_size(object)) ++ if (i >= mxt_obj_size(object)) + continue; + + byte_offset = reg + i - cfg->start_ofs; diff --git a/queue-5.15/input-synaptics-add-len2058-to-smbus-passlist-for-thinkpad-e490.patch b/queue-5.15/input-synaptics-add-len2058-to-smbus-passlist-for-thinkpad-e490.patch new file mode 100644 index 0000000000..dfdab57c80 --- /dev/null +++ b/queue-5.15/input-synaptics-add-len2058-to-smbus-passlist-for-thinkpad-e490.patch @@ -0,0 +1,45 @@ +From 16ca52bc209fa4bf9239cd9e5643e95533476b58 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nicol=C3=A1s=20Bazaes?= +Date: Wed, 13 May 2026 21:35:49 -0400 +Subject: Input: synaptics - add LEN2058 to SMBus passlist for ThinkPad E490 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Nicolás Bazaes + +commit 16ca52bc209fa4bf9239cd9e5643e95533476b58 upstream. + +The Lenovo ThinkPad E490 (PNP ID: LEN2058) has a Synaptics TM3471-020 +touchpad that supports SMBus/RMI4 mode but is not listed in +smbus_pnp_ids[]. Without this entry, RMI4 over SMBus is not enabled +by default, and the touchpad falls back to PS/2 mode. + +Adding LEN2058 to the passlist enables automatic RMI4 detection without +requiring the psmouse.synaptics_intertouch parameter, and matches +the behavior of similar ThinkPad models already in the list +(E480/LEN2054, E580/LEN2055). + +Tested on ThinkPad E490 with kernel 7.0.5-zen1 and Arch Linux. +RMI4 over SMBus is confirmed working without any kernel parameters. + +Signed-off-by: Nicolás Bazaes +Assisted-by: Claude:claude-sonnet-4-6 +Link: https://patch.msgid.link/20260514013552.14234-1-contacto@bazaes.cl +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/mouse/synaptics.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/input/mouse/synaptics.c ++++ b/drivers/input/mouse/synaptics.c +@@ -187,6 +187,7 @@ static const char * const smbus_pnp_ids[ + "LEN2044", /* L470 */ + "LEN2054", /* E480 */ + "LEN2055", /* E580 */ ++ "LEN2058", /* E490 */ + "LEN2068", /* T14 Gen 1 */ + "SYN1221", /* TUXEDO InfinityBook Pro 14 v5 */ + "SYN3003", /* HP EliteBook 850 G1 */ diff --git a/queue-5.15/scsi-fcoe-reject-fip-descriptors-with-zero-fip_dlen-in-cvl-walker.patch b/queue-5.15/scsi-fcoe-reject-fip-descriptors-with-zero-fip_dlen-in-cvl-walker.patch new file mode 100644 index 0000000000..3bcba37bde --- /dev/null +++ b/queue-5.15/scsi-fcoe-reject-fip-descriptors-with-zero-fip_dlen-in-cvl-walker.patch @@ -0,0 +1,53 @@ +From 9eed1bd59937e6828b00d2f2dfef631d964f3636 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Mon, 18 May 2026 10:43:07 -0400 +Subject: scsi: fcoe: Reject FIP descriptors with zero fip_dlen in CVL walker + +From: Michael Bommarito + +commit 9eed1bd59937e6828b00d2f2dfef631d964f3636 upstream. + +drivers/scsi/fcoe/fcoe_ctlr.c::fcoe_ctlr_recv_clr_vlink() advanced the +descriptor cursor by an attacker-supplied fip_dlen without ever +requiring dlen >= sizeof(struct fip_desc) in the default branch. The +named descriptor cases (FIP_DT_MAC, FIP_DT_NAME, FIP_DT_VN_ID) checked +their per-type minimum lengths, but a FIP_DT_NON_CRITICAL descriptor +(fip_dtype >= 128, which the standard requires receivers to silently +ignore) skipped that check entirely. + +An unauthenticated L2 peer on the FCoE control VLAN could hang +fcoe_ctlr_recv_work on an fcoe, qedf, or bnx2fc initiator indefinitely +by emitting one FIP CVL frame whose single descriptor had fip_dtype == +FIP_DT_NON_CRITICAL and fip_dlen == 0: the cursor advanced zero bytes +per iteration and the loop condition rlen >= sizeof(*desc) stayed true +forever, blocking every subsequent FIP frame on that controller. + +Tighten the outer dlen guard to also reject dlen < sizeof(struct +fip_desc), so a malformed descriptor whose length cannot even cover the +descriptor header is rejected before the switch. This is the same +lower-bound the named cases already apply and is the minimum scope that +closes the loop. + +Fixes: 97c8389d54b9 ("[SCSI] fcoe, libfcoe: Add support for FIP. FCoE discovery and keep-alive.") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-7 +Signed-off-by: Michael Bommarito +Reviewed-by: Hannes Reinecke +Link: https://patch.msgid.link/20260518144307.2820961-1-michael.bommarito@gmail.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/fcoe/fcoe_ctlr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/fcoe/fcoe_ctlr.c ++++ b/drivers/scsi/fcoe/fcoe_ctlr.c +@@ -1391,7 +1391,7 @@ static void fcoe_ctlr_recv_clr_vlink(str + + while (rlen >= sizeof(*desc)) { + dlen = desc->fip_dlen * FIP_BPW; +- if (dlen > rlen) ++ if (dlen < sizeof(*desc) || dlen > rlen) + goto err; + /* Drop CVL if there are duplicate critical descriptors */ + if ((desc->fip_dtype < 32) && diff --git a/queue-5.15/scsi-scsi_transport_fc-widen-fpin-pname-walker-counter-to-u32.patch b/queue-5.15/scsi-scsi_transport_fc-widen-fpin-pname-walker-counter-to-u32.patch new file mode 100644 index 0000000000..ac08809f76 --- /dev/null +++ b/queue-5.15/scsi-scsi_transport_fc-widen-fpin-pname-walker-counter-to-u32.patch @@ -0,0 +1,163 @@ +From a9a39233ec1fc9f97ea1340a4d09bb7ec2be5153 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Wed, 20 May 2026 09:30:15 -0400 +Subject: scsi: scsi_transport_fc: Widen FPIN pname walker counter to u32 + +From: Michael Bommarito + +commit a9a39233ec1fc9f97ea1340a4d09bb7ec2be5153 upstream. + +An adjacent Fibre Channel fabric actor that can deliver an FPIN ELS +frame to an lpfc or qla2xxx Linux initiator can trigger a non-return in +the generic FC transport. This is not a local userspace or IP network +path; the attacker must be able to inject fabric traffic, for example as +a compromised switch or fabric controller, or as a same-zone N_Port on a +fabric that permits source spoofing. + +The Link-Integrity and Peer-Congestion FPIN walkers used a u8 loop +counter against the 32-bit on-wire pname_count field, and did not bound +pname_count by the descriptor body already validated by the TLV walker. +A pname_count of 256 therefore wraps the counter and keeps the loop +condition true indefinitely. + +Factor the shared pname_list[] walk into one helper, widen the counter +to u32, and clamp pname_count against the entries that fit in the +descriptor body before iterating. + +Fixes: 3dcfe0de5a97 ("scsi: fc: Parse FPIN packets and update statistics") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-7 +Signed-off-by: Michael Bommarito +Reviewed-by: Christoph Hellwig +Reviewed-by: John Garry +Link: https://patch.msgid.link/20260520133015.1018937-1-michael.bommarito@gmail.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/scsi_transport_fc.c | 77 ++++++++++++++++++++------------------- + 1 file changed, 41 insertions(+), 36 deletions(-) + +--- a/drivers/scsi/scsi_transport_fc.c ++++ b/drivers/scsi/scsi_transport_fc.c +@@ -744,6 +744,37 @@ fc_cn_stats_update(u16 event_type, struc + } + } + ++static void ++fc_fpin_pname_stats_update(struct Scsi_Host *shost, ++ struct fc_rport *attach_rport, u16 event_type, ++ u32 desc_len, u32 fixed_len, u32 pname_count, ++ __be64 *pname_list, ++ void (*stats_update)(u16 event_type, ++ struct fc_fpin_stats *stats)) ++{ ++ u32 i; ++ struct fc_rport *rport; ++ u64 wwpn; ++ ++ if (desc_len < fixed_len) ++ pname_count = 0; ++ else ++ pname_count = min(pname_count, (desc_len - fixed_len) / ++ sizeof(pname_list[0])); ++ ++ for (i = 0; i < pname_count; i++) { ++ wwpn = be64_to_cpu(pname_list[i]); ++ rport = fc_find_rport_by_wwpn(shost, wwpn); ++ if (rport && ++ (rport->roles & FC_PORT_ROLE_FCP_TARGET || ++ rport->roles & FC_PORT_ROLE_NVME_TARGET)) { ++ if (rport == attach_rport) ++ continue; ++ stats_update(event_type, &rport->fpin_stats); ++ } ++ } ++} ++ + /* + * fc_fpin_li_stats_update - routine to update Link Integrity + * event statistics. +@@ -754,13 +785,11 @@ fc_cn_stats_update(u16 event_type, struc + static void + fc_fpin_li_stats_update(struct Scsi_Host *shost, struct fc_tlv_desc *tlv) + { +- u8 i; + struct fc_rport *rport = NULL; + struct fc_rport *attach_rport = NULL; + struct fc_host_attrs *fc_host = shost_to_fc_host(shost); + struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv; + u16 event_type = be16_to_cpu(li_desc->event_type); +- u64 wwpn; + + rport = fc_find_rport_by_wwpn(shost, + be64_to_cpu(li_desc->attached_wwpn)); +@@ -771,22 +800,11 @@ fc_fpin_li_stats_update(struct Scsi_Host + fc_li_stats_update(event_type, &attach_rport->fpin_stats); + } + +- if (be32_to_cpu(li_desc->pname_count) > 0) { +- for (i = 0; +- i < be32_to_cpu(li_desc->pname_count); +- i++) { +- wwpn = be64_to_cpu(li_desc->pname_list[i]); +- rport = fc_find_rport_by_wwpn(shost, wwpn); +- if (rport && +- (rport->roles & FC_PORT_ROLE_FCP_TARGET || +- rport->roles & FC_PORT_ROLE_NVME_TARGET)) { +- if (rport == attach_rport) +- continue; +- fc_li_stats_update(event_type, +- &rport->fpin_stats); +- } +- } +- } ++ fc_fpin_pname_stats_update(shost, attach_rport, event_type, ++ be32_to_cpu(li_desc->desc_len), ++ FC_TLV_DESC_LENGTH_FROM_SZ(*li_desc), ++ be32_to_cpu(li_desc->pname_count), ++ li_desc->pname_list, fc_li_stats_update); + + if (fc_host->port_name == be64_to_cpu(li_desc->attached_wwpn)) + fc_li_stats_update(event_type, &fc_host->fpin_stats); +@@ -834,13 +852,11 @@ static void + fc_fpin_peer_congn_stats_update(struct Scsi_Host *shost, + struct fc_tlv_desc *tlv) + { +- u8 i; + struct fc_rport *rport = NULL; + struct fc_rport *attach_rport = NULL; + struct fc_fn_peer_congn_desc *pc_desc = + (struct fc_fn_peer_congn_desc *)tlv; + u16 event_type = be16_to_cpu(pc_desc->event_type); +- u64 wwpn; + + rport = fc_find_rport_by_wwpn(shost, + be64_to_cpu(pc_desc->attached_wwpn)); +@@ -851,22 +867,11 @@ fc_fpin_peer_congn_stats_update(struct S + fc_cn_stats_update(event_type, &attach_rport->fpin_stats); + } + +- if (be32_to_cpu(pc_desc->pname_count) > 0) { +- for (i = 0; +- i < be32_to_cpu(pc_desc->pname_count); +- i++) { +- wwpn = be64_to_cpu(pc_desc->pname_list[i]); +- rport = fc_find_rport_by_wwpn(shost, wwpn); +- if (rport && +- (rport->roles & FC_PORT_ROLE_FCP_TARGET || +- rport->roles & FC_PORT_ROLE_NVME_TARGET)) { +- if (rport == attach_rport) +- continue; +- fc_cn_stats_update(event_type, +- &rport->fpin_stats); +- } +- } +- } ++ fc_fpin_pname_stats_update(shost, attach_rport, event_type, ++ be32_to_cpu(pc_desc->desc_len), ++ FC_TLV_DESC_LENGTH_FROM_SZ(*pc_desc), ++ be32_to_cpu(pc_desc->pname_count), ++ pc_desc->pname_list, fc_cn_stats_update); + } + + /* diff --git a/queue-5.15/serial-dz-fix-bootconsole-message-clobbering-at-chip-reset.patch b/queue-5.15/serial-dz-fix-bootconsole-message-clobbering-at-chip-reset.patch new file mode 100644 index 0000000000..140d941007 --- /dev/null +++ b/queue-5.15/serial-dz-fix-bootconsole-message-clobbering-at-chip-reset.patch @@ -0,0 +1,71 @@ +From ca904f4b42355287bc5ce8b7550ebe909cda4c2c Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +Date: Wed, 6 May 2026 23:42:31 +0100 +Subject: serial: dz: Fix bootconsole message clobbering at chip reset + +From: Maciej W. Rozycki + +commit ca904f4b42355287bc5ce8b7550ebe909cda4c2c upstream. + +In the DZ interface as implemented by the DC7085 gate array the serial +transmitters are double buffered, meaning that at the time a transmitter +is ready to accept the next character there is one in the transmit shift +register still being sent to the line. Issuing a master clear at this +time causes this character to be lost, so wait an extra amount of time +sufficient for the transmit shift register to drain at 9600bps, which is +the baud rate setting used by the firmware console. + +Mind the specified 1.4us TRDY recovery time in the course and continue +using iob() as the completion barrier, since the platforms involved use +a write buffer that can delay and combine writes, and reorder them with +respect to reads regardless of the MMIO locations accessed and we still +lack a platform-independent handler for that. + +When called from dz_serial_console_init() this is too early for fsleep() +to work and even before lpj has been calculated and therefore the delay +is actually not sufficient for the transmitter to drain and is merely a +placeholder now. This will be addressed in a follow-up change. + +Fixes: e6ee512f5a77 ("dz.c: Resource management") +Signed-off-by: Maciej W. Rozycki +Cc: stable@vger.kernel.org # v2.6.25+ +Link: https://patch.msgid.link/alpine.DEB.2.21.2605062259080.46195@angie.orcam.me.uk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/dz.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +--- a/drivers/tty/serial/dz.c ++++ b/drivers/tty/serial/dz.c +@@ -544,10 +544,31 @@ static int dz_encode_baud_rate(unsigned + static void dz_reset(struct dz_port *dport) + { + struct dz_mux *mux = dport->mux; ++ unsigned short tcr; ++ int loops = 10000; + + if (mux->initialised) + return; + ++ tcr = dz_in(dport, DZ_TCR); ++ ++ /* Do not disturb any ongoing transmissions. */ ++ if (dz_in(dport, DZ_CSR) & DZ_MSE) { ++ unsigned short csr, mask; ++ ++ mask = tcr; ++ while ((mask & DZ_LNENB) && loops--) { ++ csr = dz_in(dport, DZ_CSR); ++ if (!(csr & DZ_TRDY)) ++ continue; ++ mask &= ~(1 << ((csr & DZ_TLINE) >> 8)); ++ dz_out(dport, DZ_TCR, mask); ++ iob(); ++ udelay(2); /* 1.4us TRDY recovery. */ ++ } ++ udelay(1200); /* Transmitter drain. */ ++ } ++ + dz_out(dport, DZ_CSR, DZ_CLR); + while (dz_in(dport, DZ_CSR) & DZ_CLR); + iob(); diff --git a/queue-5.15/serial-fsl_lpuart-fix-rx-buffer-and-dma-map-leaks-in-start_rx_dma.patch b/queue-5.15/serial-fsl_lpuart-fix-rx-buffer-and-dma-map-leaks-in-start_rx_dma.patch new file mode 100644 index 0000000000..461e7efa73 --- /dev/null +++ b/queue-5.15/serial-fsl_lpuart-fix-rx-buffer-and-dma-map-leaks-in-start_rx_dma.patch @@ -0,0 +1,90 @@ +From 9a9254c4a2a3ca2b3da16d173f3b0dd01f397ff6 Mon Sep 17 00:00:00 2001 +From: Shitalkumar Gandhi +Date: Mon, 20 Apr 2026 19:29:03 +0530 +Subject: serial: fsl_lpuart: fix rx buffer and DMA map leaks in start_rx_dma + +From: Shitalkumar Gandhi + +commit 9a9254c4a2a3ca2b3da16d173f3b0dd01f397ff6 upstream. + +lpuart_start_rx_dma() allocates sport->rx_ring.buf with kzalloc() and +then maps a scatterlist via dma_map_sg(). On three subsequent error +paths the function returns directly without releasing those resources: + + - when dma_map_sg() returns 0 (-EINVAL): + ring->buf is leaked. + - when dmaengine_slave_config() fails: + ring->buf and the DMA mapping are leaked. + - when dmaengine_prep_dma_cyclic() returns NULL: + ring->buf and the DMA mapping are leaked. + +The sole cleanup path, lpuart_dma_rx_free(), is only reached when +lpuart_dma_rx_use is set, and the caller lpuart_rx_dma_startup() clears +that flag on failure of lpuart_start_rx_dma(). So these resources are +permanently leaked on every failure in this function. Repeated port +open/close or termios changes under error conditions will slowly consume +memory and leave stale streaming DMA mappings behind. + +Fix it by introducing two error labels that unmap the scatterlist and +free the ring buffer as appropriate. While here, replace the misleading +-EFAULT (bad userspace pointer) returned when dmaengine_prep_dma_cyclic() +fails with the more accurate -ENOMEM, matching how other dmaengine users +in the tree treat this failure. + +No functional change on the success path. + +Fixes: 5887ad43ee02 ("tty: serial: fsl_lpuart: Use cyclic DMA for Rx") +Cc: stable +Signed-off-by: Shitalkumar Gandhi +Reviewed-by: Frank Li +Link: https://patch.msgid.link/20260420135903.2062024-1-shitalkumar.gandhi@cambiumnetworks.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/fsl_lpuart.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/tty/serial/fsl_lpuart.c ++++ b/drivers/tty/serial/fsl_lpuart.c +@@ -1279,7 +1279,8 @@ static inline int lpuart_start_rx_dma(st + + if (!nent) { + dev_err(sport->port.dev, "DMA Rx mapping error\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_free_buf; + } + + dma_rx_sconfig.src_addr = lpuart_dma_datareg_addr(sport); +@@ -1291,7 +1292,7 @@ static inline int lpuart_start_rx_dma(st + if (ret < 0) { + dev_err(sport->port.dev, + "DMA Rx slave config failed, err = %d\n", ret); +- return ret; ++ goto err_unmap_sg; + } + + sport->dma_rx_desc = dmaengine_prep_dma_cyclic(chan, +@@ -1302,7 +1303,8 @@ static inline int lpuart_start_rx_dma(st + DMA_PREP_INTERRUPT); + if (!sport->dma_rx_desc) { + dev_err(sport->port.dev, "Cannot prepare cyclic DMA\n"); +- return -EFAULT; ++ ret = -ENOMEM; ++ goto err_unmap_sg; + } + + sport->dma_rx_desc->callback = lpuart_dma_rx_complete; +@@ -1320,6 +1322,13 @@ static inline int lpuart_start_rx_dma(st + } + + return 0; ++ ++err_unmap_sg: ++ dma_unmap_sg(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE); ++err_free_buf: ++ kfree(ring->buf); ++ ring->buf = NULL; ++ return ret; + } + + static void lpuart_dma_rx_free(struct uart_port *port) diff --git a/queue-5.15/serial-sh-sci-fix-memory-region-release-in-error-path.patch b/queue-5.15/serial-sh-sci-fix-memory-region-release-in-error-path.patch new file mode 100644 index 0000000000..aba6c477d1 --- /dev/null +++ b/queue-5.15/serial-sh-sci-fix-memory-region-release-in-error-path.patch @@ -0,0 +1,40 @@ +From 92b1ea22454b08a39baef3a7290fb3ec50366616 Mon Sep 17 00:00:00 2001 +From: Hongling Zeng +Date: Tue, 21 Apr 2026 14:57:37 +0800 +Subject: serial: sh-sci: fix memory region release in error path + +From: Hongling Zeng + +commit 92b1ea22454b08a39baef3a7290fb3ec50366616 upstream. + +The sci_request_port() function uses request_mem_region() to reserve +I/O memory, but in the error path when sci_remap_port() fails, it +incorrectly calls release_resource() instead of release_mem_region(). + +This mismatch can cause resource accounting issues. Fix it by using +the correct release function, consistent with sci_release_port(). + +Fixes: e2651647080930a1 ("serial: sh-sci: Handle port memory region reservations.") +Cc: stable +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/r/202604032356.SzEjYkBC-lkp@intel.com/ +Signed-off-by: Hongling Zeng +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20260421065737.724187-1-zenghongling@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/sh-sci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/tty/serial/sh-sci.c ++++ b/drivers/tty/serial/sh-sci.c +@@ -2753,7 +2753,7 @@ static int sci_request_port(struct uart_ + + ret = sci_remap_port(port); + if (unlikely(ret != 0)) { +- release_resource(res); ++ release_mem_region(port->mapbase, sport->reg_size); + return ret; + } + diff --git a/queue-5.15/serial-zs-fix-bootconsole-handover-lockup.patch b/queue-5.15/serial-zs-fix-bootconsole-handover-lockup.patch new file mode 100644 index 0000000000..21f5331ac6 --- /dev/null +++ b/queue-5.15/serial-zs-fix-bootconsole-handover-lockup.patch @@ -0,0 +1,100 @@ +From 6c05cf72e13314ce9b770b5951695dc5a2152920 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +Date: Wed, 6 May 2026 23:42:39 +0100 +Subject: serial: zs: Fix bootconsole handover lockup + +From: Maciej W. Rozycki + +commit 6c05cf72e13314ce9b770b5951695dc5a2152920 upstream. + +Calling zs_reset() in the course of setting up the serial device causes +line parameters to be reset and the transmitter disabled. We've been +lucky in that no message is usually produced to the kernel log between +this call and the later call to uart_set_options() in the course of +console setup done by zs_serial_console_init(), or the system would hang +as the console output handler in the firmware tried to access a port the +transmitter of which has been disabled and line parameters messed up. + +This will change with the next change to the driver, so fix zs_reset() +such that line parameters are set for 9600n8 console operation as with +the system firmware and the transmitter re-enabled after reset. This +also means zs_pm() serves no purpose anymore, so drop it. + +Fixes: 8b4a40809e53 ("zs: move to the serial subsystem") +Signed-off-by: Maciej W. Rozycki +Cc: stable@vger.kernel.org # v2.6.23+ +Link: https://patch.msgid.link/alpine.DEB.2.21.2605062308040.46195@angie.orcam.me.uk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/zs.c | 29 ++++++++--------------------- + 1 file changed, 8 insertions(+), 21 deletions(-) + +--- a/drivers/tty/serial/zs.c ++++ b/drivers/tty/serial/zs.c +@@ -105,18 +105,24 @@ struct zs_parms { + + static struct zs_scc zs_sccs[ZS_NUM_SCCS]; + ++/* ++ * Set parameters in WR5, WR12, WR13 such as not to interfere ++ * with the initial PROM-based console. Otherwise any output ++ * produced before the console handover would cause the system ++ * firmware to hang (TxENAB) or produce rubbish (Tx8, B9600). ++ */ + static u8 zs_init_regs[ZS_NUM_REGS] __initdata = { + 0, /* write 0 */ + PAR_SPEC, /* write 1 */ + 0, /* write 2 */ + 0, /* write 3 */ + X16CLK | SB1, /* write 4 */ +- 0, /* write 5 */ ++ Tx8 | TxENAB, /* write 5 */ + 0, 0, 0, /* write 6, 7, 8 */ + MIE | DLC | NV, /* write 9 */ + NRZ, /* write 10 */ + TCBR | RCBR, /* write 11 */ +- 0, 0, /* BRG time constant, write 12 + 13 */ ++ 0x16, 0x00, /* BRG time constant, write 12 + 13 */ + BRSRC | BRENABL, /* write 14 */ + 0, /* write 15 */ + }; +@@ -955,23 +961,6 @@ static void zs_set_termios(struct uart_p + spin_unlock_irqrestore(&scc->zlock, flags); + } + +-/* +- * Hack alert! +- * Required solely so that the initial PROM-based console +- * works undisturbed in parallel with this one. +- */ +-static void zs_pm(struct uart_port *uport, unsigned int state, +- unsigned int oldstate) +-{ +- struct zs_port *zport = to_zport(uport); +- +- if (state < 3) +- zport->regs[5] |= TxENAB; +- else +- zport->regs[5] &= ~TxENAB; +- write_zsreg(zport, R5, zport->regs[5]); +-} +- + + static const char *zs_type(struct uart_port *uport) + { +@@ -1054,7 +1043,6 @@ static const struct uart_ops zs_ops = { + .startup = zs_startup, + .shutdown = zs_shutdown, + .set_termios = zs_set_termios, +- .pm = zs_pm, + .type = zs_type, + .release_port = zs_release_port, + .request_port = zs_request_port, +@@ -1209,7 +1197,6 @@ static int __init zs_console_setup(struc + return ret; + + zs_reset(zport); +- zs_pm(uport, 0, -1); + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); diff --git a/queue-5.15/serial-zs-fix-swapped-ri-dsr-modem-line-transition-counting.patch b/queue-5.15/serial-zs-fix-swapped-ri-dsr-modem-line-transition-counting.patch new file mode 100644 index 0000000000..aacc68ee77 --- /dev/null +++ b/queue-5.15/serial-zs-fix-swapped-ri-dsr-modem-line-transition-counting.patch @@ -0,0 +1,36 @@ +From d15cd40cb1858f75846eaafa9a6bca841b790a92 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +Date: Fri, 10 Apr 2026 18:19:31 +0100 +Subject: serial: zs: Fix swapped RI/DSR modem line transition counting + +From: Maciej W. Rozycki + +commit d15cd40cb1858f75846eaafa9a6bca841b790a92 upstream. + +Fix a thinko in the status interrupt handler that has caused counters +for the RI and DSR modem line transitions to be used for the other line +each. + +Fixes: 8b4a40809e53 ("zs: move to the serial subsystem") +Cc: stable +Signed-off-by: Maciej W. Rozycki +Link: https://patch.msgid.link/alpine.DEB.2.21.2604101747110.29980@angie.orcam.me.uk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/zs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/tty/serial/zs.c ++++ b/drivers/tty/serial/zs.c +@@ -679,9 +679,9 @@ static void zs_status_handle(struct zs_p + uart_handle_dcd_change(uport, + zport->mctrl & TIOCM_CAR); + if (delta & TIOCM_RNG) +- uport->icount.dsr++; +- if (delta & TIOCM_DSR) + uport->icount.rng++; ++ if (delta & TIOCM_DSR) ++ uport->icount.dsr++; + + if (delta) + wake_up_interruptible(&uport->state->port.delta_msr_wait); diff --git a/queue-5.15/serial-zs-switch-to-using-channel-reset.patch b/queue-5.15/serial-zs-switch-to-using-channel-reset.patch new file mode 100644 index 0000000000..2971743cc5 --- /dev/null +++ b/queue-5.15/serial-zs-switch-to-using-channel-reset.patch @@ -0,0 +1,89 @@ +From 8572955630f30948837088aa98bcbe0532d1ceac Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +Date: Wed, 6 May 2026 23:42:43 +0100 +Subject: serial: zs: Switch to using channel reset + +From: Maciej W. Rozycki + +commit 8572955630f30948837088aa98bcbe0532d1ceac upstream. + +Switch the driver to using the channel reset rather than hardware reset, +simplifying handling by removing an interference between channels that +causes the other channel to become uninitialised afterwards. + +There is little difference between the two kinds of reset in terms of +register settings that result, and we initialise the whole register set +right away anyway. However this prevents a hang from happening should +the console output handler in the firmware try to access the other port +whose transmitter has been disabled and line parameters messed up. + +For example this will happen if the keyboard port (port A) is chosen for +the system console, unusually but not insanely for a headless system, as +the port is wired to a standard DA-15 connector and an adapter can be +easily made. Or with the next change in place this would happen for the +regular console port (port B), since the keyboard port (port A) will be +initialised first. + +Just remove the unnecessary complication then, a channel reset is good +enough. We still need the initialisation marker, now per channel rather +than per SCC, as for the console port zs_reset() will be called twice: +once early on via zs_serial_console_init() for the console setup only, +and then again via zs_config_port() as the port is associated with a TTY +device. + +Fixes: 8b4a40809e53 ("zs: move to the serial subsystem") +Signed-off-by: Maciej W. Rozycki +Cc: stable@vger.kernel.org # v2.6.23+ +Link: https://patch.msgid.link/alpine.DEB.2.21.2605062323430.46195@angie.orcam.me.uk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/zs.c | 7 ++++--- + drivers/tty/serial/zs.h | 2 +- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/tty/serial/zs.c ++++ b/drivers/tty/serial/zs.c +@@ -831,21 +831,22 @@ static void zs_shutdown(struct uart_port + + static void zs_reset(struct zs_port *zport) + { ++ struct zs_port *zport_a = &zport->scc->zport[ZS_CHAN_A]; + struct zs_scc *scc = zport->scc; + int irq; + unsigned long flags; + + spin_lock_irqsave(&scc->zlock, flags); + irq = !irqs_disabled_flags(flags); +- if (!scc->initialised) { ++ if (!zport->initialised) { + /* Reset the pointer first, just in case... */ + read_zsreg(zport, R0); + /* And let the current transmission finish. */ + zs_line_drain(zport, irq); +- write_zsreg(zport, R9, FHWRES); ++ write_zsreg(zport, R9, zport == zport_a ? CHRA : CHRB); + udelay(10); + write_zsreg(zport, R9, 0); +- scc->initialised = 1; ++ zport->initialised = 1; + } + load_zsregs(zport, zport->regs, irq); + spin_unlock_irqrestore(&scc->zlock, flags); +--- a/drivers/tty/serial/zs.h ++++ b/drivers/tty/serial/zs.h +@@ -22,6 +22,7 @@ + struct zs_port { + struct zs_scc *scc; /* Containing SCC. */ + struct uart_port port; /* Underlying UART. */ ++ int initialised; /* For the console port. */ + + int clk_mode; /* May be 1, 16, 32, or 64. */ + +@@ -41,7 +42,6 @@ struct zs_scc { + struct zs_port zport[2]; + spinlock_t zlock; + atomic_t irq_guard; +- int initialised; + }; + + #endif /* __KERNEL__ */ diff --git a/queue-5.15/series b/queue-5.15/series index da6d6b402b..ba368ebd87 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -100,3 +100,37 @@ netfilter-conntrack-tcp-do-not-force-close-on-invalid-seq-rst-without-direction- asoc-qcom-q6asm-dai-close-stream-only-when-running.patch asoc-qcom-q6asm-dai-do-not-set-stream-state-in-event-and-trigger-callbacks.patch xfrm-esp-restore-combined-single-frag-length-gate.patch +input-atmel_mxt_ts-fix-boundary-check-in-mxt_prepare_cfg_mem.patch +input-synaptics-add-len2058-to-smbus-passlist-for-thinkpad-e490.patch +comedi-comedi_test-fix-check-for-valid-scan_begin_src-in-waveform_ai_cmdtest.patch +comedi-comedi_test-fix-limiting-of-convert_arg-in-waveform_ai_cmdtest.patch +tty-serial-pch_uart-add-check-for-dma_alloc_coherent.patch +usb-chipidea-core-convert-ci_role_switch-to-local-variable.patch +usb-core-fix-up-interrupt-in-endpoints-with-bogus-wbytesperinterval.patch +usb-quirks-add-no_lpm-for-lenovo-thinkpad-usb-c-dock-gen2-hub-controllers.patch +usb-storage-add-quirks-for-pny-elite-portable-ssd.patch +usbip-vudc-fix-use-after-free-bug-in-vudc_remove-due-to-race-condition.patch +usb-usbtmc-check-urb-actual_length-for-interrupt-in-notifications.patch +usb-usbtmc-reject-interrupt-endpoints-with-small-wmaxpacketsize.patch +usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch +usb-serial-option-add-meig-srm813q.patch +usb-serial-option-add-missing-rsvd-5-flag-for-rolling-rw135r-gl.patch +usb-serial-belkin_sa-validate-interrupt-status-length.patch +usb-serial-cypress_m8-validate-interrupt-packet-headers.patch +usb-serial-keyspan-fix-missing-indat-transfer-sanity-check.patch +usb-serial-mxuport-fix-memory-corruption-with-small-endpoint.patch +usb-serial-mct_u232-fix-missing-interrupt-in-transfer-sanity-check.patch +usb-gadget-net2280-fix-double-free-in-probe-error-path.patch +usb-gadget-dummy_hcd-reject-hub-port-requests-for-non-existent-ports.patch +usb-gadget-f_fs-copy-only-received-bytes-on-short-ep0-read.patch +thunderbolt-property-reject-u32-wrap-in-tb_property_entry_valid.patch +thunderbolt-property-reject-dir_len-4-to-prevent-size_t-underflow.patch +scsi-fcoe-reject-fip-descriptors-with-zero-fip_dlen-in-cvl-walker.patch +scsi-scsi_transport_fc-widen-fpin-pname-walker-counter-to-u32.patch +drm-hyperv-validate-vmbus-packet-size-in-receive-callback.patch +serial-sh-sci-fix-memory-region-release-in-error-path.patch +serial-zs-fix-swapped-ri-dsr-modem-line-transition-counting.patch +serial-fsl_lpuart-fix-rx-buffer-and-dma-map-leaks-in-start_rx_dma.patch +serial-dz-fix-bootconsole-message-clobbering-at-chip-reset.patch +serial-zs-fix-bootconsole-handover-lockup.patch +serial-zs-switch-to-using-channel-reset.patch diff --git a/queue-5.15/thunderbolt-property-reject-dir_len-4-to-prevent-size_t-underflow.patch b/queue-5.15/thunderbolt-property-reject-dir_len-4-to-prevent-size_t-underflow.patch new file mode 100644 index 0000000000..7305c1800a --- /dev/null +++ b/queue-5.15/thunderbolt-property-reject-dir_len-4-to-prevent-size_t-underflow.patch @@ -0,0 +1,75 @@ +From de21b59c29e31c5108ddc04210631bbfab81b997 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Sun, 10 May 2026 19:16:57 -0400 +Subject: thunderbolt: property: Reject dir_len < 4 to prevent size_t underflow + +From: Michael Bommarito + +commit de21b59c29e31c5108ddc04210631bbfab81b997 upstream. + +On the non-root path, __tb_property_parse_dir() takes dir_len from +entry->length (u16 widened to size_t). Two distinct OOB conditions +follow when entry->length < 4: + +1. The non-root path begins with kmemdup(&block[dir_offset], + sizeof(*dir->uuid), ...) which always reads 4 dwords from + dir_offset. tb_property_entry_valid() only enforces + dir_offset + entry->length <= block_len, so a crafted entry + with dir_offset close to the end of the property block and + entry->length in 0..3 passes that gate but lets the UUID copy + run off the block (e.g. dir_offset = 497, dir_len = 3 in a + 500-dword block reads block[497..501]). + +2. After the kmemdup, content_len = dir_len - 4 underflows size_t + to ~SIZE_MAX, nentries becomes SIZE_MAX / 4, and the entry + walk runs OOB on each iteration until an entry fails + validation or the kernel oopses on an unmapped page. + +Reject dir_len < 4 on the non-root path *before* the UUID kmemdup, +which closes both holes. + +Also move INIT_LIST_HEAD(&dir->properties) up to immediately after +the dir allocation so the new error-return path (and the existing +uuid-alloc failure path) calling tb_property_free_dir() sees a +walkable list rather than the zero-initialized NULL next/prev that +list_for_each_entry_safe() would oops on. + +Fixes: cdae7c07e3e3 ("thunderbolt: Add support for XDomain properties") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-6 +Assisted-by: Codex:gpt-5-4 +Signed-off-by: Michael Bommarito +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/property.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/thunderbolt/property.c ++++ b/drivers/thunderbolt/property.c +@@ -174,10 +174,16 @@ static struct tb_property_dir *__tb_prop + if (!dir) + return NULL; + ++ INIT_LIST_HEAD(&dir->properties); ++ + if (is_root) { + content_offset = dir_offset + 2; + content_len = dir_len; + } else { ++ if (dir_len < 4) { ++ tb_property_free_dir(dir); ++ return NULL; ++ } + dir->uuid = kmemdup(&block[dir_offset], sizeof(*dir->uuid), + GFP_KERNEL); + if (!dir->uuid) { +@@ -191,8 +197,6 @@ static struct tb_property_dir *__tb_prop + entries = (const struct tb_property_entry *)&block[content_offset]; + nentries = content_len / (sizeof(*entries) / 4); + +- INIT_LIST_HEAD(&dir->properties); +- + for (i = 0; i < nentries; i++) { + struct tb_property *property; + diff --git a/queue-5.15/thunderbolt-property-reject-u32-wrap-in-tb_property_entry_valid.patch b/queue-5.15/thunderbolt-property-reject-u32-wrap-in-tb_property_entry_valid.patch new file mode 100644 index 0000000000..d6089b7624 --- /dev/null +++ b/queue-5.15/thunderbolt-property-reject-u32-wrap-in-tb_property_entry_valid.patch @@ -0,0 +1,65 @@ +From 01deda0152066c6c955f0619114ea6afa070aaec Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Sun, 10 May 2026 19:16:56 -0400 +Subject: thunderbolt: property: Reject u32 wrap in tb_property_entry_valid() + +From: Michael Bommarito + +commit 01deda0152066c6c955f0619114ea6afa070aaec upstream. + +entry->value is u32 and entry->length is u16; the sum is performed in +u32 and wraps. A malicious XDomain peer can pick +value = 0xffffff00, length = 0x100 so the sum 0x100000000 wraps to 0 +and passes the > block_len check. tb_property_parse() then passes +entry->value to parse_dwdata() as a dword offset into the property +block, reading attacker-directed memory far past the allocation. + +For TEXT-typed entries with the "deviceid" or "vendorid" keys this +lands in xd->device_name / xd->vendor_name and is readable back via +the per-XDomain device_name / vendor_name sysfs attributes; the leak +is NUL-bounded (kstrdup() stops at the first zero byte) and +untargeted (the attacker picks a delta, not an absolute address). +DATA-typed entries are parsed into property->value.data but not +generically surfaced to userspace. + +Use check_add_overflow() so a wrapped sum is rejected. + +Fixes: cdae7c07e3e3 ("thunderbolt: Add support for XDomain properties") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-6 +Assisted-by: Codex:gpt-5-4 +Signed-off-by: Michael Bommarito +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/property.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/thunderbolt/property.c ++++ b/drivers/thunderbolt/property.c +@@ -8,6 +8,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -52,13 +53,16 @@ static inline void format_dwdata(void *d + static bool tb_property_entry_valid(const struct tb_property_entry *entry, + size_t block_len) + { ++ u32 end; ++ + switch (entry->type) { + case TB_PROPERTY_TYPE_DIRECTORY: + case TB_PROPERTY_TYPE_DATA: + case TB_PROPERTY_TYPE_TEXT: + if (entry->length > block_len) + return false; +- if (entry->value + entry->length > block_len) ++ if (check_add_overflow(entry->value, entry->length, &end) || ++ end > block_len) + return false; + break; + diff --git a/queue-5.15/tty-serial-pch_uart-add-check-for-dma_alloc_coherent.patch b/queue-5.15/tty-serial-pch_uart-add-check-for-dma_alloc_coherent.patch new file mode 100644 index 0000000000..1c7287daa4 --- /dev/null +++ b/queue-5.15/tty-serial-pch_uart-add-check-for-dma_alloc_coherent.patch @@ -0,0 +1,68 @@ +From 6fe472c1bbbe238e91141f7cabc1226e96a60d43 Mon Sep 17 00:00:00 2001 +From: Zhaoyang Yu <2426767509@qq.com> +Date: Thu, 9 Apr 2026 13:41:58 +0800 +Subject: tty: serial: pch_uart: add check for dma_alloc_coherent() + +From: Zhaoyang Yu <2426767509@qq.com> + +commit 6fe472c1bbbe238e91141f7cabc1226e96a60d43 upstream. + +Add a check for dma_alloc_coherent() failure to prevent a potential +NULL pointer dereference in dma_handle_rx(). Properly release DMA +channels and the PCI device reference using a goto ladder if the +allocation fails. + +Fixes: 3c6a483275f4 ("Serial: EG20T: add PCH_UART driver") +Cc: stable +Signed-off-by: Zhaoyang Yu <2426767509@qq.com> +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/tencent_E328416B7CFD436F6029F2DF02AD7ED89C08@qq.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/pch_uart.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +--- a/drivers/tty/serial/pch_uart.c ++++ b/drivers/tty/serial/pch_uart.c +@@ -707,8 +707,7 @@ static void pch_request_dma(struct uart_ + if (!chan) { + dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Tx)\n", + __func__); +- pci_dev_put(dma_dev); +- return; ++ goto err_pci_get; + } + priv->chan_tx = chan; + +@@ -722,18 +721,26 @@ static void pch_request_dma(struct uart_ + if (!chan) { + dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Rx)\n", + __func__); +- dma_release_channel(priv->chan_tx); +- priv->chan_tx = NULL; +- pci_dev_put(dma_dev); +- return; ++ goto err_req_tx; + } + + /* Get Consistent memory for DMA */ + priv->rx_buf_virt = dma_alloc_coherent(port->dev, port->fifosize, + &priv->rx_buf_dma, GFP_KERNEL); ++ if (!priv->rx_buf_virt) ++ goto err_req_rx; + priv->chan_rx = chan; + + pci_dev_put(dma_dev); ++ return; ++ ++err_req_rx: ++ dma_release_channel(chan); ++err_req_tx: ++ dma_release_channel(priv->chan_tx); ++ priv->chan_tx = NULL; ++err_pci_get: ++ pci_dev_put(dma_dev); + } + + static void pch_dma_rx_complete(void *arg) diff --git a/queue-5.15/usb-chipidea-core-convert-ci_role_switch-to-local-variable.patch b/queue-5.15/usb-chipidea-core-convert-ci_role_switch-to-local-variable.patch new file mode 100644 index 0000000000..283761f9e6 --- /dev/null +++ b/queue-5.15/usb-chipidea-core-convert-ci_role_switch-to-local-variable.patch @@ -0,0 +1,77 @@ +From 8f6aa392653e52a45858cff5c063df550028836b Mon Sep 17 00:00:00 2001 +From: Xu Yang +Date: Mon, 27 Apr 2026 15:57:55 +0800 +Subject: usb: chipidea: core: convert ci_role_switch to local variable + +From: Xu Yang + +commit 8f6aa392653e52a45858cff5c063df550028836b upstream. + +When a system contains multiple USB controllers, the global ci_role_switch +variable may be overwritten by subsequent driver initialization code. + +This can cause issues in the following cases: + - The 2nd ci_hdrc_probe() sees ci_role_switch.fwnode as non-NULL even + though the "usb-role-switch" property is not present for the controller. + - When the ci_hdrc device is unbound and bound again, ci_role_switch + fwnode will not be reassigned, and the old value will be used instead. + +Convert ci_role_switch to a local variable to fix these issues. + +Fixes: 05559f10ed79 ("usb: chipidea: add role switch class support") +Cc: stable +Acked-by: Peter Chen +Reviewed-by: Frank Li +Signed-off-by: Xu Yang +Link: https://patch.msgid.link/20260427075755.3611217-1-xu.yang_2@nxp.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/chipidea/core.c | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +--- a/drivers/usb/chipidea/core.c ++++ b/drivers/usb/chipidea/core.c +@@ -659,12 +659,6 @@ static int ci_usb_role_switch_set(struct + return 0; + } + +-static struct usb_role_switch_desc ci_role_switch = { +- .set = ci_usb_role_switch_set, +- .get = ci_usb_role_switch_get, +- .allow_userspace_control = true, +-}; +- + static int ci_get_platdata(struct device *dev, + struct ci_hdrc_platform_data *platdata) + { +@@ -791,9 +785,6 @@ static int ci_get_platdata(struct device + cable->connected = false; + } + +- if (device_property_read_bool(dev, "usb-role-switch")) +- ci_role_switch.fwnode = dev->fwnode; +- + platdata->pctl = devm_pinctrl_get(dev); + if (!IS_ERR(platdata->pctl)) { + struct pinctrl_state *p; +@@ -1013,6 +1004,7 @@ ATTRIBUTE_GROUPS(ci); + + static int ci_hdrc_probe(struct platform_device *pdev) + { ++ struct usb_role_switch_desc ci_role_switch = {}; + struct device *dev = &pdev->dev; + struct ci_hdrc *ci; + struct resource *res; +@@ -1154,7 +1146,11 @@ static int ci_hdrc_probe(struct platform + } + } + +- if (ci_role_switch.fwnode) { ++ if (device_property_read_bool(dev, "usb-role-switch")) { ++ ci_role_switch.set = ci_usb_role_switch_set; ++ ci_role_switch.get = ci_usb_role_switch_get; ++ ci_role_switch.allow_userspace_control = true; ++ ci_role_switch.fwnode = dev_fwnode(dev); + ci_role_switch.driver_data = ci; + ci->role_switch = usb_role_switch_register(dev, + &ci_role_switch); diff --git a/queue-5.15/usb-core-fix-up-interrupt-in-endpoints-with-bogus-wbytesperinterval.patch b/queue-5.15/usb-core-fix-up-interrupt-in-endpoints-with-bogus-wbytesperinterval.patch new file mode 100644 index 0000000000..ff639ef643 --- /dev/null +++ b/queue-5.15/usb-core-fix-up-interrupt-in-endpoints-with-bogus-wbytesperinterval.patch @@ -0,0 +1,65 @@ +From 727d045d064b7c9a24db3bce9c0485a382cb768b Mon Sep 17 00:00:00 2001 +From: Michal Pecio +Date: Mon, 18 May 2026 07:32:07 +0200 +Subject: usb: core: Fix up Interrupt IN endpoints with bogus wBytesPerInterval + +From: Michal Pecio + +commit 727d045d064b7c9a24db3bce9c0485a382cb768b upstream. + +Tao Xue found that some common devices violate USB 3.x section 9.6.7 +by reporting wBytesPerInterval lower than the size of packets they +actually send. I confirmed that AX88179 may set it to 0 and RTL8153 +CDC configuration sets it to 8 but sends both 8 and 16 byte packets: + +S Ii:11:007:3 -115:128 16 < +C Ii:11:007:3 0:128 8 = a1000000 01000000 +S Ii:11:007:3 -115:128 16 < +C Ii:11:007:3 0:128 16 = a12a0000 01000800 00000000 00000000 + +Most xHCI host controllers neglect interrupt bandwidth reservations +and let such devices exceed theirs, some fail the URB with EOVERFLOW. + +Assume that wBytesPerInterval lower than wMaxPacketSize is bogus and +increase it to the worst case maximum on interrupt IN endpoints. This +solves xHCI problems and appears to have no other effect. Interrupt +transfers are not limited to one interval and drivers submit URBs of +class defined size without looking at wBytesPerInterval. Any multi- +interval transfer is considered terminated by a packet shorter than +wMaxPacketSize regardless of wBytesPerInterval - see USB3 8.10.3. + +Stay in spec on OUT endpoints and isochronous. No buggy devices are +known and we don't want to risk sending more data than the device +is prepared to handle or confusing isoc drivers regarding altsetting +capacities guaranteed by the device itself. And don't complain when +wMaxPacketSize <= wBytesPerInterval < wMaxPacketSize * (bMaxBurst+1) +because enabling this seems to be the exact goal of the spec. + +Reported-and-tested-by: Tao Xue +Closes: https://lore.kernel.org/linux-usb/20260402021400.28853-1-xuetao09@huawei.com/ +Cc: stable@vger.kernel.org +Signed-off-by: Michal Pecio +Link: https://patch.msgid.link/20260518073207.5b7d26e7.michal.pecio@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/config.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -165,7 +165,14 @@ static void usb_parse_ss_endpoint_compan + (desc->bMaxBurst + 1); + else + max_tx = 999999; +- if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { ++ /* ++ * wBytesPerInterval > max_tx is bogus, but USB3 spec doesn't forbid the opposite. ++ * Experience shows that wBytesPerInterval < wMaxPacketSize on common interrupt IN ++ * endpoints is usually bogus too, and recent HCs enforce interrupt BW limits. ++ */ ++ if (le16_to_cpu(desc->wBytesPerInterval) > max_tx || ++ (le16_to_cpu(desc->wBytesPerInterval) < usb_endpoint_maxp(&ep->desc) && ++ usb_endpoint_is_int_in(&ep->desc))) { + dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in " + "config %d interface %d altsetting %d ep %d: " + "setting to %d\n", diff --git a/queue-5.15/usb-gadget-dummy_hcd-reject-hub-port-requests-for-non-existent-ports.patch b/queue-5.15/usb-gadget-dummy_hcd-reject-hub-port-requests-for-non-existent-ports.patch new file mode 100644 index 0000000000..8fb0aca04a --- /dev/null +++ b/queue-5.15/usb-gadget-dummy_hcd-reject-hub-port-requests-for-non-existent-ports.patch @@ -0,0 +1,50 @@ +From 7d9633528dd40e33964d2dc74a5abbf5c4d116ce Mon Sep 17 00:00:00 2001 +From: Seungjin Bae +Date: Mon, 18 May 2026 19:43:14 -0400 +Subject: usb: gadget: dummy_hcd: Reject hub port requests for non-existent ports + +From: Seungjin Bae + +commit 7d9633528dd40e33964d2dc74a5abbf5c4d116ce upstream. + +The `dummy_hub_control()` function handles USB hub class requests +to the virtual root hub. The `GetPortStatus` case returns -EPIPE for +requests with `wIndex != 1`, since the virtual root hub has only a +single port. However, the `ClearPortFeature` and `SetPortFeature` +cases lack the same check. + +Fix this by extending the `wIndex != 1` rejection to both cases, +matching the existing behavior of `GetPortStatus`. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable +Suggested-by: Alan Stern +Signed-off-by: Seungjin Bae +Reviewed-by: Alan Stern +Link: https://patch.msgid.link/20260518234314.1889396-1-eeodqql09@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/dummy_hcd.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -2122,6 +2122,8 @@ static int dummy_hub_control( + case ClearHubFeature: + break; + case ClearPortFeature: ++ if (wIndex != 1) ++ goto error; + switch (wValue) { + case USB_PORT_FEAT_SUSPEND: + if (hcd->speed == HCD_USB3) { +@@ -2236,6 +2238,8 @@ static int dummy_hub_control( + retval = -EPIPE; + break; + case SetPortFeature: ++ if (wIndex != 1) ++ goto error; + switch (wValue) { + case USB_PORT_FEAT_LINK_STATE: + if (hcd->speed != HCD_USB3) { diff --git a/queue-5.15/usb-gadget-f_fs-copy-only-received-bytes-on-short-ep0-read.patch b/queue-5.15/usb-gadget-f_fs-copy-only-received-bytes-on-short-ep0-read.patch new file mode 100644 index 0000000000..c1c7105d3b --- /dev/null +++ b/queue-5.15/usb-gadget-f_fs-copy-only-received-bytes-on-short-ep0-read.patch @@ -0,0 +1,79 @@ +From 4e036c10e7f4df5d951c69cc3697bc8e209c6d02 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Sun, 19 Apr 2026 12:03:59 -0400 +Subject: usb: gadget: f_fs: copy only received bytes on short ep0 read + +From: Michael Bommarito + +commit 4e036c10e7f4df5d951c69cc3697bc8e209c6d02 upstream. + +ffs_ep0_read() allocates its control-OUT data buffer with +kmalloc() (not kzalloc) at the Length value from the Setup +packet, then copies that full len to userspace regardless of +how many bytes were actually received: + + data = kmalloc(len, GFP_KERNEL); + ... + ret = __ffs_ep0_queue_wait(ffs, data, len); + if ((ret > 0) && (copy_to_user(buf, data, len))) + ret = -EFAULT; + +__ffs_ep0_queue_wait() returns req->actual, which on a short +control OUT transfer is strictly less than len. The +copy_to_user() call still copies len bytes, so on a short OUT +the last (len - ret) bytes of the kmalloc() buffer -- +uninitialised slab residue -- are delivered to the FunctionFS +daemon. + +Short ep0 OUT completions are specified USB control-transfer +behavior and are produced by in-tree UDCs: + + * dwc2 continues on req->actual < req->length for ep0 DATA OUT + (short-not-ok is the only ep0-OUT stall path). + * aspeed_udc ends ep0 OUT on rx_len < ep->ep.maxpacket. + * renesas_usbf logs "ep0 short packet" and completes the + request. + * dwc3 stalls on short IN but not on short OUT. + +A short ep0 OUT is therefore not evidence of a broken UDC; it is +a normal condition f_fs has to cope with. The sibling gadgetfs +implementation in drivers/usb/gadget/legacy/inode.c already does +this correctly via min(len, dev->req->actual) before +copy_to_user(). This patch brings f_fs.c to the same safe +pattern rather than trimming at a defensive layer. + +The bug is reached from the FunctionFS device node, which in +real deployments is owned by the privileged gadget daemon +(adbd, UMS, composite gadget services, etc.); it is not +reachable from unprivileged userspace. Linux host stacks +normally reject short-wLength control OUTs before they reach +the gadget, so reproducing this required a build that +bypasses that host-side check. With the bypass in place, a +1-byte payload on a 64-byte Setup produces 63 bytes of +non-canary slab residue in the daemon's read buffer. + +Fix by copying only ret (actually received) bytes to +userspace. + +Fixes: ddf8abd25994 ("USB: f_fs: the FunctionFS driver") +Cc: stable +Assisted-by: Claude:claude-opus-4-7 +Signed-off-by: Michael Bommarito +Link: https://patch.msgid.link/20260419160359.1577270-1-michael.bommarito@gmail.com +Signed-off-by: Greg Kroah-Hartman +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 +@@ -592,7 +592,7 @@ static ssize_t ffs_ep0_read(struct file + + /* unlocks spinlock */ + ret = __ffs_ep0_queue_wait(ffs, data, len); +- if ((ret > 0) && (copy_to_user(buf, data, len))) ++ if ((ret > 0) && (copy_to_user(buf, data, ret))) + ret = -EFAULT; + goto done_mutex; + diff --git a/queue-5.15/usb-gadget-net2280-fix-double-free-in-probe-error-path.patch b/queue-5.15/usb-gadget-net2280-fix-double-free-in-probe-error-path.patch new file mode 100644 index 0000000000..9fdb32e136 --- /dev/null +++ b/queue-5.15/usb-gadget-net2280-fix-double-free-in-probe-error-path.patch @@ -0,0 +1,48 @@ +From c8547c74988e0b5f4cbb1b895e2a57aae084f070 Mon Sep 17 00:00:00 2001 +From: Guangshuo Li +Date: Mon, 27 Apr 2026 23:36:51 +0800 +Subject: usb: gadget: net2280: Fix double free in probe error path + +From: Guangshuo Li + +commit c8547c74988e0b5f4cbb1b895e2a57aae084f070 upstream. + +usb_initialize_gadget() installs gadget_release() as the release +callback for the embedded gadget device. The struct net2280 instance is +therefore released through gadget_release() when the gadget device's last +reference is dropped. + +The probe error path calls net2280_remove(), which tears down the +partially initialized device and drops the gadget reference with +usb_put_gadget(). Calling kfree(dev) afterwards can free the same object +again. + +Drop the explicit kfree() and let the gadget device release callback +handle the final free. This issue was found by a static analysis tool +I am developing. + +Fixes: f770fbec4165 ("USB: UDC: net2280: Fix memory leaks") +Cc: stable +Signed-off-by: Guangshuo Li +Reviewed-by: Alan Stern +Link: https://patch.msgid.link/20260427153651.337846-1-lgs201920130244@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/net2280.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/usb/gadget/udc/net2280.c ++++ b/drivers/usb/gadget/udc/net2280.c +@@ -3796,10 +3796,8 @@ static int net2280_probe(struct pci_dev + return 0; + + done: +- if (dev) { ++ if (dev) + net2280_remove(pdev); +- kfree(dev); +- } + return retval; + } + diff --git a/queue-5.15/usb-quirks-add-no_lpm-for-lenovo-thinkpad-usb-c-dock-gen2-hub-controllers.patch b/queue-5.15/usb-quirks-add-no_lpm-for-lenovo-thinkpad-usb-c-dock-gen2-hub-controllers.patch new file mode 100644 index 0000000000..80625a38a5 --- /dev/null +++ b/queue-5.15/usb-quirks-add-no_lpm-for-lenovo-thinkpad-usb-c-dock-gen2-hub-controllers.patch @@ -0,0 +1,40 @@ +From 9ddb9c0deca48d2c2a22ebf4d2f35c925a520328 Mon Sep 17 00:00:00 2001 +From: "Stephen J. Fuhry" +Date: Wed, 13 May 2026 13:14:19 -0400 +Subject: USB: quirks: add NO_LPM for Lenovo ThinkPad USB-C Dock Gen2 hub controllers + +From: Stephen J. Fuhry + +commit 9ddb9c0deca48d2c2a22ebf4d2f35c925a520328 upstream. + +The Lenovo ThinkPad USB-C Dock Gen2 (17ef:a391, 17ef:a392) hub +controllers exhibit link instability when USB Link Power Management +is enabled, similar to the dock's Ethernet adapter (17ef:a387) which +already carries USB_QUIRK_NO_LPM. + +When the dock reconnects after a transient disconnect, the hub +controllers enter LPM states between re-enumeration retries, causing +repeated disconnect/reconnect cycles lasting up to two minutes. +Disabling LPM for these devices restores stable enumeration. + +Signed-off-by: Stephen J. Fuhry +Cc: stable +Link: https://patch.msgid.link/20260513171419.44849-1-fuhrysteve@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/quirks.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -497,6 +497,10 @@ static const struct usb_device_id usb_qu + /* Lenovo ThinkPad USB-C Dock Gen2 Ethernet (RTL8153 GigE) */ + { USB_DEVICE(0x17ef, 0xa387), .driver_info = USB_QUIRK_NO_LPM }, + ++ /* Lenovo ThinkPad USB-C Dock Gen2 USB 3.1 and USB 2.0 hub controllers */ ++ { USB_DEVICE(0x17ef, 0xa391), .driver_info = USB_QUIRK_NO_LPM }, ++ { USB_DEVICE(0x17ef, 0xa392), .driver_info = USB_QUIRK_NO_LPM }, ++ + /* BUILDWIN Photo Frame */ + { USB_DEVICE(0x1908, 0x1315), .driver_info = + USB_QUIRK_HONOR_BNUMINTERFACES }, diff --git a/queue-5.15/usb-serial-belkin_sa-validate-interrupt-status-length.patch b/queue-5.15/usb-serial-belkin_sa-validate-interrupt-status-length.patch new file mode 100644 index 0000000000..f25e550eb5 --- /dev/null +++ b/queue-5.15/usb-serial-belkin_sa-validate-interrupt-status-length.patch @@ -0,0 +1,50 @@ +From 4ce058df2ee02cc2a0f0fd5cd64ce6f1482a0b65 Mon Sep 17 00:00:00 2001 +From: Zhang Cen +Date: Tue, 19 May 2026 19:11:50 +0800 +Subject: USB: serial: belkin_sa: validate interrupt status length + +From: Zhang Cen + +commit 4ce058df2ee02cc2a0f0fd5cd64ce6f1482a0b65 upstream. + +The Belkin interrupt callback treats interrupt data as a four-byte +status report and reads LSR/MSR fields at offsets 2 and 3. The +interrupt-in buffer length is derived from endpoint wMaxPacketSize, and +short interrupt transfers may complete successfully with a smaller +actual_length. + +Check the completed interrupt packet length before parsing status +fields so short interrupt endpoints and short successful packets are +ignored instead of causing out-of-bounds or stale status-byte reads. + +KASAN report as below: + +BUG: KASAN: slab-out-of-bounds in belkin_sa_read_int_callback() +Read of size 1 +Call trace: + belkin_sa_read_int_callback() (drivers/usb/serial/belkin_sa.c:202) + __usb_hcd_giveback_urb() (drivers/usb/core/hcd.c:1630) + dummy_timer() (?:?) + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Assisted-by: Codex:gpt-5.5 +Signed-off-by: Zhang Cen +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/belkin_sa.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/serial/belkin_sa.c ++++ b/drivers/usb/serial/belkin_sa.c +@@ -194,6 +194,9 @@ static void belkin_sa_read_int_callback( + + usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); + ++ if (urb->actual_length < BELKIN_SA_MSR_INDEX + 1) ++ goto exit; ++ + /* Handle known interrupt data */ + /* ignore data[0] and data[1] */ + diff --git a/queue-5.15/usb-serial-cypress_m8-validate-interrupt-packet-headers.patch b/queue-5.15/usb-serial-cypress_m8-validate-interrupt-packet-headers.patch new file mode 100644 index 0000000000..9d86f527f0 --- /dev/null +++ b/queue-5.15/usb-serial-cypress_m8-validate-interrupt-packet-headers.patch @@ -0,0 +1,86 @@ +From 9f9bfc80c67f35a275820da7e83a35dface08281 Mon Sep 17 00:00:00 2001 +From: Zhang Cen +Date: Fri, 22 May 2026 22:54:42 +0800 +Subject: USB: serial: cypress_m8: validate interrupt packet headers + +From: Zhang Cen + +commit 9f9bfc80c67f35a275820da7e83a35dface08281 upstream. + +cypress_read_int_callback() parses the interrupt-in buffer according to +the selected Cypress packet format. Format 1 has a two-byte status/count +header and format 2 has a one-byte combined status/count header. The +usb-serial core sizes the interrupt-in buffer from the endpoint +descriptor's wMaxPacketSize, and successful interrupt transfers can +complete short when URB_SHORT_NOT_OK is not set. + +Check that the completed packet contains the selected header before +reading it. Malformed short reports are ignored and the interrupt URB is +resubmitted through the existing retry path, preventing out-of-bounds +header-byte reads. + +KASAN report as below: +KASAN slab-out-of-bounds in cypress_read_int_callback+0x240/0x7f0 +Read of size 1 +Call trace: + cypress_read_int_callback() (drivers/usb/serial/cypress_m8.c:1009) + __usb_hcd_giveback_urb() + dummy_timer() + +Fixes: 3416eaa1f8f8 ("USB: cypress_m8: Packet format is separate from characteristic size") +Assisted-by: Codex:gpt-5.5 +Signed-off-by: Zhang Cen +Fixes: 3416eaa1f8f8 ("USB: cypress_m8: Packet format is separate from characteristic size") +Cc: stable@vger.kernel.org # 2.6.26 +[ johan: use constants in header length sanity checks ] +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/cypress_m8.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/cypress_m8.c ++++ b/drivers/usb/serial/cypress_m8.c +@@ -1018,8 +1018,8 @@ static void cypress_read_int_callback(st + char tty_flag = TTY_NORMAL; + int bytes = 0; + int result; +- int i = 0; + int status = urb->status; ++ int i; + + switch (status) { + case 0: /* success */ +@@ -1057,22 +1057,32 @@ static void cypress_read_int_callback(st + + spin_lock_irqsave(&priv->lock, flags); + result = urb->actual_length; ++ i = 0; + switch (priv->pkt_fmt) { + default: + case packet_format_1: + /* This is for the CY7C64013... */ ++ if (result < 2) ++ break; + priv->current_status = data[0] & 0xF8; + bytes = data[1] + 2; + i = 2; + break; + case packet_format_2: + /* This is for the CY7C63743... */ ++ if (result < 1) ++ break; + priv->current_status = data[0] & 0xF8; + bytes = (data[0] & 0x07) + 1; + i = 1; + break; + } + spin_unlock_irqrestore(&priv->lock, flags); ++ if (i == 0) { ++ dev_dbg(dev, "%s - short packet received: %d bytes\n", ++ __func__, result); ++ goto continue_read; ++ } + if (result < bytes) { + dev_dbg(dev, + "%s - wrong packet size - received %d bytes but packet said %d bytes\n", diff --git a/queue-5.15/usb-serial-keyspan-fix-missing-indat-transfer-sanity-check.patch b/queue-5.15/usb-serial-keyspan-fix-missing-indat-transfer-sanity-check.patch new file mode 100644 index 0000000000..67fef83b03 --- /dev/null +++ b/queue-5.15/usb-serial-keyspan-fix-missing-indat-transfer-sanity-check.patch @@ -0,0 +1,34 @@ +From ab8336a7e414f018430aa1af3a46944032f7ff96 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 20 May 2026 16:26:48 +0200 +Subject: USB: serial: keyspan: fix missing indat transfer sanity check + +From: Johan Hovold + +commit ab8336a7e414f018430aa1af3a46944032f7ff96 upstream. + +Add the missing sanity check on the size of usa49wg indat transfers to +avoid parsing stale or uninitialised slab data. + +Fixes: 0ca1268e109a ("USB Serial Keyspan: add support for USA-49WG & USA-28XG") +Cc: stable@vger.kernel.org # 2.6.23 +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/keyspan.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/serial/keyspan.c ++++ b/drivers/usb/serial/keyspan.c +@@ -1184,6 +1184,10 @@ static void usa49wg_indat_callback(struc + len = 0; + + while (i < urb->actual_length) { ++ if (urb->actual_length - i < 3) { ++ dev_warn_ratelimited(&urb->dev->dev, "malformed indat packet\n"); ++ break; ++ } + + /* Check port number from message */ + if (data[i] >= serial->num_ports) { diff --git a/queue-5.15/usb-serial-mct_u232-fix-missing-interrupt-in-transfer-sanity-check.patch b/queue-5.15/usb-serial-mct_u232-fix-missing-interrupt-in-transfer-sanity-check.patch new file mode 100644 index 0000000000..6e490894f2 --- /dev/null +++ b/queue-5.15/usb-serial-mct_u232-fix-missing-interrupt-in-transfer-sanity-check.patch @@ -0,0 +1,36 @@ +From 245aba83e3c288e176ed037a1f6b618b09e92ed8 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 20 May 2026 16:27:10 +0200 +Subject: USB: serial: mct_u232: fix missing interrupt-in transfer sanity check + +From: Johan Hovold + +commit 245aba83e3c288e176ed037a1f6b618b09e92ed8 upstream. + +Add the missing sanity check on the size of interrupt-in transfers to +avoid parsing stale or uninitialised slab data (and leaking it to user +space). + +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/mct_u232.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/usb/serial/mct_u232.c ++++ b/drivers/usb/serial/mct_u232.c +@@ -543,6 +543,11 @@ static void mct_u232_read_int_callback(s + goto exit; + } + ++ if (urb->actual_length < 2) { ++ dev_warn_ratelimited(&port->dev, "short interrupt-in packet\n"); ++ goto exit; ++ } ++ + /* + * The interrupt-in pipe signals exceptional conditions (modem line + * signal changes and errors). data[0] holds MSR, data[1] holds LSR. diff --git a/queue-5.15/usb-serial-mxuport-fix-memory-corruption-with-small-endpoint.patch b/queue-5.15/usb-serial-mxuport-fix-memory-corruption-with-small-endpoint.patch new file mode 100644 index 0000000000..556573c7ca --- /dev/null +++ b/queue-5.15/usb-serial-mxuport-fix-memory-corruption-with-small-endpoint.patch @@ -0,0 +1,40 @@ +From 4085f0dbb1ce2251c9a5938d693de6593f0ab2bd Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 22 May 2026 16:19:50 +0200 +Subject: USB: serial: mxuport: fix memory corruption with small endpoint + +From: Johan Hovold + +commit 4085f0dbb1ce2251c9a5938d693de6593f0ab2bd upstream. + +Make sure that the bulk-out endpoint max packet size is at least eight +bytes to avoid user-controlled slab corruption should a malicious device +report a smaller size. + +Fixes: ee467a1f2066 ("USB: serial: add Moxa UPORT 12XX/14XX/16XX driver") +Cc: stable@vger.kernel.org # 3.14 +Cc: Andrew Lunn +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/mxuport.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/usb/serial/mxuport.c ++++ b/drivers/usb/serial/mxuport.c +@@ -962,6 +962,14 @@ static int mxuport_calc_num_ports(struct + */ + BUILD_BUG_ON(ARRAY_SIZE(epds->bulk_out) < 16); + ++ /* ++ * The bulk-out buffers must be large enough for the four-byte header ++ * (and following data), but assume anything smaller than eight bytes ++ * is broken. ++ */ ++ if (usb_endpoint_maxp(epds->bulk_out[0]) < 8) ++ return -EINVAL; ++ + for (i = 1; i < num_ports; ++i) + epds->bulk_out[i] = epds->bulk_out[0]; + diff --git a/queue-5.15/usb-serial-option-add-meig-srm813q.patch b/queue-5.15/usb-serial-option-add-meig-srm813q.patch new file mode 100644 index 0000000000..cefd008b55 --- /dev/null +++ b/queue-5.15/usb-serial-option-add-meig-srm813q.patch @@ -0,0 +1,94 @@ +From 7d2b37d3e42d19071b62f4ddbee6e16e905efbf1 Mon Sep 17 00:00:00 2001 +From: Jan Volckaert +Date: Sun, 17 May 2026 17:32:37 +0200 +Subject: USB: serial: option: add MeiG SRM813Q + +From: Jan Volckaert + +commit 7d2b37d3e42d19071b62f4ddbee6e16e905efbf1 upstream. + +Add support for the Qualcomm Technology Snapdragon X35-based MeiG +SRM813Q module. + +The module can be put in different modes via AT commands to +enable/disable GPS functionality: + +MODEM - PPP mode(2dee:4d63): AT+SER=1,1 + +If#= 0: RMNET +If#= 1: DIAG/ADB +If#= 2: MODEM +If#= 3: AT + +P: Vendor=2dee ProdID=4d63 Rev=05.15 +S: Manufacturer=MEIG +S: Product=LTE-A Module +S: SerialNumber=1bd51f0e +C: #Ifs= 4 Cfg#= 1 Atr=80 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan +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= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +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=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=85(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=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms + +NMEA mode(2dee:4d64): AT+SER=51,1 + +If#= 0: RMNET +If#= 1: DIAG/ADB +If#= 2: NMEA +If#= 3: AT + +P: Vendor=2dee ProdID=4d64 Rev=05.15 +S: Manufacturer=MEIG +S: Product=LTE-A Module +S: SerialNumber=1bd51f0e +C: #Ifs= 4 Cfg#= 1 Atr=80 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan +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= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=83(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=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=85(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=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms + +Signed-off-by: Jan Volckaert +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -2450,6 +2450,12 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d38, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM825WN (Diag) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d38, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825WN (AT) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d38, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825WN (NMEA) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d63, 0xff, 0xff, 0x30) }, /* MeiG SRM813Q (Diag) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d63, 0xff, 0xff, 0x40) }, /* MeiG SRM813Q (AT) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d64, 0xff, 0xff, 0x30) }, /* MeiG SRM813Q (Diag) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d64, 0xff, 0xff, 0x40) }, /* MeiG SRM813Q (AT) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d64, 0xff, 0xff, 0x60) }, /* MeiG SRM813Q (NMEA) */ ++ + { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ diff --git a/queue-5.15/usb-serial-option-add-missing-rsvd-5-flag-for-rolling-rw135r-gl.patch b/queue-5.15/usb-serial-option-add-missing-rsvd-5-flag-for-rolling-rw135r-gl.patch new file mode 100644 index 0000000000..4da87dade0 --- /dev/null +++ b/queue-5.15/usb-serial-option-add-missing-rsvd-5-flag-for-rolling-rw135r-gl.patch @@ -0,0 +1,132 @@ +From 689f2facc689c8add11d7ff69fbbad17d65ee596 Mon Sep 17 00:00:00 2001 +From: Wanquan Zhong +Date: Wed, 20 May 2026 19:32:45 +0800 +Subject: USB: serial: option: add missing RSVD(5) flag for Rolling RW135R-GL + +From: Wanquan Zhong + +commit 689f2facc689c8add11d7ff69fbbad17d65ee596 upstream. + +The RW135R-GL entry added in commit 01e8d0f74222 ("USB: serial: option: +add support for Rolling Wireless RW135R-GL") was missing the +.driver_info = RSVD(5) flag used by other Rolling Wireless MBIM laptop +modules (e.g. RW135-GL and RW350-GL). + +Without this flag, the option driver incorrectly binds to the reserved +ADB interface (If#5) in multi-interface USB modes, causing AT/MBIM +communication failures after mode switching. This matches the handling +of other Rolling Wireless MBIM devices. + +- VID:PID 33f8:1003, RW135R-GL for laptop debug M.2 cards (with MBIM + interface for Linux/Chrome OS) + + 0x1003: mbim, diag, AT, pipe + + Here are the outputs of usb-devices: + +T: Bus=03 Lev=01 Prnt=01 Port=04 Cnt=02 Dev#= 8 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=33f8 ProdID=1003 Rev= 5.15 +S: Manufacturer=Rolling Wireless S.a.r.l. +S: Product=Rolling RW135R-GL Module +S: SerialNumber=12345678 +C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA +A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 +I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim +E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms +I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim +I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +- VID:PID 33f8:1003, RW135R-GL for laptop debug M.2 cards (with MBIM + interface for Linux/Chrome OS) + + 0x1003: mbim, diag, AT, ADB, pipe + + Here are the outputs of usb-devices: + +T: Bus=03 Lev=01 Prnt=01 Port=04 Cnt=02 Dev#= 7 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=33f8 ProdID=1003 Rev= 5.15 +S: Manufacturer=Rolling Wireless S.a.r.l. +S: Product=Rolling RW135R-GL Module +S: SerialNumber=12345678 +C:* #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA +A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 +I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim +E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms +I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim +I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +- VID:PID 33f8:1003, RW135R-GL for laptop debug M.2 cards (with MBIM + interface for Linux/Chrome OS) + + 0x1003: mbim, pipe + + Here are the outputs of usb-devices: + +T: Bus=03 Lev=01 Prnt=01 Port=04 Cnt=02 Dev#= 9 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=33f8 ProdID=1003 Rev= 5.15 +S: Manufacturer=Rolling Wireless S.a.r.l. +S: Product=Rolling RW135R-GL Module +S: SerialNumber=12345678 +C:* #Ifs= 3 Cfg#= 1 Atr=a0 MxPwr=500mA +A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 +I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim +E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms +I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim +I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Fixes: 01e8d0f74222 ("USB: serial: option: add support for Rolling Wireless RW135R-GL") +Signed-off-by: Wanquan Zhong +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -2476,7 +2476,8 @@ static const struct usb_device_id option + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0302, 0xff) }, /* Rolling RW101R-GL (laptop MBIM) */ + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0802, 0xff), /* Rolling RW350-GL (laptop MBIM) */ + .driver_info = RSVD(5) }, +- { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x1003, 0xff) }, /* Rolling RW135R-GL (laptop MBIM) */ ++ { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x1003, 0xff), /* Rolling RW135R-GL (laptop MBIM) */ ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for Global */ + { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0x00, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0xff, 0x40) }, diff --git a/queue-5.15/usb-storage-add-quirks-for-pny-elite-portable-ssd.patch b/queue-5.15/usb-storage-add-quirks-for-pny-elite-portable-ssd.patch new file mode 100644 index 0000000000..94606dacf4 --- /dev/null +++ b/queue-5.15/usb-storage-add-quirks-for-pny-elite-portable-ssd.patch @@ -0,0 +1,69 @@ +From b53ebb811e00be50a779ce4e7aee604178b4a825 Mon Sep 17 00:00:00 2001 +From: Sam Burkels +Date: Fri, 1 May 2026 15:23:46 +0200 +Subject: usb: storage: Add quirks for PNY Elite Portable SSD + +From: Sam Burkels + +commit b53ebb811e00be50a779ce4e7aee604178b4a825 upstream. + +The PNY Elite Portable SSD (USB ID 154b:f009) is a sibling of the +already-quirked PNY Pro Elite SSDs (154b:f00b and 154b:f00d). Like its +siblings, it uses a Phison-based USB-SATA bridge that exhibits +firmware bugs when bound to the uas driver. + +Without quirks, the device fails to complete READ CAPACITY commands +when accessed over UAS on a SuperSpeed (USB 3) port. The device +enumerates and reports as a SCSI direct-access device, but reports +zero logical blocks and never finishes spin-up: + + usb 2-3: new SuperSpeed USB device number 8 using xhci_hcd + usb 2-3: New USB device found, idVendor=154b, idProduct=f009 + usb 2-3: Product: PNY ELITE PSSD + usb 2-3: Manufacturer: PNY + scsi host0: uas + scsi 0:0:0:0: Direct-Access PNY PNY ELITE PSSD 0 + sd 0:0:0:0: [sda] Spinning up disk... + [...10+ seconds of polling, no progress...] + sd 0:0:0:0: [sda] Read Capacity(16) failed: hostbyte=DID_ERROR + sd 0:0:0:0: [sda] Read Capacity(10) failed: hostbyte=DID_ERROR + sd 0:0:0:0: [sda] 0 512-byte logical blocks: (0 B/0 B) + +Tested each individual quirk to find the minimum that fixes this: + - US_FL_NO_ATA_1X alone: device hangs on spin-up + - US_FL_NO_REPORT_OPCODES alone: works on USB 2.0, hangs on USB 3.0 + - US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES: works on both + +With both quirks the device enumerates correctly while still using +the uas driver, and delivers full UAS throughput (~281 MB/s +sequential read on a USB 3.0 Gen 1 port). + +The existing PNY Pro Elite entries (f00b, f00d) only set NO_ATA_1X, +but this device additionally chokes on REPORT OPCODES under +SuperSpeed. + +Signed-off-by: Sam Burkels +Acked-by: Oliver Neukum +Cc: stable +Link: https://patch.msgid.link/20260501132346.86572-1-sam@1a38.nl +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/storage/unusual_uas.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/usb/storage/unusual_uas.h ++++ b/drivers/usb/storage/unusual_uas.h +@@ -132,6 +132,13 @@ UNUSUAL_DEV(0x152d, 0x0583, 0x0000, 0x99 + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_REPORT_OPCODES), + ++/* Reported-by: Sam Burkels */ ++UNUSUAL_DEV(0x154b, 0xf009, 0x0000, 0x9999, ++ "PNY", ++ "PNY ELITE PSSD", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES), ++ + /* Reported-by: Thinh Nguyen */ + UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999, + "PNY", diff --git a/queue-5.15/usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch b/queue-5.15/usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch new file mode 100644 index 0000000000..29576c98ac --- /dev/null +++ b/queue-5.15/usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch @@ -0,0 +1,39 @@ +From d98d413ca65d0790a8f3695d0a5845538958ab84 Mon Sep 17 00:00:00 2001 +From: Myrrh Periwinkle +Date: Tue, 19 May 2026 18:41:40 +0700 +Subject: usb: typec: ucsi: Don't update power_supply on power role change if not connected + +From: Myrrh Periwinkle + +commit d98d413ca65d0790a8f3695d0a5845538958ab84 upstream. + +We only need to update the power_supply on power role change if the port +is connected, because otherwise the online status should be the same for +both cases. + +Cc: stable +Fixes: 7616f006db07 ("usb: typec: ucsi: Update power_supply on power role change") +Signed-off-by: Myrrh Periwinkle +Reported-and-tested-by: Sergey Senozhatsky +Link: https://patch.msgid.link/20260519-ucsi-fix-2-v1-2-6f1239535187@qtmlabs.xyz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/ucsi.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/usb/typec/ucsi/ucsi.c ++++ b/drivers/usb/typec/ucsi/ucsi.c +@@ -793,7 +793,12 @@ static void ucsi_handle_connector_change + + if (con->status.change & UCSI_CONSTAT_CONNECT_CHANGE) { + typec_set_pwr_role(con->port, role); +- ucsi_port_psy_changed(con); ++ ++ /* Some power_supply properties vary depending on the power direction when ++ * connected ++ */ ++ if (UCSI_CONSTAT(con, CONNECTED)) ++ ucsi_port_psy_changed(con); + + switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { + case UCSI_CONSTAT_PARTNER_TYPE_UFP: diff --git a/queue-5.15/usb-usbtmc-check-urb-actual_length-for-interrupt-in-notifications.patch b/queue-5.15/usb-usbtmc-check-urb-actual_length-for-interrupt-in-notifications.patch new file mode 100644 index 0000000000..fda50a70e5 --- /dev/null +++ b/queue-5.15/usb-usbtmc-check-urb-actual_length-for-interrupt-in-notifications.patch @@ -0,0 +1,49 @@ +From 52f2ad3f7e5eb3b5908e1d685d4342519dc9cfcd Mon Sep 17 00:00:00 2001 +From: Heitor Alves de Siqueira +Date: Tue, 5 May 2026 15:56:03 -0300 +Subject: usb: usbtmc: check URB actual_length for interrupt-IN notifications + +From: Heitor Alves de Siqueira + +commit 52f2ad3f7e5eb3b5908e1d685d4342519dc9cfcd upstream. + +USBTMC devices can use an optional interrupt endpoint for notification +messages. These typically contain two-byte headers indicating the +payload format, but the driver does not check if these headers are +present before accessing the data buffers. In cases where the URB +actual_length is not enough to fit these headers, the driver will either +cause an out-of-bounds read, or consume stale leftover data from a +previous notification. + +Fix by checking if actual_data contains enough bytes for the headers, +otherwise resubmit URB to the interrupt endpoint. + +Fixes: dbf3e7f654c0 ("Implement an ioctl to support the USMTMC-USB488 READ_STATUS_BYTE operation.") +Reported-by: syzbot+abbfd103085885cf16a2@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=abbfd103085885cf16a2 +Cc: stable +Suggested-by: Michal Pecio +Signed-off-by: Heitor Alves de Siqueira +Link: https://patch.msgid.link/20260505-usbtmc-iin-size-v3-1-a36113f62db7@igalia.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/class/usbtmc.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/usb/class/usbtmc.c ++++ b/drivers/usb/class/usbtmc.c +@@ -2310,6 +2310,14 @@ static void usbtmc_interrupt(struct urb + + switch (status) { + case 0: /* SUCCESS */ ++ /* ensure at least two bytes of headers were transferred */ ++ if (urb->actual_length < 2) { ++ dev_warn(dev, ++ "actual length %d not sufficient for interrupt headers\n", ++ urb->actual_length); ++ goto exit; ++ } ++ + /* check for valid STB notification */ + if (data->iin_buffer[0] > 0x81) { + data->bNotify1 = data->iin_buffer[0]; diff --git a/queue-5.15/usb-usbtmc-reject-interrupt-endpoints-with-small-wmaxpacketsize.patch b/queue-5.15/usb-usbtmc-reject-interrupt-endpoints-with-small-wmaxpacketsize.patch new file mode 100644 index 0000000000..d0eaa64651 --- /dev/null +++ b/queue-5.15/usb-usbtmc-reject-interrupt-endpoints-with-small-wmaxpacketsize.patch @@ -0,0 +1,41 @@ +From 121d2f682ba912b1427cddca7cf84840f41cc620 Mon Sep 17 00:00:00 2001 +From: Heitor Alves de Siqueira +Date: Tue, 5 May 2026 15:56:04 -0300 +Subject: usb: usbtmc: reject interrupt endpoints with small wMaxPacketSize + +From: Heitor Alves de Siqueira + +commit 121d2f682ba912b1427cddca7cf84840f41cc620 upstream. + +The USB488 subclass specification requires interrupt wMaxPacketSize to +be 0x02, unless the device sends vendor-specific notifications. +Endpoints that advertise less than 2 bytes for wMaxPacketSize are +unlikely to work with the current driver, as URBs will not have enough +space for interrupt headers. Considering that any notification URBs will +be ignored by the driver, reject these endpoints early during probe. + +Fixes: 041370cce889 ("USB: usbtmc: refactor endpoint retrieval") +Cc: stable +Suggested-by: Michal Pecio +Signed-off-by: Heitor Alves de Siqueira +Link: https://patch.msgid.link/20260505-usbtmc-iin-size-v3-2-a36113f62db7@igalia.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/class/usbtmc.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/usb/class/usbtmc.c ++++ b/drivers/usb/class/usbtmc.c +@@ -2444,6 +2444,12 @@ static int usbtmc_probe(struct usb_inter + data->iin_ep = int_in->bEndpointAddress; + data->iin_wMaxPacketSize = usb_endpoint_maxp(int_in); + data->iin_interval = int_in->bInterval; ++ /* wMaxPacketSize should be 0x02 or more as per USB488 Table 22 */ ++ if (iface_desc->desc.bInterfaceProtocol == 1 && ++ data->iin_wMaxPacketSize < 2) { ++ retcode = -EINVAL; ++ goto err_put; ++ } + dev_dbg(&intf->dev, "Found Int in endpoint at %u\n", + data->iin_ep); + } diff --git a/queue-5.15/usbip-vudc-fix-use-after-free-bug-in-vudc_remove-due-to-race-condition.patch b/queue-5.15/usbip-vudc-fix-use-after-free-bug-in-vudc_remove-due-to-race-condition.patch new file mode 100644 index 0000000000..2bdc0b87fc --- /dev/null +++ b/queue-5.15/usbip-vudc-fix-use-after-free-bug-in-vudc_remove-due-to-race-condition.patch @@ -0,0 +1,77 @@ +From d96209626a29ea64666be98c30b30ac82e5f1be6 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Fri, 17 Apr 2026 12:35:52 -0400 +Subject: usbip: vudc: Fix use after free bug in vudc_remove due to race condition + +From: Michael Bommarito + +commit d96209626a29ea64666be98c30b30ac82e5f1be6 upstream. + +This patch follows up Zheng Wang's 2023 report of a use-after-free in +vudc_remove(). The original thread stalled on Shuah Khan's request for +runtime testing of the unplug/unbind path. This patch supplies that +testing and keeps Zheng's original fix shape. + +In vudc_probe(), v_init_timer() binds udc->tr_timer.timer to v_timer(). +usbip_sockfd_store() starts the timer via v_start_timer()/v_kick_timer(). +vudc_remove() can then free the containing struct vudc while the timer is +still pending or executing. + +KASAN confirms the race on an unpatched x86_64 QEMU guest with +CONFIG_KASAN=y, CONFIG_USBIP_VUDC=y, CONFIG_USB_ZERO=y, and a tight loop +that repeatedly writes a socket fd to usbip_sockfd, closes the socket +pair, and unbinds/rebinds usbip-vudc.0: + + BUG: KASAN: slab-use-after-free in __run_timer_base.part.0+0x8ba/0x8e0 + Write of size 8 at addr ffff888001b80740 by task trigger_and_unb/239 + Allocated by task 239: + vudc_probe+0x4d/0xaa0 + Freed by task 239: + kfree+0x18f/0x520 + device_release_driver_internal+0x388/0x540 + unbind_store+0xd9/0x100 + +This lands in the timer core rather than v_timer() itself because the +embedded timer_list is being walked after its containing struct vudc has +already been freed. The underlying lifetime bug is the same one Zheng +reported. + +With v_stop_timer() called from vudc_remove() and the timer deleted +synchronously, the same harness completed 5000 bind/unbind iterations +with no KASAN report. + +Fixes: b6a0ca111867 ("usbip: vudc: Add UDC specific ops") +Cc: stable +Reported-by: Zheng Wang +Closes: https://lore.kernel.org/linux-usb/20230317100954.2626573-1-zyytlz.wz@163.com/ +Signed-off-by: Michael Bommarito +Acked-by: Shuah Khan +Link: https://patch.msgid.link/20260417163552.807548-1-michael.bommarito@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/usbip/vudc_dev.c | 1 + + drivers/usb/usbip/vudc_transfer.c | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/usbip/vudc_dev.c ++++ b/drivers/usb/usbip/vudc_dev.c +@@ -633,6 +633,7 @@ int vudc_remove(struct platform_device * + { + struct vudc *udc = platform_get_drvdata(pdev); + ++ v_stop_timer(udc); + usb_del_gadget_udc(&udc->gadget); + cleanup_vudc_hw(udc); + kfree(udc); +--- a/drivers/usb/usbip/vudc_transfer.c ++++ b/drivers/usb/usbip/vudc_transfer.c +@@ -490,7 +490,8 @@ void v_stop_timer(struct vudc *udc) + { + struct transfer_timer *t = &udc->tr_timer; + +- /* timer itself will take care of stopping */ ++ /* Delete the timer synchronously before teardown frees udc. */ + dev_dbg(&udc->pdev->dev, "timer stop"); ++ timer_delete_sync(&t->timer); + t->state = VUDC_TR_STOPPED; + } -- 2.47.3