[PATCH net 1/2] net: mptcp: take token lookup references with acquire ordering

From: Hang Nan

Date: Thu Nov 12 2026 - 07:54:36 EST


mptcp_token_get_sock() validates the token and the network namespace,
takes a reference on the socket and then validates them again. The
second validation only rejects a socket that is being torn down if it is
ordered after the reference acquisition: mptcp_token_destroy() unlinks
the socket and does WRITE_ONCE(msk->token, 0), so a reader that observes
the token before the acquisition can return a socket whose token has
already been cleared.

refcount_inc_not_zero() does not provide acquire ordering since the
refcount_t consolidation in fb041bb7c0a9, which removed the ordering
that the previous atomic_add_unless() based implementation gave. On
weakly ordered CPUs the loads of msk->token and sock_net(sk) can
therefore be reordered before the refcount increment, defeating the
re-validation.

The same pattern was fixed for the IPv4 and IPv6 established lookups,
inet_twsk_purge() and bpf_sk_assign() in 5b5d8f351dd9. The iterator
below has the same shape and is converted as well.

No behaviour change on strongly ordered architectures; this only
restores the ordering the second validation relies on.

Fixes: fb041bb7c0a9 ("locking/refcount: Consolidate implementations of refcount_t")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Hang Nan <2122295973@xxxxxx>
---
net/mptcp/token.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/mptcp/token.c b/net/mptcp/token.c
index e0f2823f92ef..3429b43a9f7c 100644
--- a/net/mptcp/token.c
+++ b/net/mptcp/token.c
@@ -309,7 +309,7 @@ struct mptcp_sock *mptcp_token_get_sock(struct net *net, u32 token)
!net_eq(sock_net(sk), net))
continue;

- if (!refcount_inc_not_zero(&sk->sk_refcnt))
+ if (!refcount_inc_not_zero_acquire(&sk->sk_refcnt))
goto not_found;

if (READ_ONCE(msk->token) != token ||
@@ -370,7 +370,7 @@ struct mptcp_sock *mptcp_token_iter_next(const struct net *net, long *s_slot,
if (num <= *s_num)
continue;

- if (!refcount_inc_not_zero(&sk->sk_refcnt))
+ if (!refcount_inc_not_zero_acquire(&sk->sk_refcnt))
continue;

if (!net_eq(sock_net(sk), net)) {
--
2.53.0