summaryrefslogtreecommitdiff
path: root/net/ipv6
AgeCommit message (Collapse)Author
3 daysMerge tag 'nf-26-08-27' of ↵Jakub Kicinski
git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for net: 1) Use DEBUG_NET_WARN_ON_ONCE() instead of WARN_ON() from the tproxy datapath, a recent bug found a way to reach WARN_ON from datapath due to insufficient validation of xt_TPROTO checkentry. From Fernando F. Mancera. 2) Similar to previous patch to replace WARN_ON_ONCE by DEBUG_NET_WARN_ON_ONCE() for connlimit. Not known issue, but since this patch has been around for a while, let's merge it. Also from Fernando. 3) Move nf_tables harware offload commit path after chain blob and audit to reduce chances of leaving the hardware in inconsistent state. 4) Add missing vzeroupper to nf_tables pipapo AVX2 to address performace degradation to later user of SSE code, from Eric Biggers. 5) Remove pr_debug() in x_tables extensions, a recent bogus found a way to print a unsanitized string in xt_IDLETIMER, many of these pr_debug() calls are there for historical reasons. 6) Use pr_info_ratelimited() in x_tables .checkentry. 7) Fix an imbalance in module refcount due to incorrect override expression logic with sets. Remove unnecessary clone in control plane, use the existing expressions provided by set or dynset expression. Release override expressions only. 8) Tigthen nf_tables device name removal, it is possible to remove prefix strings with exact device name. From Fernando F. Mancera. 9) Set on the set dead bit earlier, otherwise it is possible to call .commit on deleted sets. This also addresses the re-introduction of a bug. * tag 'nf-26-08-27' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: nf_tables: remove leftover set_update_list netfilter: nf_tables: set on dead bit when performing early element removal netfilter: nf_tables: skip double clone set expressions on element insert netfilter: x_tables: replace pr_{info,err}() by pr_info_ratelimited() netfilter: x_tables: remove pr_debug netfilter: nft_set_pipapo_avx2: add missing vzeroupper netfilter: nf_tables: move hardware offload step after building the chain blob netfilter: conncount: use DEBUG_NET_WARN_ON_ONCE on reaching count limit netfilter: tproxy: use DEBUG_NET_WARN_ON_ONCE for protocol fallbacks ==================== Link: https://patch.msgid.link/20260827141733.423453-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
3 daysnetfilter: x_tables: remove pr_debugPablo Neira Ayuso
Remove pr_debug() for these xtables extensions, these have no use these days. Still, turn pr_debug() into pr_info_ratelimited() in the .checkentry path since this helps provide a hint via dmesg in legacy iptables. Exception is xt_IDLETIMER in the module init path, where pr_err() is used. Add missing pr_fmt() definition in xt_REDIRECT, xt_NETMAP and xt_MASQUERADE. Add missing \n to several pr_debug() that were translated to use pr_info_ratelimited(). Link: https://patch.msgid.link/cover.1786933680.git.rakukuip@gmail.com/ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 daysnetfilter: tproxy: use DEBUG_NET_WARN_ON_ONCE for protocol fallbacksFernando Fernandez Mancera
Replace WARN_ON calls with DEBUG_NET_WARN_ON_ONCE in the default switch blocks of nf_tproxy_get_sock_v4 and v6. Unsupported transport protocols are already safely handled by returning a NULL socket pointer. This prevents unnecessary system panics when panic_on_warn=1 is enabled in production systems. Link: https://patch.msgid.link/cover.1786968834.git.zhilinz@nebusec.ai/ Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
5 daysseg6: reset IP6CB after IPv6 decapsulationZhiling Zou
decap_and_validate() pulls the outer SRv6 headers and makes the inner packet the skb network header. The IPv6 control block still contains values collected while parsing the outer packet, including nhoff and extension-header flags. End.DX6 and End.DT6 route the inner IPv6 packet directly to the IPv6 input path. An unprivileged user can reach End.DT6 from a user and net namespace by installing a local SID and injecting an outer packet with Hop-by-Hop and Destination Options headers followed by an SRH and a minimal inner IPv6 packet. The outer extension headers leave a large nhoff in IP6CB. After decapsulation, ip6_protocol_deliver_rcu() uses that stale offset on the inner packet and reads beyond the skb head. KASAN reports: BUG: KASAN: slab-out-of-bounds in ip6_protocol_deliver_rcu ip6_protocol_deliver_rcu+0x1118/0x1450 ip6_input_finish+0x11b/0x240 seg6_local_input_core+0xed/0x2e0 lwtunnel_input+0x1e9/0x4e0 ipv6_rthdr_rcv+0x525f/0x6c50 ip6_protocol_deliver_rcu+0xcb7/0x1450 Before clearing IP6CB for an inner IPv6 packet, save its incoming interface index and L3 slave state. Restore both after the clear and set nhoff to the inner IPv6 base-header nexthdr field. Use IP6CB(skb)->iif rather than skb->skb_iif because VRF processing can replace skb_iif with the L3 master while IP6CB keeps the receiving interface. Preserve IP6SKB_L3SLAVE for the same reason. Fixes: d7a669dd2f8b ("ipv6: sr: add helper functions for seg6local") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai> Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it> Signed-off-by: David S. Miller <davem@davemloft.net>
8 daystcp: clamp route advmss to TCP_MIN_MSSYong Wang
tcp_select_initial_window() assumes that callers never pass an MSS smaller than 1, but route-derived advmss values can violate that assumption. A too-small explicit RTAX_ADVMSS is one way to get there, but it is not the only one. The same divide-by-zero can also be reached through the "default advmss" path when RTAX_ADVMSS is left at 0 and the effective advmss is later driven down by route MTU and min_adv_mss. Introduce a tcp_dst_advmss() helper that clamps route advmss to TCP_MIN_MSS before TCP consumes it, and use it in the TCP paths that derive advmss from dst metrics. This keeps the effective MSS from dropping to zero before tcp_select_initial_window() rounds the receive window. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Signed-off-by: Yong Wang <edragain@163.com> Signed-off-by: Ren Wei <weir@nebusec.ai> Link: https://patch.msgid.link/251eaf8277fa7c66364c9815c5da01662d269181.1787074852.git.edragain@163.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
10 daysipv6: seg6: clear IPv4 control block on IPIP decapsulationKyle Zeng
End.DX4 and End.DT4 decapsulate an IPv4 packet through decap_and_validate() and send it directly to IPv4 routing. The inner packet therefore bypasses ip_rcv_core(), which normally clears IPCB before IPv4 interprets skb->cb. The skb instead retains IP6CB data from the outer packet. IP6CB and IPCB use the same skb->cb storage, so IP6CB(skb)->lastopt overlaps IPCB(skb)->opt.optlen and srr, while IP6CB(skb)->nhoff overlaps rr and ts. The sender can make the stale optlen byte nonzero with a valid outer extension-header chain. The reproducers put an eight-byte Destination Options header immediately after the 40-byte IPv6 header and before the Segment Routing Header. ipv6_destopt_rcv() records the sender-controlled Destination Options offset in both lastopt and nhoff, setting them to 40. On the reproduced little-endian x86-64 kernel, IPv4 therefore sees optlen = 40 and rr = 40. Both tcp_v4_save_options() and __ip_options_echo() skip option copying when optlen is zero. Here optlen is 40, so the TCP SYN path allocates room for 40 bytes of option data and calls __ip_options_echo(). The stale rr value makes that function read inner packet byte 41 as the Record Route option length. The reproducers set that sender-controlled byte to 255, so __ip_options_echo() copies 255 bytes into the 40-byte option-data area. Separate End.DX4 and End.DT4 reproducers on the unpatched v7.2-rc5 kernel both produced: BUG: KASAN: slab-out-of-bounds in __ip_options_echo() Write of size 255 The relevant End.DX4 call path is: __ip_options_echo tcp_v4_route_req tcp_conn_request tcp_v4_conn_request tcp_rcv_state_process tcp_v4_do_rcv tcp_v4_rcv ip_protocol_deliver_rcu ip_local_deliver_finish ip_local_deliver input_action_end_dx4_finish input_action_end_dx4 The relevant End.DT4 call path is: __ip_options_echo tcp_v4_route_req tcp_conn_request tcp_v4_conn_request tcp_rcv_state_process tcp_v4_do_rcv tcp_v4_rcv ip_protocol_deliver_rcu ip_local_deliver_finish ip_local_deliver input_action_end_dt4 tcp_v4_save_options() is inlined into the tcp_v4_route_req() path, so it does not appear as a separate frame. When decap_and_validate() handles IPPROTO_IPIP, save the ingress interface from IP6CB, clear IPCB, and restore the saved value. Doing this in the common decapsulation path covers End.DX4, End.DT4, and End.DT46's IPv4 arm. Use IP6CB(skb)->iif rather than skb->skb_iif. These actions run after l3mdev processing, which can replace skb_iif with the L3 master; IP6CB iif still records the receiving interface set at IPv6 ingress. Fixes: 891ef8dd2a8d ("ipv6: sr: implement additional seg6local actions") Cc: stable@vger.kernel.org Suggested-by: Andrea Mayer <andrea.mayer@uniroma2.it> Signed-off-by: Kyle Zeng <kylebot@openai.com> Co-developed-by: David Lee <david.lee@trailofbits.com> Signed-off-by: David Lee <david.lee@trailofbits.com> Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it> Link: https://patch.msgid.link/20260817085839.946321-1-david.lee@trailofbits.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
10 daysip6mr: do not clone dst in ip6mr_cache_report()Eric Dumazet
IPv6 input attaches a non-refcounted (NOREF) dst to skbs under RCU. When an ingress multicast packet misses MFC lookup, ip6mr_cache_unresolved() places the skb onto the unresolved queue, escaping the receive-side RCU grace period. If the underlying route is deleted and freed, and the MFC queue is later resolved with a wrong parent interface, ip6_mr_forward() invokes ip6mr_cache_report(..., MRT6MSG_WRONGMIF), which executes dst_clone(skb_dst(pkt)) on the freed dst entry, triggering a slab use-after-free. Report packets queued to mroute6_sk (a raw socket) and netlink notifications do not require an attached dst entry. Fix this by: 1. Removing dst_clone() in ip6mr_cache_report() and ensuring report skbs do not hold a dst. 2. Dropping skb_dst before queuing unresolved skbs in ip6mr_cache_unresolved(), matching the fact that multicast forwarding resolves outgoing routes anew via ip6_route_output(). Fixes: 67f415dd2906 ("ipv6: convert rx data path to not take refcnt on dst") Reported-by: Zero Day Initiative <zdi-disclosures@trendmicro.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn> Link: https://patch.msgid.link/20260818172755.4083692-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
10 daysipv6: avoid divide by zero in rt6_multipath_rebalanceCen Zhang (Microsoft)
rt6_multipath_rebalance() calculates the total eligible nexthop weight in one pass and programs upper bounds in a second pass. Since RTM_NEWROUTE is RTNL-free, a concurrent ignore_routes_with_linkdown update can make the first pass return zero while the second sees an eligible nexthop, causing rt6_upper_bound_set() to divide by zero. UBSAN: division-overflow in net/ipv6/route.c:4845:17 Oops: divide error: 0000 [#1] SMP KASAN NOPTI rt6_upper_bound_set() net/ipv6/route.c:4845 rt6_multipath_rebalance() fib6_add_rt2node() ip6_route_multipath_add() inet6_rtm_newroute() Skip upper-bound calculation when the first pass reports a zero total. This respects the lock-free performance considerations here and solves insecure scenarios. Fixes: bd11ff421d36 ("ipv6: Get rid of RTNL for SIOCDELRT and RTM_DELROUTE.") Reported-by: AutonomousCodeSecurity@microsoft.com Reported-by: Xiang Mei (Microsoft) <xmei5@asu.edu> Reported-by: Cen Zhang (Microsoft) <blbllhy@gmail.com> Signed-off-by: Cen Zhang (Microsoft) <blbllhy@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260817013237.2797-1-blbllhy@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
10 daysipv6: rpl: fix NULL dereference of idev in ipv6_rpl_srh_rcv()Andrea Mayer
ipv6_rpl_srh_rcv() dereferences idev from __in6_dev_get() without a NULL check when reading idev->cnf.rpl_seg_enabled. When the device's MTU drops below IPV6_MIN_MTU, addrconf_ifdown() clears dev->ip6_ptr through RCU_INIT_POINTER(). A packet that passed the idev check in ip6_rcv_core() can then reach ipv6_rpl_srh_rcv() with dev->ip6_ptr already NULL. Reproduced by flooding the receiving interface with ping6 traffic while flapping its MTU between 1500 and 1200: BUG: KASAN: null-ptr-deref in ipv6_rpl_srh_rcv+0xb3/0x1070 Read of size 4 at addr 00000000000006b4 by task ping6/394 CPU: 2 UID: 0 PID: 394 Comm: ping6 Not tainted 7.2.0-rc7-micro-vm-dev-00095-g24ef02f934ee #240 PREEMPT(full) Call Trace: <IRQ> kasan_report+0xc6/0x100 ipv6_rpl_srh_rcv+0xb3/0x1070 ip6_protocol_deliver_rcu+0x759/0x9a0 ip6_input_finish+0xa8/0x1b0 ip6_input+0xe1/0x490 ipv6_rcv+0x33d/0x460 __netif_receive_skb_one_core+0xd6/0x130 process_backlog+0x2cc/0xa00 __napi_poll.constprop.0+0x56/0x270 net_rx_action+0x327/0x730 handle_softirqs+0x11e/0x630 do_softirq+0xb3/0xf0 </IRQ> Both ipv6_rpl_srh_rcv() and ipv6_srh_rcv() are called only from ipv6_rthdr_rcv(), which already has an idev lookup. Fix the NULL dereference on the RPL path by checking idev in ipv6_rthdr_rcv(), before it calls either function. The callees take idev as an argument and no longer call __in6_dev_get(), so the packet is now dropped in one place, with SKB_DROP_REASON_IPV6DISABLED on both paths. Fixes: 8610c7c6e3bd ("net: ipv6: add support for rpl sr exthdr") Cc: stable@vger.kernel.org Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it> Tested-by: Xiang Mei <xmei5@asu.edu> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20260817132644.2223-1-andrea.mayer@uniroma2.it Signed-off-by: Jakub Kicinski <kuba@kernel.org>
10 daysnet: advertise TCP MSS from the configured MTU, not the learned PMTUJiayuan Chen
The MSS a host puts in its SYN tells the peer how big a segment it may send us. Right now we can shrink it with a PMTU we learned on our own send path, which is the wrong direction entirely. On asymmetric paths this bites - think DSR load balancers, where the request side goes through a smaller-MTU overlay. We learn a small PMTU going out, then advertise a small MSS, and the peer stays capped for the whole connection even though its path back to us is wide. MSS only shows up in the SYN and never grows back. On symmetric paths we lose nothing by dropping it either: the peer runs its own PMTU discovery and usually already knows the real path MTU. So work out the advertised MSS from the configured route or device MTU and ignore the learned PMTU. Our send side is unchanged, still clamped by tcp_current_mss(). Add ip_dst_mtu_configured()/ip6_dst_mtu_configured() and use them from the two default_advmss() paths. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Fixes: 164a5e7ad531 ("ipv4: ipv4_default_advmss() should use route mtu") Cc: stable@vger.kernel.org Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260815070413.294559-1-jiayuan.chen@linux.dev Signed-off-by: Jakub Kicinski <kuba@kernel.org>
10 daysMerge tag 'ipsec-2026-08-18' of ↵Jakub Kicinski
git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec Steffen Klassert says: ==================== pull request (net): ipsec 2026-08-18 1) xfrm6: fix out-of-bounds write in xfrm6_input_addr() when secpath is full Tighten the secpath-depth check so a full chain can't write past xvec[]. 2) Add and revert "esp: do not unref managed frag pages in esp_ssg_unref()" The patch does not fully fully resolve the issue, a corrected version will follow. 3) xfrm: espintcp: fix UAF during close Synchronize espintcp close with the xfrm_trans_reinject work queue so the freed socket message isn't dereferenced again. 4) xfrm: drop ESP-in-TCP packets with no ingress device Drop queued ESP-in-TCP records whose saved ingress device has gone away, avoiding a NULL device deref in the XFRM input path. 5) xfrm: avoid lock inversion in nat keepalive work Split the NAT keepalive walk into a reference-collection phase and a per-state lock phase to break the AB-BA with state removal. This patch has some issues that are fixed with a followup patch. 6) xfrm: Fix skb double-free in xfrm_dev_direct_output() Stop freeing the skb unconditionally in xfrm_dev_direct_output(), letting local_out()'s result indicate when ownership has moved on. 7) xfrm: ah6: validate routing header segments_left Validate the segments_left/hdrlen invariant before rearranging the routing-header addresses, avoiding an OOB memmove on malformed HDRINCL packets. 8) xfrm: fix xfrm_state_construct() auth-trunc leak Detect an already-attached auth-trunc allocation by the pointer rather than inferring it from the algorithm id, so a prior attach isn't overwritten and lost. 9) xfrm: bound nat keepalive state collection Replace the per-state allocation in the NAT keepalive walk with a fixed-size batch that drains under BH-disabled locking and resumes from the cursor, bounding the worker's memory. * tag 'ipsec-2026-08-18' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec: xfrm: bound nat keepalive state collection Revert "esp: do not unref managed frag pages in esp_ssg_unref()" xfrm: fix xfrm_state_construct() auth-trunc leak xfrm: ah6: validate routing header segments_left xfrm: Fix skb double-free in xfrm_dev_direct_output() xfrm: avoid lock inversion in nat keepalive work xfrm: drop ESP-in-TCP packets with no ingress device xfrm: espintcp: fix UAF during close esp: do not unref managed frag pages in esp_ssg_unref() xfrm6: fix out-of-bounds write in xfrm6_input_addr() when secpath is full ==================== Link: https://patch.msgid.link/20260818092920.653034-1-steffen.klassert@secunet.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
10 daysipv6: use RCU iterator to dump route exceptionsYuyang Huang
rt6_nh_dump_exceptions() uses hlist_for_each_entry() to iterate over RCU-protected exception lists. The caller holds rcu_read_lock(), but does not hold rt6_exception_lock, so rt6_insert_exception() can concurrently add an entry with hlist_add_head_rcu(). KCSAN reports this race (irrelevant details omitted): ================================================================== BUG: KCSAN: data-race in rt6_insert_exception / rt6_nh_dump_exceptions write (marked) to 0xffff8a7c44c59620 of 8 bytes by interrupt on cpu 5: rt6_insert_exception+0x3bb/0x760 __ip6_rt_update_pmtu+0x4fe/0x750 ip6_sk_update_pmtu+0x19a/0x3b0 udpv6_err+0x3ff/0x800 icmpv6_notify+0x1e1/0x440 icmpv6_rcv+0x8c0/0xab0 ip6_protocol_deliver_rcu+0x616/0x840 ip6_input_finish+0xb9/0x160 ... entry_SYSCALL_64_after_hwframe+0x77/0x7f read to 0xffff8a7c44c59620 of 8 bytes by task 549 on cpu 14: rt6_nh_dump_exceptions+0xb3/0x260 rt6_dump_route+0x53e/0x5f0 fib6_dump_node+0x6d/0xf0 fib6_walk_continue+0x290/0x2d0 fib6_dump_table+0x28d/0x360 inet6_dump_fib+0x37d/0x620 rtnl_dumpit+0x7b/0xd0 netlink_dump+0x3ae/0x7e0 ... entry_SYSCALL_64_after_hwframe+0x77/0x7f 4 locks held by dumper/549: ... #1: (rcu_read_lock){....}-{1:3}, at: inet6_dump_fib+0x88/0x620 #2: (&tb->tb6_lock){+.-.}-{3:3}, at: fib6_dump_table+0x1e9/0x360 #3: (rcu_read_lock){....}-{1:3}, at: rt6_dump_route+0x483/0x5f0 value changed: 0xffff8a7c44e05700 -> 0xffff8a7c45d60100 Reported by Kernel Concurrency Sanitizer on: CPU: 14 UID: 0 PID: 549 Comm: dumper Not tainted 7.2.0-rc7-virtme #38 PREEMPT(lazy) ... Use hlist_for_each_entry_rcu() to safely iterate over the exception list. Fixes: 1e47b4837f3b ("ipv6: Dump route exceptions if requested") Cc: stable@vger.kernel.org Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com> Reviewed-by: Stefano Brivio <sbrivio@redhat.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260815084651.69477-1-sigefriedhyy@gmail.com Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
12 daysMerge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Merge in late fixes in preparation for the net-next PR. Conflicts: drivers/dpll/dpll_core.c drivers/dpll/dpll_netlink.c 33f016b23a219 ("dpll: fix NULL deref in dpll_device_ops() during teardown race") b1d0c412088e3 ("dpll: add STATE_CONNECTED_OVERRIDE pin capability") https://lore.kernel.org/aoR9YYY2P5--3x0N@sirena.org.uk https://lore.kernel.org/aoR9VmKllVGwmQn_@sirena.org.uk No adjacent changes. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
13 daysip: orphan prefetched skbs before multicast forwardingZhiling Zou
IPv4 and IPv6 input preserve an skb->sk association installed by bpf_sk_assign() so that local delivery can use the selected socket under RCU. Both address families can also prefetch a socket in UDP early demux. In both paths (BPF and UDP early demux) a reference is not guaranteed to be held on the socket. When a multicast packet is not locally deliverable, IPv6 hands the original skb to ip6_mr_input(). IPv4's ip_mr_input() similarly keeps the original skb when local delivery is not needed. Either path can put the skb on an unresolved multicast route queue or forward it after the receive-side RCU section ends. After the prefetched socket is destroyed, a later skb free invokes sock_pfree() and dereferences the stale skb->sk. Orphan the skb before each non-local multicast forwarding path. Local delivery retains the original skb; the existing skb_clone() calls provide multicast forwarding with a socket-free clone. Fixes: cf7fbe660f2d ("bpf: Add socket assign support") Fixes: 08842c43d016 ("udp: no longer touch sk->sk_refcnt in early demux") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai> Reported-by: Vega <vega@nebusec.ai> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/0c52eb3d7532aaf8bccf37e0f7c922143c639735.1786552223.git.zhilinz@nebusec.ai Signed-off-by: Paolo Abeni <pabeni@redhat.com>
13 daysnet: cap advertised IP tunnel headroomZhiling Zou
IP tunnel devices derive their advertised needed_headroom from lower output devices. A stack of user-created devices can make the derived value larger than the 16-bit skb header offsets can represent. Once IP output reserves it, skb head expansion can wrap those offsets. The runtime transmit path already caps a growing needed_headroom at 512. Apply the same cap when tunnel configuration publishes needed_headroom derived from a lower output device. Capping the advertised value is safe: IP tunnel transmit still expands the skb when a packet needs more headroom. A nonsensical stacked configuration can therefore incur an extra reallocation, but it cannot publish an unbounded reservation to upper layers. Fixes: 1a37e412a022 ("net: Use 16bits for *_headers fields of struct skbuff") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/ba04a1fd6bfae2377607fad5d8f80f7eb80fd4c4.1786542637.git.zhilinz@nebusec.ai Signed-off-by: Paolo Abeni <pabeni@redhat.com>
13 daysip6_gre: fix hardware header length for NBMA tunnelsZhiling Zou
ip6gre_tnl_link_config_route() accumulates the lower device's hardware header length into dev->hard_header_len whenever header_ops is set. This is incorrect for both users of header_ops. ip6gretap and ip6erspan have a fixed Ethernet hardware header length. For an NBMA ip6gre tunnel, ip6gre_header() creates only the GRE header, the optional FOU or GUE header, and the outer IPv6 header. The lower device header is headroom needed later, not part of the tunnel device's hardware header. Keep the lower device header in needed_headroom. Set hard_header_len to the tunnel header length only for ARPHRD_IP6GRE devices with header_ops, and leave the fixed Ethernet header length unchanged for tap and erspan devices. Fixes: 832ba596494b ("net: ip6_gre: set dev->hard_header_len when using header_ops") Cc: stable@vger.kernel.org Suggested-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/64b46542bbe1701f07702aaa50273e2a87903db5.1786542637.git.zhilinz@nebusec.ai Signed-off-by: Paolo Abeni <pabeni@redhat.com>
13 daysip6_tunnel: use skb_cow_head() in ip6_tnl_xmit()Zhiling Zou
ip6_tnl_xmit() may need to expand headroom before it can push the outer IPv6 and optional encap headers. It currently does that with skb_realloc_headroom(), copies skb->sk ownership, consumes the original skb, and then continues processing with the replacement skb kept only in its local variable. That is safe only if the helper cannot fail afterwards. But this helper still has post-reallocation error exits. collect_md tunnels reject non-NONE encap after the replacement, and ip6_tnl_encap() can also fail later. In those cases the helper returns an error to its callers while the caller still only has the original skb pointer. Both ip6_tnl_start_xmit() and the IPv6 GRE paths free the caller skb on error, so they can end up freeing an skb that ip6_tnl_xmit() already consumed. Use skb_cow_head() instead. It provides the required headroom and writability without privately replacing the caller-owned skb, so later error returns cannot leave callers with a stale pointer. The Ethernet users, ip6gretap and ip6erspan, clear IFF_TX_SKB_SHARING and already call skb_cow_head() before entering ip6_tnl_xmit(). They do not rely on the removed skb_shared() reallocation. This also makes the IPv6 tunnel path consistent with ip_tunnel_xmit(). Fixes: 058214a4d1df ("ip6_tun: Add infrastructure for doing encapsulation") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai> Link: https://patch.msgid.link/30807a062ccc5c9c8a5ec2c5eb805ef279c50bdd.1786452593.git.zhilinz@nebusec.ai Signed-off-by: Jakub Kicinski <kuba@kernel.org>
13 daysipv6: fix use-after-free in ip6_finish_output2()Luxiao Xu
ip6_finish_output2() caches a pointer to the IPv6 destination address (daddr) before invoking lwtunnel_xmit(). The LWT-BPF transmit path or other encapsulation operations within lwtunnel_xmit() can reallocate the skb head, freeing the memory that daddr points to. When lwtunnel_xmit() returns LWTUNNEL_XMIT_CONTINUE, the function continues to use the stale daddr pointer to compute the nexthop and to look up or create the neighbour entry. This results in a use-after-free read, which can leak sensitive kernel data, pollute the neighbour table with arbitrary values, misdirect traffic, or crash the system. Fix this by re-fetching the IPv6 header and the destination address pointer after lwtunnel_xmit() returns LWTUNNEL_XMIT_CONTINUE, ensuring that the subsequent nexthop computation and neighbour lookup operate on valid memory. Fixes: e415ed3a4b8b ("ipv6: use skb_expand_head in ip6_finish_output2") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Signed-off-by: Luxiao Xu <rakukuip@gmail.com> Signed-off-by: Ren Wei <weir@nebusec.ai> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/4aa3f53bc44e79572c6dd2340ec7b68ef1a3d87d.1786516730.git.rakukuip@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
14 daysRevert "esp: do not unref managed frag pages in esp_ssg_unref()"Steffen Klassert
This reverts commit 21697720ff43b8dfa25b8e8d9ca7f56f4597fc80. The patch does not fix the issue completely, so revert for now and wait for an updated version. Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
2026-08-14gre: fix ERSPAN o_flags race/corruption in xmit and fill_infoEric Dumazet
For IPv4 ERSPAN: In erspan_xmit(), the driver clears IP_TUNNEL_SEQ_BIT (for version 0) and IP_TUNNEL_KEY_BIT directly in the shared tunnel->parms.o_flags structure. Since transmit paths can run locklessly and concurrently, this leads to a data race. Furthermore, modifying tunnel->parms.o_flags permanently alters the tunnel configuration. To work around this, erspan_fill_info() (which reports config to userspace) was setting IP_TUNNEL_KEY_BIT back. If erspan_fill_info (running under RTNL) and erspan_xmit (running locklessly) race, erspan_xmit might see IP_TUNNEL_KEY_BIT set when it shouldn't, leading to GRE header corruption (injecting a key field into the ERSPAN GRE header). Fix this by: 1) Passing flags as an argument to __gre_xmit(). 2) Using local stack flags in ipgre_xmit(), gre_tap_xmit(), and erspan_xmit() to prevent TOCTOU data races with concurrent configuration updates, and passing them to __gre_xmit(). 3) Removing the racy modification of t->parms.o_flags in erspan_fill_info(). 4) Forcing IP_TUNNEL_KEY_BIT in the reported flags for ERSPAN locally in ipgre_fill_info(). For IPv6 ERSPAN: ip6erspan_tunnel_xmit() was locklessly clearing IP_TUNNEL_KEY_BIT in t->parms.o_flags even though it does not use these flags for building the GRE header (it uses local flags). This permanently corrupts the configuration and races with ip6gre_fill_info() which reads it. Remove the redundant and racy modification. This should remove false sharing in a fast path. Add const qualifiers in ipgre_fill_info(), erspan_fill_info() and ip6gre_fill_info() to clarify that these methods are not supposed to write any live parameters. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20260812142257.21283-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-14Merge tag 'nf-next-26-08-10' of ↵Jakub Kicinski
git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next Pablo Neira Ayuso says: ==================== Netfilter updates for net This includes an enhancement to detect ct memleaks easier via DEBUG_NET and flowtable preparation patches for IPv4 over IPV6 and vice-versa. This also includes a fix for the nft_ct custom expectation support. 1) Add DEBUG_NET_WARN_ON_ONCE to nf_ct_set() to spot ct memleaks. 2) Pass struct net_device_path_ctx to dev_fill_forward_path() to make it easier to pass more parameters to this function. From Lorenzo Bianconi. 3) Add ether_type field to net_device_path context structucture. 4) Rename tun.l3_proto field to tun.inner_proto. 5) Rename ctx.tun.proto to ctx.tun.inner_proto. 6) Store ether_type in flowtable context. 7) Move IPv4 and IPv6 xmit path to a helper function. 8) Move encapsulation header parser out of the flowtable lookup function. 9) Rework nft_ct custom expectation support to address a possible reallocation of ct extension area while expectation list also contains expectations. Move datapath to a ct helper to fix it. 10) Ensure timeout is always lowered for the non-closing RST case in the TCP connection tracking. 11) Bail out when inserting already dead expectation, this should not ever happen, hence report it via DEBUG_NET. 12) Comestic updates for improving the conntrack selftest dump and flush userspace program, from Qingshuang Fu. * tag 'nf-next-26-08-10' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next: selftests: netfilter: conntrack_dump_flush: remove unused variables and fix typo netfilter: nf_conntrack_expect: bail out on insert dead expectations netfilter: conntrack: always lower timeout for non-closing RST packets netfilter: nft_ct: move custom expectation support to helper netfilter: flowtable: detach layer 2 encapsulation parser from lookup netfilter: flowtable: move ipv4 and ipv6 xmit path to function netfilter: flowtable: store ethertype in flowtable context netfilter: flowtable: rename ctx.tun.proto to ctx.tun.inner_proto netfilter: flowtable: rename tun.l3_proto to tun.inner_proto net: netfilter: add ether_type to net_device_path_ctx and use it net: pass net_device_path_ctx to dev_fill_forward_path() netfilter: add DEBUG_NET_WARN_ON_ONCE to skb_set_nfct() ==================== Link: https://patch.msgid.link/20260810194015.932627-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-13net: Const qualify network templated ctl_tables ArraysJoel Granados
Add duplication helpers in the cases where the ctl_table array elements are modified after duplication. Helpers return a ctl_table as const pointer allowing the const qualification of the static global ctl_table array. Signed-off-by: Joel Granados <joel.granados@kernel.org> Link: https://patch.msgid.link/20260810-jag-net_const_qualify-v4-3-77e888237c69@kernel.org Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-13net: Const qualify ctl_tables that kmemdup unconditionallyJoel Granados
Const qualify clt_table arrays in the net directory that always pass a memory duplicate to sysctl register. The template would then be in .rodata and the kmemdup'ed array would be outside. Signed-off-by: Joel Granados <joel.granados@kernel.org> Link: https://patch.msgid.link/20260810-jag-net_const_qualify-v4-2-77e888237c69@kernel.org Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-13ipv6: add inet6_rt_del_notify()Yuyang Huang
Move the body of inet6_rt_notify() to __inet6_rt_notify() and give it the deletion reason. inet6_rt_notify() keeps its prototype, so the route addition path does not change. Add inet6_rt_del_notify() and call it from fib6_del_route(). RTA_DEL_REASON now reaches user space on RTM_DELROUTE for routes the kernel deleted on its own. Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260808005642.26901-7-sigefriedhyy@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-13ipv6: expose the route deletion reason in RTM_DELROUTEYuyang Huang
Emit RTA_DEL_REASON from rt6_fill_node() when the deletion reason is not RT_DEL_REASON_UNSPEC, and reserve room for it in rt6_nlmsg_size(). Every caller still passes RT_DEL_REASON_UNSPEC. Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260808005642.26901-6-sigefriedhyy@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-13ipv6: add a deletion reason argument to rt6_fill_node()Yuyang Huang
Add the deletion reason to rt6_fill_node() so that it can report it to user space. All callers pass RT_DEL_REASON_UNSPEC for now. Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260808005642.26901-5-sigefriedhyy@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-13ipv6: record the reason for kernel-initiated route deletionsYuyang Huang
Record why the kernel deletes an IPv6 route on its own: - RT_DEL_REASON_EXPIRED for routes reaped by the FIB6 garbage collector after their RTF_EXPIRES lifetime ran out. - RT_DEL_REASON_RA_WITHDRAWN for default routes, prefix routes and RFC 4191 route information routes withdrawn by a zero-lifetime Router Advertisement. Deleting a default route because its metric changed is not a withdrawal, so it keeps RT_DEL_REASON_UNSPEC. Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260808005642.26901-4-sigefriedhyy@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-13ipv6: propagate the route deletion reason to fib6_del_route()Yuyang Huang
Pass the deletion reason from ip6_del_rt_reason() down through __ip6_del_rt(), fib6_del() and into fib6_del_route(). All existing callers pass RT_DEL_REASON_UNSPEC. fib6_del_route() ignores the reason until the notification path learns to report it. Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260808005642.26901-3-sigefriedhyy@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-13ipv6: add ip6_del_rt_reason()Yuyang Huang
Add RTA_DEL_REASON and enum rt_del_reason to the rtnetlink uAPI, and add ip6_del_rt_reason(), which takes the reason a route is being deleted. It has no skip_notify argument: a caller that records a deletion reason wants the notification that carries it. The reason is unused for now. Subsequent patches propagate it to the deletion path and report it on RTM_DELROUTE. Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260808005642.26901-2-sigefriedhyy@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-08-10netfilter: flowtable: rename tun.l3_proto to tun.inner_protoPablo Neira Ayuso
This field refers to the inner protocol that is encapsulated by the tunnel header, just a comestic change. No functional changes are expected. Acked-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2026-08-10net: netfilter: add ether_type to net_device_path_ctx and use itPablo Neira Ayuso
Add an ether_type field to struct net_device_path_ctx to reject IPv4 over IPv6 and vice-versa, this is currently not support. Otherwise, incorrect dst_entry family can be reached from datapath. Acked-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2026-08-07bridge: Use ndisc_parse_options() to parse ND options in br_nd_send()Danielle Ratson
Replace the manual ND option parsing loop in br_nd_send() with ndisc_parse_options(), which provides proper validation and avoids the class of bugs that were fixed by commit 53fc685243bd ("bridge: Avoid infinite loop when suppressing NS messages with invalid options") and commit 850837965af1 ("bridge: br_nd_send: validate ND option lengths"). Use ndisc_opt_addr_data() to extract the source link-layer address from the parsed options, which correctly validates the option length for the underlying device type. Export ndisc_parse_options() so that it can be resolved from the bridge when it is built as a module (CONFIG_BRIDGE=m); otherwise modpost fails with an undefined symbol. Reviewed-by: Petr Machata <petrm@nvidia.com> Acked-by: Nikolay Aleksandrov <razor@blackwall.org> Signed-off-by: Danielle Ratson <danieller@nvidia.com> Link: https://patch.msgid.link/20260803112505.613873-6-danieller@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-07ipv6: ndisc: Add ndisc_check_ns_na() validation helperDanielle Ratson
Add ndisc_check_ns_na(), a standalone NS/NA packet validator modeled after ipv6_mc_check_mld(). It performs the RFC 4861 section 7.1.1 (Neighbor Solicitation) and 7.1.2 (Neighbor Advertisement) mandatory checks that are relevant for software operating at the bridge level, where packets bypass the normal IPv6 stack path: - Hop Limit must be 255 (packet was not forwarded by a router) - ICMPv6 checksum is valid - ICMP Code is 0 - ICMP length is at least 24 octets (sizeof(struct nd_msg)) - Target Address must not be a multicast address - All included options have a length that is greater than zero - NS/DAD: destination must be a solicited-node multicast address - NS/DAD: no Source Link-Layer Address option when source is unspecified - NA: Solicited flag must be 0 when IP Destination is multicast On success the function sets the skb transport header and returns 0, matching the convention of ipv6_mc_check_mld(). Reviewed-by: Petr Machata <petrm@nvidia.com> Acked-by: Nikolay Aleksandrov <razor@blackwall.org> Signed-off-by: Danielle Ratson <danieller@nvidia.com> Link: https://patch.msgid.link/20260803112505.613873-3-danieller@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-06Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.2-rc7). No conflicts, or adjacent changes. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-05ip6_tunnel: clear skb2->cb[] in ip6ip6_err()Zhiling Zou
ip6ip6_err() clones an outer IPv6 ICMP error skb, pulls it to the quoted inner IPv6 packet, and then passes the clone to icmpv6_send(). The clone still carries the outer packet's inet6_skb_parm in skb->cb. If the outer packet had a Home Address Option, IP6CB(skb2)->dsthao remains non-zero after skb_pull(). icmpv6_send() later calls mip6_addr_swap(), which uses that stale dsthao offset against the quoted inner packet. A malformed inner destination-options header can then make the HAO lookup and address swap run past the end of the quoted packet and corrupt skb_shared_info. Clear skb2->cb[] before pulling the quoted inner IPv6 packet so the reply path does not reuse metadata left by the outer IPv6 stack. Fixes: e490d1d85cf5 ("[IPV6] IP6TUNNEL: Split out generic routine in ip6ip6_err().") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/fe1a5e765fbca88d69391887f0ed26a19e3e4d39.1785736562.git.zhilinz@nebusec.ai Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-05Merge tag 'nf-next-26-07-31' of ↵Jakub Kicinski
git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following patchset contains Netfilter updates for net-next: 1) Update conncount to use the original tuple after ct lookup to ensure consistent counting, from Fernando F. Mancera. 2) Remove redundant net_device field in info structure that helps parse the flowtable path discovery. 3) Move net_device to flowtable check to the flowtable discovery path parser. This is preparation work to pass the tunnel dst_entry via .fill_forward_path. 4) Update DSA .fill_forward_path to break at the user DSA, since the conduit DSA is not used in the datapath. This slighly simplifies the flowtable path discovery parser. 5) Do not advance index in the path stack prematurely, otherwise it points to uninitialized slots on error. Not an issue currently but it could be once tunnel dst_entry is passed via .fill_forward_path. 6) Pass the tunnel dst_entry via dev_fill_forward_path(). 7) Update ipip and ip6ip6 tunnels to pass the dst_entry through dev_fill_forward_path(). 8) Call skb_valid_dst() before accessing skb_dst() to ensure dst_entry is not a template. 9) Use UNACK timeout when RST packet does not match the expected window while in ESTABLISHED state, the existing approach the CLOSE state timeout which is only 10 seconds. Adopt a more conservative timeout by default for this case. * tag 'nf-next-26-07-31' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next: netfilter: conntrack: tcp: use UNACK timeout for non-closing RST packets netfilter: nf_tables: call skb_valid_dst() before skb_dst() netfilter: flowtable: release tunnel route on error when building forward path net: pass dst via net_device_path in dev_fill_forward_path() net: do not advance stack index from dev_fwd_path() net: dsa: stop at the user device in .fill_forward_path netfilter: flowtable: consolidate flowtable device check netfilter: flowtable: consolidate net_device field in nft_forward_info struct netfilter: conncount: normalize tuple and zone on successful ct lookup ==================== Link: https://patch.msgid.link/20260731153402.851224-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-03ipv6: raw: convert do_rawv6_getsockopt to sockopt_tBreno Leitao
Convert do_rawv6_getsockopt to the new sockopt_t model, mirroring what we have in ipv4. The overall goal is to move these callbacks gradually from __user points to use sockopt_t, and this part touches do_rawv6_getsockopt. No functional change. Reviewed-by: Joe Damato <joe@dama.to> Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Breno Leitao <leitao@debian.org> Link: https://patch.msgid.link/20260729-getsockopt_phase4-v4-2-c44576757c17@debian.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-03ipv6: raw: drop unused level argument from do_rawv6_getsockoptBreno Leitao
do_rawv6_getsockopt() takes a level argument but never uses it; the level dispatch is handled by the caller, rawv6_getsockopt(). Drop it, matching ipv4's do_raw_getsockopt(). No functional change. Reviewed-by: Joe Damato <joe@dama.to> Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Breno Leitao <leitao@debian.org> Link: https://patch.msgid.link/20260729-getsockopt_phase4-v4-1-c44576757c17@debian.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-03ipv6: fix Route Information option length validationYuejie Shi
rt6_route_rcv() validates the Route Information option (RFC 4191) length against the prefix length, but both checks are off by one. rinfo->length is the ND option length in units of 8 octets and it *includes* the 8-byte option header, so an option carrying N bytes of prefix has length == 1 + N/8. RFC 4191 section 2.3 requires length 3 when Prefix Length is greater than 64, and 2 or 3 when it is greater than 0. The code accepts length >= 2 and length >= 1 respectively. ipv6_addr_prefix() then copies prefix_len/8 bytes out of rinfo->prefix, so a Router Advertisement with (prefix_len=128, length=2) or (prefix_len=64, length=1) makes the kernel read up to 8 bytes past the end of the option. Those bytes end up in the prefix of the route that gets installed, so they are visible to userspace: # RA with a Route Information option (prefix_len=128, length=2) # followed by a source link-layer address option, 01 01 de ad be ef ca fe $ ip -6 route show 2001:db8:dead:beef:101:dead:beef:cafe via fe80::1234 dev veth0 proto ra ^^^^^^^^^^^^^^^^^^ the next option, read out of bounds When the Route Information option is the last one in the packet, those eight bytes come from the skb tail room instead. Reject the option lengths RFC 4191 does not allow. Fixes: 70ceb4f53929 ("[IPV6]: ROUTE: Add experimental support for Route Information Option in RA (RFC4191).") Cc: stable@vger.kernel.org Signed-off-by: Yuejie Shi <syjcnss@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260730035310.74584-1-syjcnss@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-07-31netfilter: nf_tables: call skb_valid_dst() before skb_dst()Pablo Neira Ayuso
When fetching the dst_entry from the skb, check if it valid, ie. this is not a template dst, for extensions that can be used from the netdev ingress and egress chains. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2026-07-31netfilter: flowtable: release tunnel route on error when building forward pathPablo Neira Ayuso
nft_flow_tunnel_update_route() can lazy fail, leaving an incomplete forward path set ip. The route lookup also happens twice, once from dev_fill_forward_path() and again in this aforementioned function. Update ipip and ip6ip6 not to release the dst_entry and pass it on via the tunnel forward path information. In case of failure when setting up the forwarding path, release the tunnel dst that was provided via dev_fill_forward_path(). Acked-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2026-07-30Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.2-rc6). No conflicts. Adjacent changes: net/ipv4/route.c dbc3791e3b24 ("net: do not send ICMP/NDISC Redirects when peer allocation fails") 7804eaa057fe ("ipv4: snapshot dst.dev in ip_rt_send_redirect() and ip_rt_get_source()") drivers/net/tun.c 23dad2d088df ("tun: no longer rely on RTNL in tun_fill_info()") c3da92af07ea ("Revert "tun/tap: add ptr_ring consume helper with netdev queue wakeup"") drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c 3bd438a58e91 ("octeontx2-af: Block VFs from clobbering special CGX PKIND state") 5ba5611ef946 ("octeontx2-af: reserve 4 PKINDs for skip-size custom use") drivers/net/wireless/ath/ath12k/core.h drivers/net/wireless/ath/ath12k/mac.c drivers/net/wireless/ath/ath12k/peer.c 469d7e6077c1 ("wifi: ath12k: resolve PENDING ML peer ID from MLO_PEER_MAP HTT event") 378e659029d5 ("wifi: ath12k: introduce host_alloc_ml_id hardware parameter") c42b27336eef ("wifi: ath12k: fix survey indexing across bands") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-07-30ipv6: remove unnecessary reset of position pointerFernando Fernandez Mancera
The position pointer is only advanced if the return value of the proc handler is positive at new_sync_write(). Therefore no need to manually reset it when doing error handling. Reviewed-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de> Link: https://patch.msgid.link/20260727091834.6645-2-fmancera@suse.de Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-07-29ipv6: release fib6_null_entry on subtree failureShuangpeng Bai
When adding a source-specific route creates a new subtree, fib6_add() installs fib6_null_entry as the temporary leaf of the new subtree root and takes a fib6_info reference for that holder. If adding the first source leaf fails, the code frees the just allocated subtree root but leaves that hold behind. fib6_null_entry is a per-netns sentinel and is freed directly at netns teardown, so this does not keep the object alive. However, it leaves its visible refcount permanently elevated and can eventually saturate the refcount on repeated failures. Drop the null-entry reference before freeing the unlinked subtree root. Fixes: 5ea715289af6 ("ipv6: broadly use fib6_info_hold() helper") Signed-off-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Link: https://patch.msgid.link/20260727185339.1545169-1-shuangpeng.kernel@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-07-28net: ip6_tunnel: use tunnel parameters for fill_forward_path route lookupLorenzo Bianconi
Reuse the flowi6 template t->fl.u.ip6 built by ip6_tnl_link_config() in ip6_tnl_fill_forward_path(), aligning the fast-path route lookup with the slow path in ipxip6_tnl_xmit(). This automatically inherits the correct conditional FLOWLABEL masking based on the IP6_TNL_F_USE_ORIG_FLOWLABEL flag. Return -EOPNOTSUPP when IP6_TNL_F_USE_ORIG_TCLASS, IP6_TNL_F_USE_ORIG_FLOWLABEL or IP6_TNL_F_USE_ORIG_FWMARK is set, or for collect_md tunnels, since fill_forward_path has no access to the original skb and cannot recover the per-packet traffic class, flowlabel, mark or tunnel destination needed for the route lookup. Reviewed-by: David Ahern <dsahern@kernel.org> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Link: https://patch.msgid.link/20260724-ip6ip6-route-lookup-fill_forward_path-v3-1-7b7991538614@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-07-27net: ipv6: clear suppressed fib6 rule resultZhiling Zou
fib6_rule_suppress() drops a suppressed route with ip6_rt_put_flags(), but leaves res->rt6 pointing at the released rt6_info. If no later rule supplies a replacement, fib6_rule_lookup() still sees res.rt6 and returns that stale dst to its caller. A suppressing rule can therefore leak a released route back to rt6_lookup(), and the next put hits rcuref_put_slowpath() from dst_release(). Clear res->rt6 when suppressing the route so suppressed lookups fall through to the null dst instead of reusing the released one. Fixes: cdef485217d3 ("ipv6: fix memory leak in fib6_rule_suppress") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai> Signed-off-by: Ren Wei <enjou1224z@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/4b8acb7787d54e440155585dd32ebdf0bef7d122.1784710966.git.zhilinz@nebusec.ai Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-07-27net: do not send ICMP/NDISC Redirects when peer allocation failsEric Dumazet
When inet_getpeer_v4() or inet_getpeer_v6() fails to allocate a peer entry under memory pressure or tree size caps, redirect handlers previously fell back to sending un-rate-limited ICMP/NDISC Redirect messages. In IPv4, ip_rt_send_redirect() called icmp_send() directly when peer == NULL. In IPv6, ip6_forward() and ndisc_send_redirect() passed a NULL peer into inet_peer_xrlim_allow(), which returned true when peer == NULL. Because ICMP/NDISC Redirects are not part of the default global rate limit mask (sysctl_icmp_ratemask), sending redirects when peer == NULL creates an un-rate-limited ICMP packet storm. Fix this by failing closed in ip_rt_send_redirect(), ip6_forward(), and ndisc_send_redirect() when peer is NULL. Fixes: 92d868292634 ("inetpeer: Move ICMP rate limiting state into inet_peer entries.") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260724072901.1633601-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-07-27xfrm: ah6: validate routing header segments_leftAsim Viladi Oglu Manizada
AH6 rearranges routing-header addresses before computing or verifying the ICV. ipv6_rearrange_rthdr() assumes that segments_left is not larger than the number of addresses described by the routing header's hdrlen field. That assumption does not hold for raw IPv6 HDRINCL packets. A packet with hdrlen equal to 2 describes one address, but can carry an arbitrary segments_left value. With segments_left equal to 255, the function moves its address pointer 4,064 bytes backwards and passes a 4,064-byte length to memmove(), resulting in an out-of-bounds access. Validate the invariant locally before modifying the routing header or performing any address-pointer arithmetic, and propagate malformed-header errors to the existing AH6 input and output error paths. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Assisted-by: avom-custom-harness:gpt-5.5-qwen3.6-mod-mix Signed-off-by: Asim Viladi Oglu Manizada <manizada@pm.me> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
2026-07-23Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.2-rc5). Conflicts: drivers/net/amt.c 3656a79f94c47 ("amt: re-read skb header pointers after every pull") 586c4dcf28eb6 ("amt: no longer rely on RTNL in amt_fill_info()") https://lore.kernel.org/amIaJr3aOQNS_Fvl@sirena.org.uk Adjacent changes: drivers/net/geneve.c 8efb8f8bbb35 ("geneve: require CAP_NET_ADMIN in the device netns for changelink") 0ba269933f73 ("geneve: convert config to RCU-protected pointer") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-07-23ipv6: Change allocation flags to match rcu_read_lock section requirementsNikola Z. Ivanov
Since the call to __ip6_del_rt_siblings has been converted under rcu read lock and it only has one call point we should no longer block or yield. Our stack trace from the syzbot reproducer looks as follows: __ip6_del_rt_siblings rtnl_notify (Here we pass gfp_any() -> GFP_KERNEL) nlmsg_notify nlmsg_multicast nlmsg_multicast_filtered netlink_broadcast_filtered (GFP_KERNEL passed from earlier) netlink_broadcast_filtered can yield if GFP_KERNEL is passed, which we do not want to happen. Fix this by changing the allocation flag of rtnl_notify. Also change the flag passed to nlmsg_new. Even though it is not related to the syzbot generated bug it still falls under the same requirements. Reported-by: syzbot+84d4a405ed798b40c96d@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=84d4a405ed798b40c96d Fixes: bd11ff421d36 ("ipv6: Get rid of RTNL for SIOCDELRT and RTM_DELROUTE.") Signed-off-by: Nikola Z. Ivanov <zlatistiv@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260719105759.558050-1-zlatistiv@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>