Skip to content

Commit 8143a22

Browse files
matttbegregkh
authored andcommitted
mptcp: pm: ADD_ADDR rtx: free sk if last
commit b7b9a46 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 25e3740 commit 8143a22

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;
@@ -340,22 +341,22 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
340341
add_timer);
341342
struct mptcp_sock *msk = entry->sock;
342343
struct sock *sk = (struct sock *)msk;
343-
unsigned int timeout;
344+
unsigned int timeout = 0;
344345

345346
pr_debug("msk=%p\n", msk);
346347

348+
bh_lock_sock(sk);
347349
if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE))
348-
goto exit;
350+
goto out;
349351

350-
bh_lock_sock(sk);
351352
if (sock_owned_by_user(sk)) {
352353
/* Try again later. */
353-
sk_reset_timer(sk, timer, jiffies + HZ / 20);
354+
timeout = HZ / 20;
354355
goto out;
355356
}
356357

357358
if (mptcp_pm_should_add_signal_addr(msk)) {
358-
sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
359+
timeout = TCP_RTO_MAX / 8;
359360
goto out;
360361
}
361362

@@ -373,18 +374,23 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
373374
}
374375

375376
if (entry->retrans_times < ADD_ADDR_RETRANS_MAX)
376-
sk_reset_timer(sk, timer,
377-
jiffies + (timeout << entry->retrans_times));
377+
timeout <<= entry->retrans_times;
378+
else
379+
timeout = 0;
378380

379381
spin_unlock_bh(&msk->pm.lock);
380382

381383
if (entry->retrans_times == ADD_ADDR_RETRANS_MAX)
382384
mptcp_pm_subflow_established(msk);
383385

384386
out:
387+
if (timeout)
388+
sk_reset_timer(sk, timer, jiffies + timeout);
389+
else
390+
/* if sock_put calls sk_free: avoid waiting for this timer */
391+
entry->timer_done = true;
385392
bh_unlock_sock(sk);
386-
exit:
387-
__sock_put(sk);
393+
sock_put(sk);
388394
}
389395

390396
struct mptcp_pm_add_entry *
@@ -447,6 +453,7 @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
447453

448454
timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0);
449455
reset_timer:
456+
add_entry->timer_done = false;
450457
timeout = mptcp_adjust_add_addr_timeout(msk);
451458
if (timeout)
452459
sk_reset_timer(sk, &add_entry->add_timer, jiffies + timeout);
@@ -467,7 +474,8 @@ static void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
467474
spin_unlock_bh(&msk->pm.lock);
468475

469476
list_for_each_entry_safe(entry, tmp, &free_list, list) {
470-
sk_stop_timer_sync(sk, &entry->add_timer);
477+
if (!entry->timer_done)
478+
sk_stop_timer_sync(sk, &entry->add_timer);
471479
kfree_rcu(entry, rcu);
472480
}
473481
}

0 commit comments

Comments
 (0)