From: Greg Kroah-Hartman Date: Mon, 27 Jul 2026 13:34:02 +0000 (+0200) Subject: 5.10-stable patches X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=b74b4813633c84a248b5453d22d2657ddf8174a9;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: usb-chipidea-fix-usage_count-leak-when-autosuspend_delay-is-negative.patch usb-gadget-dummy_hcd-prevent-fifo_req-reuse-during-giveback.patch usb-gadget-f_midi-cancel-pending-in-work-before-freeing-the-midi-object.patch usb-gadget-f_ncm-validate-datagram-bounds-in-ncm_unwrap_ntb.patch usb-gadget-fsl-udc-fix-device-name-leak-on-probe-failure.patch usb-gadget-printer-fix-infinite-loop-in-printer_read.patch usb-gadget-snps-udc-fix-device-name-leak-on-probe-failure.patch usb-gadget-uvc-clamp-send_response-length-to-the-response-buffer.patch usb-serial-ftdi_sio-add-support-for-e-h-fxa291.patch usb-serial-io_edgeport-cap-received-transmit-credits.patch usb-serial-option-add-tdtech-mt5710-cn.patch usb-storage-add-no_ata_1x-quirk-for-longmai-usb-key.patch wifi-at76c50x-usb-avoid-length-underflow-in-at76_guess_freq.patch --- diff --git a/queue-5.10/series b/queue-5.10/series index 1bf01b8acb..8dafb6c3db 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -42,3 +42,16 @@ drm-i915-selftests-fix-gt-pm-sort-comparators.patch net-sched-act_tunnel_key-defer-dst_release-to-rcu-ca.patch sctp-fix-auth_hmacs-array-size-in-struct-sctp_cookie.patch mpls-fix-null-deref-in-mpls_valid_fib_dump_req-on-co.patch +wifi-at76c50x-usb-avoid-length-underflow-in-at76_guess_freq.patch +usb-storage-add-no_ata_1x-quirk-for-longmai-usb-key.patch +usb-chipidea-fix-usage_count-leak-when-autosuspend_delay-is-negative.patch +usb-gadget-dummy_hcd-prevent-fifo_req-reuse-during-giveback.patch +usb-gadget-f_midi-cancel-pending-in-work-before-freeing-the-midi-object.patch +usb-gadget-printer-fix-infinite-loop-in-printer_read.patch +usb-gadget-snps-udc-fix-device-name-leak-on-probe-failure.patch +usb-gadget-fsl-udc-fix-device-name-leak-on-probe-failure.patch +usb-gadget-f_ncm-validate-datagram-bounds-in-ncm_unwrap_ntb.patch +usb-gadget-uvc-clamp-send_response-length-to-the-response-buffer.patch +usb-serial-ftdi_sio-add-support-for-e-h-fxa291.patch +usb-serial-io_edgeport-cap-received-transmit-credits.patch +usb-serial-option-add-tdtech-mt5710-cn.patch diff --git a/queue-5.10/usb-chipidea-fix-usage_count-leak-when-autosuspend_delay-is-negative.patch b/queue-5.10/usb-chipidea-fix-usage_count-leak-when-autosuspend_delay-is-negative.patch new file mode 100644 index 0000000000..775a55becf --- /dev/null +++ b/queue-5.10/usb-chipidea-fix-usage_count-leak-when-autosuspend_delay-is-negative.patch @@ -0,0 +1,37 @@ +From fc3afb5728e297994863f8a2a01b88a920bbf53e Mon Sep 17 00:00:00 2001 +From: Xu Yang +Date: Thu, 16 Jul 2026 18:41:26 +0800 +Subject: usb: chipidea: fix usage_count leak when autosuspend_delay is negative + +From: Xu Yang + +commit fc3afb5728e297994863f8a2a01b88a920bbf53e upstream. + +The probe() calls pm_runtime_use_autosuspend(), but remove() does not call +pm_runtime_dont_use_autosuspend(). This can lead to a usage_count leak if +autosuspend_delay is set to a negative value. + +The pm_runtime_use_autosuspend() also notes that it's important to undo +this with pm_runtime_dont_use_autosuspend() at driver exit time. + +Fixes: 1f874edcb731 ("usb: chipidea: add runtime power management support") +Cc: stable +Assisted-by: Claude:claude-sonnet-4.6 +Signed-off-by: Xu Yang +Reviewed-by: Frank Li +Link: https://patch.msgid.link/20260716104126.2763454-1-xu.yang_2@oss.nxp.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/chipidea/core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/chipidea/core.c ++++ b/drivers/usb/chipidea/core.c +@@ -1238,6 +1238,7 @@ static int ci_hdrc_remove(struct platfor + usb_role_switch_unregister(ci->role_switch); + + if (ci->supports_runtime_pm) { ++ pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); diff --git a/queue-5.10/usb-gadget-dummy_hcd-prevent-fifo_req-reuse-during-giveback.patch b/queue-5.10/usb-gadget-dummy_hcd-prevent-fifo_req-reuse-during-giveback.patch new file mode 100644 index 0000000000..a8670ae914 --- /dev/null +++ b/queue-5.10/usb-gadget-dummy_hcd-prevent-fifo_req-reuse-during-giveback.patch @@ -0,0 +1,141 @@ +From d5e5cd3654d2b5359a12ea6586120f05b28634ee Mon Sep 17 00:00:00 2001 +From: Jinchao Wang +Date: Thu, 16 Jul 2026 06:42:17 -0400 +Subject: usb: gadget: dummy_hcd: prevent fifo_req reuse during giveback + +From: Jinchao Wang + +commit d5e5cd3654d2b5359a12ea6586120f05b28634ee upstream. + +dummy_hcd embeds a single shared usb_request (dum->fifo_req) that the +"emulated single-request FIFO" fast-path in dummy_queue() reuses for +small IN transfers: it copies the caller's request into it +(req->req = *_req) and queues it, treating list_empty(&fifo_req.queue) +as "the slot is free". + +The completion side (dummy_timer/transfer/nuke/dummy_dequeue) follows +the standard pattern: list_del_init(&req->queue) unlinks the request, +then the lock is dropped and usb_gadget_giveback_request() invokes +req->complete(). But list_del_init() makes fifo_req.queue look empty +*before* the completion callback returns, so a concurrent dummy_queue() +on another CPU sees the slot as free, reuses fifo_req and runs +req->req = *_req -- overwriting req->complete while dummy_timer is +mid-calling it. The indirect call then jumps to a clobbered pointer, +causing a general protection fault / page fault in dummy_timer +(syzkaller extid faf3a6cf579fc65591ca). The clobbering write is an +in-bounds memcpy on a live shared object, so KASAN cannot flag it. + +Add a fifo_req_busy bit covering the shared request's whole lifetime: +set it in dummy_queue() when the FIFO fast-path takes fifo_req (making +it the fast-path guard, replacing the list_empty(&fifo_req.queue) +test), and clear it after the completion callback has returned, via a +dummy_giveback() helper used at all four gadget-request giveback +sites. The shared slot can no longer be reused until its completion +callback has finished. + +Reported-by: syzbot+faf3a6cf579fc65591ca@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=faf3a6cf579fc65591ca +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable +Signed-off-by: Jinchao Wang +Reviewed-by: Alan Stern +Link: https://patch.msgid.link/5db8bba5b3499a86cd2e776f9918126b68b2508b.1784198306.git.wangjinchao600@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/dummy_hcd.c | 40 ++++++++++++++++++++++++------------- + 1 file changed, 27 insertions(+), 13 deletions(-) + +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -274,6 +274,7 @@ struct dummy { + unsigned ints_enabled:1; + unsigned udc_suspended:1; + unsigned pullup:1; ++ unsigned fifo_req_busy:1; + + /* + * HOST side support +@@ -325,6 +326,26 @@ static inline struct dummy *gadget_dev_t + + /* DEVICE/GADGET SIDE UTILITY ROUTINES */ + ++/* ++ * Give back a gadget request with dum->lock dropped around the callback. ++ * If @req is the shared fifo_req, clear fifo_req_busy afterward: the flag ++ * was set in dummy_queue() when the shared request was taken and must stay ++ * set until its completion callback has returned; list_del_init() alone ++ * makes the request look idle while the callback is still running. ++ * Caller holds dum->lock and has already done list_del_init() + status. ++ */ ++static void dummy_giveback(struct dummy *dum, struct usb_ep *_ep, ++ struct dummy_request *req) ++{ ++ bool fifo = req == &dum->fifo_req; ++ ++ spin_unlock(&dum->lock); ++ usb_gadget_giveback_request(_ep, &req->req); ++ spin_lock(&dum->lock); ++ if (fifo) ++ dum->fifo_req_busy = 0; ++} ++ + /* called with spinlock held */ + static void nuke(struct dummy *dum, struct dummy_ep *ep) + { +@@ -335,9 +356,7 @@ static void nuke(struct dummy *dum, stru + list_del_init(&req->queue); + req->req.status = -ESHUTDOWN; + +- spin_unlock(&dum->lock); +- usb_gadget_giveback_request(&ep->ep, &req->req); +- spin_lock(&dum->lock); ++ dummy_giveback(dum, &ep->ep, req); + } + } + +@@ -722,10 +741,11 @@ static int dummy_queue(struct usb_ep *_e + + /* implement an emulated single-request FIFO */ + if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) && +- list_empty(&dum->fifo_req.queue) && ++ !dum->fifo_req_busy && + list_empty(&ep->queue) && + _req->length <= FIFO_SIZE) { + req = &dum->fifo_req; ++ dum->fifo_req_busy = 1; + req->req = *_req; + req->req.buf = dum->fifo_buf; + memcpy(dum->fifo_buf, _req->buf, _req->length); +@@ -779,9 +799,7 @@ static int dummy_dequeue(struct usb_ep * + dev_dbg(udc_dev(dum), + "dequeued req %p from %s, len %d buf %p\n", + req, _ep->name, _req->length, _req->buf); +- spin_unlock(&dum->lock); +- usb_gadget_giveback_request(_ep, _req); +- spin_lock(&dum->lock); ++ dummy_giveback(dum, _ep, req); + } + spin_unlock_irqrestore(&dum->lock, flags); + return retval; +@@ -1506,9 +1524,7 @@ top: + if (req->req.status != -EINPROGRESS) { + list_del_init(&req->queue); + +- spin_unlock(&dum->lock); +- usb_gadget_giveback_request(&ep->ep, &req->req); +- spin_lock(&dum->lock); ++ dummy_giveback(dum, &ep->ep, req); + + /* requests might have been unlinked... */ + rescan = 1; +@@ -1891,9 +1907,7 @@ restart: + dev_dbg(udc_dev(dum), "stale req = %p\n", + req); + +- spin_unlock(&dum->lock); +- usb_gadget_giveback_request(&ep->ep, &req->req); +- spin_lock(&dum->lock); ++ dummy_giveback(dum, &ep->ep, req); + ep->already_seen = 0; + goto restart; + } diff --git a/queue-5.10/usb-gadget-f_midi-cancel-pending-in-work-before-freeing-the-midi-object.patch b/queue-5.10/usb-gadget-f_midi-cancel-pending-in-work-before-freeing-the-midi-object.patch new file mode 100644 index 0000000000..568414e192 --- /dev/null +++ b/queue-5.10/usb-gadget-f_midi-cancel-pending-in-work-before-freeing-the-midi-object.patch @@ -0,0 +1,68 @@ +From 5650c18d93a1db7e27cb5a40b394747eb4686d5b Mon Sep 17 00:00:00 2001 +From: Fan Wu +Date: Thu, 9 Jul 2026 15:07:17 +0000 +Subject: usb: gadget: f_midi: cancel pending IN work before freeing the midi object + +From: Fan Wu + +commit 5650c18d93a1db7e27cb5a40b394747eb4686d5b upstream. + +The f_midi driver embeds a work item (midi->work) whose handler, +f_midi_in_work(), dereferences the enclosing struct f_midi through +container_of(). This work is armed from two sites: f_midi_complete(), +on a normal IN-endpoint completion, and f_midi_in_trigger(), on an ALSA +rawmidi output-stream start. + +Neither f_midi_disable() nor f_midi_unbind() cancels midi->work. +f_midi_disable() only disables the endpoints and drains the in_req_fifo; +it does not synchronize the work item, and the sound card is released +asynchronously to the final free of the midi object. + +The midi object is reference-counted (midi->free_ref) and is freed in +f_midi_free() only once both the usb_function reference and the rawmidi +private_data reference have been dropped. In f_midi_unbind(), +f_midi_disable() runs before the sound card is released, so while the +USB endpoints are already disabled the rawmidi device is still usable by +an open substream. A concurrent userspace write on such a substream can +reach f_midi_in_trigger() and queue midi->work again after +f_midi_disable() has returned. A work item armed this way may still be +pending when the last reference drops and f_midi_free() proceeds to +kfree(midi), letting f_midi_in_work() dereference the struct after it +has been freed, a use-after-free. + +For this reason cancelling midi->work in f_midi_disable() would not be +sufficient: the ALSA trigger path can rearm the work after disable() +returns. Cancelling at the refcount-zero free site is the boundary +after which neither arming source can survive, because by then both +references that keep the midi object alive have been dropped: the USB +endpoints are already disabled and the rawmidi device has been released. + +Fix this by calling cancel_work_sync(&midi->work) in the refcount-zero +block of f_midi_free(), before the embedded work_struct is freed along +with the rest of the structure. opts->lock is a sleeping mutex, so +calling cancel_work_sync() under it is permitted, and the handler takes +midi->transmit_lock rather than opts->lock, so no self-deadlock can +occur while it waits for a running instance of the work to finish. + +This issue was found by an in-house static analysis tool. + +Fixes: 8653d71ce3763 ("usb/gadget: f_midi: Replace tasklet with work") +Cc: stable +Assisted-by: Codex:gpt-5.5 +Signed-off-by: Fan Wu +Link: https://patch.msgid.link/20260709150717.399083-1-fanwu01@zju.edu.cn +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_midi.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/gadget/function/f_midi.c ++++ b/drivers/usb/gadget/function/f_midi.c +@@ -1258,6 +1258,7 @@ static void f_midi_free(struct usb_funct + opts = container_of(f->fi, struct f_midi_opts, func_inst); + mutex_lock(&opts->lock); + if (!--midi->free_ref) { ++ cancel_work_sync(&midi->work); + kfree(midi->id); + kfifo_free(&midi->in_req_fifo); + kfree(midi); diff --git a/queue-5.10/usb-gadget-f_ncm-validate-datagram-bounds-in-ncm_unwrap_ntb.patch b/queue-5.10/usb-gadget-f_ncm-validate-datagram-bounds-in-ncm_unwrap_ntb.patch new file mode 100644 index 0000000000..4b5c7b52b1 --- /dev/null +++ b/queue-5.10/usb-gadget-f_ncm-validate-datagram-bounds-in-ncm_unwrap_ntb.patch @@ -0,0 +1,91 @@ +From 1febec7e47cdcd01f43fb0211094e3010474666e Mon Sep 17 00:00:00 2001 +From: Sonali Pradhan +Date: Fri, 3 Jul 2026 08:37:24 +0000 +Subject: usb: gadget: f_ncm: validate datagram bounds in ncm_unwrap_ntb() + +From: Sonali Pradhan + +commit 1febec7e47cdcd01f43fb0211094e3010474666e upstream. + +When unpacking host-supplied NTBs, ncm_unwrap_ntb() checks datagram length +against frame_max but does not verify that the datagram fits within the +declared block length. Additionally, when decoding multiple NTBs from a +single socket buffer, subsequent block lengths are not checked against the +actual remaining buffer data. + +With these checks missing, a malicious USB host can specify datagram +offsets and lengths that point beyond the block, or supply secondary NTB +headers declaring lengths larger than the buffer. skb_put_data() then +copies adjacent kernel memory from skb_shared_info into the network skb. + +Fix this by verifying that sufficient buffer space remains for the NTB +header before parsing, handling zero-length block declarations, ensuring +that block lengths never exceed the remaining buffer space, and verifying +that each datagram payload stays strictly within the block boundary. + +Fixes: 427694cfaafa ("usb: gadget: ncm: Handle decoding of multiple NTB's in unwrap call") +Fixes: 2b74b0a04d3e ("USB: gadget: f_ncm: add bounds checks to ncm_unwrap_ntb()") +Cc: stable +Assisted-by: Jetski:Gemini-2.5-Pro +Signed-off-by: Sonali Pradhan +Link: https://patch.msgid.link/20260703083725.1903850-1-sonalipradhan@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_ncm.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +--- a/drivers/usb/gadget/function/f_ncm.c ++++ b/drivers/usb/gadget/function/f_ncm.c +@@ -1197,6 +1197,10 @@ static int ncm_unwrap_ntb(struct gether + int to_process = skb->len; + + parse_ntb: ++ if (to_process < (int)opts->nth_size) { ++ INFO(port->func.config->cdev, "Packet too small for headers\n"); ++ goto err; ++ } + tmp = (__le16 *)ntb_ptr; + + /* dwSignature */ +@@ -1217,8 +1221,12 @@ parse_ntb: + tmp++; /* skip wSequence */ + + block_len = get_ncm(&tmp, opts->block_length); ++ if (block_len == 0) ++ block_len = to_process; ++ + /* (d)wBlockLength */ +- if ((block_len < opts->nth_size + opts->ndp_size) || (block_len > ntb_max)) { ++ if ((block_len < opts->nth_size + opts->ndp_size) || (block_len > ntb_max) || ++ (block_len > to_process)) { + INFO(port->func.config->cdev, "Bad block length: %#X\n", block_len); + goto err; + } +@@ -1281,7 +1289,7 @@ parse_ntb: + index = index2; + /* wDatagramIndex[0] */ + if ((index < opts->nth_size) || +- (index > block_len - opts->dpe_size)) { ++ (index > block_len)) { + INFO(port->func.config->cdev, + "Bad index: %#X\n", index); + goto err; +@@ -1293,7 +1301,8 @@ parse_ntb: + * ethernet hdr + crc or larger than max frame size + */ + if ((dg_len < 14 + crc_len) || +- (dg_len > frame_max)) { ++ (dg_len > frame_max) || ++ (dg_len > block_len - index)) { + INFO(port->func.config->cdev, + "Bad dgram length: %#X\n", dg_len); + goto err; +@@ -1318,7 +1327,7 @@ parse_ntb: + dg_len2 = get_ncm(&tmp, opts->dgram_item_len); + + /* wDatagramIndex[1] */ +- if (index2 > block_len - opts->dpe_size) { ++ if (index2 > block_len) { + INFO(port->func.config->cdev, + "Bad index: %#X\n", index2); + goto err; diff --git a/queue-5.10/usb-gadget-fsl-udc-fix-device-name-leak-on-probe-failure.patch b/queue-5.10/usb-gadget-fsl-udc-fix-device-name-leak-on-probe-failure.patch new file mode 100644 index 0000000000..9562520196 --- /dev/null +++ b/queue-5.10/usb-gadget-fsl-udc-fix-device-name-leak-on-probe-failure.patch @@ -0,0 +1,32 @@ +From 6b874d00c466e73c6448a89856407fe46b2f50e4 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 2 Jul 2026 16:15:33 +0200 +Subject: USB: gadget: fsl-udc: fix device name leak on probe failure + +From: Johan Hovold + +commit 6b874d00c466e73c6448a89856407fe46b2f50e4 upstream. + +The gadget device name is set by UDC core when registering the gadget +and must not be set before to avoid leaking the name in intermediate +error paths (e.g. on dma pool creation failure). + +Fixes: eab35c4e6d95 ("usb: gadget: fsl_udc_core: let udc-core manage gadget->dev") +Cc: stable +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20260702141536.90887-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/fsl_udc_core.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/usb/gadget/udc/fsl_udc_core.c ++++ b/drivers/usb/gadget/udc/fsl_udc_core.c +@@ -2480,7 +2480,6 @@ static int fsl_udc_probe(struct platform + udc_controller->gadget.name = driver_name; + + /* Setup gadget.dev and register with kernel */ +- dev_set_name(&udc_controller->gadget.dev, "gadget"); + udc_controller->gadget.dev.of_node = pdev->dev.of_node; + + if (!IS_ERR_OR_NULL(udc_controller->transceiver)) diff --git a/queue-5.10/usb-gadget-printer-fix-infinite-loop-in-printer_read.patch b/queue-5.10/usb-gadget-printer-fix-infinite-loop-in-printer_read.patch new file mode 100644 index 0000000000..ce90651e9a --- /dev/null +++ b/queue-5.10/usb-gadget-printer-fix-infinite-loop-in-printer_read.patch @@ -0,0 +1,77 @@ +From c2e819be6a5c7f34344926b4bd7e3dfca58cf48a Mon Sep 17 00:00:00 2001 +From: Melbin K Mathew +Date: Thu, 9 Jul 2026 21:56:22 +0100 +Subject: usb: gadget: printer: fix infinite loop in printer_read() + +From: Melbin K Mathew + +commit c2e819be6a5c7f34344926b4bd7e3dfca58cf48a upstream. + +printer_read() uses the same variable for the requested copy size and +the number of bytes actually copied to user space. copy_to_user() +returns the number of bytes not copied, so when it fails to copy +anything, the computed copied length becomes zero. + +In that case len, buf, current_rx_bytes and current_rx_buf are left +unchanged. If RX data is available and the user buffer remains +unwritable, the read loop can repeat indefinitely. + +Track the copied length separately and return -EFAULT, or the number of +bytes already copied, if an iteration makes no progress. + +Fixes: b185f01a9ab7 ("usb: gadget: printer: factor out f_printer") +Cc: stable +Reviewed-by: Peter Chen +Signed-off-by: Melbin K Mathew +Link: https://patch.msgid.link/20260709205622.55700-1-mlbnkm1@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_printer.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +--- a/drivers/usb/gadget/function/f_printer.c ++++ b/drivers/usb/gadget/function/f_printer.c +@@ -426,7 +426,7 @@ printer_read(struct file *fd, char __use + { + struct printer_dev *dev = fd->private_data; + unsigned long flags; +- size_t size; ++ size_t size, not_copied, copied; + size_t bytes_copied; + struct usb_request *req; + /* This is a pointer to the current USB rx request. */ +@@ -519,10 +519,12 @@ printer_read(struct file *fd, char __use + else + size = len; + +- size -= copy_to_user(buf, current_rx_buf, size); +- bytes_copied += size; +- len -= size; +- buf += size; ++ not_copied = copy_to_user(buf, current_rx_buf, size); ++ copied = size - not_copied; ++ ++ bytes_copied += copied; ++ len -= copied; ++ buf += copied; + + spin_lock_irqsave(&dev->lock, flags); + +@@ -537,6 +539,17 @@ printer_read(struct file *fd, char __use + if (dev->interface < 0) + goto out_disabled; + ++ if (!copied) { ++ dev->current_rx_req = current_rx_req; ++ dev->current_rx_bytes = current_rx_bytes; ++ dev->current_rx_buf = current_rx_buf; ++ spin_unlock_irqrestore(&dev->lock, flags); ++ mutex_unlock(&dev->lock_printer_io); ++ return bytes_copied ? bytes_copied : -EFAULT; ++ } ++ ++ size = copied; ++ + /* If we not returning all the data left in this RX request + * buffer then adjust the amount of data left in the buffer. + * Othewise if we are done with this RX request buffer then diff --git a/queue-5.10/usb-gadget-snps-udc-fix-device-name-leak-on-probe-failure.patch b/queue-5.10/usb-gadget-snps-udc-fix-device-name-leak-on-probe-failure.patch new file mode 100644 index 0000000000..d0a51a70fe --- /dev/null +++ b/queue-5.10/usb-gadget-snps-udc-fix-device-name-leak-on-probe-failure.patch @@ -0,0 +1,32 @@ +From 29a142d3e8b35ebc9e0bcc78f4bc26c9b6a9ac0b Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 2 Jul 2026 16:15:34 +0200 +Subject: USB: gadget: snps-udc: fix device name leak on probe failure + +From: Johan Hovold + +commit 29a142d3e8b35ebc9e0bcc78f4bc26c9b6a9ac0b upstream. + +The gadget device name is set by UDC core when registering the gadget +and must not be set before to avoid leaking the name in intermediate +error paths (e.g. when detecting an older chip revision). + +Fixes: 12ad0fcaf2fb ("usb: gadget: amd5536udc: let udc-core manage gadget->dev") +Cc: stable +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20260702141536.90887-3-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/snps_udc_core.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/usb/gadget/udc/snps_udc_core.c ++++ b/drivers/usb/gadget/udc/snps_udc_core.c +@@ -3158,7 +3158,6 @@ int udc_probe(struct udc *dev) + /* device struct setup */ + dev->gadget.ops = &udc_ops; + +- dev_set_name(&dev->gadget.dev, "gadget"); + dev->gadget.name = name; + dev->gadget.max_speed = USB_SPEED_HIGH; + diff --git a/queue-5.10/usb-gadget-uvc-clamp-send_response-length-to-the-response-buffer.patch b/queue-5.10/usb-gadget-uvc-clamp-send_response-length-to-the-response-buffer.patch new file mode 100644 index 0000000000..82bbedaae3 --- /dev/null +++ b/queue-5.10/usb-gadget-uvc-clamp-send_response-length-to-the-response-buffer.patch @@ -0,0 +1,46 @@ +From b70dc75e85ba968b7b76eebfe5d63000080b875b Mon Sep 17 00:00:00 2001 +From: Muhammad Bilal +Date: Tue, 30 Jun 2026 00:50:04 +0500 +Subject: usb: gadget: uvc: clamp SEND_RESPONSE length to the response buffer + +From: Muhammad Bilal + +commit b70dc75e85ba968b7b76eebfe5d63000080b875b upstream. + +uvc_send_response() builds the UVC control response from a user-supplied +struct uvc_request_data: + + req->length = min_t(unsigned int, uvc->event_length, data->length); + ... + memcpy(req->buf, data->data, req->length); + +req->length is clamped to uvc->event_length, which is taken from the +host control request wLength (up to UVC_MAX_REQUEST_SIZE, 64), and to +data->length, which comes from the UVCIOC_SEND_RESPONSE ioctl and is +only checked for being negative. The source buffer data->data is only +60 bytes, so a response with uvc->event_length and data->length both +greater than 60 makes memcpy() read past the end of data->data. + +Clamp req->length to sizeof(data->data) as well. + +Fixes: a5eaaa1f33e7 ("usb: gadget: uvc: use capped length value") +Cc: stable +Signed-off-by: Muhammad Bilal +Link: https://patch.msgid.link/20260629195004.148405-1-meatuni001@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/uvc_v4l2.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/gadget/function/uvc_v4l2.c ++++ b/drivers/usb/gadget/function/uvc_v4l2.c +@@ -39,6 +39,8 @@ uvc_send_response(struct uvc_device *uvc + return usb_ep_set_halt(cdev->gadget->ep0); + + req->length = min_t(unsigned int, uvc->event_length, data->length); ++ if (req->length > sizeof(data->data)) ++ req->length = sizeof(data->data); + req->zero = data->length < uvc->event_length; + + memcpy(req->buf, data->data, req->length); diff --git a/queue-5.10/usb-serial-ftdi_sio-add-support-for-e-h-fxa291.patch b/queue-5.10/usb-serial-ftdi_sio-add-support-for-e-h-fxa291.patch new file mode 100644 index 0000000000..72ad030113 --- /dev/null +++ b/queue-5.10/usb-serial-ftdi_sio-add-support-for-e-h-fxa291.patch @@ -0,0 +1,57 @@ +From fad0fd120e29041b3e6cdf41bb12e3184fb524a2 Mon Sep 17 00:00:00 2001 +From: Tim Pambor +Date: Sat, 11 Jul 2026 17:36:30 +0000 +Subject: USB: serial: ftdi_sio: add support for E+H FXA291 + +From: Tim Pambor + +commit fad0fd120e29041b3e6cdf41bb12e3184fb524a2 upstream. + +The Commubox FXA291 by Endress+Hauser AG is a USB serial converter +based on FT232B which is used to communicate with field devices. + +It enumerates using the FTDI vendor ID and a custom PID. + +usb 1-9: New USB device found, idVendor=0403, idProduct=e510, bcdDevice= 4.00 +usb 1-9: New USB device strings: Mfr=1, Product=2, SerialNumber=0 +usb 1-9: Product: FXA291 +usb 1-9: Manufacturer: Endress+Hauser +usb 1-9: SerialNumber: 00000000 +ftdi_sio 1-9:1.0: FTDI USB Serial Device converter detected +usb 1-9: Detected FT232B +usb 1-9: FTDI USB Serial Device converter now attached to ttyUSB0 + +Signed-off-by: Tim Pambor +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/ftdi_sio.c | 2 ++ + drivers/usb/serial/ftdi_sio_ids.h | 5 +++++ + 2 files changed, 7 insertions(+) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1053,6 +1053,8 @@ static const struct usb_device_id id_tab + { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 3) }, + /* Abacus Electrics */ + { USB_DEVICE(FTDI_VID, ABACUS_OPTICAL_PROBE_PID) }, ++ /* Endress+Hauser AG devices */ ++ { USB_DEVICE(FTDI_VID, FTDI_EH_FXA291_PID) }, + { } /* Terminating entry */ + }; + +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -307,6 +307,11 @@ + #define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */ + + /* ++ * Endress+Hauser AG product ids (FTDI_VID) ++ */ ++#define FTDI_EH_FXA291_PID 0xE510 ++ ++/* + * EVER Eco Pro UPS (http://www.ever.com.pl/) + */ + diff --git a/queue-5.10/usb-serial-io_edgeport-cap-received-transmit-credits.patch b/queue-5.10/usb-serial-io_edgeport-cap-received-transmit-credits.patch new file mode 100644 index 0000000000..ad69016a11 --- /dev/null +++ b/queue-5.10/usb-serial-io_edgeport-cap-received-transmit-credits.patch @@ -0,0 +1,42 @@ +From faaddd811c5099f11a5f52e68a6b31a5898cda4f Mon Sep 17 00:00:00 2001 +From: Sunho Park +Date: Tue, 14 Jul 2026 19:42:30 +0900 +Subject: USB: serial: io_edgeport: cap received transmit credits + +From: Sunho Park + +commit faaddd811c5099f11a5f52e68a6b31a5898cda4f upstream. + +The interrupt-status packet reports transmit credits returned by the +device. edge_interrupt_callback() adds the 16-bit value to txCredits +without checking maxTxCredits. + +edge_write() uses txCredits minus the software FIFO count as the amount +of data that fits. Since the FIFO is allocated with maxTxCredits bytes, +txCredits exceeding maxTxCredits can cause OOB write in ring buffer. + +Cap accumulated credits at maxTxCredits. Conforming devices should never +hit the cap. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org +Assisted-by: Codex:GPT-5 +Signed-off-by: Sunho Park +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/io_edgeport.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -722,7 +722,8 @@ static void edge_interrupt_callback(stru + if (edge_port && edge_port->open) { + spin_lock_irqsave(&edge_port->ep_lock, + flags); +- edge_port->txCredits += txCredits; ++ edge_port->txCredits = min(edge_port->txCredits + txCredits, ++ edge_port->maxTxCredits); + spin_unlock_irqrestore(&edge_port->ep_lock, + flags); + dev_dbg(dev, "%s - txcredits for port%d = %d\n", diff --git a/queue-5.10/usb-serial-option-add-tdtech-mt5710-cn.patch b/queue-5.10/usb-serial-option-add-tdtech-mt5710-cn.patch new file mode 100644 index 0000000000..d02559cfcc --- /dev/null +++ b/queue-5.10/usb-serial-option-add-tdtech-mt5710-cn.patch @@ -0,0 +1,59 @@ +From 55645e4f3c6022ffb160ad3617d2b624eaa38501 Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Wed, 8 Jul 2026 18:00:01 +0800 +Subject: USB: serial: option: add TDTECH MT5710-CN + +From: Chukun Pan + +commit 55645e4f3c6022ffb160ad3617d2b624eaa38501 upstream. + +Add support for the TDTECH MT5710-CN (5G redcap) module based on the +Huawei HiSilicon Balong chip. + +T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=3466 ProdID=3301 Rev=ff.ff +S: Manufacturer=TD Tech Ltd. +S: Product=TDTECH MT571X +S: SerialNumber=0123456789ABCDEF +C:* #Ifs= 6 Cfg#= 1 Atr=c0 MxPwr= 0mA +A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0d Prot=00 +I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0d Prot=00 Driver=cdc_ncm +E: Ad=82(I) Atr=03(Int.) MxPS= 16 Ivl=32ms +I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm +I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm +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=06 Prot=13 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=06 Prot=12 Driver=option +E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=1c Driver=option +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=06 Prot=14 Driver=option +E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Interface: ECM / NCM + DIAG + AT + SERIAL + GPS + +Signed-off-by: Chukun Pan +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -2497,6 +2497,7 @@ static const struct usb_device_id option + .driver_info = RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x1003, 0xff), /* Rolling RW135R-GL (laptop MBIM) */ + .driver_info = RSVD(5) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x3466, 0x3301, 0xff) }, /* TDTECH MT5710-CN */ + { 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.10/usb-storage-add-no_ata_1x-quirk-for-longmai-usb-key.patch b/queue-5.10/usb-storage-add-no_ata_1x-quirk-for-longmai-usb-key.patch new file mode 100644 index 0000000000..d951cfb349 --- /dev/null +++ b/queue-5.10/usb-storage-add-no_ata_1x-quirk-for-longmai-usb-key.patch @@ -0,0 +1,58 @@ +From 3b4ca2e01c1dd8c00b675b794732945f460a471b Mon Sep 17 00:00:00 2001 +From: Huang Wei +Date: Thu, 16 Jul 2026 11:33:41 +0800 +Subject: USB: storage: add NO_ATA_1X quirk for Longmai USB Key + +From: Huang Wei + +commit 3b4ca2e01c1dd8c00b675b794732945f460a471b upstream. + +The Longmai Technologies USB Key (0x04b4:0xb708) advertises itself as a +SCSI/Bulk-only mass storage device but does not correctly handle ATA +pass-through commands. When such a command (ATA_12 or ATA_16) is sent to +the device it fails to respond and the transfer eventually times out, +leaving the device unusable. + +Add an unusual_devs entry for this device that sets the US_FL_NO_ATA_1X +flag, so usb-storage short-circuits ATA pass-through commands and returns +INVALID COMMAND OPERATION CODE (0x20 0x05 0x24 0x00) instead of forwarding +them to the device. + +Information about the device in /sys/kernel/debug/usb/devices: + +T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 12 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=00(>ifc ) Sub=06 Prot=50 MxPS=64 #Cfgs= 1 +P: Vendor=04b4 ProdID=b708 Rev= 1.00 +S: Manufacturer=Longmai Technologies +S: Product=USB Key +C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA +I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Reported-by: Ai Chao +Cc: stable +Signed-off-by: Huang Wei +Acked-by: Alan Stern +Link: https://patch.msgid.link/20260716033341.2830872-1-huangwei@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/storage/unusual_devs.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -395,6 +395,13 @@ UNUSUAL_DEV( 0x04b3, 0x4001, 0x0110, 0x + USB_SC_DEVICE, USB_PR_CB, NULL, + US_FL_MAX_SECTORS_MIN), + ++/* Reported by Ai Chao */ ++UNUSUAL_DEV( 0x04b4, 0xb708, 0x0000, 0xffff, ++ "Longmai Technologies", ++ "USB Key", ++ USB_SC_SCSI, USB_PR_BULK, NULL, ++ US_FL_NO_ATA_1X), ++ + /* + * Reported by Simon Levitt + * This entry needs Sub and Proto fields diff --git a/queue-5.10/wifi-at76c50x-usb-avoid-length-underflow-in-at76_guess_freq.patch b/queue-5.10/wifi-at76c50x-usb-avoid-length-underflow-in-at76_guess_freq.patch new file mode 100644 index 0000000000..4d69bd5b8b --- /dev/null +++ b/queue-5.10/wifi-at76c50x-usb-avoid-length-underflow-in-at76_guess_freq.patch @@ -0,0 +1,59 @@ +From 61a799ffd1e5a4fd3702d547828b7ff3d161468e Mon Sep 17 00:00:00 2001 +From: Huihui Huang +Date: Wed, 15 Jul 2026 22:08:10 +0800 +Subject: wifi: at76c50x-usb: avoid length underflow in at76_guess_freq() + +From: Huihui Huang + +commit 61a799ffd1e5a4fd3702d547828b7ff3d161468e upstream. + +at76_guess_freq() checks only that the received frame is at least a bare +802.11 header (24 bytes) before subtracting the fixed management-body +offset: + + len -= el_off; + +For both beacon and probe response frames, el_off is 36. If the frame is +shorter than el_off, subtracting it causes the calculated IE length to +wrap. The length is eventually passed to cfg80211_find_elem_match() as a +very large unsigned value, so the element walk runs beyond the RX skb. + +This path is reached from at76_rx_tasklet() while scanning. If the device +delivers a truncated beacon or probe response, the oversized IE length +causes an out-of-bounds read during scanning. + +Skip the IE lookup if the frame does not reach the variable elements, +before subtracting el_off. + +Fixes: 1264b951463a ("at76c50x-usb: add driver") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-8 +Signed-off-by: Huihui Huang +Link: https://patch.msgid.link/20260715140815.1242033-1-hhhuang@smu.edu.sg +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/atmel/at76c50x-usb.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/atmel/at76c50x-usb.c ++++ b/drivers/net/wireless/atmel/at76c50x-usb.c +@@ -1527,13 +1527,16 @@ static inline int at76_guess_freq(struct + + if (ieee80211_is_probe_resp(hdr->frame_control)) { + el_off = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); +- el = ((struct ieee80211_mgmt *)hdr)->u.probe_resp.variable; + } else if (ieee80211_is_beacon(hdr->frame_control)) { + el_off = offsetof(struct ieee80211_mgmt, u.beacon.variable); +- el = ((struct ieee80211_mgmt *)hdr)->u.beacon.variable; + } else { + goto exit; + } ++ ++ if (len < el_off) ++ goto exit; ++ ++ el = priv->rx_skb->data + el_off; + len -= el_off; + + el = cfg80211_find_ie(WLAN_EID_DS_PARAMS, el, len);