CVE-2026-74714

CVE-2026-74714

High · published August 22, 2026

CVSS v3.1
7.8
EPSS
0%
Percentile
2.1
In the wild
Unconfirmed
What it is

In the Linux kernel, the following vulnerability has been resolved:

bpf: tcp: Fix use-after-free in bpf_iter_tcp_established_batch()

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.

The record
Technical detail
CVSS v3.1
7.8 · HIGH
Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS v4.0
Not supplied
EPSS
0.00126 · 2.1th percentile
Published
2026-08-22T20:16Z
References (6)
EPSS history
Timeline
  • 22 AUG 15:33Z
    bpf: tcp: Fix use-after-free in bpf_iter_tcp_established_batch()
    cvelistv5