FAILED: patch "[PATCH] mptcp: pm: userspace: fix address ID overflow" failed to apply to 6.12-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x f9f0068e8813d8c10d016b030fc3a320d0b6767c
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026091626-embassy-overhead-d482@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f9f0068e8813d8c10d016b030fc3a320d0b6767c Mon Sep 17 00:00:00 2001
From: Qing Luo <[email protected]>
Date: Tue, 8 Sep 2026 16:07:13 +0200
Subject: [PATCH] mptcp: pm: userspace: fix address ID overflow
When all MPTCP address IDs (1-255) are exhausted in the userspace PM, find_next_zero_bit() returns MPTCP_PM_MAX_ADDR_ID + 1 (256). This value overflows when stored in the u8 field e->addr.id, resulting in ID 0 being stored and the entry being incorrectly added to the list.
ID 0 is reserved for the initial connection in MPTCP, so this overflow can cause address conflicts.
Note: the in-kernel PM already has an 'endpoints == MPTCP_PM_MAX_ADDR_ID' check in mptcp_pm_nl_append_new_local_addr() that returns -ERANGE before reaching find_next_zero_bit(), preventing this overflow. So this fix only addresses the userspace PM path.
Check the find_next_zero_bit() result against MPTCP_PM_MAX_ADDR_ID and return -ENOSPC if all IDs are truly exhausted. Move the ID allocation check before the memory allocation so that the error path does not need to free the allocated entry.
net/mptcp/pm_userspace.c +14 -4
@@ -69,6 +69,19 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, }if (!addr_match && !id_match) { +unsigned int id; + +if (!entry->addr.id && needs_id) { + id =find_next_zero_bit (id_bitmap, +MPTCP_PM_MAX_ADDR_ID +1 ,1 ); +if (id >MPTCP_PM_MAX_ADDR_ID ) { + ret = -ENOSPC ; + goto append_err; + } + }else { + id = entry->addr.id; + } +/* Memory for the entry is allocated from the * sock option buffer. */
@@ -78,10 +91,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, goto append_err; } -if (!e->addr.id && needs_id) - e->addr.id =find_next_zero_bit (id_bitmap, -MPTCP_PM_MAX_ADDR_ID +1 , -1 ); + e->addr.id = id;list_add_tail_rcu (&e->list, &msk->pm.userspace_pm_local_addr_list); msk->pm.local_addr_used++; ret = e->addr.id;
Sasha Levin
maintainerPATCH 1/4 mptcp: pm: drop match in userspace_pm_append_new_local_addr
From: Geliang Tang <[email protected]>
[ Upstream commit 640e3d69d0bc70d7d3de34800a1640793262bd08 ]
The variable 'match' in mptcp_userspace_pm_append_new_local_addr() is a redundant one, and this patch drops it.
No need to define 'match' as 'struct mptcp_pm_addr_entry *' type. In this function, it's only used to check whether it's NULL. It can be defined as a Boolean one.
Also other variables 'addr_match' and 'id_match' make 'match' a redundant one, which can be replaced by directly checking 'addr_match && id_match'.
Stable-dep-of: f9f0068e8813 ("mptcp: pm: userspace: fix address ID overflow")
--- net/mptcp/pm_userspace.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
net/mptcp/pm_userspace.c +3 -8
@@ -41,7 +41,6 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, bool needs_id) {DECLARE_BITMAP (id_bitmap,MPTCP_PM_MAX_ADDR_ID +1 ); -struct mptcp_pm_addr_entry *match =NULL ;struct sock *sk = (struct sock *)msk;struct mptcp_pm_addr_entry *e;bool addr_match = false;
@@ -60,16 +59,12 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,if (addr_match && entry->addr.id ==0 && needs_id) entry->addr.id = e->addr.id; id_match = (e->addr.id == entry->addr.id); -if (addr_match && id_match) { - match = e; +if (addr_match || id_match)break ; - }else if (addr_match || id_match) { -break ; - }__set_bit (e->addr.id, id_bitmap); } -if (!match && !addr_match && !id_match) { +if (!addr_match && !id_match) {/* Memory for the entry is allocated from the * sock option buffer. */
@@ -87,7 +82,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,list_add_tail_rcu (&e->list, &msk->pm.userspace_pm_local_addr_list); msk->pm.local_addr_used++; ret = e->addr.id; - }else if (match) { + }else if (addr_match && id_match) { ret = entry->addr.id; }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/4 sock: add sock_kmemdup helper
From: Geliang Tang <[email protected]>
[ Upstream commit 456cc675b6d4cadd4872a477d8976ff56eef4b6f ]
This patch adds the sock version of kmemdup() helper, named sock_kmemdup(), to duplicate the input "src" memory block using the socket's option memory buffer.
Stable-dep-of: f9f0068e8813 ("mptcp: pm: userspace: fix address ID overflow")
--- include/net/sock.h | 2 ++ net/core/sock.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+)
include/net/sock.h +2 -0
@@ -1840,6 +1840,8 @@ static inline struct sk_buff *sock_alloc_send_skb(struct sock *sk, }void *sock_kmalloc (struct sock *sk,int size,gfp_t priority); +void *sock_kmemdup (struct sock *sk,const void *src, +int size,gfp_t priority);void sock_kfree_s (struct sock *sk,void *mem,int size);void sock_kzfree_s (struct sock *sk,void *mem,int size);void sk_send_sigurg (struct sock *sk);
net/core/sock.c +16 -0
@@ -2837,6 +2837,22 @@ void *sock_kmalloc(struct sock *sk, int size, gfp_t priority) }EXPORT_SYMBOL (sock_kmalloc); +/* +* Duplicate the input "src" memory block using the socket's +* option memory buffer. +*/ +void *sock_kmemdup (struct sock *sk,const void *src, +int size,gfp_t priority) +{ +void *mem; + + mem =sock_kmalloc (sk, size, priority); +if (mem) +memcpy (mem, src, size); +return mem; +} +EXPORT_SYMBOL (sock_kmemdup); +/* Free an option memory block. Note, we actually want the inline * here as this allows gcc to detect the nullify and fold away the * condition entirely.
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/4 mptcp: use sock_kmemdup for address entry
In reply to Sasha LevinFrom: Geliang Tang <[email protected]>
[ Upstream commit 52f83c0b5f857dbe24f66fc9a7f035523e9ffbc9 ]
Instead of using sock_kmalloc() to allocate an address entry "e" and then immediately duplicate the input "entry" to it, the newly added sock_kmemdup() helper can be used in mptcp_userspace_pm_append_new_local_addr() to simplify the code.
More importantly, the code "*e = *entry;" that assigns "entry" to "e" is not easy to implemented in BPF if we use the same code to implement an append_new_local_addr() helper of a BFP path manager. This patch avoids this type of memory assignment operation.
Stable-dep-of: f9f0068e8813 ("mptcp: pm: userspace: fix address ID overflow")
--- net/mptcp/pm_userspace.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
net/mptcp/pm_userspace.c +1 -2
@@ -68,13 +68,12 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,/* Memory for the entry is allocated from the * sock option buffer. */ - e =sock_kmalloc (sk,sizeof (*e),GFP_ATOMIC ); + e =sock_kmemdup (sk, entry,sizeof (*entry),GFP_ATOMIC );if (!e) { ret = -ENOMEM ; goto append_err; } - *e = *entry;if (!e->addr.id && needs_id) e->addr.id = find_next_zero_bit(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1,
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 4/4 mptcp: pm: userspace: fix address ID overflow
In reply to Sasha LevinFrom: Qing Luo <[email protected]>
[ Upstream commit f9f0068e8813d8c10d016b030fc3a320d0b6767c ]
When all MPTCP address IDs (1-255) are exhausted in the userspace PM, find_next_zero_bit() returns MPTCP_PM_MAX_ADDR_ID + 1 (256). This value overflows when stored in the u8 field e->addr.id, resulting in ID 0 being stored and the entry being incorrectly added to the list.
ID 0 is reserved for the initial connection in MPTCP, so this overflow can cause address conflicts.
Note: the in-kernel PM already has an 'endpoints == MPTCP_PM_MAX_ADDR_ID' check in mptcp_pm_nl_append_new_local_addr() that returns -ERANGE before reaching find_next_zero_bit(), preventing this overflow. So this fix only addresses the userspace PM path.
Check the find_next_zero_bit() result against MPTCP_PM_MAX_ADDR_ID and return -ENOSPC if all IDs are truly exhausted. Move the ID allocation check before the memory allocation so that the error path does not need to free the allocated entry.
--- net/mptcp/pm_userspace.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
net/mptcp/pm_userspace.c +14 -4
@@ -65,6 +65,19 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, }if (!addr_match && !id_match) { +unsigned int id; + +if (!entry->addr.id && needs_id) { + id =find_next_zero_bit (id_bitmap, +MPTCP_PM_MAX_ADDR_ID +1 ,1 ); +if (id >MPTCP_PM_MAX_ADDR_ID ) { + ret = -ENOSPC ; + goto append_err; + } + }else { + id = entry->addr.id; + } +/* Memory for the entry is allocated from the * sock option buffer. */
@@ -74,10 +87,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, goto append_err; } -if (!e->addr.id && needs_id) - e->addr.id =find_next_zero_bit (id_bitmap, -MPTCP_PM_MAX_ADDR_ID +1 , -1 ); + e->addr.id = id;list_add_tail_rcu (&e->list, &msk->pm.userspace_pm_local_addr_list); msk->pm.local_addr_used++; ret = e->addr.id;
Signature · 1 line
2.53.0