summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTao Cui <cuitao@kylinos.cn>2026-06-16 12:18:46 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-04 13:41:32 +0200
commit42da6ee329613c253f8bc7c74aba6338bd7ca6c7 (patch)
treeaa992515e30c97d4dd4c9c2c191d3f5a5fd76860
parenta1f18ce9b26e2bcabed8d78772e724f907090988 (diff)
downloadlinux-42da6ee329613c253f8bc7c74aba6338bd7ca6c7.tar.gz
linux-42da6ee329613c253f8bc7c74aba6338bd7ca6c7.zip
mptcp: pm: fix extra_subflows underflow on userspace PM subflow creation
[ Upstream commit 14e9fea30b68fc75b2b3d97396a7e6adb544bd2a ] 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 <cuitao@kylinos.cn> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260602-net-mptcp-misc-fixes-7-1-rc7-v2-5-856831229976@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/mptcp/pm_userspace.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 9016f8900c19..5260a34a617e 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -410,18 +410,21 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info)
goto create_err;
}
+ spin_lock_bh(&msk->pm.lock);
+ msk->pm.subflows++;
+ spin_unlock_bh(&msk->pm.lock);
+
lock_sock(sk);
err = __mptcp_subflow_connect(sk, &addr_l, &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, &local);
- else
- msk->pm.subflows++;
- spin_unlock_bh(&msk->pm.lock);
+ spin_unlock_bh(&msk->pm.lock);
+ }
create_err:
sock_put((struct sock *)msk);