From: Greg Kroah-Hartman Date: Wed, 8 Apr 2026 07:05:09 +0000 (+0200) Subject: 5.10-stable patches X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e812a4925b3e6bfb0bd321a4fda1fcd4e4b060b4;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: net-ftgmac100-fix-ring-allocation-unwind-on-open-failure.patch thunderbolt-fix-property-read-in-nhi_wake_supported.patch usb-dummy-hcd-fix-locking-synchronization-error.patch usb-gadget-dummy_hcd-fix-premature-urb-completion-when-zlp-follows-partial-transfer.patch vxlan-validate-nd-option-lengths-in-vxlan_na_create.patch --- diff --git a/queue-5.10/net-ftgmac100-fix-ring-allocation-unwind-on-open-failure.patch b/queue-5.10/net-ftgmac100-fix-ring-allocation-unwind-on-open-failure.patch new file mode 100644 index 0000000000..5630ad990d --- /dev/null +++ b/queue-5.10/net-ftgmac100-fix-ring-allocation-unwind-on-open-failure.patch @@ -0,0 +1,83 @@ +From c0fd0fe745f5e8c568d898cd1513d0083e46204a Mon Sep 17 00:00:00 2001 +From: Yufan Chen +Date: Sun, 29 Mar 2026 00:32:57 +0800 +Subject: net: ftgmac100: fix ring allocation unwind on open failure + +From: Yufan Chen + +commit c0fd0fe745f5e8c568d898cd1513d0083e46204a upstream. + +ftgmac100_alloc_rings() allocates rx_skbs, tx_skbs, rxdes, txdes, and +rx_scratch in stages. On intermediate failures it returned -ENOMEM +directly, leaking resources allocated earlier in the function. + +Rework the failure path to use staged local unwind labels and free +allocated resources in reverse order before returning -ENOMEM. This +matches common netdev allocation cleanup style. + +Fixes: d72e01a0430f ("ftgmac100: Use a scratch buffer for failed RX allocations") +Cc: stable@vger.kernel.org +Signed-off-by: Yufan Chen +Link: https://patch.msgid.link/20260328163257.60836-1-yufan.chen@linux.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/faraday/ftgmac100.c | 28 ++++++++++++++++++++++++---- + 1 file changed, 24 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/faraday/ftgmac100.c ++++ b/drivers/net/ethernet/faraday/ftgmac100.c +@@ -931,19 +931,19 @@ static int ftgmac100_alloc_rings(struct + priv->tx_skbs = kcalloc(MAX_TX_QUEUE_ENTRIES, sizeof(void *), + GFP_KERNEL); + if (!priv->tx_skbs) +- return -ENOMEM; ++ goto err_free_rx_skbs; + + /* Allocate descriptors */ + priv->rxdes = dma_alloc_coherent(priv->dev, + MAX_RX_QUEUE_ENTRIES * sizeof(struct ftgmac100_rxdes), + &priv->rxdes_dma, GFP_KERNEL); + if (!priv->rxdes) +- return -ENOMEM; ++ goto err_free_tx_skbs; + priv->txdes = dma_alloc_coherent(priv->dev, + MAX_TX_QUEUE_ENTRIES * sizeof(struct ftgmac100_txdes), + &priv->txdes_dma, GFP_KERNEL); + if (!priv->txdes) +- return -ENOMEM; ++ goto err_free_rxdes; + + /* Allocate scratch packet buffer */ + priv->rx_scratch = dma_alloc_coherent(priv->dev, +@@ -951,9 +951,29 @@ static int ftgmac100_alloc_rings(struct + &priv->rx_scratch_dma, + GFP_KERNEL); + if (!priv->rx_scratch) +- return -ENOMEM; ++ goto err_free_txdes; + + return 0; ++ ++err_free_txdes: ++ dma_free_coherent(priv->dev, ++ MAX_TX_QUEUE_ENTRIES * ++ sizeof(struct ftgmac100_txdes), ++ priv->txdes, priv->txdes_dma); ++ priv->txdes = NULL; ++err_free_rxdes: ++ dma_free_coherent(priv->dev, ++ MAX_RX_QUEUE_ENTRIES * ++ sizeof(struct ftgmac100_rxdes), ++ priv->rxdes, priv->rxdes_dma); ++ priv->rxdes = NULL; ++err_free_tx_skbs: ++ kfree(priv->tx_skbs); ++ priv->tx_skbs = NULL; ++err_free_rx_skbs: ++ kfree(priv->rx_skbs); ++ priv->rx_skbs = NULL; ++ return -ENOMEM; + } + + static void ftgmac100_init_rings(struct ftgmac100 *priv) diff --git a/queue-5.10/series b/queue-5.10/series index bc367fa630..b55e1c9e8f 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -404,3 +404,8 @@ comedi-ni_atmio16d-fix-invalid-clean-up-after-failed-attach.patch comedi-me_daq-fix-potential-overrun-of-firmware-buffer.patch comedi-me4000-fix-potential-overrun-of-firmware-buffer.patch netfilter-ipset-drop-logically-empty-buckets-in-mtype_del.patch +vxlan-validate-nd-option-lengths-in-vxlan_na_create.patch +net-ftgmac100-fix-ring-allocation-unwind-on-open-failure.patch +thunderbolt-fix-property-read-in-nhi_wake_supported.patch +usb-dummy-hcd-fix-locking-synchronization-error.patch +usb-gadget-dummy_hcd-fix-premature-urb-completion-when-zlp-follows-partial-transfer.patch diff --git a/queue-5.10/thunderbolt-fix-property-read-in-nhi_wake_supported.patch b/queue-5.10/thunderbolt-fix-property-read-in-nhi_wake_supported.patch new file mode 100644 index 0000000000..ccd59ecbde --- /dev/null +++ b/queue-5.10/thunderbolt-fix-property-read-in-nhi_wake_supported.patch @@ -0,0 +1,37 @@ +From 73a505dc48144ec72e25874e2b2a72487b02d3bc Mon Sep 17 00:00:00 2001 +From: Konrad Dybcio +Date: Mon, 9 Mar 2026 10:39:49 +0100 +Subject: thunderbolt: Fix property read in nhi_wake_supported() + +From: Konrad Dybcio + +commit 73a505dc48144ec72e25874e2b2a72487b02d3bc upstream. + +device_property_read_foo() returns 0 on success and only then modifies +'val'. Currently, val is left uninitialized if the aforementioned +function returns non-zero, making nhi_wake_supported() return true +almost always (random != 0) if the property is not present in device +firmware. + +Invert the check to make it make sense. + +Fixes: 3cdb9446a117 ("thunderbolt: Add support for Intel Ice Lake") +Cc: stable@vger.kernel.org +Signed-off-by: Konrad Dybcio +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/nhi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/thunderbolt/nhi.c ++++ b/drivers/thunderbolt/nhi.c +@@ -899,7 +899,7 @@ static bool nhi_wake_supported(struct pc + * If power rails are sustainable for wakeup from S4 this + * property is set by the BIOS. + */ +- if (device_property_read_u8(&pdev->dev, "WAKE_SUPPORTED", &val)) ++ if (!device_property_read_u8(&pdev->dev, "WAKE_SUPPORTED", &val)) + return !!val; + + return true; diff --git a/queue-5.10/usb-dummy-hcd-fix-locking-synchronization-error.patch b/queue-5.10/usb-dummy-hcd-fix-locking-synchronization-error.patch new file mode 100644 index 0000000000..b01a3cc581 --- /dev/null +++ b/queue-5.10/usb-dummy-hcd-fix-locking-synchronization-error.patch @@ -0,0 +1,70 @@ +From 616a63ff495df12863692ab3f9f7b84e3fa7a66d Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Sun, 15 Mar 2026 14:30:43 -0400 +Subject: USB: dummy-hcd: Fix locking/synchronization error + +From: Alan Stern + +commit 616a63ff495df12863692ab3f9f7b84e3fa7a66d upstream. + +Syzbot testing was able to provoke an addressing exception and crash +in the usb_gadget_udc_reset() routine in +drivers/usb/gadgets/udc/core.c, resulting from the fact that the +routine was called with a second ("driver") argument of NULL. The bad +caller was set_link_state() in dummy_hcd.c, and the problem arose +because of a race between a USB reset and driver unbind. + +These sorts of races were not supposed to be possible; commit +7dbd8f4cabd9 ("USB: dummy-hcd: Fix erroneous synchronization change"), +along with a few followup commits, was written specifically to prevent +them. As it turns out, there are (at least) two errors remaining in +the code. Another patch will address the second error; this one is +concerned with the first. + +The error responsible for the syzbot crash occurred because the +stop_activity() routine will sometimes drop and then re-acquire the +dum->lock spinlock. A call to stop_activity() occurs in +set_link_state() when handling an emulated USB reset, after the test +of dum->ints_enabled and before the increment of dum->callback_usage. +This allowed another thread (doing a driver unbind) to sneak in and +grab the spinlock, and then clear dum->ints_enabled and dum->driver. +Normally this other thread would have to wait for dum->callback_usage +to go down to 0 before it would clear dum->driver, but in this case it +didn't have to wait since dum->callback_usage had not yet been +incremented. + +The fix is to increment dum->callback_usage _before_ calling +stop_activity() instead of after. Then the thread doing the unbind +will not clear dum->driver until after the call to +usb_gadget_udc_reset() safely returns and dum->callback_usage has been +decremented again. + +Signed-off-by: Alan Stern +Reported-by: syzbot+19bed92c97bee999e5db@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/linux-usb/68fc7c9c.050a0220.346f24.023c.GAE@google.com/ +Tested-by: syzbot+19bed92c97bee999e5db@syzkaller.appspotmail.com +Fixes: 7dbd8f4cabd9 ("USB: dummy-hcd: Fix erroneous synchronization change") +Cc: stable +Link: https://patch.msgid.link/46135f42-fdbe-46b5-aac0-6ca70492af15@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/dummy_hcd.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -458,8 +458,13 @@ static void set_link_state(struct dummy_ + + /* Report reset and disconnect events to the driver */ + if (dum->ints_enabled && (disconnect || reset)) { +- stop_activity(dum); + ++dum->callback_usage; ++ /* ++ * stop_activity() can drop dum->lock, so it must ++ * not come between the dum->ints_enabled test ++ * and the ++dum->callback_usage. ++ */ ++ stop_activity(dum); + spin_unlock(&dum->lock); + if (reset) + usb_gadget_udc_reset(&dum->gadget, dum->driver); diff --git a/queue-5.10/usb-gadget-dummy_hcd-fix-premature-urb-completion-when-zlp-follows-partial-transfer.patch b/queue-5.10/usb-gadget-dummy_hcd-fix-premature-urb-completion-when-zlp-follows-partial-transfer.patch new file mode 100644 index 0000000000..314cad5059 --- /dev/null +++ b/queue-5.10/usb-gadget-dummy_hcd-fix-premature-urb-completion-when-zlp-follows-partial-transfer.patch @@ -0,0 +1,70 @@ +From f50200dd44125e445a6164e88c217472fa79cdbc Mon Sep 17 00:00:00 2001 +From: Sebastian Urban +Date: Sun, 15 Mar 2026 16:10:45 +0100 +Subject: usb: gadget: dummy_hcd: fix premature URB completion when ZLP follows partial transfer + +From: Sebastian Urban + +commit f50200dd44125e445a6164e88c217472fa79cdbc upstream. + +When a gadget request is only partially transferred in transfer() +because the per-frame bandwidth budget is exhausted, the loop advances +to the next queued request. If that next request is a zero-length +packet (ZLP), len evaluates to zero and the code takes the +unlikely(len == 0) path, which sets is_short = 1. This bypasses the +bandwidth guard ("limit < ep->ep.maxpacket && limit < len") that +lives in the else branch and would otherwise break out of the loop for +non-zero requests. The is_short path then completes the URB before all +data from the first request has been transferred. + +Reproducer (bulk IN, high speed): + + Device side (FunctionFS with Linux AIO): + 1. Queue a 65024-byte write via io_submit (127 * 512, i.e. a + multiple of the HS bulk max packet size). + 2. Immediately queue a zero-length write (ZLP) via io_submit. + + Host side: + 3. Submit a 65536-byte bulk IN URB. + + Expected: URB completes with actual_length = 65024. + Actual: URB completes with actual_length = 53248, losing 11776 + bytes that leak into subsequent URBs. + +At high speed the per-frame budget is 53248 bytes (512 * 13 * 8). +The 65024-byte request exhausts this budget after 53248 bytes, leaving +the request incomplete (req->req.actual < req->req.length). Neither +the request nor the URB is finished, and rescan is 0, so the loop +advances to the ZLP. For the ZLP, dev_len = 0, so len = min(12288, 0) += 0, taking the unlikely(len == 0) path and setting is_short = 1. +The is_short handler then sets *status = 0, completing the URB with +only 53248 of the expected 65024 bytes. + +Fix this by breaking out of the loop when the current request has +remaining data (req->req.actual < req->req.length). The request +resumes on the next timer tick, preserving correct data ordering. + +Signed-off-by: Sebastian Urban +Cc: stable +Reviewed-by: Alan Stern +Link: https://patch.msgid.link/20260315151045.1155850-1-surban@surban.net +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/dummy_hcd.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -1521,6 +1521,12 @@ top: + /* rescan to continue with any other queued i/o */ + if (rescan) + goto top; ++ ++ /* request not fully transferred; stop iterating to ++ * preserve data ordering across queued requests. ++ */ ++ if (req->req.actual < req->req.length) ++ break; + } + return sent; + } diff --git a/queue-5.10/vxlan-validate-nd-option-lengths-in-vxlan_na_create.patch b/queue-5.10/vxlan-validate-nd-option-lengths-in-vxlan_na_create.patch new file mode 100644 index 0000000000..14bb335a83 --- /dev/null +++ b/queue-5.10/vxlan-validate-nd-option-lengths-in-vxlan_na_create.patch @@ -0,0 +1,54 @@ +From afa9a05e6c4971bd5586f1b304e14d61fb3d9385 Mon Sep 17 00:00:00 2001 +From: Yang Yang +Date: Thu, 26 Mar 2026 03:44:41 +0000 +Subject: vxlan: validate ND option lengths in vxlan_na_create + +From: Yang Yang + +commit afa9a05e6c4971bd5586f1b304e14d61fb3d9385 upstream. + +vxlan_na_create() walks ND options according to option-provided +lengths. A malformed option can make the parser advance beyond the +computed option span or use a too-short source LLADDR option payload. + +Validate option lengths against the remaining NS option area before +advancing, and only read source LLADDR when the option is large enough +for an Ethernet address. + +Fixes: 4b29dba9c085 ("vxlan: fix nonfunctional neigh_reduce()") +Cc: stable@vger.kernel.org +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Tested-by: Ao Zhou +Co-developed-by: Yuan Tan +Signed-off-by: Yuan Tan +Suggested-by: Xin Liu +Signed-off-by: Yang Yang +Reviewed-by: Ido Schimmel +Acked-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/20260326034441.2037420-4-n05ec@lzu.edu.cn +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/vxlan/vxlan_core.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -2098,12 +2098,14 @@ static struct sk_buff *vxlan_na_create(s + ns_olen = request->len - skb_network_offset(request) - + sizeof(struct ipv6hdr) - sizeof(*ns); + for (i = 0; i < ns_olen-1; i += (ns->opt[i+1]<<3)) { +- if (!ns->opt[i + 1]) { ++ if (!ns->opt[i + 1] || i + (ns->opt[i + 1] << 3) > ns_olen) { + kfree_skb(reply); + return NULL; + } + if (ns->opt[i] == ND_OPT_SOURCE_LL_ADDR) { +- daddr = ns->opt + i + sizeof(struct nd_opt_hdr); ++ if ((ns->opt[i + 1] << 3) >= ++ sizeof(struct nd_opt_hdr) + ETH_ALEN) ++ daddr = ns->opt + i + sizeof(struct nd_opt_hdr); + break; + } + }