From: "Kumar Kartikeya Dwivedi" <memxor@gmail.com>
To: "Kuniyuki Iwashima" <kuniyu@google.com>,
"Jose Fernandez (Anthropic)" <jose.fernandez@linux.dev>
Cc: "Eric Dumazet" <edumazet@google.com>,
"Neal Cardwell" <ncardwell@google.com>,
"David S. Miller" <davem@davemloft.net>,
"Jakub Kicinski" <kuba@kernel.org>,
"Paolo Abeni" <pabeni@redhat.com>,
"Simon Horman" <horms@kernel.org>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Yonghong Song" <yonghong.song@linux.dev>,
"Martin KaFai Lau" <martin.lau@linux.dev>,
<netdev@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<bpf@vger.kernel.org>, "Daniel Borkmann" <daniel@iogearbox.net>,
"Jiayuan Chen" <jiayuan.chen@linux.dev>,
"Emil Tsalapatis" <emil@etsalapatis.com>
Subject: Re: [PATCH bpf v3] bpf: tcp: Fix use-after-free in bpf_iter_tcp_established_batch()
Date: Mon, 03 Aug 2026 02:30:05 +0200 [thread overview]
Message-ID: <DKEVUJFTGKN5.HQGLRFLQMISY@gmail.com> (raw)
In-Reply-To: <CAAVpQUAoxyhmfbfCGeMUyQK7F4RifMsFDM0XyDqO9SOMZmASvA@mail.gmail.com>
On Fri Jul 31, 2026 at 7:39 AM CEST, Kuniyuki Iwashima wrote:
> On Fri, Jul 31, 2026 at 12:33 AM Jose Fernandez (Anthropic)
> <jose.fernandez@linux.dev> wrote:
>>
>> reqsk_queue_hash_req() publishes a TCP_NEW_SYN_RECV request_sock onto
>> the ehash chain, drops the bucket lock, and only afterwards sets
>> rsk_refcnt to 3.
>>
>> Lockless readers such as __inet_lookup_established() handle this with
>> refcount_inc_not_zero(), but bpf_iter_tcp_established_batch() uses plain
>> sock_hold() while holding the bucket lock, on the assumption that the
>> lock guarantees sk_refcnt > 0. That assumption does not hold for
>> request_sock:
>>
>> CPU 0 CPU 1
>> ----- -----
>> tcp_conn_request()
>> reqsk_queue_hash_req()
>> inet_ehash_insert(req)
>> spin_lock(bucket)
>> __sk_nulls_add_node_rcu(req) // rsk_refcnt == 0
>> spin_unlock(bucket)
>> bpf_iter_tcp_established_batch()
>> spin_lock(bucket)
>> sock_hold(req) <-- addition on 0
>> spin_unlock(bucket)
>> refcount_set(&req->rsk_refcnt, 3) // clobbers saturated value
>>
>> which surfaces as:
>>
>> refcount_t: addition on 0; use-after-free.
>> WARNING: lib/refcount.c:25 at refcount_warn_saturate+0x48/0x90, CPU#1
>> Call Trace:
>> bpf_iter_tcp_established_batch+0x14e/0x170
>> bpf_iter_tcp_batch+0x53/0x200
>> bpf_iter_tcp_seq_next+0x27/0x70
>> bpf_seq_read+0x107/0x410
>> vfs_read+0xb9/0x380
>>
>> The iterator's stolen reference is lost when the publishing CPU's
>> refcount_set() overwrites the count, leaving the socket one reference
>> short. When the last legitimate owner drops its reference the reqsk is
>> freed while still reachable, leading to use-after-free.
>>
>> This reproduces in seconds with tcp_syncookies=0, a handful of threads
>> doing connect()/close() to a local listener while others read an
>> iter/tcp link in a tight loop.
>>
>> Use refcount_inc_not_zero() and skip the socket on failure. A skipped
>> socket is still part of the bucket, so keep counting it in expected.
>> The reallocations are sized from expected, and a request sock whose
>> refcount gets published while the lock is held across the last realloc
>> must already have room.
>>
>> A skipped socket is counted in expected but never batched, so end_sk
>> can be short of expected on a batch that is actually complete. Decide
>> completeness by whether the walk left any socket behind instead. The
>> WARN after the locked realloc checks the same, replacing an
>> end_sk == expected check that could not hold on that path since
>> commit cdec67a489d4 ("bpf: tcp: Make sure iter->batch always
>> contains a full bucket snapshot").
>>
>> If every matching socket in a bucket is mid-init (refcount 0), end_sk
>> stays 0. Advance to the next bucket rather than returning a batch entry
>> that was never filled this round.
>>
>> Fixes: 04c7820b776f ("bpf: tcp: Bpf iter batching and lock_sock")
>> Assisted-by: Claude:unspecified
>> Signed-off-by: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev>
>
> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
>
> Thanks !
pw-bot is asleep. Applied to bpf.
prev parent reply other threads:[~2026-08-03 0:30 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-30 22:32 [PATCH bpf v3] bpf: tcp: Fix use-after-free in bpf_iter_tcp_established_batch() Jose Fernandez (Anthropic)
2026-07-30 22:45 ` sashiko-bot
2026-07-31 5:39 ` Kuniyuki Iwashima
2026-08-03 0:30 ` Kumar Kartikeya Dwivedi [this message]
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=DKEVUJFTGKN5.HQGLRFLQMISY@gmail.com \
--to=memxor@gmail.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=emil@etsalapatis.com \
--cc=horms@kernel.org \
--cc=jiayuan.chen@linux.dev \
--cc=jose.fernandez@linux.dev \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=ncardwell@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=yonghong.song@linux.dev \
/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.