linux/net/ipv6
Jiayuan Chen 21ec92774d net: ipv6: fix panic when IPv4 route references loopback IPv6 nexthop
When a standalone IPv6 nexthop object is created with a loopback device
(e.g., "ip -6 nexthop add id 100 dev lo"), fib6_nh_init() misclassifies
it as a reject route. This is because nexthop objects have no destination
prefix (fc_dst=::), causing fib6_is_reject() to match any loopback
nexthop. The reject path skips fib_nh_common_init(), leaving
nhc_pcpu_rth_output unallocated. If an IPv4 route later references this
nexthop, __mkroute_output() dereferences NULL nhc_pcpu_rth_output and
panics.

Simplify the check in fib6_nh_init() to only match explicit reject
routes (RTF_REJECT) instead of using fib6_is_reject(). The loopback
promotion heuristic in fib6_is_reject() is handled separately by
ip6_route_info_create_nh(). After this change, the three cases behave
as follows:

1. Explicit reject route ("ip -6 route add unreachable 2001:db8::/64"):
   RTF_REJECT is set, enters reject path, skips fib_nh_common_init().
   No behavior change.

2. Implicit loopback reject route ("ip -6 route add 2001:db8::/32 dev lo"):
   RTF_REJECT is not set, takes normal path, fib_nh_common_init() is
   called. ip6_route_info_create_nh() still promotes it to reject
   afterward. nhc_pcpu_rth_output is allocated but unused, which is
   harmless.

3. Standalone nexthop object ("ip -6 nexthop add id 100 dev lo"):
   RTF_REJECT is not set, takes normal path, fib_nh_common_init() is
   called. nhc_pcpu_rth_output is properly allocated, fixing the crash
   when IPv4 routes reference this nexthop.

Suggested-by: Ido Schimmel <idosch@nvidia.com>
Fixes: 493ced1ac4 ("ipv4: Allow routes to use nexthop objects")
Reported-by: syzbot+334190e097a98a1b81bb@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/698f8482.a70a0220.2c38d7.00ca.GAE@google.com/T/
Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20260304113817.294966-2-jiayuan.chen@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-03-05 07:53:17 -08:00
..
ila Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
netfilter
Kconfig
Makefile gro: inline tcp6_gro_receive() 2026-01-21 19:28:32 -08:00
addrconf.c Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses 2026-02-22 08:26:33 -08:00
addrconf_core.c
addrlabel.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
af_inet6.c Convert more 'alloc_obj' cases to default GFP_KERNEL arguments 2026-02-21 20:03:00 -08:00
ah6.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
anycast.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
calipso.c Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses 2026-02-22 08:26:33 -08:00
datagram.c ipv6: use inet->cork.fl.u.ip6 and np->final in ip6_datagram_dst_update() 2026-02-10 20:57:49 -08:00
esp6.c
esp6_offload.c
exthdrs.c ipv6: ioam: fix heap buffer overflow in __ioam6_fill_trace_data() 2026-02-13 12:24:05 -08:00
exthdrs_core.c
exthdrs_offload.c
fib6_notifier.c
fib6_rules.c
fou6.c
icmp.c ipv6: icmp: icmpv6_xrlim_allow() optimization if net.ipv6.icmp.ratelimit is zero 2026-02-18 16:46:37 -08:00
inet6_connection_sock.c tcp: inet6_csk_xmit() optimization 2026-02-10 20:57:50 -08:00
inet6_hashtables.c inet: annotate data-races around isk->inet_num 2026-02-27 17:16:59 -08:00
ioam6.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
ioam6_iptunnel.c ipv6: ioam: fix heap buffer overflow in __ioam6_fill_trace_data() 2026-02-13 12:24:05 -08:00
ip6_checksum.c
ip6_fib.c Convert more 'alloc_obj' cases to default GFP_KERNEL arguments 2026-02-21 20:03:00 -08:00
ip6_flowlabel.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
ip6_gre.c ipv6: use dst6_mtu() instead of dst_mtu() 2026-02-02 17:49:29 -08:00
ip6_icmp.c
ip6_input.c net/ipv6: Introduce payload_len helpers 2026-02-06 20:50:03 -08:00
ip6_offload.c net/ipv6: Remove jumbo_remove step from TX path 2026-02-06 20:50:12 -08:00
ip6_offload.h
ip6_output.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
ip6_tunnel.c ipv6: use dst6_mtu() instead of dst_mtu() 2026-02-02 17:49:29 -08:00
ip6_udp_tunnel.c
ip6_vti.c
ip6mr.c
ipcomp6.c
ipv6_sockglue.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
mcast.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
mcast_snoop.c
mip6.c
ndisc.c ipv6: annotate data-race in ndisc_router_discovery() 2026-01-20 18:37:45 -08:00
netfilter.c
output_core.c net/ipv6: Introduce payload_len helpers 2026-02-06 20:50:03 -08:00
ping.c
proc.c
protocol.c
raw.c ipv6: do not use skb_header_pointer() in icmpv6_filter() 2026-02-06 20:34:20 -08:00
reassembly.c
route.c net: ipv6: fix panic when IPv4 route references loopback IPv6 nexthop 2026-03-05 07:53:17 -08:00
rpl.c
rpl_iptunnel.c
seg6.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
seg6_hmac.c
seg6_iptunnel.c
seg6_local.c
sit.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
syncookies.c tcp: secure_seq: add back ports to TS offset 2026-03-04 17:44:35 -08:00
sysctl_net_ipv6.c
tcp_ao.c
tcp_ipv6.c tcp: secure_seq: add back ports to TS offset 2026-03-04 17:44:35 -08:00
tcpv6_offload.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2026-01-29 17:28:54 -08:00
tunnel6.c
udp.c udp: udplite is unlikely 2026-01-06 17:06:03 -08:00
udp_impl.h
udp_offload.c gro: inline tcp6_gro_complete() 2026-01-21 19:28:32 -08:00
udplite.c udplite: Fix null-ptr-deref in __udp_enqueue_schedule_skb(). 2026-02-20 16:14:10 -08:00
xfrm6_input.c
xfrm6_output.c
xfrm6_policy.c xfrm6: fix uninitialized saddr in xfrm6_get_saddr() 2026-02-02 08:03:47 +01:00
xfrm6_protocol.c
xfrm6_state.c
xfrm6_tunnel.c