From: Tao Cui Date: Tue, 2 Jun 2026 12:14:12 +0000 (+1000) Subject: mptcp: pm: fix extra_subflows underflow on userspace PM subflow creation X-Git-Tag: v6.12.94~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ede079218fd4dc06543b23fcf2bdfeaf95253ad9;p=thirdparty%2Fkernel%2Fstable.git mptcp: pm: fix extra_subflows underflow on userspace PM subflow creation commit 14e9fea30b68fc75b2b3d97396a7e6adb544bd2a upstream. The userspace PM increments extra_subflows after __mptcp_subflow_connect() succeeds, but __mptcp_subflow_connect() calls mptcp_pm_close_subflow() on failure to roll back the pre-increment done by the kernel PM's fill_*() helpers. Because the userspace PM hasn't incremented yet at that point, this decrement is spurious and causes extra_subflows to underflow. Fix it by aligning the userspace PM with the kernel PM: increment extra_subflows before calling __mptcp_subflow_connect(), so the existing error path in subflow.c correctly rolls it back on failure. Also simplify the error handling by taking pm.lock only when needed for cleanup. Fixes: 77e4b94a3de6 ("mptcp: update userspace pm infos") Cc: stable@vger.kernel.org Signed-off-by: Tao Cui Reviewed-by: Matthieu Baerts (NGI0) Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20260602-net-mptcp-misc-fixes-7-1-rc7-v2-5-856831229976@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index bb76295d04c56..bc3eb242f2980 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -402,16 +402,19 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info) local.flags = entry.flags; local.ifindex = entry.ifindex; + spin_lock_bh(&msk->pm.lock); + msk->pm.subflows++; + spin_unlock_bh(&msk->pm.lock); + lock_sock(sk); err = __mptcp_subflow_connect(sk, &local, &addr_r); release_sock(sk); - spin_lock_bh(&msk->pm.lock); - if (err) + if (err) { + spin_lock_bh(&msk->pm.lock); mptcp_userspace_pm_delete_local_addr(msk, &entry); - else - msk->pm.subflows++; - spin_unlock_bh(&msk->pm.lock); + spin_unlock_bh(&msk->pm.lock); + } create_err: sock_put(sk);