From: Eric Dumazet <edumazet@kernel.org>
To: "David S . Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Kuniyuki Iwashima <kuniyu@google.com>,
Neal Cardwell <ncardwell@google.com>
Cc: Simon Horman <horms@kernel.org>,
netdev@vger.kernel.org, Kyle Zeng <kylebot@openai.com>,
Eric Dumazet <edumazet@kernel.org>
Subject: [PATCH net] tcp: avoid double destroy in tcp_abort() of an unaccepted child
Date: Wed, 28 Oct 2026 17:08:47 +0100 [thread overview]
Message-ID: <20261028160847.2170959-1-edumazet@kernel.org> (raw)
From: Kyle Zeng <kylebot@openai.com>
tcp_abort() checks for TCP_CLOSE while only owning the socket lock,
then grabs the BH lock before calling tcp_done_with_error().
For a child still sitting in a listener accept queue (which can be
reached via SOCK_DESTROY or bpf_sock_destroy()), inet_csk_listen_stop()
can run in this window: it only holds the child BH lock, and calls
inet_child_forget(), which disconnects, orphans and destroys the child.
tcp_abort() then calls tcp_done_with_error() -> tcp_done(), which sees
SOCK_DEAD and calls inet_csk_destroy_sock() a second time, leading to
a double sock_put() and a use-after-free.
Recheck TCP_CLOSE after acquiring the BH lock, unless we just closed
a listener ourselves, in which case tcp_done_with_error() must still
run to report the error.
Note that the WARN_ON(sock_owned_by_user(child)) in
inet_csk_listen_stop() can still trigger in this window.
Fixes: bac76cf89816 ("tcp: fix forever orphan socket caused by tcp_abort")
Signed-off-by: Kyle Zeng <kylebot@openai.com>
[edumazet: recheck TCP_CLOSE under the BH lock instead of moving the test, smaller diff]
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
---
net/ipv4/tcp.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 1f56d8c0c5fe947072eb5ce50217b13fd33ff74d..6a9566f179e02c3a2e3c91f4ffa96a85190c861d 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -5128,6 +5128,8 @@ void tcp_done(struct sock *sk)
int tcp_abort(struct sock *sk, int err)
{
int state = inet_sk_state_load(sk);
+ bool listener = false;
+ int ret = 0;
if (state == TCP_NEW_SYN_RECV) {
struct request_sock *req = inet_reqsk(sk);
@@ -5162,21 +5164,31 @@ int tcp_abort(struct sock *sk, int err)
if (sk->sk_state == TCP_LISTEN) {
tcp_set_state(sk, TCP_CLOSE);
inet_csk_listen_stop(sk);
+ listener = true;
}
/* Don't race with BH socket closes such as inet_csk_listen_stop. */
local_bh_disable();
bh_lock_sock(sk);
+ /* An unaccepted child might have been closed by
+ * inet_csk_listen_stop() while we were not holding its BH lock.
+ */
+ if (!listener && sk->sk_state == TCP_CLOSE) {
+ ret = -ENOENT;
+ goto out;
+ }
+
if (tcp_need_reset(sk->sk_state))
tcp_send_active_reset(sk, SK_RST_REASON_TCP_STATE);
tcp_done_with_error(sk, err);
+out:
bh_unlock_sock(sk);
local_bh_enable();
if (!has_current_bpf_ctx())
release_sock(sk);
- return 0;
+ return ret;
}
EXPORT_SYMBOL_GPL(tcp_abort);
--
2.53.0
next reply other threads:[~2026-10-28 16:08 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 16:08 Eric Dumazet [this message]
2026-10-28 16:11 ` [PATCH net] tcp: avoid double destroy in tcp_abort() of an unaccepted child netdev-bot+sinfo
2026-10-28 19:54 ` Kuniyuki Iwashima
2026-10-29 16:20 ` patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261028160847.2170959-1-edumazet@kernel.org \
--to=edumazet@kernel.org \
--cc=davem@davemloft.net \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=kylebot@openai.com \
--cc=ncardwell@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.