From: Greg Kroah-Hartman Date: Mon, 13 Apr 2026 11:55:45 +0000 (+0200) Subject: 6.6-stable patches X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d79eae7f153b355e902a7341cacffb6a6c70313d;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: mptcp-fix-soft-lockup-in-mptcp_recvmsg.patch netfilter-nft_set_pipapo-do-not-rely-on-zero_size_ptr.patch revert-drm-fix-use-after-free-on-framebuffers-and-property-blobs-when-calling-drm_dev_unplug.patch revert-mptcp-add-needs_id-for-netlink-appending-addr.patch seg6-separate-dst_cache-for-input-and-output-paths-in-seg6-lwtunnel.patch usb-gadget-f_hid-move-list-and-spinlock-inits-from-bind-to-alloc.patch virtio_net-clamp-rss_max_key_size-to-netdev_rss_key_len.patch --- diff --git a/queue-6.6/mptcp-fix-soft-lockup-in-mptcp_recvmsg.patch b/queue-6.6/mptcp-fix-soft-lockup-in-mptcp_recvmsg.patch new file mode 100644 index 0000000000..9afd58304d --- /dev/null +++ b/queue-6.6/mptcp-fix-soft-lockup-in-mptcp_recvmsg.patch @@ -0,0 +1,125 @@ +From matttbe@kernel.org Thu Apr 9 13:45:35 2026 +From: "Matthieu Baerts (NGI0)" +Date: Thu, 9 Apr 2026 13:45:26 +0200 +Subject: mptcp: fix soft lockup in mptcp_recvmsg() +To: stable@vger.kernel.org, gregkh@linuxfoundation.org, sashal@kernel.org +Cc: MPTCP Upstream , Li Xiasong , "Matthieu Baerts (NGI0)" , Jakub Kicinski +Message-ID: <20260409114525.1159899-2-matttbe@kernel.org> + +From: Li Xiasong + +commit 5dd8025a49c268ab6b94d978532af3ad341132a7 upstream. + +syzbot reported a soft lockup in mptcp_recvmsg() [0]. + +When receiving data with MSG_PEEK | MSG_WAITALL flags, the skb is not +removed from the sk_receive_queue. This causes sk_wait_data() to always +find available data and never perform actual waiting, leading to a soft +lockup. + +Fix this by adding a 'last' parameter to track the last peeked skb. +This allows sk_wait_data() to make informed waiting decisions and prevent +infinite loops when MSG_PEEK is used. + +[0]: +watchdog: BUG: soft lockup - CPU#2 stuck for 156s! [server:1963] +Modules linked in: +CPU: 2 UID: 0 PID: 1963 Comm: server Not tainted 6.19.0-rc8 #61 PREEMPT(none) +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 +RIP: 0010:sk_wait_data+0x15/0x190 +Code: 80 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 41 56 41 55 41 54 49 89 f4 55 48 89 d5 53 48 89 fb <48> 83 ec 30 65 48 8b 05 17 a4 6b 01 48 89 44 24 28 31 c0 65 48 8b +RSP: 0018:ffffc90000603ca0 EFLAGS: 00000246 +RAX: 0000000000000000 RBX: ffff888102bf0800 RCX: 0000000000000001 +RDX: 0000000000000000 RSI: ffffc90000603d18 RDI: ffff888102bf0800 +RBP: 0000000000000000 R08: 0000000000000002 R09: 0000000000000101 +R10: 0000000000000000 R11: 0000000000000075 R12: ffffc90000603d18 +R13: ffff888102bf0800 R14: ffff888102bf0800 R15: 0000000000000000 +FS: 00007f6e38b8c4c0(0000) GS:ffff8881b877e000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 000055aa7bff1680 CR3: 0000000105cbe000 CR4: 00000000000006f0 +Call Trace: + + mptcp_recvmsg+0x547/0x8c0 net/mptcp/protocol.c:2329 + inet_recvmsg+0x11f/0x130 net/ipv4/af_inet.c:891 + sock_recvmsg+0x94/0xc0 net/socket.c:1100 + __sys_recvfrom+0xb2/0x130 net/socket.c:2256 + __x64_sys_recvfrom+0x1f/0x30 net/socket.c:2267 + do_syscall_64+0x59/0x2d0 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x76/0x7e arch/x86/entry/entry_64.S:131 +RIP: 0033:0x7f6e386a4a1d +Code: 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 8d 05 f1 de 2c 00 41 89 ca 8b 00 85 c0 75 20 45 31 c9 45 31 c0 b8 2d 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 6b f3 c3 66 0f 1f 84 00 00 00 00 00 41 56 41 +RSP: 002b:00007ffc3c4bb078 EFLAGS: 00000246 ORIG_RAX: 000000000000002d +RAX: ffffffffffffffda RBX: 000000000000861e RCX: 00007f6e386a4a1d +RDX: 00000000000003ff RSI: 00007ffc3c4bb150 RDI: 0000000000000004 +RBP: 00007ffc3c4bb570 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000103 R11: 0000000000000246 R12: 00005605dbc00be0 +R13: 00007ffc3c4bb650 R14: 0000000000000000 R15: 0000000000000000 + + +Fixes: 8e04ce45a8db ("mptcp: fix MSG_PEEK stream corruption") +Signed-off-by: Li Xiasong +Reviewed-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260330120335.659027-1-lixiasong1@huawei.com +Signed-off-by: Jakub Kicinski +[ Conflicts in protocol.c, because commit bc68b0efa1bf ("mptcp: move the + whole rx path under msk socket lock protection") and commit + d88b2127b242 ("mptcp: add eat_recv_skb helper") (with some + dependences) are not in this version. These conflicts were in the + context, and not related to this fix. ] +Signed-off-by: Matthieu Baerts (NGI0) +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/protocol.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -1960,7 +1960,7 @@ static int __mptcp_recvmsg_mskq(struct m + struct msghdr *msg, + size_t len, int flags, int copied_total, + struct scm_timestamping_internal *tss, +- int *cmsg_flags) ++ int *cmsg_flags, struct sk_buff **last) + { + struct sk_buff *skb, *tmp; + int total_data_len = 0; +@@ -1976,6 +1976,7 @@ static int __mptcp_recvmsg_mskq(struct m + /* skip already peeked skbs */ + if (total_data_len + data_len <= copied_total) { + total_data_len += data_len; ++ *last = skb; + continue; + } + +@@ -2016,6 +2017,8 @@ static int __mptcp_recvmsg_mskq(struct m + WRITE_ONCE(msk->rmem_released, msk->rmem_released + skb->truesize); + __skb_unlink(skb, &msk->receive_queue); + __kfree_skb(skb); ++ } else { ++ *last = skb; + } + + if (copied >= len) +@@ -2237,10 +2240,12 @@ static int mptcp_recvmsg(struct sock *sk + cmsg_flags = MPTCP_CMSG_INQ; + + while (copied < len) { ++ struct sk_buff *last = NULL; + int err, bytes_read; + + bytes_read = __mptcp_recvmsg_mskq(msk, msg, len - copied, flags, +- copied, &tss, &cmsg_flags); ++ copied, &tss, &cmsg_flags, ++ &last); + if (unlikely(bytes_read < 0)) { + if (!copied) + copied = bytes_read; +@@ -2298,7 +2303,7 @@ static int mptcp_recvmsg(struct sock *sk + + pr_debug("block timeout %ld\n", timeo); + mptcp_cleanup_rbuf(msk, copied); +- err = sk_wait_data(sk, &timeo, NULL); ++ err = sk_wait_data(sk, &timeo, last); + if (err < 0) { + err = copied ? : err; + goto out_err; diff --git a/queue-6.6/netfilter-nft_set_pipapo-do-not-rely-on-zero_size_ptr.patch b/queue-6.6/netfilter-nft_set_pipapo-do-not-rely-on-zero_size_ptr.patch new file mode 100644 index 0000000000..6d40bb47a3 --- /dev/null +++ b/queue-6.6/netfilter-nft_set_pipapo-do-not-rely-on-zero_size_ptr.patch @@ -0,0 +1,72 @@ +From stable+bounces-235903-greg=kroah.com@vger.kernel.org Mon Apr 13 06:40:43 2026 +From: Keerthana K +Date: Mon, 13 Apr 2026 04:32:23 +0000 +Subject: netfilter: nft_set_pipapo: do not rely on ZERO_SIZE_PTR +To: stable@vger.kernel.org, gregkh@linuxfoundation.org +Cc: pablo@netfilter.org, kadlec@netfilter.org, fw@strlen.de, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, ajay.kaher@broadcom.com, alexey.makhalov@broadcom.com, vamsi-krishna.brahmajosyula@broadcom.com, yin.ding@broadcom.com, tapas.kundu@broadcom.com, Stefano Brivio , Mukul Sikka , Brennan Lamoreaux , Keerthana K +Message-ID: <20260413043223.3327827-1-keerthana.kalyanasundaram@broadcom.com> + +From: Florian Westphal + +commit 07ace0bbe03b3d8e85869af1dec5e4087b1d57b8 upstream + +pipapo relies on kmalloc(0) returning ZERO_SIZE_PTR (i.e., not NULL +but pointer is invalid). + +Rework this to not call slab allocator when we'd request a 0-byte +allocation. + +Reviewed-by: Stefano Brivio +Signed-off-by: Florian Westphal +Signed-off-by: Mukul Sikka +Signed-off-by: Brennan Lamoreaux +[Keerthana: In older stable branches (v6.6 and earlier), the allocation logic in +pipapo_clone() still relies on `src->rules` rather than `src->rules_alloc` +(introduced in v6.9 via 9f439bd6ef4f). Consequently, the previously +backported INT_MAX clamping check uses `src->rules`. This patch correctly +moves that `src->rules > (INT_MAX / ...)` check inside the new +`if (src->rules > 0)` block] +Signed-off-by: Keerthana K +Signed-off-by: Greg Kroah-Hartman +--- + net/netfilter/nft_set_pipapo.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +--- a/net/netfilter/nft_set_pipapo.c ++++ b/net/netfilter/nft_set_pipapo.c +@@ -525,6 +525,8 @@ static struct nft_pipapo_elem *pipapo_ge + int i; + + m = priv->clone; ++ if (m->bsize_max == 0) ++ return ret; + + res_map = kmalloc_array(m->bsize_max, sizeof(*res_map), GFP_ATOMIC); + if (!res_map) { +@@ -1394,14 +1396,20 @@ static struct nft_pipapo_match *pipapo_c + src->bsize * sizeof(*dst->lt) * + src->groups * NFT_PIPAPO_BUCKETS(src->bb)); + +- if (src->rules > (INT_MAX / sizeof(*src->mt))) +- goto out_mt; ++ if (src->rules > 0) { ++ if (src->rules > (INT_MAX / sizeof(*src->mt))) ++ goto out_mt; ++ ++ dst->mt = kvmalloc_array(src->rules, sizeof(*src->mt), ++ GFP_KERNEL); ++ if (!dst->mt) ++ goto out_mt; + +- dst->mt = kvmalloc(src->rules * sizeof(*src->mt), GFP_KERNEL_ACCOUNT); +- if (!dst->mt) +- goto out_mt; ++ memcpy(dst->mt, src->mt, src->rules * sizeof(*src->mt)); ++ } else { ++ dst->mt = NULL; ++ } + +- memcpy(dst->mt, src->mt, src->rules * sizeof(*src->mt)); + src++; + dst++; + } diff --git a/queue-6.6/revert-drm-fix-use-after-free-on-framebuffers-and-property-blobs-when-calling-drm_dev_unplug.patch b/queue-6.6/revert-drm-fix-use-after-free-on-framebuffers-and-property-blobs-when-calling-drm_dev_unplug.patch new file mode 100644 index 0000000000..a27af70946 --- /dev/null +++ b/queue-6.6/revert-drm-fix-use-after-free-on-framebuffers-and-property-blobs-when-calling-drm_dev_unplug.patch @@ -0,0 +1,178 @@ +From linux@leemhuis.info Mon Apr 13 10:06:33 2026 +From: Thorsten Leemhuis +Date: Mon, 13 Apr 2026 10:03:33 +0200 +Subject: Revert "drm: Fix use-after-free on framebuffers and property blobs when calling drm_dev_unplug" +To: regressions@leemhuis.info +Cc: dri-devel@lists.freedesktop.org, gregkh@linuxfoundation.org, matt.fagnani@bell.net, regressions@lists.linux.dev, sashal@kernel.org, stable@vger.kernel.org, "Maarten Lankhorst" , "Thomas Hellström" , "Guenter Roeck" , "Simona Vetter" , "Thorsten Leemhuis" +Message-ID: <20260413080333.3079490-1-linux@leemhuis.info> + +From: Maarten Lankhorst + +commit 45ebe43ea00d6b9f5b3e0db9c35b8ca2a96b7e70 upstream. + +This reverts commit 6bee098b91417654703e17eb5c1822c6dfd0c01d. + +Den 2026-03-25 kl. 22:11, skrev Simona Vetter: +> On Wed, Mar 25, 2026 at 10:26:40AM -0700, Guenter Roeck wrote: +>> Hi, +>> +>> On Fri, Mar 13, 2026 at 04:17:27PM +0100, Maarten Lankhorst wrote: +>>> When trying to do a rather aggressive test of igt's "xe_module_load +>>> --r reload" with a full desktop environment and game running I noticed +>>> a few OOPSes when dereferencing freed pointers, related to +>>> framebuffers and property blobs after the compositor exits. +>>> +>>> Solve this by guarding the freeing in drm_file with drm_dev_enter/exit, +>>> and immediately put the references from struct drm_file objects during +>>> drm_dev_unplug(). +>>> +>> +>> With this patch in v6.18.20, I get the warning backtraces below. +>> The backtraces are gone with the patch reverted. +> +> Yeah, this needs to be reverted, reasoning below. Maarten, can you please +> take care of that and feed the revert through the usual channels? I don't +> think it's critical enough that we need to fast-track this into drm.git +> directly. +> +> Quoting the patch here again: +> +>> drivers/gpu/drm/drm_file.c| 5 ++++- +>> drivers/gpu/drm/drm_mode_config.c | 9 ++++++--- +>> 2 files changed, 10 insertions(+), 4 deletions(-) +>> +>> diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c +>> index ec820686b3021..f52141f842a1f 100644 +>> --- a/drivers/gpu/drm/drm_file.c +>> +++ b/drivers/gpu/drm/drm_file.c +>> @@ -233,6 +233,7 @@ static void drm_events_release(struct drm_file *file_priv) +>> void drm_file_free(struct drm_file *file) +>> { +>> struct drm_device *dev; +>> +int idx; +>> +>> if (!file) +>> return; +>> @@ -249,9 +250,11 @@ void drm_file_free(struct drm_file *file) +>> +>> drm_events_release(file); +>> +>> -if (drm_core_check_feature(dev, DRIVER_MODESET)) { +>> +if (drm_core_check_feature(dev, DRIVER_MODESET) && +>> +drm_dev_enter(dev, &idx)) { +> +> This is misplaced for two reasons: +> +> - Even if we'd want to guarantee that we hold a drm_dev_enter/exit +> reference during framebuffer teardown, we'd need to do this +> _consistently over all callsites. Not ad-hoc in just one place that a +> testcase hits. This also means kerneldoc updates of the relevant hooks +> and at least a bunch of acks from other driver people to document the +> consensus. +> +> - More importantly, this is driver responsibilities in general unless we +> have extremely good reasons to the contrary. Which means this must be +> placed in xe. +> +>> drm_fb_release(file); +>> drm_property_destroy_user_blobs(dev, file); +>> +drm_dev_exit(idx); +>> } +>> +>> if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) +>> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c +>> index 84ae8a23a3678..e349418978f79 100644 +>> --- a/drivers/gpu/drm/drm_mode_config.c +>> +++ b/drivers/gpu/drm/drm_mode_config.c +>> @@ -583,10 +583,13 @@ void drm_mode_config_cleanup(struct drm_device *dev) +>> */ +>> WARN_ON(!list_empty(&dev->mode_config.fb_list)); +>> list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { +>> -struct drm_printer p = drm_dbg_printer(dev, DRM_UT_KMS, "[leaked fb]"); +>> +if (list_empty(&fb->filp_head) || drm_framebuffer_read_refcount(fb) > 1) { +>> +struct drm_printer p = drm_dbg_printer(dev, DRM_UT_KMS, "[leaked fb]"); +> +> This is also wrong: +> +> - Firstly, it's a completely independent bug, we do not smash two bugfixes +> into one patch. +> +> - Secondly, it's again a driver bug: drm_mode_cleanup must be called when +> the last drm_device reference disappears (hence the existence of +> drmm_mode_config_init), not when the driver gets unbound. The fact that +> this shows up in a callchain from a devres cleanup means the intel +> driver gets this wrong (like almost everyone else because historically +> we didn't know better). +> +> If we don't follow this rule, then we get races with this code here +> running concurrently with drm_file fb cleanups, which just does not +> work. Review pointed that out, but then shrugged it off with a confused +> explanation: +> +> https://lore.kernel.org/all/e61e64c796ccfb17ae673331a3df4b877bf42d82.camel@linux.intel.com/ +> +> Yes this also means a lot of the other drm_device teardown that drivers +> do happens way too early. There is a massive can of worms here of a +> magnitude that most likely is much, much bigger than what you can +> backport to stable kernels. Hotunplug is _hard_. + +Back to the drawing board, and fixing it in the intel display driver +instead. + +Cc: Thomas Hellström +Fixes: 6bee098b9141 ("drm: Fix use-after-free on framebuffers and property blobs when calling drm_dev_unplug") +Reported-by: Guenter Roeck +Tested-by: Guenter Roeck +Acked-by: Simona Vetter +Signed-off-by: Maarten Lankhorst +Link: https://patch.msgid.link/20260326082217.39941-2-dev@lankhorst.se +[ Thorsten: adjust to the v6.6.y/v6.6.y backports of 6bee098b9141 ] +Signed-off-by: Thorsten Leemhuis +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_file.c | 5 +---- + drivers/gpu/drm/drm_mode_config.c | 9 +++------ + 2 files changed, 4 insertions(+), 10 deletions(-) + +--- a/drivers/gpu/drm/drm_file.c ++++ b/drivers/gpu/drm/drm_file.c +@@ -243,7 +243,6 @@ static void drm_events_release(struct dr + void drm_file_free(struct drm_file *file) + { + struct drm_device *dev; +- int idx; + + if (!file) + return; +@@ -269,11 +268,9 @@ void drm_file_free(struct drm_file *file + + drm_events_release(file); + +- if (drm_core_check_feature(dev, DRIVER_MODESET) && +- drm_dev_enter(dev, &idx)) { ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { + drm_fb_release(file); + drm_property_destroy_user_blobs(dev, file); +- drm_dev_exit(idx); + } + + if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) +--- a/drivers/gpu/drm/drm_mode_config.c ++++ b/drivers/gpu/drm/drm_mode_config.c +@@ -546,13 +546,10 @@ void drm_mode_config_cleanup(struct drm_ + */ + WARN_ON(!list_empty(&dev->mode_config.fb_list)); + list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { +- if (list_empty(&fb->filp_head) || drm_framebuffer_read_refcount(fb) > 1) { +- struct drm_printer p = drm_debug_printer("[leaked fb]"); ++ struct drm_printer p = drm_debug_printer("[leaked fb]"); + +- drm_printf(&p, "framebuffer[%u]:\n", fb->base.id); +- drm_framebuffer_print_info(&p, 1, fb); +- } +- list_del_init(&fb->filp_head); ++ drm_printf(&p, "framebuffer[%u]:\n", fb->base.id); ++ drm_framebuffer_print_info(&p, 1, fb); + drm_framebuffer_free(&fb->base.refcount); + } + diff --git a/queue-6.6/revert-mptcp-add-needs_id-for-netlink-appending-addr.patch b/queue-6.6/revert-mptcp-add-needs_id-for-netlink-appending-addr.patch new file mode 100644 index 0000000000..2f86372ea6 --- /dev/null +++ b/queue-6.6/revert-mptcp-add-needs_id-for-netlink-appending-addr.patch @@ -0,0 +1,109 @@ +From stable+bounces-235832-greg=kroah.com@vger.kernel.org Sun Apr 12 18:58:10 2026 +From: Sasha Levin +Date: Sun, 12 Apr 2026 12:58:02 -0400 +Subject: Revert "mptcp: add needs_id for netlink appending addr" +To: stable@vger.kernel.org +Cc: "Matthieu Baerts (NGI0)" , Geliang Tang , Jakub Kicinski , Sasha Levin +Message-ID: <20260412165802.2349149-1-sashal@kernel.org> + +From: "Matthieu Baerts (NGI0)" + +[ Upstream commit 8e2760eaab778494fc1fa257031e0e1799647f46 ] + +This commit was originally adding the ability to add MPTCP endpoints +with ID 0 by accident. The in-kernel PM, handling MPTCP endpoints at the +net namespace level, is not supposed to handle endpoints with such ID, +because this ID 0 is reserved to the initial subflow, as mentioned in +the MPTCPv1 protocol [1], a per-connection setting. + +Note that 'ip mptcp endpoint add id 0' stops early with an error, but +other tools might still request the in-kernel PM to create MPTCP +endpoints with this restricted ID 0. + +In other words, it was wrong to call the mptcp_pm_has_addr_attr_id +helper to check whether the address ID attribute is set: if it was set +to 0, a new MPTCP endpoint would be created with ID 0, which is not +expected, and might cause various issues later. + +Fixes: 584f38942626 ("mptcp: add needs_id for netlink appending addr") +Cc: stable@vger.kernel.org +Link: https://datatracker.ietf.org/doc/html/rfc8684#section-3.2-9 [1] +Reviewed-by: Geliang Tang +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260407-net-mptcp-revert-pm-needs-id-v2-1-7a25cbc324f8@kernel.org +Signed-off-by: Jakub Kicinski +[ applied changes to net/mptcp/pm_netlink.c instead of renamed net/mptcp/pm_kernel.c ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/pm_netlink.c | 24 +++++------------------- + 1 file changed, 5 insertions(+), 19 deletions(-) + +--- a/net/mptcp/pm_netlink.c ++++ b/net/mptcp/pm_netlink.c +@@ -1079,7 +1079,7 @@ static void __mptcp_pm_release_addr_entr + + static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet, + struct mptcp_pm_addr_entry *entry, +- bool needs_id, bool replace) ++ bool replace) + { + struct mptcp_pm_addr_entry *cur, *del_entry = NULL; + unsigned int addr_max; +@@ -1138,7 +1138,7 @@ static int mptcp_pm_nl_append_new_local_ + } + } + +- if (!entry->addr.id && needs_id) { ++ if (!entry->addr.id) { + find_next: + entry->addr.id = find_next_zero_bit(pernet->id_bitmap, + MPTCP_PM_MAX_ADDR_ID + 1, +@@ -1149,7 +1149,7 @@ find_next: + } + } + +- if (!entry->addr.id && needs_id) ++ if (!entry->addr.id) + goto out; + + __set_bit(entry->addr.id, pernet->id_bitmap); +@@ -1282,7 +1282,7 @@ int mptcp_pm_nl_get_local_id(struct mptc + entry->ifindex = 0; + entry->flags = MPTCP_PM_ADDR_FLAG_IMPLICIT; + entry->lsk = NULL; +- ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true, false); ++ ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, false); + if (ret < 0) + kfree(entry); + +@@ -1524,18 +1524,6 @@ next: + return 0; + } + +-static bool mptcp_pm_has_addr_attr_id(const struct nlattr *attr, +- struct genl_info *info) +-{ +- struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1]; +- +- if (!nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr, +- mptcp_pm_addr_policy, info->extack) && +- tb[MPTCP_PM_ADDR_ATTR_ID]) +- return true; +- return false; +-} +- + static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info) + { + struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR]; +@@ -1577,9 +1565,7 @@ static int mptcp_nl_cmd_add_addr(struct + goto out_free; + } + } +- ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, +- !mptcp_pm_has_addr_attr_id(attr, info), +- true); ++ ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true); + if (ret < 0) { + GENL_SET_ERR_MSG_FMT(info, "too many addresses or duplicate one: %d", ret); + goto out_free; diff --git a/queue-6.6/seg6-separate-dst_cache-for-input-and-output-paths-in-seg6-lwtunnel.patch b/queue-6.6/seg6-separate-dst_cache-for-input-and-output-paths-in-seg6-lwtunnel.patch new file mode 100644 index 0000000000..cc366a7d91 --- /dev/null +++ b/queue-6.6/seg6-separate-dst_cache-for-input-and-output-paths-in-seg6-lwtunnel.patch @@ -0,0 +1,132 @@ +From stable+bounces-235833-greg=kroah.com@vger.kernel.org Sun Apr 12 18:58:57 2026 +From: Sasha Levin +Date: Sun, 12 Apr 2026 12:58:30 -0400 +Subject: seg6: separate dst_cache for input and output paths in seg6 lwtunnel +To: stable@vger.kernel.org +Cc: Andrea Mayer , Nicolas Dichtel , Justin Iurman , Jakub Kicinski , Sasha Levin +Message-ID: <20260412165830.2349698-1-sashal@kernel.org> + +From: Andrea Mayer + +[ Upstream commit c3812651b522fe8437ebb7063b75ddb95b571643 ] + +The seg6 lwtunnel uses a single dst_cache per encap route, shared +between seg6_input_core() and seg6_output_core(). These two paths +can perform the post-encap SID lookup in different routing contexts +(e.g., ip rules matching on the ingress interface, or VRF table +separation). Whichever path runs first populates the cache, and the +other reuses it blindly, bypassing its own lookup. + +Fix this by splitting the cache into cache_input and cache_output, +so each path maintains its own cached dst independently. + +Fixes: 6c8702c60b88 ("ipv6: sr: add support for SRH encapsulation and injection with lwtunnels") +Cc: stable@vger.kernel.org +Signed-off-by: Andrea Mayer +Reviewed-by: Nicolas Dichtel +Reviewed-by: Justin Iurman +Link: https://patch.msgid.link/20260404004405.4057-2-andrea.mayer@uniroma2.it +Signed-off-by: Jakub Kicinski +[ added missing dst reference loop guard in seg6_output_core() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/seg6_iptunnel.c | 41 ++++++++++++++++++++++++++++------------- + 1 file changed, 28 insertions(+), 13 deletions(-) + +--- a/net/ipv6/seg6_iptunnel.c ++++ b/net/ipv6/seg6_iptunnel.c +@@ -48,7 +48,8 @@ static size_t seg6_lwt_headroom(struct s + } + + struct seg6_lwt { +- struct dst_cache cache; ++ struct dst_cache cache_input; ++ struct dst_cache cache_output; + struct seg6_iptunnel_encap tuninfo[]; + }; + +@@ -486,7 +487,7 @@ static int seg6_input_core(struct net *n + slwt = seg6_lwt_lwtunnel(lwtst); + + local_bh_disable(); +- dst = dst_cache_get(&slwt->cache); ++ dst = dst_cache_get(&slwt->cache_input); + local_bh_enable(); + + err = seg6_do_srh(skb, dst); +@@ -500,7 +501,7 @@ static int seg6_input_core(struct net *n + /* cache only if we don't create a dst reference loop */ + if (!dst->error && lwtst != dst->lwtstate) { + local_bh_disable(); +- dst_cache_set_ip6(&slwt->cache, dst, ++ dst_cache_set_ip6(&slwt->cache_input, dst, + &ipv6_hdr(skb)->saddr); + local_bh_enable(); + } +@@ -560,7 +561,7 @@ static int seg6_output_core(struct net * + slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); + + local_bh_disable(); +- dst = dst_cache_get(&slwt->cache); ++ dst = dst_cache_get(&slwt->cache_output); + local_bh_enable(); + + err = seg6_do_srh(skb, dst); +@@ -585,9 +586,12 @@ static int seg6_output_core(struct net * + goto drop; + } + +- local_bh_disable(); +- dst_cache_set_ip6(&slwt->cache, dst, &fl6.saddr); +- local_bh_enable(); ++ /* cache only if we don't create a dst reference loop */ ++ if (orig_dst->lwtstate != dst->lwtstate) { ++ local_bh_disable(); ++ dst_cache_set_ip6(&slwt->cache_output, dst, &fl6.saddr); ++ local_bh_enable(); ++ } + + err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); + if (unlikely(err)) +@@ -694,11 +698,13 @@ static int seg6_build_state(struct net * + + slwt = seg6_lwt_lwtunnel(newts); + +- err = dst_cache_init(&slwt->cache, GFP_ATOMIC); +- if (err) { +- kfree(newts); +- return err; +- } ++ err = dst_cache_init(&slwt->cache_input, GFP_ATOMIC); ++ if (err) ++ goto err_free_newts; ++ ++ err = dst_cache_init(&slwt->cache_output, GFP_ATOMIC); ++ if (err) ++ goto err_destroy_input; + + memcpy(&slwt->tuninfo, tuninfo, tuninfo_len); + +@@ -713,11 +719,20 @@ static int seg6_build_state(struct net * + *ts = newts; + + return 0; ++ ++err_destroy_input: ++ dst_cache_destroy(&slwt->cache_input); ++err_free_newts: ++ kfree(newts); ++ return err; + } + + static void seg6_destroy_state(struct lwtunnel_state *lwt) + { +- dst_cache_destroy(&seg6_lwt_lwtunnel(lwt)->cache); ++ struct seg6_lwt *slwt = seg6_lwt_lwtunnel(lwt); ++ ++ dst_cache_destroy(&slwt->cache_input); ++ dst_cache_destroy(&slwt->cache_output); + } + + static int seg6_fill_encap_info(struct sk_buff *skb, diff --git a/queue-6.6/series b/queue-6.6/series index 63124c3228..5ddab8b86f 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -10,3 +10,10 @@ mips-mm-suppress-tlb-uniquification-on-ehinv-hardwar.patch mips-mm-rewrite-tlb-uniquification-for-the-hidden-bi.patch asoc-simple-card-utils-don-t-use-__free-device_node-.patch scsi-ufs-core-fix-use-after-free-in-init-error-and-r.patch +virtio_net-clamp-rss_max_key_size-to-netdev_rss_key_len.patch +mptcp-fix-soft-lockup-in-mptcp_recvmsg.patch +usb-gadget-f_hid-move-list-and-spinlock-inits-from-bind-to-alloc.patch +revert-mptcp-add-needs_id-for-netlink-appending-addr.patch +seg6-separate-dst_cache-for-input-and-output-paths-in-seg6-lwtunnel.patch +netfilter-nft_set_pipapo-do-not-rely-on-zero_size_ptr.patch +revert-drm-fix-use-after-free-on-framebuffers-and-property-blobs-when-calling-drm_dev_unplug.patch diff --git a/queue-6.6/usb-gadget-f_hid-move-list-and-spinlock-inits-from-bind-to-alloc.patch b/queue-6.6/usb-gadget-f_hid-move-list-and-spinlock-inits-from-bind-to-alloc.patch new file mode 100644 index 0000000000..88affd058f --- /dev/null +++ b/queue-6.6/usb-gadget-f_hid-move-list-and-spinlock-inits-from-bind-to-alloc.patch @@ -0,0 +1,72 @@ +From stable+bounces-235777-greg=kroah.com@vger.kernel.org Sun Apr 12 03:02:52 2026 +From: Sasha Levin +Date: Sat, 11 Apr 2026 21:02:47 -0400 +Subject: usb: gadget: f_hid: move list and spinlock inits from bind to alloc +To: stable@vger.kernel.org +Cc: Michael Zimmermann , stable , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20260412010247.1905349-1-sashal@kernel.org> + +From: Michael Zimmermann + +[ Upstream commit 4e0a88254ad59f6c53a34bf5fa241884ec09e8b2 ] + +There was an issue when you did the following: +- setup and bind an hid gadget +- open /dev/hidg0 +- use the resulting fd in EPOLL_CTL_ADD +- unbind the UDC +- bind the UDC +- use the fd in EPOLL_CTL_DEL + +When CONFIG_DEBUG_LIST was enabled, a list_del corruption was reported +within remove_wait_queue (via ep_remove_wait_queue). After some +debugging I found out that the queues, which f_hid registers via +poll_wait were the problem. These were initialized using +init_waitqueue_head inside hidg_bind. So effectively, the bind function +re-initialized the queues while there were still items in them. + +The solution is to move the initialization from hidg_bind to hidg_alloc +to extend their lifetimes to the lifetime of the function instance. + +Additionally, I found many other possibly problematic init calls in the +bind function, which I moved as well. + +Signed-off-by: Michael Zimmermann +Cc: stable +Link: https://patch.msgid.link/20260331184844.2388761-1-sigmaepsilon92@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_hid.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/usb/gadget/function/f_hid.c ++++ b/drivers/usb/gadget/function/f_hid.c +@@ -1000,13 +1000,8 @@ static int hidg_bind(struct usb_configur + if (status) + goto fail; + +- spin_lock_init(&hidg->write_spinlock); + hidg->write_pending = 1; + hidg->req = NULL; +- spin_lock_init(&hidg->read_spinlock); +- init_waitqueue_head(&hidg->write_queue); +- init_waitqueue_head(&hidg->read_queue); +- INIT_LIST_HEAD(&hidg->completed_out_req); + + /* create char device */ + cdev_init(&hidg->cdev, &f_hidg_fops); +@@ -1275,6 +1270,12 @@ static struct usb_function *hidg_alloc(s + + mutex_lock(&opts->lock); + ++ spin_lock_init(&hidg->write_spinlock); ++ spin_lock_init(&hidg->read_spinlock); ++ init_waitqueue_head(&hidg->write_queue); ++ init_waitqueue_head(&hidg->read_queue); ++ INIT_LIST_HEAD(&hidg->completed_out_req); ++ + device_initialize(&hidg->dev); + hidg->dev.release = hidg_release; + hidg->dev.class = &hidg_class; diff --git a/queue-6.6/virtio_net-clamp-rss_max_key_size-to-netdev_rss_key_len.patch b/queue-6.6/virtio_net-clamp-rss_max_key_size-to-netdev_rss_key_len.patch new file mode 100644 index 0000000000..ed90d50620 --- /dev/null +++ b/queue-6.6/virtio_net-clamp-rss_max_key_size-to-netdev_rss_key_len.patch @@ -0,0 +1,69 @@ +From stable+bounces-233908-greg=kroah.com@vger.kernel.org Wed Apr 8 15:44:31 2026 +From: Sasha Levin +Date: Wed, 8 Apr 2026 09:39:21 -0400 +Subject: virtio_net: clamp rss_max_key_size to NETDEV_RSS_KEY_LEN +To: stable@vger.kernel.org +Cc: Srujana Challa , "Michael S. Tsirkin" , Jakub Kicinski , Sasha Levin +Message-ID: <20260408133921.1094528-1-sashal@kernel.org> + +From: Srujana Challa + +[ Upstream commit b4e5f04c58a29c499faa85d12952ca9a4faf1cb9 ] + +rss_max_key_size in the virtio spec is the maximum key size supported by +the device, not a mandatory size the driver must use. Also the value 40 +is a spec minimum, not a spec maximum. + +The current code rejects RSS and can fail probe when the device reports a +larger rss_max_key_size than the driver buffer limit. Instead, clamp the +effective key length to min(device rss_max_key_size, NETDEV_RSS_KEY_LEN) +and keep RSS enabled. + +This keeps probe working on devices that advertise larger maximum key sizes +while respecting the netdev RSS key buffer size limit. + +Fixes: 3f7d9c1964fc ("virtio_net: Add hash_key_length check") +Cc: stable@vger.kernel.org +Signed-off-by: Srujana Challa +Acked-by: Michael S. Tsirkin +Link: https://patch.msgid.link/20260326142344.1171317-1-schalla@marvell.com +Signed-off-by: Jakub Kicinski +[ changed clamp target from NETDEV_RSS_KEY_LEN to VIRTIO_NET_RSS_MAX_KEY_SIZE ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/virtio_net.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -4465,6 +4465,7 @@ static int virtnet_probe(struct virtio_d + struct virtnet_info *vi; + u16 max_queue_pairs; + int mtu = 0; ++ u16 key_sz; + + /* Find if host supports multiqueue/rss virtio_net device */ + max_queue_pairs = 1; +@@ -4589,14 +4590,13 @@ static int virtnet_probe(struct virtio_d + } + + if (vi->has_rss || vi->has_rss_hash_report) { +- vi->rss_key_size = +- virtio_cread8(vdev, offsetof(struct virtio_net_config, rss_max_key_size)); +- if (vi->rss_key_size > VIRTIO_NET_RSS_MAX_KEY_SIZE) { +- dev_err(&vdev->dev, "rss_max_key_size=%u exceeds the limit %u.\n", +- vi->rss_key_size, VIRTIO_NET_RSS_MAX_KEY_SIZE); +- err = -EINVAL; +- goto free; +- } ++ key_sz = virtio_cread8(vdev, offsetof(struct virtio_net_config, rss_max_key_size)); ++ ++ vi->rss_key_size = min_t(u16, key_sz, VIRTIO_NET_RSS_MAX_KEY_SIZE); ++ if (key_sz > vi->rss_key_size) ++ dev_warn(&vdev->dev, ++ "rss_max_key_size=%u exceeds driver limit %u, clamping\n", ++ key_sz, vi->rss_key_size); + + vi->rss_hash_types_supported = + virtio_cread32(vdev, offsetof(struct virtio_net_config, supported_hash_types));