mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
v7.4-rc1
9298 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4c6fbb1fba |
ipv6: Protect multiple routes insertion by table lock.
syzbot reported the warning below. [0]
While call_fib6_multipath_entry_notifiers() is called locklessly,
fib6_siblings could be changed concurrently, leading to the
warning (and later null-ptr-deref).
Let's protect multiple routes insertion with tb6_lock.
Along with that, __ip6_ins_rt() and ip6_route_del() are changed
to fib6_add() and fib6_del().
Note that fib6_del() finally calls rt6_multipath_rebalance(),
which requires rcu_read_lock().
[0]:
i != fen6_info->nsiblings
WARNING: drivers/net/netdevsim/fib.c:831 at nsim_fib6_event_init drivers/net/netdevsim/fib.c:831 [inline], CPU#0: syz.0.157/6279
WARNING: drivers/net/netdevsim/fib.c:831 at nsim_fib6_prepare_event drivers/net/netdevsim/fib.c:947 [inline], CPU#0: syz.0.157/6279
WARNING: drivers/net/netdevsim/fib.c:831 at nsim_fib_event_schedule_work drivers/net/netdevsim/fib.c:1003 [inline], CPU#0: syz.0.157/6279
WARNING: drivers/net/netdevsim/fib.c:831 at nsim_fib_event_nb+0x1029/0x11d0 drivers/net/netdevsim/fib.c:1043, CPU#0: syz.0.157/6279
Modules linked in:
CPU: 0 UID: 0 PID: 6279 Comm: syz.0.157 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026
RIP: 0010:nsim_fib6_event_init drivers/net/netdevsim/fib.c:831 [inline]
RIP: 0010:nsim_fib6_prepare_event drivers/net/netdevsim/fib.c:947 [inline]
RIP: 0010:nsim_fib_event_schedule_work drivers/net/netdevsim/fib.c:1003 [inline]
RIP: 0010:nsim_fib_event_nb+0x1029/0x11d0 drivers/net/netdevsim/fib.c:1043
Code: eb 0d 4d 89 fd e8 b7 c5 6c fa be 01 00 00 00 48 89 df e8 5a 38 85 fd 4d 89 ef 4c 8b 6c 24 20 e9 4a f3 ff ff e8 98 c5 6c fa 90 <0f> 0b 90 e9 db fa ff ff 89 e9 80 e1 07 80 c1 03 38 c1 0f 8c df f0
RSP: 0018:ffffc900047bef10 EFLAGS: 00010293
RAX: ffffffff875b59a8 RBX: 0000000000000002 RCX: ffff888079770000
RDX: 0000000000000000 RSI: 0000000000000002 RDI: 0000000000000001
RBP: ffffc900047bf0a0 R08: ffff88805c0bb02f R09: 1ffff1100b817605
R10: dffffc0000000000 R11: ffffed100b817606 R12: dffffc0000000000
R13: 0000000000000000 R14: 0000000000000001 R15: ffff88802c792000
FS: 00007f334ba076c0(0000) GS:ffff888123ad0000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f334ba06ff8 CR3: 000000007a5b2000 CR4: 00000000003526f0
Call Trace:
<TASK>
notifier_call_chain+0x1a5/0x3d0 kernel/notifier.c:85
atomic_notifier_call_chain+0xda/0x180 kernel/notifier.c:223
call_fib_notifiers+0x31/0x60 net/core/fib_notifier.c:36
call_fib6_multipath_entry_notifiers+0xf5/0x160 net/ipv6/ip6_fib.c:428
ip6_route_multipath_add net/ipv6/route.c:5542 [inline]
inet6_rtm_newroute+0x14f5/0x1a30 net/ipv6/route.c:5664
rtnetlink_rcv_msg+0x802/0xc00 net/core/rtnetlink.c:7163
netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2572
netlink_unicast_kernel net/netlink/af_netlink.c:1335 [inline]
netlink_unicast+0x7bd/0x940 net/netlink/af_netlink.c:1361
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1916
sock_sendmsg_nosec+0x14e/0x190 net/socket.c:800
__sock_sendmsg net/socket.c:818 [inline]
____sys_sendmsg+0x54e/0x850 net/socket.c:2715
___sys_sendmsg+0x2a5/0x360 net/socket.c:2769
__sys_sendmmsg+0x273/0x4d0 net/socket.c:2858
__do_sys_sendmmsg net/socket.c:2885 [inline]
__se_sys_sendmmsg net/socket.c:2882 [inline]
__x64_sys_sendmmsg+0xa0/0xc0 net/socket.c:2882
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f334ab9e1d9
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f334ba07028 EFLAGS: 00000246 ORIG_RAX: 0000000000000133
RAX: ffffffffffffffda RBX: 00007f334ae26090 RCX: 00007f334ab9e1d9
RDX: 04000000000001f2 RSI: 0000200000000000 RDI: 0000000000000004
RBP: 00007f334ac35888 R08: 0000000000000000 R09: 0000000000000000
R10: 00000000000000fc R11: 0000000000000246 R12: 0000000000000000
R13: 00007f334ae26128 R14: 00007f334ae26090 R15: 00007ffd96688aa8
</TASK>
Fixes:
|
||
|
|
564313447e |
Revert "net: advertise TCP MSS from the configured MTU, not the learned PMTU"
This reverts commit |
||
|
|
6fb4e32f2c |
inet: frags: prevent acceptance of partially authenticated reassembly
A reassembled skb retains the secpath from its first fragment, which
makes it possible for the final policy check to accept bytes that were
not covered by the transform recorded on the skb. This can affect IPsec
tunnel traffic, including AH and ESP, and allow a packet to be accepted
even though only part of its payload was authenticated.
Reject a fragment when its secpath differs from the fragments already
in the queue, and keep overlap statistics limited to actual overlaps.
Fixes:
|
||
|
|
09280680f2 |
ipmr: drop packets with unknown ingress VIF
A packet can race with VIF publication and make ipmr_find_vif() return -1 even though the VIF device pointer is already visible. The parent VIF device check can then pass with an invalid ingress VIF. For (*,G) entries, this can also let the packet be forwarded back out its ingress VIF. Drop packets whose ingress VIF lookup fails in both IPv4 and IPv6 forwarding, before checking the MFC parent device. This prevents forwarding with an unknown ingress VIF and avoids the (*,G) hairpin. Without the early check, the negative index can reach the IPv4 offload lookup only for an skb marked for L3 forwarding offload, currently done by mlxsw. The race is rare; the supplied PoC reports only the UBSAN negative-index diagnostic. Fixes: |
||
|
|
aa1799e93f |
ipmr, ip6mr: validate packets injected into the register vif on xmit
reg_vif_xmit() passes the packet to ipmr_cache_report() which copies its IP header into the IGMPMSG_WHOLEPKT report that is queued to the mroute socket. Nothing guarantees that the packet contains a full IP header, so when a short packet is injected on the register device (e.g., using AF_PACKET), the copy reads past the end of the packet and a recvmsg() on the mroute socket leaks the uninitialized bytes to user space [1]. IPv6 has the same problem [2]. Its reg_vif_xmit() does call pskb_inet_may_pull(), but the helper keys off skb->protocol and does not pull anything when the protocol is neither IPv4 nor IPv6. Fix by dropping packets whose protocol does not match the address family of the register device or that do not contain a full network header. [1] BUG: KMSAN: kernel-infoleak in _copy_to_iter raw_recvmsg Uninit was stored to memory at: ipmr_cache_report reg_vif_xmit packet_sendmsg Uninit was created at: __alloc_skb sock_alloc_send_pskb packet_sendmsg Bytes 1-3 of 21 are uninitialized [2] BUG: KMSAN: kernel-infoleak in _copy_to_iter rawv6_recvmsg Uninit was stored to memory at: ip6mr_cache_report reg_vif_xmit packet_sendmsg Uninit was created at: __alloc_skb sock_alloc_send_pskb packet_sendmsg Bytes 8-23 of 41 are uninitialized Fixes: |
||
|
|
207dd12bc1 |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Merge in late fixes in preparation for the net-next PR. Conflicts: net/netfilter/nf_conntrack_netlink.c |
||
|
|
d5d524f469 |
netfilter pull request 26-10-19
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEjF9xRqF1emXiQiqU1w0aZmrPKyEFAmrWLcoACgkQ1w0aZmrP
KyGlNg/+OGCFkcwos/7Ph9XHFwZWmSAfqB9dJefnJC3Pz4s1q22ZQzZNaKfUHD8y
LDlgLzXjBw8XIfiM9yT6/1vaJiBE8ciWYnynDBxOB9QX01t23GqPDA/EdPJ16ket
LrkJm2tpjNXdqaTm1D8144TaP0/mUGzjqPpH8PwsjCxuDMx0WaaQG4tcU9nWE0S/
YzfgRq0JmWX0um/TIGA3PCZeCVeJ65yhjpDdWm+/ExzmPr29tTlmTedqLz82EPAf
Bw/D1MKk3qAs+IJgUCoTTScLPPsS+zMRvO0Go/ftc9A9hztw/iN/Pfd0J8ZdhMcp
ekwPWvWaZQ1M0WLaffCClao3+86OOSPG0vAQkTHD943asAzu2sv01pnLMopxmJzJ
gq0irC9Zf7X01M6VazGmJtkvWl7MFee1JJDBO3VsRBw4qBm4pu1D+qTJoqwzgAcG
X+p3f6mp7rNL7qT7tgG41BaQ727zI9IOFeZstcqDbn+QyCwdgDZkziF3CynUT2St
FmrhbzxEIQGLMlMRAxNfoX2u64pZ0CU+p2bQku613sFA9WkYLAbsUfyuHGXeIgec
DqMDRxeuI+82mUdPy4+cEAgPlvN+/tCFdTyoeALM/8GyvUCI1Y6Gj80ky1+Y4Bku
kA0GVevusfv0H3Fek/Zozi7hXxOctpLDCnNo2PRB4FM0/mqkUQU=
=ZrLH
-----END PGP SIGNATURE-----
Merge tag 'nf-26-10-19' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf
Pablo Neira Ayuso says:
====================
Netfilter/IPVS fixes for net
The following patchset contains Netfilter/IPVS for net:
1) Fix IPv6 nexthdr offset truncation in fragment reassembly,
this has been uncovered by LLM, from Jeremy Jean.
2) Restrict checksums in nfqueue to known protocols and offset,
after this patch the plan is to re-enable nfqueue in userns,
this came via LLM report. from Florian Westhphal.
3) Fix races when handling overload flag in IPVS, this patch
is not perfect but Julian considers this improves the situation.
This was uncovered by LLM. From Julian Anastasov.
4) Error handling for IPVS sync_threshold sysctl, from Joel Granados.
5) Use skb_vlan_tag_get_id() to retrieve the VLAN id, discard tci
bits, when handling VLAN in the flowtable, from Shuangfeng He.
6) Initialize IPCB for inet/ingress reject, uncovered by LLM.
7) Restrict completion of binary search array to anonymous set.
8) Restrict DCCP option matching to avoid out-of-bound read,
from Sung Byeongchan.
9) Reset transport header offset in flowtable after tunnel
decapsulation to fix issue with qdisc xmit path,
from Lorenzo Bianconi.
10) Fix inverted matching in ctnetlink dump filtering,
from Liu Chao.
* tag 'nf-26-10-19' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
netfilter: nf_conntrack_netlink: fix inverted IPv6 tuple filter
netfilter: flowtable: reset transport header after nf_flow_encap_pop()
netfilter: xt_dccp: handle reserved options as single-byte
netfilter: nft_set_rbtree: narrow down range completion to anonymous sets
netfilter: nf_reject: initialize IPCB at inet ingress
netfilter: flowtable: use the vlan id, not the full tci, in the tuple key
ipvs: skip committing sync_threshold when proc_dointvec fails
ipvs: fix more races around the overload flag
netfilter: nft_payload: restrict checksum offsets to known values
netfilter: nf_conntrack: avoid truncating IPv6 nexthdr offset
====================
Link: https://patch.msgid.link/20261019150249.1879516-1-pablo@netfilter.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||
|
|
7c9cb1edaf |
ipv6: Hold RCU when emitting route hardware flags notification
fib6_info_hw_flags_set() is called by drivers from process context
without RTNL or RCU. When the route uses a nexthop object,
rt6_nlmsg_size() and rt6_fill_node() access the nexthop's RCU protected
nexthop info and group pointers via rcu_dereference_rtnl(), resulting in
suspicious RCU usage splats [1].
Fix by holding RCU while sizing and filling the notification, like
fib_alias_hw_flags_set() already does. Switch to GFP_ATOMIC for the skb
allocation accordingly.
Reproducer:
# echo "10 0" > /sys/bus/netdevsim/new_device
# sysctl -wq net.ipv6.fib_notify_on_flag_change=1
# sysctl -wq net.ipv4.nexthop_compat_mode=1
# ip -6 nexthop add id 1 blackhole
# ip -6 route add 2001:db8:1::1/128 nhid 1
[1]
WARNING: suspicious RCU usage
7.3.0-rc7-virtme-g191aa41548b2 #38 Not tainted
net/ipv4/nexthop.c:1539 suspicious rcu_dereference_check() usage!
[...]
Workqueue: events nsim_fib_event_work
Call Trace:
<TASK>
dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120)
lockdep_rcu_suspicious.cold (kernel/locking/lockdep.c:6972)
nexthop_for_each_fib6_nh (net/ipv4/nexthop.c:1539 (discriminator 16))
rt6_nlmsg_size (net/ipv6/route.c:5728)
fib6_info_hw_flags_set (net/ipv6/route.c:6503)
nsim_fib6_rt_add (drivers/net/netdevsim/fib.c:671 drivers/net/netdevsim/fib.c:694)
nsim_fib6_rt_insert (drivers/net/netdevsim/fib.c:759)
nsim_fib_event_work (drivers/net/netdevsim/fib.c:856 drivers/net/netdevsim/fib.c:889 drivers/net/netdevsim/fib.c:1493)
process_one_work (kernel/workqueue.c:3396)
worker_thread (kernel/workqueue.c:3479 kernel/workqueue.c:3560)
kthread (kernel/kthread.c:436)
ret_from_fork (arch/x86/kernel/process.c:158)
ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
</TASK>
Fixes:
|
||
|
|
2381642014 |
ip6mr: clear skb->cb[] in reg_vif_xmit()
reg_vif_xmit() hands the skb to ip6mr_cache_report() as an MRT6MSG_WHOLEPKT report. skb_realloc_headroom() copies skb->cb[] into the report, which is queued to the mroute socket, where rawv6_recvmsg() reads it as IP6CB. By the time the pim6reg device transmits the packet, skb->cb[] is not IP6CB anymore: qdisc_pkt_len_init() overwrites iif and ra, and any qdisc installed on the device (fq, fq_codel, pie, cake...) or a tc BPF program writing skb->cb[] fills the area holding dst0, srcrt, dst1, lastopt and flags. Since commit |
||
|
|
5d1b850ea3 |
netfilter pull request 26-10-18
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEjF9xRqF1emXiQiqU1w0aZmrPKyEFAmrUFrcACgkQ1w0aZmrP
KyFIQBAAtxAixSPZjXTlsm+aMwwy2n8kpP8J9nra2kBufvhBOAnrsmrbTuCe2Rk2
n2zinfeAZ2Fv/gkq+LjdP0OoCkhhGha83TuWIFgj5iUHre0N5R6r2lYPPKY19p/1
lHk4I/44HR/5OWCJau1ag72sKj749hUhHevvjedikqu2XD9mCm6dhmwLccGgIgfG
LL8M5oDViy2D6gBJUeHQsvvoYFcF3hQN4GxR6hzWYwTDW1Au3zouWBdUpdgm4k8Z
MIal8A3rHd2I9K94kJWu9KLDt7yBryVeNGH7iD60F7w9gtkBSh4dR6hnHozy0yfl
HzfqLPyFomYVuHMDX6GbKGxMXlWNREGWQQA88V8s5C3JeF/q8sUtlPbfxN97i+hf
GfKV2kc9+ys1RNTUPd5V3EqOzXljgZMGzaZYRPWAjcyr5qAptrE0fQyuGpsBekh5
Qfsvz21C6hPWoQ69rViL9c7SDUNDVJiXmKAMDOuI9FmwVEzDN26t1Droxef0cTGA
AfoplK61yco5Ee89velbAubtO6/7x3FvHS+l9FDpQ4c6+6r//OR1vMjBf3DheaI+
NniU3O6ImDviX5nJfem3OFXSDWoLMruOT9oTv4w+4SCmljNiEtFp3jwI1W6kNnDV
AggfbAEsuvPWw34VvvRu5x7ZKXsf6Om3IS7z3YQzE7mgKD59/Gc=
=/jel
-----END PGP SIGNATURE-----
Merge tag 'nf-next-26-10-18' of 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/IPVS updates for net-next:
1) Disable br_netfilter in userns and schedule it for removal in 2027,
from Florian Westphal.
2) Update selftest nft_queue.sh to make it more stable on debug
kernels, from Jakub Kicinski.
3) Fix a overflow in IPVS sync messages which can only happen in very
old 2.6 kernels, from Julian Anastasov.
4) Finer grain packet drop in nfnetlink_queue when dependency objects
are going away, from Antonio Ojea.
5) Add a selftest for the nfnetlink_queue packet drop case, also
from Antonio Ojea.
6) Flush conntrack gc worker when existing netns to address a unlikely
UaF, from Florian Westphal.
7) Switch nf_tables chain types to use rcu, otherwise module removal
can trigger UaF, also from Florian.
8) Remove redundant parsing in nft_exthdr for the tcp options case,
from Fernando F. Mancera.
9) Remove redundant skb_header_pointer() calls in nft_exthdr for tcp
options, from Fernando F. Mancera.
10) Fix conntrack_vrf.sh selftest return value in zone subtest,
from Florian Westphal.
11) Restrict raw table in nft_compat to specific family, hook and
priority, from Florian Westphal.
Prepare the flowtable to support for IPv4 over IPv6 tunneling and
vice-versa, this includes 4 patches from Lorenzo Bianconi.
12) Explicitly set inner protocol when popping header, this is not
needed for the existing IPIP and IP6IP6 case because skb->protocol
remains the same.
13) Simplify tuple tunnel information fill up when parsing outer
tunnel IP headers.
14) Add a new encap_proto which determines the outer tunnel protocol
family.
15) Prepare flowtable forwarding path to deal with mixed IPv4-IPv6
tunnels.
* tag 'nf-next-26-10-18' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next:
netfilter: flowtable: unify tunnel push for IPv4 and IPv6
netfilter: flowtable: add encap_proto to flow_offload_tunnel
netfilter: flowtable: populate tunnel tuple regardless of inner protocol
netfilter: flowtable: set inner protocol when popping tunnel header
netfilter: nft_compat: restrict raw table targets/matches
selftests: netfilter: fix return value in zone subtest
netfilter: nft_exthdr: avoid 60 bytes stack buffer in TCP option mangling
netfilter: nft_exthdr: remove redundant op parsing in tcp_set_init
netfilter: nf_tables: switch chain_types array to rcu
netfilter: conntrack: fix unlikely UaF in gc worker
selftests: netfilter: nft_queue: check the scope of the hook drop flush
netfilter: nf_queue: limit the hook drop flush to the unregistered hook point
ipvs: fix buffer overflow when sending sync messages
selftests: netfilter: nft_queue.sh: only queue icmp echo request/reply
netfilter: disable br_netfilter in user namespaces
====================
Link: https://patch.msgid.link/20261018005638.1776148-1-pablo@netfilter.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||
|
|
8ff017b891 |
ipv6: account route exceptions to the netns of their dst
rt6_insert_exception() and rt6_remove_exception() update
rt6_stats->fib_rt_cache of dev_net(rt6i->dst.dev), but the device of an
exception dst can move to another netns while the exception is still in
its bucket.
This happens when the bucket is flushed from an RCU callback, for
instance from nexthop_free_rcu() for the nh_info of a replaced nexthop,
whose exceptions still point to live routes. If the device moves to
another netns before that callback runs, the decrement hits the other
netns, whose u32 counter underflows in /proc/net/rt6_stats, while the
counter of the original netns never goes back down.
Account exceptions to the netns their dst was allocated in, derived from
dst->ops as ip6_dst_gc() already does, which does not depend on the
device. The dst already relies on that netns' ip6_dst_ops being alive
when it is destroyed, which happens after the exception is removed.
Fixes:
|
||
|
|
ffb668669c |
ipv6: do not restart DAD for a dead ifaddr
addrconf_dad_failure() can create a stable-privacy replacement without
RTNL. After ipv6_add_addr() publishes it, addrconf_ifdown() can mark the
new ifaddr DEAD, clear its route, and unlink it before the recovery path
takes ifp2->lock.
The recovery path then unconditionally changes the state back to PREDAD
and queues delayed DAD work. The MTU teardown path can leave IF_READY
set. For an optimistic address, addrconf_dad_begin() can consequently
pass the cleared NULL route to ip6_ins_rt().
This follow-on was found by source review and was not separately
triggered at runtime.
The new ifaddr is already initialized in PREDAD. Under ifp2->lock, record
the retry and queue DAD only if teardown has not changed the state to
DEAD. If teardown wins after this check, the work observes DEAD and exits
without reviving the address.
This complements the existing lock_errdad check that preserves the original
ifaddr's DEAD state after the same function reacquires its lock.
Fixes:
|
||
|
|
ed7f278812 |
ipv6: initialize temporary ifaddr before publication
ipv6_create_tempaddr() holds a reference to the public ifaddr, publishes
the new temporary address through ipv6_add_addr(), and only then stores
the reference and final timestamps.
addrconf_ifdown() can remove the temporary address before ifpub is
stored, leaking the public ifaddr reference. Publishing ifpub alone is
insufficient: manage_tempaddrs() can then find the object before cstamp
and tstamp are final, update its lifetimes, and have the constructor
overwrite its timestamp with an older value.
This follow-on was found by source review and was not separately
triggered at runtime.
Pass the public ifaddr and both timestamps in ifa6_config. Initialize all
three fields before adding the temporary address to either the hash or
per-device lists. On success the existing public-ifaddr reference
transfers to the temporary object. On error it remains owned and released
by ipv6_create_tempaddr().
Fixes:
|
||
|
|
06227034e2 |
ipv6: serialize address publication with device teardown
ipv6_add_addr() checks idev state before allocating an ifaddr, but
publishes the object later. addrconf_ifdown() can mark and detach the
idev between the check and publication.
This happens when a non-loopback device MTU falls below IPV6_MIN_MTU. A
forced interleaving published an address on a dead idev, and
ipv6_get_ifaddr() still returned it after teardown. Later device deletion
remained blocked with:
unregister_netdevice: waiting for ac0 to become free. Usage count = 3
Protect the dead indication with idev->lock and keep that lock across
both hash and device-list publication. Recheck dead before publishing;
if teardown wins the lock, reject the unpublished object.
Non-unregister teardown does not set dead. The preceding change covers an
add that misses the initial hash scan but reaches the per-device list
snapshot. Both changes are required when backporting this fix.
Fixes:
|
||
|
|
6ace56ed7b |
ipv6: remove ifaddr from hash during ifdown list cleanup
addrconf_ifdown() clears the address hash before snapshotting the
per-device address list. A concurrent ipv6_add_addr() can publish an
address after the hash scan and before the list snapshot.
The ifdown path then removes the address from the device list and drops
the list-owned reference while it is still linked in the hash. Once the
remaining references are released, inet6_ifa_finish_destroy() warns, but
a DEAD address continues to kfree_rcu(). The hash therefore points to
freed memory that later RCU walkers can dereference.
This follow-on was found by source review and was not separately
triggered at runtime.
Remove each non-kept address from the hash immediately before removing
it from the per-device list. Keeping it hashed through the delete
notification blocks same-address publication until NETDEV_DOWN has been
delivered. hlist_del_init_rcu() is safe when the earlier hash scan
already removed the address.
This handles a late publisher captured by the list snapshot. The next
change serializes publication with teardown so an add cannot miss both
observations. Both changes are required when backporting the complete fix.
Fixes:
|
||
|
|
4d68808407 |
net: skbuff: replace skb_page_unref() and __skb_frag_unref() with skb_netmem_unref()
Unreferencing a page_pool fragment with recycle=false decrements the non-pp backing refcount instead of pp_ref_count, underflowing the page refcount when the fragment was owned via page_pool (as on mlx4's RX error path). Having both skb_page_unref() and __skb_frag_unref(frag, recycle) made it easy for callers to pass hardcoded recycle=false on SKB-owned fragments. Replace skb_page_unref() and __skb_frag_unref() with skb_netmem_unref(netmem, recycle), which dispatches to napi_pp_put_page() when recycle is true and put_netmem() otherwise: - Use skb_frag_unref(skb, ...) on SKB-owned fragments in mlx4, sky2, tls_strp, and skb_shift() so unrefs always match skb->pp_recycle. - Use put_netmem() directly in tls_device's destroy_record(), which releases raw non-pp page references outside an SKB. Found by code inspection and confirmed with the KUnit tests added later in this series; not observed in production. The mlx4, sky2, and TLS call-site changes are compile-tested only. Assisted-by: LLM Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20261014173945.373295-4-almasrymina@google.com Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Paolo Abeni <pabeni@redhat.com> |
||
|
|
73a73d442f |
netfilter: nf_reject: initialize IPCB at inet ingress
The inet ingress hook runs before ip_rcv_core() and ip6_rcv_core(), so
neither IPCB nor IP6CB has been initialized when nft_reject_inet passes
a packet to nf_send_unreach() or nf_send_unreach6(). skb->cb can
therefore retain metadata from an earlier protocol layer.
For IPv4, icmp_send() treats IPCB(skb)->opt as parsed IPv4 options.
Stale option offsets can make __ip_options_echo() copy an
attacker-controlled length into its 40-byte reply option buffer and
overflow the stack. On an unpatched v7.2-rc5 kernel, the IPv4
reproducer produced:
BUG: KASAN: stack-out-of-bounds in __ip_options_echo()
Write of size 255
For IPv6, icmpv6_send() consumes IP6CB(skb) as parsed IPv6 metadata. It
always uses iif for source selection and, when MIP6 is enabled, uses
dsthao as an extension-header offset. These fields must not be stale.
For NF_INET_INGRESS, clear the address-family-specific control block and
restore its input interface before constructing the ICMP error. This
matches similar initialization normally performed by ip_rcv_core() and
ip6_rcv_core().
Fixes:
|
||
|
|
48d522b65f |
netfilter: nf_conntrack: avoid truncating IPv6 nexthdr offset
find_prev_fhdr() returns the offset of the Next Header field before an
IPv6 Fragment header through an int pointer, but stores the offset in a
u8 local. An extension header chain can put this field beyond byte 255,
causing the offset to wrap before it is saved in the fragment queue.
Reassembly later uses the wrapped value to update the preceding Next
Header field. This overwrites another byte in the IPv6 header chain and
can make conntrack parse a different transport tuple from the one used
by IPv6 local delivery. A two-fragment packet can, for example, be
recorded as UDP destination port 53 while its payload is delivered to
UDP port 9999.
Use int for the working offset, matching the output argument and the
other offset variables in this path.
Fixes:
|
||
|
|
3dcafe6cb5 |
netfilter: flowtable: add encap_proto to flow_offload_tunnel
Add encap_proto (AF_INET or AF_INET6) to struct flow_offload_tunnel to allow its use as part of the hash table key during flowtable entry lookup. This is a preliminary change to support IPv4 over IPv6 tunneling via the flowtable infrastructure for software acceleration. Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |
||
|
|
00accbd9d5 |
calipso: update payload_len when removing the CALIPSO option
calipso_skbuff_delattr() removes the CALIPSO option from the hop-by-hop
extension header, or the whole extension header if CALIPSO is its only
option, and pulls the skb by the removed length. It never updates
ipv6hdr->payload_len, so after a successful removal the header still
claims the original length.
calipso_skbuff_setattr() already adjusts payload_len by the length it
adds; the delete path was missed.
This is reached on the forward path when a packet carrying CALIPSO is
sent to a destination mapped to an unlabeled NetLabel domain. The
forwarded packet then has a payload_len larger than its real payload
by the removed length (8 to 264 bytes), and the receiver drops it as
truncated. So removing the label on the forward path has been broken
for every packet that is not resegmented later (SYN, UDP, ICMPv6...).
Adjust payload_len after the header is moved. BIG TCP packets carry
payload_len == 0 (see ipv6_set_payload_len()), and ipv6_payload_len()
then falls back to skb->len, so leave them alone.
Tested with client, router and server network namespaces on one kernel
(arm64, QEMU): SELinux permissive with a minimal mdp-generated policy
(network_peer_controls=1), "netlabelctl calipso add pass doi:16", the
default NetLabel mapping left unlabeled, IPv6 forwarding on the router.
The client sends 5 UDP datagrams with a CALIPSO hop-by-hop option
(DOI 16, set through IPV6_HOPOPTS) to the server through the router:
before: router Ip6OutForwDatagrams 5, server receives 0,
server Ip6InTruncatedPkts 5
after: router Ip6OutForwDatagrams 5, server receives 5,
server Ip6InTruncatedPkts 0
Fixes:
|
||
|
|
5dfa91a5ec |
ipv6: defrag: orphan skb before queuing
IPv4 and nf_conntrack fragment queues orphan skbs before returning -EINPROGRESS, but ip6_frag_queue() leaves the socket association intact. Commit |
||
|
|
2d36ec7383 |
net: erspan: set lltx to avoid sch_direct_xmit deadlock
The ERSPAN xmit path re-enters the network stack, causing nested acquisition of _xmit_lock on the underlay device while already holding the ERSPAN device's _xmit_lock, creating an ABBA deadlock. This happens for both IPv4 ERSPAN (erspan_xmit() -> ip_tunnel_xmit()) and IPv6 ERSPAN (ip6erspan_tunnel_xmit() -> ip6_tnl_xmit()): sch_direct_xmit [lock erspan] -> erspan_xmit -> ip_tunnel_xmit -> ip_output -> __dev_queue_xmit -> sch_direct_xmit [lock underlay] sch_direct_xmit [lock erspan] -> ip6erspan_tunnel_xmit -> ip6_tnl_xmit -> ip6_output -> __dev_queue_xmit -> sch_direct_xmit [lock underlay] Set dev->lltx = true so HARD_TX_LOCK() skips the spinlock for ERSPAN. This is safe as the ERSPAN xmit path has no shared mutable state: o_seqno is atomic, TX stats are per-CPU u64_stats, dst_cache is per-CPU, and o_flags is no longer modified in the xmit path since commit |
||
|
|
f5e575a787 |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Cross-merge networking fixes after downstream PR (net-7.3-rc8). No conflicts. Adjacent changes: drivers/net/ethernet/microchip/lan865x/lan865x.c |
||
|
|
8070ed578b |
calipso: keep BIG TCP payload_len in calipso_skbuff_setattr()
calipso_skbuff_setattr() adjusts payload_len by the length of the
option it inserts or resizes:
payload = ntohs(ip6_hdr->payload_len);
ip6_hdr->payload_len = htons(payload + len_delta);
GRO can build BIG TCP packets larger than IPV6_MAXPLEN, and stores
payload_len == 0 for them; ipv6_payload_len() then falls back to
skb->len. For such a packet forwarded to a destination mapped to
CALIPSO, the code above writes len_delta (or 65536 + len_delta when
shrinking) into payload_len, and ipv6_payload_len() no longer falls
back to skb->len. nf_tables, conntrack and sch_cake rely on it.
The same arithmetic also wraps when a packet grows past IPV6_MAXPLEN,
and a BIG TCP packet that shrinks below IPV6_MAXPLEN should get its
real length back.
Set payload_len from the skb length with ipv6_set_payload_len(), which
stores 0 above IPV6_MAXPLEN and the real length otherwise, as
ipv6_gro_complete() does. The network header was just reset to
skb->data, so skb->len - sizeof(*ip6_hdr) is the payload length.
Tested on one kernel (arm64, QEMU) with SELinux permissive, a minimal
mdp-generated policy (network_peer_controls=1), "netlabelctl calipso
add pass doi:16" and a NetLabel mapping of fd00:2::/64 to CALIPSO
DOI 16. calipso_skbuff_setattr() was called through
netlbl_skbuff_setattr() from a test-only debugfs hook (not part of
this patch) adding a level-only label; payload_len after the call:
case before fix after fix real length
1000, unlabeled 1016 1016 1016
70000 GSO, payload_len 0 16 0 70016
65530 GSO, grows past MAXPLEN 10 0 65546
65540 GSO with a 24 byte hop
header, shrinks below MAXPLEN 65528 65532 65532
1000 with a 24 byte hop header 992 992 992
(0 means ipv6_payload_len() returns the real length.) On the forward
path, with a client injecting unlabeled UDP through a router to a
server, the router adds the CALIPSO option and the server delivers all
datagrams (Udp6InDatagrams 5, Ip6InTruncatedPkts 0) with this patch.
Fixes:
|
||
|
|
a39a3a3278 |
net: ipv6: seg6: report lwtunnel setup errors via extack
seg6_build_state() rejected invalid configurations with a generic -EINVAL, so "ip route add ... encap seg6 ..." sometimes reported "Invalid argument". Add extack messages to the checks that lacked one, and use NL_REQ_ATTR_CHECK() for the missing SRH attribute so that userspace can tell which attribute is missing. The checks themselves and their return values are unchanged. Signed-off-by: Gabriel Goller <g.goller@proxmox.com> Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn> Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it> Link: https://patch.msgid.link/20261009152015.462383-1-g.goller@proxmox.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> |
||
|
|
d538cc3ec0 |
calipso: hash the cache key, not the option start, in calipso_cache_add()
calipso_cache_add() stores calipso_ptr + 2 as the cache key, but
computes entry->hash over calipso_ptr, i.e. starting two bytes earlier
at the option type and length. calipso_opt_getattr() looks entries up
with calipso_cache_check(calipso + 2, calipso[1], ...), which hashes the
key itself.
The two hashes only match on a jhash collision, so the CALIPSO label
cache never hits and every labelled packet takes the full DOI lookup and
category conversion path. The memcmp() on the key keeps lookups
correct, so this is a performance bug only.
Hash the stored key, as cipso_v4_cache_add() does for CIPSO.
Fixes:
|
||
|
|
d8674294ae |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Cross-merge networking fixes after downstream PR (net-7.3-rc7). Conflicts: include/net/strparser.h |
||
|
|
f3f5d7ab19 |
ip6_gre: let collect_md ip6gretap send from the unspecified address
ip6gre_xmit_ipv6() drops an IPv6 packet whose source address equals the tunnel remote, to avoid a trivial tunneling loop. On a collect_md ip6gretap device t->parms.raddr is not the exit point: the outer destination comes from the per-packet tunnel metadata. Such devices are normally created without a remote, so raddr is ::, and the check never matches a real tunnel endpoint. It matches every frame sent from the unspecified address instead. On an L2 tunnel those frames are regular link traffic. Duplicate Address Detection sends its Neighbor Solicitations from :: (RFC 4862, section 5.4.2), and MLD reports are sent from :: while an interface has no link-local address yet (RFC 3590, section 4). Frames bridged into a collect_md ip6gretap device, e.g. with tc tunnel_key and mirred, are dropped even though they carry valid metadata, so DAD cannot detect a duplicate address on the other side of the tunnel. Skip the check for collect_md devices of type ARPHRD_ETHER. It stays for L3 ip6gre, where sending a packet with an unspecified source means forwarding it (RFC 4291, section 2.5.2), and for ip6gretap without collect_md. ip6erspan does not run this check in collect_md mode either. Signed-off-by: Anton Danilov <littlesmilingcloud@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20261005191227.894665-1-littlesmilingcloud@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
||
|
|
c97426ec64 |
ipv6: do not warn on route notification size race
fib6_info_hw_flags_set() sizes the skb with rt6_nlmsg_size() and later
fills it with rt6_fill_node(). With nexthop compatibility mode enabled,
a concurrent replacement can grow the group between these independent
snapshots. rt6_fill_node() can then legitimately return -EMSGSIZE, so
the warning does not prove a sizing bug.
Remove the warning. The existing error path still frees the skb and
reports the error to listeners.
Fixes:
|
||
|
|
6c0509aa89 |
ip_tunnel: make __iptunnel_pull_header() return a drop reason
__iptunnel_pull_header() returns -ENOMEM whenever it fails. It can fail in two pskb_may_pull() calls, one for the tunnel header and one for the inner Ethernet header of ETH_P_TEB, and in the skb_unclone() done for GSO packets. pskb_may_pull() fails when the packet is shorter than the requested length as well as when pulling from the frags cannot allocate, so a truncated packet and an allocation failure look the same to the callers. The ones that report a drop reason can only pick SKB_DROP_REASON_NOMEM, as vxlan_rcv() does, and so would the GRE receive paths once they report drop reasons. In ip6_gre, gre_rcv() pulls the header before the tunnel lookup, so a packet from any sender whose ETH_P_TEB inner Ethernet header or WCCPv2 extra word is cut short would be reported as an out of memory condition. Make __iptunnel_pull_header() and iptunnel_pull_header() return the reason pskb_may_pull_reason() already computes, SKB_DROP_REASON_NOMEM when skb_unclone() fails, and SKB_NOT_DROPPED_YET on success. A failure is still non-zero, so the callers that only test the result keep working. Three callers, in ip_gre and ip6_gre, test it with "< 0" instead; the enum has no negative values, so that test would always be false, and the compiler does not warn about it. Make them test for a non-zero value. vxlan_rcv() keeps reporting NOMEM for any failure until the next patch has it report the returned reason. Suggested-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Anton Danilov <littlesmilingcloud@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20261005201417.906344-3-littlesmilingcloud@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
||
|
|
0e59523b44 |
ipv6: Use ipv6_neigh_lookup() and friends.
syzbot reported the splat below in neigh_mark_dead() [0]
where tbl->lock was not held while neigh_ifdown() should
have acquired one.
This only happens when a neigh_table accidentally has a
neighbour from a different netns.
In ip6_finish_output2(), the net argument is the caller's and
does not always match dev_net(dev) fetched from dst. (e.g. xfrm)
It is error-prone to require callers to fetch netns and
neigh_table and pass it with dev to neigh_lookup(), etc.
Let's replace neigh_lookup() and friends with IPv6 helpers.
Note that __neigh_lookup() is split into ipv6_neigh_lookup()
and ipv6_neigh_create().
[0]:
debug_locks && !(lock_is_held(&(&n->tbl->lock)->dep_map) != 0)
WARNING: net/core/neighbour.c:154 at neigh_mark_dead+0x2fb/0x340 net/core/neighbour.c:154, CPU#0: syz.0.857/9765
Modules linked in:
CPU: 0 UID: 0 PID: 9765 Comm: syz.0.857 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026
RIP: 0010:neigh_mark_dead+0x2fb/0x340 net/core/neighbour.c:154
Code: e8 03 42 80 3c 28 00 74 08 48 89 df e8 ee 9a 80 f8 4c 89 33 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc cc e8 86 95 10 f8 90 <0f> 0b 90 e9 8f fd ff ff 48 c7 c1 80 9a 7a 90 80 e1 07 80 c1 03 38
RSP: 0018:ffffc90003726600 EFLAGS: 00010287
RAX: ffffffff89b7467a RBX: ffff888022e86000 RCX: 0000000000080000
RDX: ffffc900047fa000 RSI: 0000000000003e08 RDI: 0000000000003e09
RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000004
R10: dffffc0000000000 R11: fffff520006e4cb8 R12: ffff888022e8613c
R13: dffffc0000000000 R14: ffff888022e86020 R15: ffff888022e86000
FS: 00007f9c30f046c0(0000) GS:ffff888124cc6000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 0000000076c56000 CR4: 00000000003526f0
Call Trace:
<TASK>
neigh_flush_one+0x27c/0x5a0 net/core/neighbour.c:388
neigh_flush_dev net/core/neighbour.c:432 [inline]
__neigh_ifdown+0x1fb/0xc70 net/core/neighbour.c:465
neigh_ifdown+0x1f/0x30 net/core/neighbour.c:487
rt6_disable_ip+0x751/0x7e0 net/ipv6/route.c:5058
addrconf_ifdown+0x155/0x1ad0 net/ipv6/addrconf.c:3892
addrconf_notify+0x1bc/0x1050 net/ipv6/addrconf.c:-1
notifier_call_chain+0x1a5/0x3d0 kernel/notifier.c:85
call_netdevice_notifiers_mtu net/core/dev.c:2350 [inline]
netif_set_mtu_ext+0x5ac/0x830 net/core/dev.c:9963
do_setlink+0xa81/0x47a0 net/core/rtnetlink.c:3247
rtnl_setlink+0x578/0x820 net/core/rtnetlink.c:3623
rtnetlink_rcv_msg+0x802/0xc00 net/core/rtnetlink.c:7159
netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2572
netlink_unicast_kernel net/netlink/af_netlink.c:1335 [inline]
netlink_unicast+0x7bd/0x940 net/netlink/af_netlink.c:1361
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1916
sock_sendmsg_nosec+0x13a/0x180 net/socket.c:800
__sock_sendmsg net/socket.c:815 [inline]
sock_write_iter+0x2de/0x3e0 net/socket.c:1266
do_iter_readv_writev+0x612/0x8c0 fs/read_write.c:-1
vfs_writev+0x343/0x990 fs/read_write.c:1058
do_writev+0x154/0x2e0 fs/read_write.c:1104
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f9c2ff9e159
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f9c30f04028 EFLAGS: 00000246 ORIG_RAX: 0000000000000014
RAX: ffffffffffffffda RBX: 00007f9c30225fa0 RCX: 00007f9c2ff9e159
RDX: 0000000000000001 RSI: 00002000000003c0 RDI: 0000000000000004
RBP: 00007f9c3003506b R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f9c30226038 R14: 00007f9c30225fa0 R15: 00007ffed3c74808
</TASK>
Fixes:
|
||
|
|
3e33cdcf54 |
ipv6: Rename ip6_neigh_lookup() to __ip6_dst_neigh_lookup().
Later, we will add ipv6_neigh_lookup() as a wrapper for neigh_lookup(nd_table(net), ...). The existing ip6_neigh_lookup() is called from ip6_dst_neigh_lookup() with a gateway address. Let's rename ip6_neigh_lookup() to __ip6_dst_neigh_lookup(). Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20261003212336.1304988-3-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
||
|
|
8bc60db48e |
ip6_gre: remove obsolete ERSPAN PMTU update
A tc tunnel_key action can attach a METADATA_IP_TUNNEL dst to an skb, and mirred can redirect it to a native ip6erspan device. The legacy PMTU update in ip6erspan_tunnel_xmit() treats that metadata dst as a route. Since it has no output device, dst_dev(dst)->mtu dereferences NULL. On v7.2 with KASAN, an initial UID/GID 65534 process with CapEff 0 used self-created user and network namespaces to trigger: KASAN: null-ptr-deref RIP: ip6erspan_tunnel_xmit+0x10fc/0x2cc0 Kernel panic - not syncing: Fatal exception in interrupt The update is obsolete. Commit |
||
|
|
f12d290799 |
ipv6: Batch rt6_uncached_list_flush_dev() in netdev_run_todo().
IPv6 uncached routes are linked to the global per-cpu lists,
rt6_uncached_list.
When unregistering a netdev, rt6_uncached_list_flush_dev() iterates
over the potentially long lists to find uncached routes tied to
the device and swap it with blackhole_netdev.
Since it is called for every device in dying netns under RTNL,
it adds O(N_dev x (N_cpu + N_route)) costs to any batched device
unregistration.
Let's call it once per batched device unregistration without RTNL.
Because it now runs without RTNL, rt->dst.dev and rt->rt6i_idev->dev
may transition to NETREG_UNREGISTERED at different times. Thus, we
must check that both devices are blackhole_netdev before unlinking
the route; otherwise, the remaining device reference would not be
flushed when the other device is unregistered.
In addition, since netdev_run_todo() runs even when IPv6 is disabled,
rt6_uncached_list_flush_dev() must check ipv6_mod_enabled() before
touching rt6_uncached_list.
Note also that netdev_run_todo() cannot be called before
rt6_uncached_list is initialised because:
1. unregister_netdevice_many_notify() panics when
dev_boot_phase == 1 (net_dev_init() is subsys_initcall()).
2. the only device registered before fs_initcall_sync() is
loopback and loopback_net_init() panics in case of failure.
Reported-by: Chris J Arges <carges@cloudflare.com>
Closes: https://lore.kernel.org/netdev/20260917-hash-bucket-route-lists-v3-0-30493a37b6eb@cloudflare.com/
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Tested-by: Chris J Arges <carges@cloudflare.com>
Link: https://patch.msgid.link/20261001204752.2572265-7-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||
|
|
20dff14006 |
net: Order blackhole_netdev_init(), inet_init(), and inet6_init().
Commit
|
||
|
|
86a1928442 |
net: psp: require an established connection for association setup
Check sk_state under the socket lock in both the rx-assoc and tx-assoc handlers, and only allow association setup on sockets in TCP_ESTABLISHED. Also, fail connect() when PSP assoc state is already present, and remove the dead PSP MSS adjustment from tcp_v[46]_connect(). The net effect of this commit is: 1. PSP assoc state can never exist on a listen socket. 2. The upgrade to PSP must be done while the socket is in TCP_ESTABLISHED. This change defeatures behavior that was previously allowed under the PSP uapi. My justification is: Nothing useful can be done after association setup on closed or listen sockets today. Listen sockets could accept a PSP-encrypted TCP SYN, but the child socket will not inherit any PSP state. On the other side, establishing PSP state prior to connect() will result in a PSP-encrypted TCP SYN sent to a listening peer, which in turn has the aforementioned limitations. That implies that there cannot be any users of this feature, so it should be safe to remove it from the PSP uapi. In theory, the check in the tx-assoc path is more restrictive than necessary. FIN_WAIT1/2, CLOSING, LAST_ACK and CLOSE_WAIT could be allowed, and the peer would accept PSP-encrypted ACKs in the post-FIN-sent states, or data in the half-close case, but it is simpler to disallow those states because they don't fit the upgrade model. The check in the tx-assoc path fixes a bug in commit |
||
|
|
f49defea76 |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Cross-merge networking fixes after downstream PR (net-7.3-rc6).
Conflicts:
net/mac80211/tx.c
net/mac80211/ieee80211_i.h
8effab902fa34 ("wifi: mac80211: prevent AP VLAN tx from other interfaces")
|
||
|
|
f9cb4d296d |
seg6: fix HMAC validation when an extension header precedes the SRH
seg6_hmac_validate_skb() derived the SRH from skb_transport_header(). That only holds while the two coincide, which is not true on the seg6_local input path. ip6_rcv_core() leaves the transport header just past the IPv6 header. A Hop-by-Hop options header is consumed before the route lookup and advances it, but a Destination Options header is not: the seg6_local lwtunnel is entered through an input redirect from the route lookup, which bypasses the extension header handlers. The transport header then still points at the Destination Options header while seg6_get_srh() has located the real SRH further down the chain. The HMAC is therefore computed over the Destination Options header, and a packet carrying a valid HMAC TLV is dropped when seg6_require_hmac is set. Such a packet is legitimate: RFC 8200 allows Destination Options before a routing header, and get_srh() has walked the header chain since commit |
||
|
|
8ec454dcd0 |
ipv6: sr: use skb_get_hash_net() in seg6_make_flowlabel()
Since commit |
||
|
|
bf515c9fae |
seg6: reallocate the skb head on L2 encapsulation only when needed
The L2 encapsulation modes of the seg6 lwtunnel reallocate the skb head on every packet, where the IPv6 encapsulation modes reallocate only when they have to. Ask for the whole encapsulation up front instead, so that the reallocation happens at most once and only when the headroom really is too small: skb->mac_len + sizeof(struct ipv6hdr) + ipv6_optlen(tinfo->srh) + dst_dev_overhead(cache_dst, skb) __seg6_do_srh_encap() then finds the room it needs and its own skb_cow_head() becomes a no-op. Drivers reserve more than that on the forwarding path, so the reallocation usually disappears altogether. A single-segment policy on ixgbe needs 14 (mac_len) + 40 (ipv6hdr) + 24 (SRH) + 16 (LL_RESERVED_SPACE) = 94 against the 206 bytes the driver leaves. Where the headroom is smaller, as on a veth pair, pskb_expand_head() is called once per forwarded packet instead of twice. Asking only for skb->mac_len would still take two whenever the skb is header-cloned, because the cow that unclones it does not also make room for the outer header. The cost is amplified by CONFIG_INIT_ON_ALLOC_DEFAULT_ON, which many distributions enable: every new head is zeroed in full, and that memset alone accounts for 16% of the datapath profile. Throughput at 0.5% packet loss, 64-byte frames forwarded through one 2.30 GHz core (Xeon E5-2650 v3, ixgbe 82599ES), offered by TRex and binary-searched over 10 runs of 10 s: Before: 654.6 kpps After: 965.7 kpps Signed-off-by: Yuya Kusakabe <yuya.kusakabe@gmail.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn> Link: https://patch.msgid.link/20260925-seg6-l2cow-v3-1-fc83821542a7@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
||
|
|
24717a02ae |
ipv6: update NUD_FAILED neighbors from NA messages
Transition a FAILED neighbor entry to STALE upon receipt of an NA message on routers when accept_untracked_na is enabled. This extends the RFC 9131 accept_untracked_na behavior so that FAILED entries are treated the same as non-existent entries. RFC 4861 section 7.3.3 says that an entry should be deleted when address resolution fails. Linux instead retains the entry in NUD_FAILED, so treating it as untracked is consistent with the protocol model. Trying to resolve FAILED neighbors via periodic probing (e.g. using NTF_EXT_MANAGED) is more work compared to this approach which uses information in NAs that the kernel may already be receiving. Note that because this behavior in IPv6 is dependent on the accept_untracked_na sysctl setting, this approach is more conservative than IPv4 which transitions FAILED neighbors to STALE by default upon receiving GARPs. Link: https://lore.kernel.org/r/20260813233344.445265-1-lfqlee314@gmail.com Signed-off-by: Lawrence Lee <lfqlee314@gmail.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/6be400e601f4ffa59e47ddb5daa33ecdd85dd88b.1790127207.git.lfqlee314@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
||
|
|
006c8b834a |
net: gso: limit recursive IP-in-IP segmentation
IP-in-IP GSO can re-enter inet_gso_segment() or ipv6_gso_segment()
for each nested IP header. encap_level tracks header bytes, not callback
depth, so a deep chain can exhaust the kernel stack. Making
inet_gso_segment() stackable introduced unbounded IPv4 nesting; IPIP
GSO/TSO later made the path reachable. The IPv6 stackable path was
introduced separately and uses the same guard.
Count IPv4 and IPv6 GSO handler entries in skb_gso_cb, initialized once
per top-level GSO operation and preserved across GRE/UDP context changes.
Use the existing IP_TUNNEL_RECURSION_LIMIT for both handlers. The first
five entries pass, and the sixth returns -EINVAL before dispatching
another GSO callback.
Fixes:
|
||
|
|
c66d93e687 |
ipv6: Remove FIB6_EXCEPTION_BUCKET_FLUSHED.
The FIB6_EXCEPTION_BUCKET_FLUSHED logic has been dead since added.
Commit
|
||
|
|
8ae3f4067b |
seg6: ensure packet data is writable before modifying SRH and IPv6 DA
advance_nextseg() modifies the SRH Segments Left field and the IPv6
destination address without ensuring the packet data is writable.
seg6_next_csid_advance_arg() has the same problem when it advances the
NEXT-C-SID argument in the destination address.
The skb may be cloned, for example by an AF_PACKET socket receiving on
the ingress device. advance_nextseg() and seg6_next_csid_advance_arg()
then write into the packet data shared with the clone. A read from that
socket can return the modified packet instead of the received one. The
simplified path below shows this for advance_nextseg():
__netif_receive_skb_one_core
__netif_receive_skb_core
deliver_skb [orig: users=2, cloned=0]
packet_rcv
skb_clone clone queued to the AF_PACKET socket
consume_skb(orig) [orig: users=1, cloned=1]
ipv6_rcv
ip6_rcv_core skb_share_check: no-op [orig: users=1]
[...]
input_action_end_core
advance_nextseg writes into the data shared with the clone
Call skb_ensure_writable() in advance_nextseg() and in
seg6_next_csid_advance_arg() before they modify the packet data.
skb_ensure_writable() may reallocate skb->head, which invalidates the
pointers into the packet data taken before the call.
advance_nextseg() now returns a valid SRH pointer, or NULL if
skb_ensure_writable() fails.
seg6_next_csid_advance_arg() takes the pointer to the destination
address from the skb after skb_ensure_writable().
On failure, the callers drop the packet with SKB_DROP_REASON_NOMEM.
Fixes:
|
||
|
|
a7bfaba482 |
ipv6: fix prefix route expiry in modify_prefix_route()
modify_prefix_route() is given the lifetime in clock_t relative to now,
but fib6_set_expires() wants an absolute jiffies value. So when a
permanent address is changed to a finite valid_lft, the prefix route
ends up already expired and GC removes it.
Steps to reproduce:
ip link add dummy9 type dummy
ip link set dummy9 up
ip -6 addr add 2001:db8:9::1/64 dev dummy9
ip -6 addr change 2001:db8:9::1/64 dev dummy9 valid_lft 3600 preferred_lft 3600
ip -6 route show dev dummy9 # expires is negative
Fixes:
|
||
|
|
42a9fb3382 |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Cross-merge networking fixes after downstream PR (net-7.3-rc5). Conflicts: drivers/net/mdio/mdio-realtek-rtl9300.c |
||
|
|
2d959c75c2 |
ipv6: sr: enforce exact attribute length for SEG6_ATTR_DST
In seg6_genl_policy, SEG6_ATTR_DST is defined with .type = NLA_BINARY and
.len = sizeof(struct in6_addr). For NLA_BINARY, .len only enforces the
maximum payload length and permits shorter payloads (e.g., 0 bytes).
When seg6_genl_set_tunsrc() copies sizeof(struct in6_addr) bytes via
kmemdup(val, sizeof(*val), GFP_KERNEL), a short SEG6_ATTR_DST attribute
triggers a 16-byte out-of-bounds read past skb->tail into uninitialized
skb->head memory, which is stored in sdata->tun_src and leaked back to
userspace via SEG6_CMD_GET_TUNSRC.
Switch SEG6_ATTR_DST in seg6_genl_policy to
NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)) so that generic netlink
validation rejects any attribute whose length is not exactly
sizeof(struct in6_addr) with -ERANGE.
Tested in QEMU against Linux 7.3.0-rc3 by sending a SEG6_CMD_SET_TUNSRC
Generic Netlink message with a 0-byte SEG6_ATTR_DST attribute followed
by SEG6_CMD_GET_TUNSRC. On the unfixed kernel, SEG6_CMD_SET_TUNSRC
succeeds (err = 0) and SEG6_CMD_GET_TUNSRC leaks 16 bytes of
uninitialized kernel heap memory (tun_src =
836a61ecc4d25a1042a8d60411cfb378); with this patch applied,
SEG6_CMD_SET_TUNSRC is rejected by netlink policy validation with
-ERANGE (-34) and tun_src remains zeroed.
Fixes:
|
||
|
|
be31fe6333 |
ipv6: Fix dst leak for uncached routes.
ip6_route_output_flags(), ip6_rt_put_flags(), and ip6_dst_check() detect an uncached route by list_empty(&rt->dst.rt_uncached), which replaced the static DST_NOCACHE flag check in commit |
||
|
|
0346ec2f08 |
ipv6: Prevent rt6_insert_exception() for dying fib6_info.
Before the cited commit, fib6_nh_flush_exceptions() always set
from->exception_bucket_flushed = 1 under rt6_exception_lock to
prevent rt6_insert_exception() from inserting a new exception
for a dying fib6_info.
The flag was replaced with the FIB6_EXCEPTION_BUCKET_FLUSHED
bit stored in nh->rt6i_exception_bucket.
The problem is that now the bit is only set when the bucket
is not NULL and fib6_nh_flush_exceptions() is called from
fib6_nh_release() after fib6_ref has already reached zero.
If rt6_insert_exception() is called while the target fib6_info
is being removed via fib6_purge_rt(), a new exception could be
created successfully because rt6_flush_exceptions() no longer
sets the bit.
This creates a reference cycle between the fib6_info and the
exception route, leaking the fib6_info, its nexthop device,
and all per-CPU routes in fib6_nh->rt6i_pcpu, which stalls netdev
unregistration.
[ 34.680602] unregister_netdevice: waiting for gre6 to become free. Usage count = 68
[ 44.920675] unregister_netdevice: waiting for gre6 to become free. Usage count = 68
[ 55.176582] unregister_netdevice: waiting for gre6 to become free. Usage count = 68
Let's call fib6_drop_pcpu_from() before rt6_flush_exceptions(),
to set fib6_destroying before rt6_exception_lock, and check
f6i->fib6_destroying in rt6_insert_exception().
Note that FIB6_EXCEPTION_BUCKET_FLUSHED logic is dead and
we can clean it up in net-next.
Fixes:
|
||
|
|
12fec40907 |
netfilter pull request 26-09-18
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEjF9xRqF1emXiQiqU1w0aZmrPKyEFAmqtHzMACgkQ1w0aZmrP KyGtkQ//bMKQGEudQKCMCtQmPqaHyW1ajmAo17aumfczaE/nSjqrsGY5Ahw7OKlQ 4otcdPvI4qpV9sLTg41KFaIHIC5sozxt4Q3m3RNB2TbyCkGn9xpSpZxM5IpHybvE 83tVjSA0wpfIqxBEqKUqk8Z9AXtBLo/JocdfYry+6JUyj4PM76X2ViKpzaPbpoMU 1mndfLAYtADIIvs3805CmfdJmOkoSV6XCEsiNutPrJhiRfN4xJZ9leP9xb1zA0IQ cnqiaw1xkTcFyWCicu4MqOkEALRknr9SL2yX1S9wx5Q6WHwU9JXUeQTlvfv7OoVP uxuMlNr3WcbwHC9e1GfOHapzjrYgnvEe2Z79i2GFh51Ci+5L9Yr9XCQ/fc6G5NNZ 3W52kh35s3lXq32hll9Tkr7pf4cKLBA+IAJ19VNlRfMrPB0cz4EqbIZ6xNNuLqdh DbEb3VgTT2dHwuGxEshJVmSfzfR+VeHBG2ZRlRmZElfhViHEwgPaAxkaJhNpPyub qmHbZCXK0BVp/UrGHDm5rmHJtdkwprXY9YceZBRfW8Fr2Ler4rWQvy+uo9sRRFgN oF9B6qzSl78THBv3UDB3U+aWuDv0I+VlDub0DKf0k9iWg8OoMlM9yw6OE9ULHt3m LRvSAfF0LnF/z7byzumUYMVjpVuIVueDzasGrEZjWbHHE7MCsp0= =RfSQ -----END PGP SIGNATURE----- Merge tag 'nf-26-09-18' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf Pablo Neira Ayuso says: ==================== Netfilter/IPVS fixes for net The following patchset contains Netfilter/IPVS fixes for net, they are: 1) Set on HW_DEAD after HW_PENDING is cleared in the flowtable offload to ensure GC does not zap it, from Jérémy Jean. 2) Hold the nfnetlink_queue mutex while removing the queue instance from the netlink notifier that handles NETLINK_URELEASE to fix a possible race with the UNBIND command. From Florian Westphal. 3) Reject route with NULL rt6i_idev in ip6t_rpfilter. From Weiming Shi. 4) Reject rtinfo->addrnr set to zero from ip6t_rt .checkentry path. This also fortifies the datapath loop as per Florian's request. From Luxiao Xu. 5) Fix checksuming in nft_synproxy for IPv6, from Karl Mehltretter. 6) Revalidate ihl before calling icmp_send() in IPVS, from Julian Anastasov. 7) Fix suspicious RCU usage splat in ctnetlink with expectations. 8) Check for expired catchall elements in the insert and deactivate path. From Aohan Mei. * tag 'nf-26-09-18' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: nf_tables: skip expired catchall elements on insert and delete netfilter: ctnetlink: fix suspicious RCU usage in expect_iter_name ipvs: revalidate ihl before icmp_send netfilter: nft_synproxy: use the family-aware checksum helper netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read netfilter: ip6t_rpfilter: reject routes without inet6_dev netfilter: nfnetlink_queue: hold nfnl mutex in event notifier netfilter: flowtable: publish HW_DEAD after worker is done ==================== Link: https://patch.msgid.link/20260918112844.194503-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org> |