Skip to content

Commit b7b9a46

Browse files
matttbekuba-moo
authored andcommitted
mptcp: pm: ADD_ADDR rtx: free sk if last
When an ADD_ADDR is retransmitted, the sk is held in sk_reset_timer(), and released at the end. If at that moment, it was the last reference being held, the sk would not be freed. sock_put() should then be called instead of __sock_put(). But that's not enough: if it is the last reference, sock_put() will call sk_free(), which will end up calling sk_stop_timer_sync() on the same timer, and waiting indefinitely to finish. So it is needed to mark that the timer is done at the end of the timer handler when it has not been rescheduled, not to call sk_stop_timer_sync() on "itself". Fixes: 00cfd77 ("mptcp: retransmit ADD_ADDR when timeout") Cc: stable@vger.kernel.org Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260505-net-mptcp-pm-fixes-7-1-rc3-v1-5-fca8091060a4@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 9634cb3 commit b7b9a46

1 file changed

Lines changed: 18 additions & 10 deletions

File tree

net/mptcp/pm.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct mptcp_pm_add_entry {
1616
struct list_head list;
1717
struct mptcp_addr_info addr;
1818
u8 retrans_times;
19+
bool timer_done;
1920
struct timer_list add_timer;
2021
struct mptcp_sock *sock;
2122
struct rcu_head rcu;
@@ -327,22 +328,22 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
327328
add_timer);
328329
struct mptcp_sock *msk = entry->sock;
329330
struct sock *sk = (struct sock *)msk;
330-
unsigned int timeout;
331+
unsigned int timeout = 0;
331332

332333
pr_debug("msk=%p\n", msk);
333334

335+
bh_lock_sock(sk);
334336
if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE))
335-
goto exit;
337+
goto out;
336338

337-
bh_lock_sock(sk);
338339
if (sock_owned_by_user(sk)) {
339340
/* Try again later. */
340-
sk_reset_timer(sk, timer, jiffies + HZ / 20);
341+
timeout = HZ / 20;
341342
goto out;
342343
}
343344

344345
if (mptcp_pm_should_add_signal_addr(msk)) {
345-
sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
346+
timeout = TCP_RTO_MAX / 8;
346347
goto out;
347348
}
348349

@@ -360,18 +361,23 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
360361
}
361362

362363
if (entry->retrans_times < ADD_ADDR_RETRANS_MAX)
363-
sk_reset_timer(sk, timer,
364-
jiffies + (timeout << entry->retrans_times));
364+
timeout <<= entry->retrans_times;
365+
else
366+
timeout = 0;
365367

366368
spin_unlock_bh(&msk->pm.lock);
367369

368370
if (entry->retrans_times == ADD_ADDR_RETRANS_MAX)
369371
mptcp_pm_subflow_established(msk);
370372

371373
out:
374+
if (timeout)
375+
sk_reset_timer(sk, timer, jiffies + timeout);
376+
else
377+
/* if sock_put calls sk_free: avoid waiting for this timer */
378+
entry->timer_done = true;
372379
bh_unlock_sock(sk);
373-
exit:
374-
__sock_put(sk);
380+
sock_put(sk);
375381
}
376382

377383
struct mptcp_pm_add_entry *
@@ -434,6 +440,7 @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
434440

435441
timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0);
436442
reset_timer:
443+
add_entry->timer_done = false;
437444
timeout = mptcp_adjust_add_addr_timeout(msk);
438445
if (timeout)
439446
sk_reset_timer(sk, &add_entry->add_timer, jiffies + timeout);
@@ -454,7 +461,8 @@ static void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
454461
spin_unlock_bh(&msk->pm.lock);
455462

456463
list_for_each_entry_safe(entry, tmp, &free_list, list) {
457-
sk_stop_timer_sync(sk, &entry->add_timer);
464+
if (!entry->timer_done)
465+
sk_stop_timer_sync(sk, &entry->add_timer);
458466
kfree_rcu(entry, rcu);
459467
}
460468
}

0 commit comments

Comments
 (0)