[PATCH mptcp-net] mptcp: pm: cap userspace extra_subflows at U8_MAX

Quanye Yang via B4 Relay posted 1 patch 2 days, 13 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/multipath-tcp/mptcp_net-next tags/patchew/20260902-mptcp-pm-extra-subflows-v1-1-68540a866e5a@proton.me
net/mptcp/pm.c           |  6 ++++--
net/mptcp/pm_userspace.c | 20 +++++++++++++-------
2 files changed, 17 insertions(+), 9 deletions(-)
[PATCH mptcp-net] mptcp: pm: cap userspace extra_subflows at U8_MAX
Posted by Quanye Yang via B4 Relay 2 days, 13 hours ago
From: Quanye Yang <quanyeyang@proton.me>

The userspace PM increments extra_subflows with no upper bound. The
field is a u8, so the 256th extra subflow wraps the counter to 0 and
the next close hits WARN_ON_ONCE().

Refuse admission at U8_MAX for incoming MP_JOIN and for the Netlink
create path.

Fixes: 77e4b94a3de6 ("mptcp: update userspace pm infos")
Cc: stable@vger.kernel.org
Link: https://github.com/multipath-tcp/mptcp_net-next/issues/629
Signed-off-by: Quanye Yang <quanyeyang@proton.me>
---
 net/mptcp/pm.c           |  6 ++++--
 net/mptcp/pm_userspace.c | 20 +++++++++++++-------
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index b0b71adefb8f..d2ea0bd39a69 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -563,9 +563,11 @@ bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk)
 	if (mptcp_pm_is_userspace(msk)) {
 		if (mptcp_userspace_pm_active(msk)) {
 			spin_lock_bh(&pm->lock);
-			pm->extra_subflows++;
+			ret = pm->extra_subflows < U8_MAX;
+			if (ret)
+				pm->extra_subflows++;
 			spin_unlock_bh(&pm->lock);
-			return true;
+			return ret;
 		}
 		return false;
 	}
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index fab16d953dbf..6d798dd96702 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -427,16 +427,22 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
 	local.ifindex = entry.ifindex;
 
 	spin_lock_bh(&msk->pm.lock);
-	msk->pm.extra_subflows++;
-	spin_unlock_bh(&msk->pm.lock);
+	if (msk->pm.extra_subflows == U8_MAX) {
+		spin_unlock_bh(&msk->pm.lock);
+		GENL_SET_ERR_MSG(info, "too many extra subflows");
+		err = -ENOSPC;
+	} else {
+		msk->pm.extra_subflows++;
+		spin_unlock_bh(&msk->pm.lock);
 
-	lock_sock(sk);
-	err = __mptcp_subflow_connect(sk, &local, &addr_r);
-	release_sock(sk);
+		lock_sock(sk);
+		err = __mptcp_subflow_connect(sk, &local, &addr_r);
+		release_sock(sk);
+		if (err)
+			GENL_SET_ERR_MSG_FMT(info, "connect error: %d", err);
+	}
 
 	if (err) {
-		GENL_SET_ERR_MSG_FMT(info, "connect error: %d", err);
-
 		spin_lock_bh(&msk->pm.lock);
 		mptcp_userspace_pm_delete_local_addr(msk, &entry);
 		spin_unlock_bh(&msk->pm.lock);

---
base-commit: 9fbdf9ec14b806afdf66ea265477cb9d4790c866
change-id: 20260902-mptcp-pm-extra-subflows-dfaf79f1f198

Best regards,
--  
Quanye Yang <quanyeyang@proton.me>
Re: [PATCH mptcp-net] mptcp: pm: cap userspace extra_subflows at U8_MAX
Posted by MPTCP CI 2 days, 12 hours ago
Hi Quanye,

Thank you for your modifications, that's great!

Our CI did some validations and here is its report:

- KVM Validation: normal (except selftest_mptcp_join): Success! ✅
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Success! ✅
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Perf: 
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/33652679146

Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/6c23d697943d
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1156285


If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:

    $ cd [kernel source code]
    $ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
        --pull always mptcp/mptcp-upstream-virtme-docker:latest \
        auto-normal

For more details:

    https://github.com/multipath-tcp/mptcp-upstream-virtme-docker


Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)
Re: [PATCH mptcp-net] mptcp: pm: cap userspace extra_subflows at U8_MAX
Posted by Matthieu Baerts 2 days, 12 hours ago
Hi Quanye,

+ Cc: Tao Cui

On 02/09/2026 17:39, Quanye Yang via B4 Relay wrote:
> From: Quanye Yang <quanyeyang@proton.me>
> 
> The userspace PM increments extra_subflows with no upper bound. The
> field is a u8, so the 256th extra subflow wraps the counter to 0 and
> the next close hits WARN_ON_ONCE().
> 
> Refuse admission at U8_MAX for incoming MP_JOIN and for the Netlink
> create path.
> 
> Fixes: 77e4b94a3de6 ("mptcp: update userspace pm infos")
> Cc: stable@vger.kernel.org

(No need to add stable on patches sent to the MPTCP ML, that will be
added later when sending these patches to netdev)

> Link: https://github.com/multipath-tcp/mptcp_net-next/issues/629

"Closes:" can be used here.

(...)

> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index fab16d953dbf..6d798dd96702 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -427,16 +427,22 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
>  	local.ifindex = entry.ifindex;
>  
>  	spin_lock_bh(&msk->pm.lock);
> -	msk->pm.extra_subflows++;
> -	spin_unlock_bh(&msk->pm.lock);
> +	if (msk->pm.extra_subflows == U8_MAX) {
> +		spin_unlock_bh(&msk->pm.lock);
> +		GENL_SET_ERR_MSG(info, "too many extra subflows");
> +		err = -ENOSPC;

Maybe a goto could be used here ...

> +	} else {
> +		msk->pm.extra_subflows++;
> +		spin_unlock_bh(&msk->pm.lock);
>  
> -	lock_sock(sk);
> -	err = __mptcp_subflow_connect(sk, &local, &addr_r);
> -	release_sock(sk);
> +		lock_sock(sk);
> +		err = __mptcp_subflow_connect(sk, &local, &addr_r);
> +		release_sock(sk);
> +		if (err)
> +			GENL_SET_ERR_MSG_FMT(info, "connect error: %d", err);
> +	}
>  
>  	if (err) {
> -		GENL_SET_ERR_MSG_FMT(info, "connect error: %d", err);
> -

... to here, not to modify the rest of the code?
>  		spin_lock_bh(&msk->pm.lock);
>  		mptcp_userspace_pm_delete_local_addr(msk, &entry);
>  		spin_unlock_bh(&msk->pm.lock);

This part hasn't been fixed on Tao's series [1]. Would it be OK for both
of you if this part of Quanye's patch is added to Tao's v2 series with
Quanye as author?

[1] https://lore.kernel.org/20260831093206.689827-1-cui.tao@linux.dev

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.
Re: [PATCH mptcp-net] mptcp: pm: cap userspace extra_subflows at U8_MAX
Posted by Matthieu Baerts 2 days, 12 hours ago
Hi Quanye,

+cc Tao

On 02/09/2026 17:39, Quanye Yang via B4 Relay wrote:
> From: Quanye Yang <quanyeyang@proton.me>
> 
> The userspace PM increments extra_subflows with no upper bound. The
> field is a u8, so the 256th extra subflow wraps the counter to 0 and
> the next close hits WARN_ON_ONCE().
> 
> Refuse admission at U8_MAX for incoming MP_JOIN and for the Netlink
> create path.

Thank you for the patch. It looks like Tao already addresses the same
issues, see:

https://lore.kernel.org/20260831093206.689827-1-cui.tao@linux.dev

Do you mind syncing with him, please?

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.
Re: [PATCH mptcp-net] mptcp: pm: cap userspace extra_subflows at U8_MAX
Posted by sashiko-bot@kernel.org 2 days, 13 hours ago
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Error paths in mptcp_pm_nl_subflow_create_doit unconditionally delete pre-existing local addresses, corrupting state and underflowing local_addr_used.
--

commit 09af196be93604649e0aad5970acd8810bf5dcca
Author: Quanye Yang <quanyeyang@proton.me>

mptcp: pm: cap userspace extra_subflows at U8_MAX

The userspace PM increments extra_subflows with no upper bound. The
field is a u8, so the 256th extra subflow wraps the counter to 0 and
the next close hits WARN_ON_ONCE().

Link: https://github.com/multipath-tcp/mptcp_net-next/issues/629

> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index fab16d953dbfe..6d798dd967029 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -427,16 +427,22 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
>  	local.ifindex = entry.ifindex;
>  
>  	spin_lock_bh(&msk->pm.lock);
> -	msk->pm.extra_subflows++;
> -	spin_unlock_bh(&msk->pm.lock);
> +	if (msk->pm.extra_subflows == U8_MAX) {
> +		spin_unlock_bh(&msk->pm.lock);
> +		GENL_SET_ERR_MSG(info, "too many extra subflows");
> +		err = -ENOSPC;
> +	} else {
> +		msk->pm.extra_subflows++;
> +		spin_unlock_bh(&msk->pm.lock);
>  
> -	lock_sock(sk);
> -	err = __mptcp_subflow_connect(sk, &local, &addr_r);
> -	release_sock(sk);
> +		lock_sock(sk);
> +		err = __mptcp_subflow_connect(sk, &local, &addr_r);
> +		release_sock(sk);
> +		if (err)
> +			GENL_SET_ERR_MSG_FMT(info, "connect error: %d", err);
> +	}
>  
>  	if (err) {
> -		GENL_SET_ERR_MSG_FMT(info, "connect error: %d", err);
> -
>  		spin_lock_bh(&msk->pm.lock);
>  		mptcp_userspace_pm_delete_local_addr(msk, &entry);
>  		spin_unlock_bh(&msk->pm.lock);

[Severity: High]
This is a pre-existing issue, but does this error path incorrectly delete
pre-existing local addresses?

If a user issues MPTCP_PM_CMD_SUBFLOW_CREATE using a local address that was
already appended, mptcp_userspace_pm_append_new_local_addr() returns success
without allocating a new entry or incrementing local_addr_used.

However, if the new subflow connection fails (or if the newly introduced
extra_subflows == U8_MAX limit is hit), the error handling path blindly invokes
mptcp_userspace_pm_delete_local_addr(msk, &entry) inside 
mptcp_pm_nl_subflow_create_doit().

Will this inadvertently destroy pre-existing PM state for existing subflows
relying on that address, and underflow the 8-bit msk->pm.local_addr_used
counter since it wasn't incremented?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902-mptcp-pm-extra-subflows-v1-1-68540a866e5a@proton.me?part=1