bpf: tcp: Get rid of st_bucket_done

[ Upstream commit e25ab9b874 ]

Get rid of the st_bucket_done field to simplify TCP iterator state and
logic. Before, st_bucket_done could be false if bpf_iter_tcp_batch
returned a partial batch; however, with the last patch ("bpf: tcp: Make
sure iter->batch always contains a full bucket snapshot"),
st_bucket_done == true is equivalent to iter->cur_sk == iter->end_sk.

Signed-off-by: Jordan Rife <jordan@jrife.io>
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Stable-dep-of: e5fd3f514e ("bpf: tcp: Fix use-after-free in bpf_iter_tcp_established_batch()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Jordan Rife
2026-08-19 18:13:06 +02:00
committed by Greg Kroah-Hartman
parent 1d7a82c1df
commit beb8ffae31
+6 -8
View File
@@ -2782,7 +2782,6 @@ struct bpf_tcp_iter_state {
unsigned int end_sk;
unsigned int max_sk;
struct sock **batch;
bool st_bucket_done;
};
struct bpf_iter__tcp {
@@ -2805,8 +2804,10 @@ static int tcp_prog_seq_show(struct bpf_prog *prog, struct bpf_iter_meta *meta,
static void bpf_iter_tcp_put_batch(struct bpf_tcp_iter_state *iter)
{
while (iter->cur_sk < iter->end_sk)
sock_gen_put(iter->batch[iter->cur_sk++]);
unsigned int cur_sk = iter->cur_sk;
while (cur_sk < iter->end_sk)
sock_gen_put(iter->batch[cur_sk++]);
}
static int bpf_iter_tcp_realloc_batch(struct bpf_tcp_iter_state *iter,
@@ -2923,7 +2924,7 @@ static struct sock *bpf_iter_tcp_batch(struct seq_file *seq)
* one by one in the current bucket and eventually find out
* it has to advance to the next bucket.
*/
if (iter->st_bucket_done) {
if (iter->end_sk && iter->cur_sk == iter->end_sk) {
st->offset = 0;
st->bucket++;
if (st->state == TCP_SEQ_STATE_LISTENING &&
@@ -2935,7 +2936,6 @@ static struct sock *bpf_iter_tcp_batch(struct seq_file *seq)
iter->cur_sk = 0;
iter->end_sk = 0;
iter->st_bucket_done = true;
sk = tcp_seek_last_pos(seq);
if (!sk)
@@ -3083,10 +3083,8 @@ static void bpf_iter_tcp_seq_stop(struct seq_file *seq, void *v)
(void)tcp_prog_seq_show(prog, &meta, v, 0);
}
if (iter->cur_sk < iter->end_sk) {
if (iter->cur_sk < iter->end_sk)
bpf_iter_tcp_put_batch(iter);
iter->st_bucket_done = false;
}
}
static const struct seq_operations bpf_iter_tcp_seq_ops = {