linux-stable/net/core
Liang Chen 71850b5af9 skbuff: Fix a race between coalescing and releasing SKBs
[ Upstream commit 0646dc31ca ]

Commit 1effe8ca4e ("skbuff: fix coalescing for page_pool fragment
recycling") allowed coalescing to proceed with non page pool page and page
pool page when @from is cloned, i.e.

to->pp_recycle    --> false
from->pp_recycle  --> true
skb_cloned(from)  --> true

However, it actually requires skb_cloned(@from) to hold true until
coalescing finishes in this situation. If the other cloned SKB is
released while the merging is in process, from_shinfo->nr_frags will be
set to 0 toward the end of the function, causing the increment of frag
page _refcount to be unexpectedly skipped resulting in inconsistent
reference counts. Later when SKB(@to) is released, it frees the page
directly even though the page pool page is still in use, leading to
use-after-free or double-free errors. So it should be prohibited.

The double-free error message below prompted us to investigate:
BUG: Bad page state in process swapper/1  pfn:0e0d1
page:00000000c6548b28 refcount:-1 mapcount:0 mapping:0000000000000000
index:0x2 pfn:0xe0d1
flags: 0xfffffc0000000(node=0|zone=1|lastcpupid=0x1fffff)
raw: 000fffffc0000000 0000000000000000 ffffffff00000101 0000000000000000
raw: 0000000000000002 0000000000000000 ffffffffffffffff 0000000000000000
page dumped because: nonzero _refcount

CPU: 1 PID: 0 Comm: swapper/1 Tainted: G            E      6.2.0+
Call Trace:
 <IRQ>
dump_stack_lvl+0x32/0x50
bad_page+0x69/0xf0
free_pcp_prepare+0x260/0x2f0
free_unref_page+0x20/0x1c0
skb_release_data+0x10b/0x1a0
napi_consume_skb+0x56/0x150
net_rx_action+0xf0/0x350
? __napi_schedule+0x79/0x90
__do_softirq+0xc8/0x2b1
__irq_exit_rcu+0xb9/0xf0
common_interrupt+0x82/0xa0
</IRQ>
<TASK>
asm_common_interrupt+0x22/0x40
RIP: 0010:default_idle+0xb/0x20

Fixes: 53e0961da1 ("page_pool: add frag page recycling support in page pool")
Signed-off-by: Liang Chen <liangchen.linux@gmail.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20230413090353.14448-1-liangchen.linux@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-04-20 12:35:10 +02:00
..
bpf_sk_storage.c net: Fix data-races around sysctl_optmem_max. 2022-08-24 13:46:57 +01:00
datagram.c tcp: TX zerocopy should not sense pfmemalloc status 2022-09-02 12:29:02 +01:00
dev.c net: openvswitch: fix race on port output 2023-04-20 12:35:09 +02:00
dev.h net: add skb_defer_max sysctl 2022-05-16 11:33:59 +01:00
dev_addr_lists.c net: extract a few internals from netdevice.h 2022-04-07 20:32:09 -07:00
dev_addr_lists_test.c net: kunit: add a test for dev_addr_lists 2021-11-20 12:25:57 +00:00
dev_ioctl.c net: rename reference+tracking helpers 2022-06-09 21:52:55 -07:00
devlink.c devlink: protect devlink dump by the instance lock 2022-12-31 13:32:55 +01:00
drop_monitor.c genetlink: start to validate reserved header bytes 2022-08-29 12:47:15 +01:00
dst.c net: rename reference+tracking helpers 2022-06-09 21:52:55 -07:00
dst_cache.c wireguard: device: reset peer src endpoint when netns exits 2021-11-29 19:50:45 -08:00
failover.c net: rename reference+tracking helpers 2022-06-09 21:52:55 -07:00
fib_notifier.c
fib_rules.c fib: expand fib_rule_policy 2021-12-16 07:18:35 -08:00
filter.c bpf: bpf_fib_lookup should not return neigh in NUD_FAILED state 2023-03-03 11:52:23 +01:00
flow_dissector.c netfilter: conntrack: Fix data-races around ct mark 2022-11-18 15:21:00 +01:00
flow_offload.c flow_offload: Introduce flow_match_l2tpv3 2022-09-20 09:13:38 +02:00
gen_estimator.c
gen_stats.c net: sched: fix misuse of qcpu->backlog in gnet_stats_add_queue_cpu 2022-08-16 19:38:20 -07:00
gro.c skb: Do mix page pool and page referenced frags in GRO 2023-02-09 11:28:05 +01:00
gro_cells.c net: drop the weight argument from netif_napi_add 2022-09-28 18:57:14 -07:00
hwbm.c
link_watch.c net: rename reference+tracking helpers 2022-06-09 21:52:55 -07:00
lwt_bpf.c bpf, lwt: Fix crash when using bpf_skb_set_tunnel_key() from bpf_xmit lwt hook 2022-04-22 17:45:25 +02:00
lwtunnel.c xfrm: lwtunnel: squelch kernel warning in case XFRM encap type is not available 2022-10-12 10:45:51 +02:00
Makefile net: skb: export skb drop reaons to user by TRACE_DEFINE_ENUM 2022-09-07 15:28:08 +01:00
neighbour.c neigh: make sure used and confirmed times are valid 2023-03-03 11:52:22 +01:00
net-procfs.c net: extract a few internals from netdevice.h 2022-04-07 20:32:09 -07:00
net-sysfs.c net-sysfs: Convert to use sysfs_emit() APIs 2022-09-30 12:27:44 +01:00
net-sysfs.h
net-traces.c
net_namespace.c net: fix UaF in netns ops registration error path 2023-02-01 08:34:43 +01:00
netclassid_cgroup.c core: Variable type completion 2022-08-31 09:40:34 +01:00
netevent.c
netpoll.c net: don't let netpoll invoke NAPI if in xmit context 2023-04-13 16:55:21 +02:00
netprio_cgroup.c
of_net.c Revert "of: net: support NVMEM cells with MAC in text format" 2022-01-12 14:14:36 +00:00
page_pool.c - The usual batches of cleanups from Baoquan He, Muchun Song, Miaohe 2022-08-05 16:32:45 -07:00
pktgen.c treewide: use get_random_u32() when possible 2022-10-11 17:42:58 -06:00
ptp_classifier.c ptp: Add generic PTP is_sync() function 2022-03-07 11:31:34 +00:00
request_sock.c
rtnetlink.c net: rtnetlink: Enslave device before bringing it up 2022-09-20 08:37:44 -07:00
scm.c scm: add user copy checks to put_cmsg() 2023-03-10 09:33:54 +01:00
secure_seq.c tcp: Fix data-races around sysctl knobs related to SYN option. 2022-07-20 10:14:49 +01:00
selftests.c
skbuff.c skbuff: Fix a race between coalescing and releasing SKBs 2023-04-20 12:35:10 +02:00
skmsg.c bpf, sockmap: Fix missing BPF_F_INGRESS flag when using apply_bytes 2022-12-31 13:32:20 +01:00
sock.c net: use indirect calls helpers for sk_exit_memory_pressure() 2023-03-17 08:50:24 +01:00
sock_destructor.h
sock_diag.c net: Don't include filter.h from net/sock.h 2021-12-29 08:48:14 -08:00
sock_map.c bpf, sockmap: Don't let sock_map_{close,destroy,unhash} call itself 2023-02-22 12:59:42 +01:00
sock_reuseport.c soreuseport: Fix socket selection for SO_INCOMING_CPU. 2022-12-31 13:32:04 +01:00
stream.c net: Remove WARN_ON_ONCE(sk->sk_forward_alloc) from sk_stream_kill_queues(). 2023-03-03 11:52:23 +01:00
sysctl_net_core.c net: sysctl: remove unused variable long_max 2022-09-07 15:31:19 +01:00
timestamping.c
tso.c
utils.c net: core: Use csum_replace_by_diff() and csum_sub() instead of opencoding 2022-02-21 11:40:44 +00:00
xdp.c xdp: improve page_pool xdp_return performance 2022-09-26 11:28:19 -07:00