linux/net/core
Jakub Kicinski a046f183d2 net: clear the dst when changing skb protocol
[ Upstream commit ba9db6f907 ]

A not-so-careful NAT46 BPF program can crash the kernel
if it indiscriminately flips ingress packets from v4 to v6:

  BUG: kernel NULL pointer dereference, address: 0000000000000000
    ip6_rcv_core (net/ipv6/ip6_input.c:190:20)
    ipv6_rcv (net/ipv6/ip6_input.c:306:8)
    process_backlog (net/core/dev.c:6186:4)
    napi_poll (net/core/dev.c:6906:9)
    net_rx_action (net/core/dev.c:7028:13)
    do_softirq (kernel/softirq.c:462:3)
    netif_rx (net/core/dev.c:5326:3)
    dev_loopback_xmit (net/core/dev.c:4015:2)
    ip_mc_finish_output (net/ipv4/ip_output.c:363:8)
    NF_HOOK (./include/linux/netfilter.h:314:9)
    ip_mc_output (net/ipv4/ip_output.c:400:5)
    dst_output (./include/net/dst.h:459:9)
    ip_local_out (net/ipv4/ip_output.c:130:9)
    ip_send_skb (net/ipv4/ip_output.c:1496:8)
    udp_send_skb (net/ipv4/udp.c:1040:8)
    udp_sendmsg (net/ipv4/udp.c:1328:10)

The output interface has a 4->6 program attached at ingress.
We try to loop the multicast skb back to the sending socket.
Ingress BPF runs as part of netif_rx(), pushes a valid v6 hdr
and changes skb->protocol to v6. We enter ip6_rcv_core which
tries to use skb_dst(). But the dst is still an IPv4 one left
after IPv4 mcast output.

Clear the dst in all BPF helpers which change the protocol.
Try to preserve metadata dsts, those may carry non-routing
metadata.

Cc: stable@vger.kernel.org
Reviewed-by: Maciej Żenczykowski <maze@google.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Fixes: d219df60a7 ("bpf: Add ipip6 and ip6ip decap support for bpf_skb_adjust_room()")
Fixes: 1b00e0dfe7 ("bpf: update skb->protocol in bpf_skb_net_grow")
Fixes: 6578171a7f ("bpf: add bpf_skb_change_proto helper")
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20250610001245.1981782-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ The context change is due to the commit d219df60a7
("bpf: Add ipip6 and ip6ip decap support for bpf_skb_adjust_room()")
in v6.3 which is irrelevant to the logic of this patch. ]
Signed-off-by: Johnny Hao <johnny_haocn@sina.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2026-06-01 17:35:11 +02:00
..
bpf_sk_storage.c bpf: Add length check for SK_DIAG_BPF_STORAGE_REQ_MAP_FD parsing 2023-08-11 15:13:50 +02:00
datagram.c net: fix rc7's __skb_datagram_iter() 2024-07-18 13:07:37 +02:00
datagram.h net/core: Allow the compiler to verify declaration and definition consistency 2019-03-27 13:49:44 -07:00
dev.c net: Handle napi_schedule() calls from non-interrupt 2026-04-18 10:33:18 +02:00
dev_addr_lists.c net: dev_addr_list: handle first address in __hw_addr_add_ex 2021-09-30 13:29:09 +01:00
dev_ioctl.c net: Remove RTNL dance for SIOCBRADDIF and SIOCBRDELIF. 2026-01-19 13:10:11 +01:00
devlink.c devlink: report devlink_port_type_warn source device 2024-03-01 13:21:55 +01:00
drop_monitor.c drop_monitor: fix incorrect initialization order 2025-03-13 12:50:53 +01:00
dst.c net: do not delay dst_entries_add() in dst_release() 2024-11-14 13:13:40 +01:00
dst_cache.c wireguard: device: reset peer src endpoint when netns exits 2021-12-08 09:04:46 +01:00
failover.c failover: allow name change on IFF_UP slave interfaces 2019-04-10 22:12:26 -07:00
fib_notifier.c net: fib_notifier: propagate extack down to the notifier block callback 2019-10-04 11:10:56 -07:00
fib_rules.c ipv6: fix memory leak in fib6_rule_suppress 2021-12-08 09:04:43 +01:00
filter.c net: clear the dst when changing skb protocol 2026-06-01 17:35:11 +02:00
flow_dissector.c flow_dissector: Fix port range key handling in BPF conversion 2025-03-13 12:50:52 +01:00
flow_offload.c net: extract port range fields from fl_flow_key 2025-03-13 12:50:52 +01:00
gen_estimator.c net_sched: gen_estimator: support large ewma log 2021-01-15 18:11:06 -08:00
gen_stats.c docs: networking: convert gen_stats.txt to ReST 2020-04-28 14:39:46 -07:00
gro_cells.c net: Fix data-races around netdev_max_backlog. 2022-08-31 17:16:42 +02:00
hwbm.c net: hwbm: Make the hwbm_pool lock a mutex 2019-06-09 19:40:10 -07:00
link_watch.c net: linkwatch: use system_unbound_wq 2024-08-19 05:45:35 +02:00
lwt_bpf.c lwt: Fix return values of BPF xmit ops 2023-09-19 12:22:33 +02:00
lwtunnel.c lwtunnel: Validate RTA_ENCAP_TYPE attribute length 2022-01-11 15:35:14 +01:00
Makefile of: net: move of_net under net/ 2022-03-08 19:12:41 +01:00
neighbour.c net/neighbor: add missing policy for NDTPA_QUEUE_LENBYTES 2025-04-10 14:31:54 +02:00
net-procfs.c net-procfs: show net devices bound packet types 2022-02-01 17:27:08 +01:00
net-sysfs.c ethtool: check device is present when getting link settings 2024-09-04 13:23:40 +02:00
net-sysfs.h net-sysfs: add netdev_change_owner() 2020-02-26 20:07:25 -08:00
net-traces.c tcp: add tracepoint for checksum errors 2021-05-14 15:26:03 -07:00
net_namespace.c net: defer final 'struct net' free in netns dismantle 2025-05-02 07:44:23 +02:00
netclassid_cgroup.c bpf, cgroups: Fix cgroup v2 fallback on v1/v2 mixed mode 2021-09-13 16:35:58 -07:00
netevent.c net: core: Correct function name netevent_unregister_notifier() in the kerneldoc 2021-03-28 17:56:56 -07:00
netpoll.c net: netpoll: fix incorrect refcount handling causing incorrect cleanup 2025-12-07 06:09:32 +09:00
netprio_cgroup.c bpf, cgroups: Fix cgroup v2 fallback on v1/v2 mixed mode 2021-09-13 16:35:58 -07:00
of_net.c of: net: add a helper for loading netdev->dev_addr 2023-07-27 08:46:59 +02:00
page_pool.c page_pool: Fix use-after-free in page_pool_recycle_in_ring 2026-01-19 13:10:11 +01:00
pktgen.c net: pktgen: fix access outside of user given buffer in pktgen_thread_write() 2025-06-04 14:38:01 +02:00
ptp_classifier.c ptp: Add generic PTP is_sync() function 2025-09-09 18:50:20 +02:00
request_sock.c tcp: make sure init the accept_queue's spinlocks once 2024-02-23 08:54:27 +01:00
rtnetlink.c rtnetlink: count IFLA_INFO_SLAVE_KIND in if_nlmsg_size 2026-04-18 10:33:24 +02:00
scm.c io_uring/unix: drop usage of io_uring socket 2024-03-26 18:21:11 -04:00
secure_seq.c tcp: Fix data-races around sysctl knobs related to SYN option. 2022-07-29 17:25:22 +02:00
selftests.c net: selftests: fix TCP packet checksum 2025-07-10 15:57:39 +02:00
skbuff.c net: skbuff: propagate shared-frag marker through frag-transfer helpers 2026-05-23 13:40:45 +02:00
skmsg.c bpf, sockmap: Fix psock incorrectly pointing to sk 2025-08-28 16:24:07 +02:00
sock.c net: sock: fix hardened usercopy panic in sock_recv_errqueue 2026-01-19 13:10:16 +01:00
sock_destructor.h skb_expand_head() adjust skb->truesize incorrectly 2021-10-22 12:35:51 -07:00
sock_diag.c sock_diag: annotate data-races around sock_diag_handlers[family] 2024-03-26 18:21:17 -04:00
sock_map.c bpf, sockmap: Fix race between element replace and close() 2025-04-10 14:31:55 +02:00
sock_reuseport.c soreuseport: Fix socket selection for SO_INCOMING_CPU. 2022-12-31 13:14:07 +01:00
stream.c net: deal with most data-races in sk_wait_event() 2023-05-24 17:36:42 +01:00
sysctl_net_core.c net: let net.core.dev_weight always be non-zero 2025-03-13 12:49:59 +01:00
timestamping.c net: Introduce a new MII time stamping interface. 2019-12-25 19:51:33 -08:00
tso.c net: tso: add UDP segmentation support 2020-06-18 20:46:23 -07:00
utils.c net: Fix checksum update for ILA adj-transport 2025-06-27 11:05:38 +01:00
xdp.c xdp: fix invalid wait context of page_pool_destroy() 2024-08-19 05:44:59 +02:00