Re: [PATCH mptcp-net v3] mptcp: pm: fix data race in add_addr timer callback
Matthieu Baerts <[email protected]> Wed, 22 Jul 2026 11:47:28 +0200
| Newsgroups | dev.linux.lists.mptcp |
|---|---|
| Organization | NGI0 Core |
| Message-ID | <[email protected]> |
Hi Qing, Thank you for the new version. On 22/07/2026 11:13, luoqing wrote: > From: Qing Luo <[email protected]> > > 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. Don't forget to reply to each question from previous reviews ;) How did you find the bug? Do you have a reproducer or is it by analysing the code? Were you assisted by a tool/LLM? If yes, please add the Assisted-by tag. > Use a local 'completed' flag set inside pm.lock when retrans_times > reaches ADD_ADDR_RETRANS_MAX. This ensures that > mptcp_pm_subflow_established() is only called when the retransmission > naturally exhausts. > > Fixes: 348d5c1dec60 ("mptcp: move to next addr when timeout") > Signed-off-by: Qing Luo <[email protected]> > --- > net/mptcp/pm.c | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) > > diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c > index 6afd39aea110..f93fefbb727e 100644 > --- a/net/mptcp/pm.c > +++ b/net/mptcp/pm.c > @@ -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 completed = false; > > pr_debug("msk=%p\n", msk); > > @@ -414,12 +415,14 @@ static void mptcp_pm_add_addr_timer(struct timer_list *timer) > > if (entry->retrans_times < ADD_ADDR_RETRANS_MAX) > timeout <<= entry->retrans_times; > - else > + else { > timeout = 0; > + completed = true; > + } Here, you still have the checkpatch warning Gang reported: CHECK: braces {} should be used on all arms of this statement To avoid all these modifications, I think it would be better to have: bool completed; (...) completed = entry->retrans_times >= ADD_ADDR_RETRANS_MAX; if (!completed) timeout <<= entry->retrans_times; else timeout = 0; Or maybe better with the opposite: bool retransmit; (...) retransmit = entry->retrans_times < ADD_ADDR_RETRANS_MAX; if (retransmit) timeout <<= entry->retrans_times; else timeout = 0; (...) if (!retransmit) mptcp_pm_subflow_established(msk); By doing that, you only need to modify the if conditions, not the "else" parts. > > spin_unlock_bh(&msk->pm.lock); > > - if (entry->retrans_times == ADD_ADDR_RETRANS_MAX) > + if (completed) > mptcp_pm_subflow_established(msk); > > out: Cheers, Matt -- Sponsored by the NGI0 Core fund.