linux/net/core
Mohammad Heib 238e03d046 net: fix memory leak in skb_segment_list for GRO packets
When skb_segment_list() is called during packet forwarding, it handles
packets that were aggregated by the GRO engine.

Historically, the segmentation logic in skb_segment_list assumes that
individual segments are split from a parent SKB and may need to carry
their own socket memory accounting. Accordingly, the code transfers
truesize from the parent to the newly created segments.

Prior to commit ed4cccef64 ("gro: fix ownership transfer"), this
truesize subtraction in skb_segment_list() was valid because fragments
still carry a reference to the original socket.

However, commit ed4cccef64 ("gro: fix ownership transfer") changed
this behavior by ensuring that fraglist entries are explicitly
orphaned (skb->sk = NULL) to prevent illegal orphaning later in the
stack. This change meant that the entire socket memory charge remained
with the head SKB, but the corresponding accounting logic in
skb_segment_list() was never updated.

As a result, the current code unconditionally adds each fragment's
truesize to delta_truesize and subtracts it from the parent SKB. Since
the fragments are no longer charged to the socket, this subtraction
results in an effective under-count of memory when the head is freed.
This causes sk_wmem_alloc to remain non-zero, preventing socket
destruction and leading to a persistent memory leak.

The leak can be observed via KMEMLEAK when tearing down the networking
environment:

unreferenced object 0xffff8881e6eb9100 (size 2048):
  comm "ping", pid 6720, jiffies 4295492526
  backtrace:
    kmem_cache_alloc_noprof+0x5c6/0x800
    sk_prot_alloc+0x5b/0x220
    sk_alloc+0x35/0xa00
    inet6_create.part.0+0x303/0x10d0
    __sock_create+0x248/0x640
    __sys_socket+0x11b/0x1d0

Since skb_segment_list() is exclusively used for SKB_GSO_FRAGLIST
packets constructed by GRO, the truesize adjustment is removed.

The call to skb_release_head_state() must be preserved. As documented in
commit cf673ed0e0 ("net: fix fraglist segmentation reference count
leak"), it is still required to correctly drop references to SKB
extensions that may be overwritten during __copy_skb_header().

Fixes: ed4cccef64 ("gro: fix ownership transfer")
Signed-off-by: Mohammad Heib <mheib@redhat.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260104213101.352887-1-mheib@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-01-05 17:01:28 -08:00
..
Makefile
bpf_sk_storage.c bpf: Remove smap argument from bpf_selem_free() 2025-11-18 16:20:25 -08:00
datagram.c net: datagram: introduce datagram_poll_queue for custom receive queues 2025-10-23 15:46:04 +02:00
dev.c net: avoid prefetching NULL pointers 2025-12-28 10:19:11 +01:00
dev.h for-6.19/io_uring-20251201 2025-12-03 18:58:57 -08:00
dev_addr_lists.c
dev_addr_lists_test.c
dev_api.c
dev_ioctl.c phy: add hwtstamp_get callback to phy drivers 2025-11-26 16:56:33 -08:00
devmem.c netmem, devmem, tcp: access pp fields through @desc in net_iov 2025-11-27 17:41:51 -08:00
devmem.h net: devmem: Remove unused declaration net_devmem_bind_tx_release() 2025-11-04 17:29:19 -08:00
drop_monitor.c
dst.c
dst_cache.c
failover.c
fib_notifier.c
fib_rules.c
filter.c Networking changes for 6.19. 2025-12-03 17:24:33 -08:00
flow_dissector.c
flow_offload.c
gen_estimator.c
gen_stats.c
gro.c net: gro: clear skb_shinfo(skb)->hwtstamps in napi_reuse_skb() 2025-10-16 15:42:49 -07:00
gro_cells.c net: gro_cells: Reduce lock scope in gro_cell_poll 2025-11-05 17:41:29 -08:00
gso.c
hotdata.c net: increase skb_defer_max default to 128 2025-11-07 19:02:40 -08:00
hwbm.c
ieee8021q_helpers.c
link_watch.c net: replace use of system_unbound_wq with system_dfl_wq 2025-09-22 17:40:30 -07:00
lock_debug.c
lwt_bpf.c
lwtunnel.c
mp_dmabuf_devmem.h
neighbour.c neighbour: Convert rwlock of struct neigh_table to spinlock. 2025-10-24 17:57:20 -07:00
net-procfs.c
net-sysfs.c Networking changes for 6.18. 2025-10-02 15:17:01 -07:00
net-sysfs.h
net-traces.c
net_namespace.c Networking changes for 6.19. 2025-12-03 17:24:33 -08:00
net_test.c
netclassid_cgroup.c
netdev-genl-gen.c tools: ynl-gen: add regeneration comment 2025-11-25 19:20:42 -08:00
netdev-genl-gen.h tools: ynl-gen: add regeneration comment 2025-11-25 19:20:42 -08:00
netdev-genl.c
netdev_queues.c
netdev_rx_queue.c
netevent.c
netmem_priv.h netmem: replace __netmem_clear_lsb() with netmem_to_nmdesc() 2025-10-14 13:37:26 +02:00
netpoll.c net: netpoll: initialize work queue before error checks 2025-11-28 20:16:57 -08:00
netprio_cgroup.c
of_net.c
page_pool.c net: page_pool: sanitise allocation order 2025-12-02 11:08:39 -08:00
page_pool_priv.h
page_pool_user.c
pktgen.c
ptp_classifier.c
request_sock.c tcp: Remove stale locking comment for TFO. 2025-09-23 18:21:36 -07:00
rtnetlink.c rtnetlink: honor RTEXT_FILTER_SKIP_STATS in IFLA_STATS 2025-11-04 16:07:37 -08:00
scm.c scm: Convert put_cmsg() to scoped user access 2025-11-18 15:27:34 +01:00
secure_seq.c
selftests.c net: selftests: export packet creation helpers for driver use 2025-11-06 13:38:11 +01:00
skb_fault_injection.c
skbuff.c net: fix memory leak in skb_segment_list for GRO packets 2026-01-05 17:01:28 -08:00
skmsg.c net: replace use of system_wq with system_percpu_wq 2025-09-22 17:40:30 -07:00
sock.c net: sock: fix hardened usercopy panic in sock_recv_errqueue 2026-01-04 09:54:32 -08:00
sock_destructor.h
sock_diag.c net: WQ_PERCPU added to alloc_workqueue users 2025-09-22 17:40:30 -07:00
sock_map.c
sock_reuseport.c
stream.c
sysctl_net_core.c net: Introduce net.core.bypass_prot_mem sysctl. 2025-10-16 12:04:47 -07:00
timestamping.c
tso.c
utils.c
xdp.c