]> git.itanic.dy.fi Git - linux-stable/commit
tcp: Fix NEW_SYN_RECV handling in inet_twsk_purge()
authorEric Dumazet <edumazet@google.com>
Fri, 8 Mar 2024 20:01:21 +0000 (12:01 -0800)
committerJakub Kicinski <kuba@kernel.org>
Wed, 13 Mar 2024 01:56:15 +0000 (18:56 -0700)
commit1c4e97dd2d3c9a3e84f7e26346aa39bc426d3249
tree7db511ba3a514c959aba113623175e8b39fe616c
parent9187210eee7d87eea37b45ea93454a88681894a4
tcp: Fix NEW_SYN_RECV handling in inet_twsk_purge()

inet_twsk_purge() uses rcu to find TIME_WAIT and NEW_SYN_RECV
objects to purge.

These objects use SLAB_TYPESAFE_BY_RCU semantic and need special
care. We need to use refcount_inc_not_zero(&sk->sk_refcnt).

Reuse the existing correct logic I wrote for TIME_WAIT,
because both structures have common locations for
sk_state, sk_family, and netns pointer.

If after the refcount_inc_not_zero() the object fields longer match
the keys, use sock_gen_put(sk) to release the refcount.

Then we can call inet_twsk_deschedule_put() for TIME_WAIT,
inet_csk_reqsk_queue_drop_and_put() for NEW_SYN_RECV sockets,
with BH disabled.

Then we need to restart the loop because we had drop rcu_read_lock().

Fixes: 740ea3c4a0b2 ("tcp: Clean up kernel listener's reqsk in inet_twsk_purge()")
Link: https://lore.kernel.org/netdev/CANn89iLvFuuihCtt9PME2uS1WJATnf5fKjDToa1WzVnRzHnPfg@mail.gmail.com/T/#u
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20240308200122.64357-2-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ipv4/inet_timewait_sock.c