Skip to contentSkip to conversation

FAILED: patch "[PATCH] mptcp: pm: fix data race in add_addr timer callback" failed to apply to 6.6-stable tree

PATCH New [email protected] 2 participants 2 messages Aug 20 – Aug 24

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 6.6-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.6.y
git checkout FETCH_HEAD
git cherry-pick -x a7aad5b69d3bdaec20a3ed9284e184502450c0cd
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026082025-multitask-unfazed-269a@gregkh' --subject-prefix 'PATCH 6.6.y' 'HEAD^..'

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From a7aad5b69d3bdaec20a3ed9284e184502450c0cd Mon Sep 17 00:00:00 2001
From: Qing Luo <[email protected]>
Date: Mon, 3 Aug 2026 18:16:36 +0200
Subject: [PATCH] mptcp: pm: fix data race in add_addr timer callback

The timer callback reads entry->retrans_times outside pm.lock to decide whether to call mptcp_pm_subflow_established(). Since mptcp_pm_announced_del_timer() can concurrently set retrans_times = ADD_ADDR_RETRANS_MAX under pm.lock, a race condition exists.

I discovered this issue while studying the code. AI tools helped me to verify the issue can potentially happen under race conditions.

Use a local 'retransmit' flag set inside pm.lock to capture whether retransmission is still possible when the lock is taken. This allows to call mptcp_pm_subflow_established() accordingly, and not depending on the situation that can be different when checked outside the pm.lock.

net/mptcp/pm.c +4 -2
index 6afd39aea110..c71dcf887683 100644
@@ -380,6 +380,7 @@ static void mptcp_pm_add_addr_timer(struct timer_list *timer)
 	struct mptcp_sock *msk = entry->sock;
 	struct sock *sk = (struct sock *)msk;
 	unsigned int timeout = 0;
+	bool retransmit;
 
 	pr_debug("msk=%p\n", msk);
 
@@ -412,14 +413,15 @@ static void mptcp_pm_add_addr_timer(struct timer_list *timer)
 		entry->retrans_times++;
 	}
 
-	if (entry->retrans_times < ADD_ADDR_RETRANS_MAX)
+	retransmit = entry->retrans_times < ADD_ADDR_RETRANS_MAX;
+	if (retransmit)
 		timeout <<= entry->retrans_times;
 	else
 		timeout = 0;
 
 	spin_unlock_bh(&msk->pm.lock);
 
-	if (entry->retrans_times == ADD_ADDR_RETRANS_MAX)
+	if (!retransmit)
 		mptcp_pm_subflow_established(msk);
 
 out:
maintainer
#1 lore raw

PATCH 1/1 mptcp: pm: fix data race in add_addr timer callback

From: Qing Luo <[email protected]>

[ Upstream commit a7aad5b69d3bdaec20a3ed9284e184502450c0cd ]

The timer callback reads entry->retrans_times outside pm.lock to decide whether to call mptcp_pm_subflow_established(). Since mptcp_pm_announced_del_timer() can concurrently set retrans_times = ADD_ADDR_RETRANS_MAX under pm.lock, a race condition exists.

I discovered this issue while studying the code. AI tools helped me to verify the issue can potentially happen under race conditions.

Use a local 'retransmit' flag set inside pm.lock to capture whether retransmission is still possible when the lock is taken. This allows to call mptcp_pm_subflow_established() accordingly, and not depending on the situation that can be different when checked outside the pm.lock.

Fixes 348d5c1dec60 ("mptcp: move to next addr when timeout")
[ applied to mptcp_pm_add_timer() in pm_netlink.c instead of pm.c and collapsed the adaptive backoff branch to `if (!retransmit) timeout = 0;` since the tree lacks exponential ADD_ADDR retransmission timeouts ]
---
 net/mptcp/pm_netlink.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
net/mptcp/pm_netlink.c +4 -2
index 242011de052a8..6ae37d017d893 100644
@@ -297,6 +297,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
 	struct mptcp_sock *msk = entry->sock;
 	struct sock *sk = (struct sock *)msk;
 	unsigned int timeout = 0;
+	bool retransmit;
 
 	pr_debug("msk=%p\n", msk);
 
@@ -334,12 +335,13 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
 		entry->retrans_times++;
 	}
 
-	if (entry->retrans_times >= ADD_ADDR_RETRANS_MAX)
+	retransmit = entry->retrans_times < ADD_ADDR_RETRANS_MAX;
+	if (!retransmit)
 		timeout = 0;
 
 	spin_unlock_bh(&msk->pm.lock);
 
-	if (entry->retrans_times == ADD_ADDR_RETRANS_MAX)
+	if (!retransmit)
 		mptcp_pm_subflow_established(msk);
 
 out:
Signature · 1 line
2.53.0