diff options
| author | Eric Dumazet <edumazet@kernel.org> | 2026-10-20 17:19:54 +0200 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-10-21 17:32:26 -0700 |
| commit | 4957ea03bf2696f5da12c09144f48d040696ecc2 (patch) | |
| tree | 70be0e5a3d45a3015e517b15c3d014b32cc806c2 /scripts/Makefile.thinlto | |
| parent | d06e106229d6c5af67aed5146c22bdebf6eff0a0 (diff) | |
| download | linux-4957ea03bf2696f5da12c09144f48d040696ecc2.tar.gz linux-4957ea03bf2696f5da12c09144f48d040696ecc2.zip | |
net: shrink the payload-only part of skb dataref to one bit
skb_shinfo(skb)->dataref is split in two 16-bit halves: the lower
one counts all references, the upper one the payload-only (nohdr)
references.
__skb_clone() increments dataref without bound, and skb_cloned()
only checks the low 16 bits. With 65,537 references the low half
reads 1, the head looks private, and pskb_expand_head() (or
skb_unclone(), skb_cow(), ...) frees it while clones still point
to it.
An unprivileged user can reach this from a user and network namespace:
about 32,770 AF_PACKET sockets on lo bring dataref to 0x10001, then
any pskb_expand_head() on the receive path (here a pull of a large
IPv6 Hop-by-Hop header) frees the shared head:
BUG: KASAN: slab-use-after-free in _copy_to_iter+0x187/0x1330
Read of size 1590 at addr ff110001104a9002 by task dataref_wrap/87
skb_copy_datagram_iter+0x60/0x190
packet_recvmsg+0x1f5/0x12b0
__sys_recvfrom+0x18d/0x290
Freed by task 87:
kfree+0xf3/0x3b0
pskb_expand_head+0x344/0xeb0
__pskb_pull_tail+0xf9/0x1bf0
ipv6_parse_hopopts+0x377/0x4f0
ip6_rcv_core+0xc67/0x1620
The upper half never holds more than 1. It is only set by
__skb_header_release(), with atomic_set() on an skb owning its head
(TCP/SCTP output, and GRO which never sees cloned skbs).
__skb_clone() clears nohdr, and __copy_skb_header() does not copy it.
Move SKB_DATAREF_SHIFT to 30, so that the reference count gets 30 bits,
and dataref stays positive. Wrapping it would need 2^30 live clones of
a single skb, which socket buffer limits and memory make unreachable.
This issue was found by Anthropic using Claude, and validated by
Ada Logics.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Stephan Lipp <Stephan@adalogics.com>
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/20261020151954.22953-1-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'scripts/Makefile.thinlto')
0 files changed, 0 insertions, 0 deletions
