summaryrefslogtreecommitdiff
path: root/net
AgeCommit message (Collapse)Author
16 hoursMerge tag 'ceph-for-7.3-rc1' of https://github.com/ceph/ceph-clientLinus Torvalds
Pull ceph updates from Ilya Dryomov: "A wide variety of mostly CephFS fixes and cleanups, split between changes that address edge cases (Sam, Xiubo, Matthew), efficiency improvements (Max) and AI-assisted hardening (Michael, Jeremy). One thing that stands out is Alex's change to how CephFS behaves in NEARFULL scenarios: the long-standing "make all writes synchronous" behavior has become opt-in. It was always somewhat controversial and doesn't make much sense for modern deployments; the new default is to continue normal operation (i.e. buffer writes as MDS allows, etc). The behavior in case the cluster reaches any FULL state remains the same as before" * tag 'ceph-for-7.3-rc1' of https://github.com/ceph/ceph-client: (32 commits) ceph: force a cap message when a deferred revoke can't be acked immediately libceph: reject buckets with mismatched CRUSH ids ceph: reject export_targets ranks >= CEPH_MAX_MDS in mdsmap decode ceph: fix leaked inode reference on writeback abort at umount libceph: remove ceph_put_page_vector() libceph: validate banner payload length ceph: make nearfull sync writes opt-in ceph: do not repeat ceph_trim_dentries() if no progress possible ceph: drop mdsc->mutex before decoding the MDS reply ceph: fix UAF in check_new_map() on session freed during unlock ceph: fix UAF in __kick_flushing_caps() on cf entry freed during unlock ceph: pass inode pointer around instead of reloading it ceph: mark cap remove with RB_CLEAR_NODE() instead of setting ci=NULL ceph: add helper function ceph_cap_is_removed() ceph: make __ceph_remove_cap() static ceph: cap delegated inode count in ceph_parse_deleg_inos() ceph: bound num_export_targets array for mds info v2/v3 ceph: bound MDSCapAuth path and fs_name decode in handle_session() ceph: bound xattr value length in __build_xattrs() ceph: bound copied dentry name length in NFS export get_name ...
38 hoursMerge tag 'net-7.3-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Including fixes from Bluetooth, IPSec and Netfilter. Current release - fix to a fix: - netfilter: ipset: remove need to allocate memory on delete operations Current release - regressions: - macb: drop CONFIG_OF #if block, fix build Previous releases - always broken: - stream of fixes for SCTP continues - inet: frags: strip GSO state from fragments before reassembly - virtio-net: ensure that TCP packets don't overflow gso_segs - tcp-ao: fix use-after-free of current_key on reconnect to another peer - page_pool: remove zone/policy GFP flags when allocating XArray entries - Bluetooth: L2CAP: reject accept queue add unless BT_LISTEN - tls: device: fix out-of-bounds write in tls_append_frag() - eth: bnxt: - ring the doorbell when SW USO exits early, avoid packets stuck in Tx - gate TPH enablement behind BNXT_SUPPORTS_QUEUE_API check, avoid users of older NICs seeing non-actionable warning messages - eth: qede: fix NULL pointer dereference in TPA fragment processing" * tag 'net-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (216 commits) inet: frags: strip GSO state from fragments before reassembly net/sched: sch_htb: limit htb_classify inner-class filter hops selftests/net: packetdrill: add tcp_urg_ptr_retransmit tcp: fix corruption of urgent data on multi-segment retransmit usb: atm: usbatm: fix invalid ci_range initialization net: fec: only stop PTP if it was initialized slip: remove slip_hangup() to fix use-after-free in slip_receive_buf() net: bridge: mcast: fix use-after-free of a master VLAN's multicast context net/sched: bound qdisc_pkt_len to prevent qdisc soft lockup net: dsa: mxl862xx: enable assisted learning on CPU port net: stmmac: restore NET_IP_ALIGN in the RX DMA offset net: stmmac: drop gso_enabled_types and rely on netdev features net: stmmac: selftests: Don't test flow control for small rx fifos net: stmmac: selftests: Account for the UC filter list for filtering tests net: stmmac: dwxgmac: Account for the primary MAC address for UC filtering net: stmmac: dwmac4: Account for the primary MAC address for UC filtering net: stmmac: dwmac1000: Account for the primary MAC address for UC filtering net: stmmac: selftests: Check multiple MMC counters selftests: net: Fix slow configurations in big_tcp_tunnels.sh selftests: net: Lower threshold with csum offload off in big_tcp_tunnels.sh ...
38 hoursMerge 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>
39 hoursinet: frags: strip GSO state from fragments before reassemblyXinyang Ge
A virtio_net_hdr (tun/tap, or AF_PACKET with PACKET_VNET_HDR) can mark an IPv4 or IPv6 fragment as GSO; nothing relates gso_type to frag_off. inet_frag_reasm_prepare()/inet_frag_reasm_finish() keep the first fragment's skb as the head of the reassembled datagram, including its shinfo->gso_size/gso_type/gso_segs, and chain the remaining fragments on frag_list with whatever linear/paged layout they arrived with. After ip_defrag() (ip_local_deliver(), nf_defrag_ipv4, ...) the reassembled skb therefore still claims to be GSO (SKB_GSO_DODGY), and the next software segmentation point - udp_rcv_segment() on local delivery, validate_xmit_skb(), or the ip_finish_output_gso() slow path - hands it to skb_segment(). skb_segment()'s frag_list walk assumes GRO-shaped input and hits one of its BUG_ON()s. Two writes to a tap by an unprivileged user in its own userns are enough: kernel BUG at net/core/skbuff.c:4899! Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI CPU: 0 UID: 1000 PID: 82 Comm: poc Not tainted 7.2.0-pentest+ #2 RIP: 0010:skb_segment+0x20ca/0x48b0 Call Trace: <TASK> __udp_gso_segment+0x29a/0x27d0 udp4_ufo_fragment+0x458/0x6c0 inet_gso_segment+0x429/0x1340 skb_mac_gso_segment+0x233/0x4f0 __skb_gso_segment+0x308/0x660 udp_queue_rcv_skb+0x440/0xad0 udp_unicast_rcv_skb+0xc7/0x2c0 udp_rcv+0x16ce/0x2260 ip_protocol_deliver_rcu+0x197/0x2d0 ip_local_deliver+0x430/0x690 ip_rcv+0x16f/0x1f0 __netif_receive_skb_one_core+0x15e/0x1c0 __netif_receive_skb+0x1e/0x110 netif_receive_skb+0xf6/0x5c0 tun_rx_batched.isra.0+0x3ab/0x790 tun_get_user+0x17c3/0x3550 tun_chr_write_iter+0xba/0x1b0 vfs_write+0x646/0x1130 </TASK> Kernel panic - not syncing: Fatal exception in interrupt This runs with BH disabled, so it is a panic rather than an oops. The same is reachable with CAP_NET_RAW in a netns where a defrag point precedes a GSO point, and from a guest whose VMM forwards virtio_net_hdr to a tap. The SKB_GSO_DODGY frag_list checks added by commit 3dcbdb134f32 ("net: gso: Fix skb_segment splat when splitting gso_size mangled skb having linear-headed frag_list") and by commit 9e4b7a99a03a ("net: gso: fix panic on frag_list with mixed head alloc types") do not cover it: page-backed heads skip them, and kmalloc heads skip them when gso_size == skb_headlen(head), which the sender controls. An skb entering a frag queue is an IP fragment by definition and cannot legitimately carry GSO state: GRO does not merge fragments and the stack segments before it fragments, so only untrusted sources are affected. This has been reachable since commit f43798c27684 ("tun: Allow GSO using virtio_net_hdr"), the first path that let userspace attach GSO metadata to an IP fragment. Reset the GSO fields of every fragment as it is queued, in inet_frag_queue_insert(), which IPv4, IPv6, nf_conntrack_reasm and 6lowpan reassembly share; then neither the head nor the frag_list members of the reassembled skb carry them (the members matter too: the ip_do_fragment()/ip6_fragment() fast paths send them out as they are). The head may remain CHECKSUM_PARTIAL; that is already accepted on receive and resolved by skb_checksum_help() in ip_do_fragment()/ip6_fragment() on forward. Tested on top of net.git (dc4b95b8fee9), x86_64: the tap reproducer above, two further IPv4 frag_list geometries that reach BUG_ON(i >= nfrags) and BUG_ON(!list_skb->head_frag), and an IPv6 fragment-header variant (udp6_ufo_fragment()) each panic the unpatched kernel; with this patch all four datagrams are delivered intact and nothing is logged. Fixes: f43798c27684 ("tun: Allow GSO using virtio_net_hdr") Cc: stable@kernel.org Suggested-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Xinyang Ge <xinyang@anthropic.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/937926e509f2acd8e0e66520dc2b30fd6b4d1687.1787839506.git.pabeni@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
39 hoursnet/sched: sch_htb: limit htb_classify inner-class filter hopsJamal Hadi Salim
htb_classify() follows each filter-selected inner class by switching to cl->filter_list, but never bounds the number of hops. A filter on an inner class can point back to itself or to another inner class that points back, creating an infinite loop in the packet classification path with the qdisc lock held and BH disabled — a soft lockup / panic from a single packet. Bound the traversal with a hop counter and drop the packet with a rate-limited warning once the bound is exceeded. The counter is incremented at the point the inner filter chain is picked up, after the TC_ACT_* switch has consumed the classifier verdict, so a terminal TC_ACT_QUEUED/STOLEN/TRAP on the last permitted chain still sets *qerr to __NET_XMIT_STOLEN and the packet is not charged as a drop by this qdisc or its parent. The bound is TC_HTB_MAXDEPTH, taken from HTB's own parameters rather than from the qdisc hierarchy depth limit. Class levels run from 0 to TC_HTB_MAXDEPTH - 1, so a traversal that strictly descends in level can take at most TC_HTB_MAXDEPTH hops. That descent is what a sane configuration does, but it is assumed here rather than enforced: htb_find() resolves a classid against every class in the qdisc, so a filter may equally select a sibling or an ancestor. The normal root -> inner -> leaf path takes a single hop, so the bound does not affect legitimate classification. htb_classify() can now return NULL irrespective of CONFIG_NET_CLS_ACT, whereas previously every NULL return sat inside that ifdef. The NULL handler in htb_enqueue() therefore cannot stay conditional either, so drop the ifdef around it. This matches hfsc_enqueue(), which has always handled a NULL class unconditionally. Without it, a kernel built without actions would dereference a NULL class instead of dropping. Conditions to recreate the bug: - CONFIG_NET_SCHED, CONFIG_NET_SCH_HTB, CONFIG_NET_CLS_U32, CONFIG_LOCKUP_DETECTOR. - Create an HTB qdisc on a device (e.g. lo), add an inner class 1:1 with a leaf child 1:10, install a root u32 filter selecting 1:1, and an inner-class u32 filter on 1:1 also selecting 1:1. - Send one packet (ping). On the unfixed kernel the classify loop spins with the qdisc lock held; with softlockup_panic=1 it panics. - Reachable from unprivileged user via unshare -Urn (CAP_NET_ADMIN). Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: Vega <vega@nebusec.ai> Co-developed-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260826143339.271935-1-victor@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
39 hourstcp: fix corruption of urgent data on multi-segment retransmitJiayuan Chen
On the normal xmit path, while in urgent mode we refuse to build a multi-segment TSO packet, so every segment gets its own urg_ptr: /* tcp_write_xmit() */ limit = mss_now; if (tso_segs > 1 && !tcp_urg_mode(tp)) limit = tcp_mss_split_point(...); The retransmit path has no such guard. __tcp_retransmit_skb() builds a segs > 1 skb and hands it to the GSO layer, which only advances th->seq per segment and copies urg_ptr verbatim: /* __tcp_retransmit_skb() */ len = cur_mss * segs; /* segs > 1, no urg_mode check */ ... /* tcp_gso_segment(): bumps seq only, urg_ptr is copied */ urg_ptr is an offset from the segment's own seq, so a copied value points at a different place on each segment. The receiver rebuilds the absolute urgent seq as seg.seq + urg_ptr, so it walks a moving urgent point instead of the one OOB byte: seg1 seq 1 urg_ptr 5001 -> urgent @ 5001 (ok) seg2 seq 1001 urg_ptr 5001 -> urgent @ 6001 (wrong, +MSS) seg3 seq 2001 urg_ptr 5001 -> urgent @ 7001 (wrong, +2*MSS) The real OOB byte is never pointed at, so the receiver stops splicing it out and delivers it as normal in-band data, corrupting the stream. Guard the retransmit length like the xmit path: keep segs = 1 while in urgent mode. Fixes: 10d3be569243 ("tcp-tso: do not split TSO packets at retransmit time") Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260826141145.67823-1-jiayuan.chen@linux.dev Signed-off-by: Jakub Kicinski <kuba@kernel.org>
39 hoursnet: bridge: mcast: fix use-after-free of a master VLAN's multicast contextNorbert Szetei
br_multicast_toggle_one_vlan() clears BR_VLFLAG_MCAST_ENABLED under br->multicast_lock before stopping a VLAN's multicast context. That is the teardown handshake: lockless readers gate on the flag through br_multicast_ctx_should_use() -> br_multicast_ctx_vlan_disabled(), so once it is cleared under the lock no reader can arm the context again. For a master VLAN the handshake never runs. __vlan_del() clears BRIDGE_VLAN_INFO_BRENTRY before calling br_vlan_put_master(), so br_multicast_toggle_one_vlan(masterv, false) returns early on !br_vlan_is_brentry(vlan): the flag stays set and br->multicast_lock is never taken. br_vlan_put_master() then drains the context in br_multicast_ctx_deinit() and frees the VLAN through call_rcu(), while a reader still inside rcu_read_lock() sees the context as enabled and re-arms it. The port and port-VLAN branch of the function has no br_vlan_is_brentry() test and flips the flag under br->multicast_lock, so it is not affected. The reader is the bridge transmit path. For a master VLAN br_multicast_rcv() selects brmctx = &vlan->br_mcast_ctx with pmctx = NULL, so IGMP sent to the bridge device re-arms the context's timers after br_multicast_ctx_deinit() has already stopped them. BUG: KASAN: slab-use-after-free in detach_if_pending+0x412/0x4a0 Write of size 8 at addr ffff88810ac39918 by task brmc/601 __mod_timer+0x51a/0xc50 br_multicast_host_join+0x25b/0x390 __br_multicast_add_group+0x468/0x530 br_ip4_multicast_add_group+0x1a0/0x260 br_multicast_rcv+0x2cda/0x61e0 br_dev_xmit+0x6c4/0x1540 Allocated by task 610: br_vlan_add+0x111/0xb40 br_vlan_info+0x370/0x3e0 Freed by task 0: kfree+0x1a7/0x4f0 rcu_core+0x7dc/0x10a0 Only test br_vlan_is_brentry() when enabling, like the br_multicast_ctx_vlan_global_disabled() test next to it. Disabling then always clears BR_VLFLAG_MCAST_ENABLED under br->multicast_lock before br_multicast_ctx_deinit() drains the context. Fixes: 7b54aaaf53cb ("net: bridge: multicast: add vlan state initialization and control") Cc: stable@vger.kernel.org Signed-off-by: Norbert Szetei <norbert@doyensec.com> Acked-by: Nikolay Aleksandrov <razor@blackwall.org> Link: https://patch.msgid.link/D400F6C7-543A-4B79-9E5B-D1D8974DE5C9@doyensec.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
39 hoursnet/sched: bound qdisc_pkt_len to prevent qdisc soft lockupJamal Hadi Salim
qdisc_get_stab() accepts a user-supplied size table, and __qdisc_calculate_pkt_len() amplifies qdisc_pkt_len() through the overhead, the size-table data (u16), and size_log (up to STAB_SIZE_LOG_MAX). A crafted stab can therefore set qdisc_pkt_len() to ~1 GiB for an ordinary skb. Per-flow deficit schedulers such as DRR and ETS replenish one quantum per loop iteration; with a tiny quantum (1) they spin billions of times under the qdisc lock, producing a soft lockup / RCU stall as illustrated by vega@nebusec.ai. Cap the final qdisc_pkt_len() to QDISC_PKT_LEN_MAX so the size-table amplification cannot drive deficit schedulers into an unbounded loop. A legitimate size table (e.g. qfq's overhead 999999999, which is handled by dropping) is still accepted. Introduce cap QDISC_PKT_LEN_MAX (1 << 20) = 1 MiB which is well above any legitimate single-skb wire length: the largest current skb->len is GSO_MAX_SIZE (524280), and an ATM-style size table (53/48 cell tax) amplifies that to ~578 KB, both comfortably below 1 MiB. At the same time, 1 MiB bounds the deficit refill loop to ~1M iterations per packet with quantum=1, which completes in a few milliseconds well under the demonstrated softlockup threshold (~10^9 iterations). Conditions to recreate the bug: - CONFIG_NET_SCHED=y, CONFIG_NET_SCH_DRR=y (or CONFIG_NET_SCH_ETS=y). - Attach a DRR (or ETS) root qdisc with a crafted TCA_STAB that amplifies qdisc_pkt_len to ~1 GiB (e.g. size_log=15, data=[32768]). - Add a class with a tiny quantum of 1 and send one small packet; the deficit loop spins billions of times under the qdisc lock and trips the softlockup detector (panic with kernel.softlockup_panic=1). - Reachable as root or from an unprivileged user in a fresh user+net namespace (unshare -Urn) with namespace-local CAP_NET_ADMIN. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: vega@nebusec.ai Tested-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/20260825081403.133992-1-jhs@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
44 hoursnetfilter: nf_tables: remove leftover set_update_listPablo Neira Ayuso
This list has been moved to per-netns, remove onstack list which is not used anymore. Fixes: b343ededb3f9 ("netfilter: nf_tables: move set_update_list to nftables per-netns") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
44 hoursnetfilter: nf_tables: set on dead bit when performing early element removalPablo Neira Ayuso
.commit call for sets is skipped if set->dead flag is set on, but this flag is set on later in the commit path. This also reintroduces the bug fixed in commit 7315dc1e122c8 ("netfilter: nf_tables: skip set commit for deleted/destroyed sets"). Fixes: 1e3b9e1c77fe ("netfilter: nf_tables: call set ops .commit when building new ruleset blob") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
44 hoursnetfilter: nf_tables: skip double clone set expressions on element insertPablo Neira Ayuso
Both the dynset and newsetelem path clone the existing set expressions when setting set element expressions if no override expressions are provided. This results in a double clone, once to clone the template set expressions then another clone on the new element. Add a flag to annotate if userspace provides a override expression (ie. expression of the same type of the set but different configuration), otherwise borrow the existing expression from the set. Add conditionals to release expression iif they represent an override. Use this new override_exprs flag to dump the dynset expression override to userspace. This simplifies the existing logic and it also fixes a bug with the connlimit expression which results in a module refcount imbalance WARNING splat when resorting on the default set expressions. Fixes: 65038428b2c6 ("netfilter: nf_tables: allow to specify stateful expression in set definition") Fixes: fca05d4d61e6 ("netfilter: nft_dynset: honor stateful expressions in set definition") Reported-by: Xingyuan Mo <hdthky0@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
44 hoursnetfilter: x_tables: replace pr_{info,err}() by pr_info_ratelimited()Pablo Neira Ayuso
Several xtables extension still use pr_err() or pr_info() without ratelimit. For xt_cgroup, while at this, remove redundant "xt_cgroup:" prefix since pr_fmt is already set on. Fixes: c38c4597e4bf ("netfilter: implement xt_cgroup cgroup2 path match") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
44 hoursnetfilter: 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>
44 hoursnetfilter: nft_set_pipapo_avx2: add missing vzeroupperEric Biggers
Since pipapo_get_avx2() uses YMM registers, execute vzeroupper before returning from it. This is needed to avoid degrading the performance of any later SSE code that may happen to be executed. Fixes: 7400b063969b ("nft_set_pipapo: Introduce AVX2-based lookup implementation") Cc: stable@vger.kernel.org Signed-off-by: Eric Biggers <ebiggers@kernel.org> Reviewed-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
44 hoursnetfilter: nf_tables: move hardware offload step after building the chain blobPablo Neira Ayuso
Allocate the chain blob before the ruleset offload to reduce chances of entering an inconsistent state where the offloaded ruleset in the nic and the software ruleset differ. Fixes: c9626a2cbdb2 ("netfilter: nf_tables: add hardware offload support") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
45 hoursnet: Guard for gso_segs overflow in skb_segmentAlice Mikityanska
skb_segment calculates 32-bit partial_segs as len / gso_size, and then assigns it to the 16-bit gso_segs field. The division might overflow in some edge cases where the SKB is BIG TCP (65536 <= len <= 8*65535), and gso_size < TCP_MIN_GSO_SIZE = 8. While normally this can't happen due to TCP_MIN_GSO_SIZE, an AF_PACKET PACKET_VNET_HDR socket could generate such a malformed packet until the previous patch. Blocking malformed virtio_net packets was implemented in the previous patch, but this patch clamps partial_segs in skb_segment itself for more generic robustness. Should len / gso_size happen to be bigger than 65535 in partial GSO, skb_segment will now just produce more than two output SKBs, all of which will be valid with gso_segs <= 65535. In order to catch possible other cases of too many partial_segs, add a DEBUG_NET_WARN_ON_ONCE when len / gso_size happens to be too big. Signed-off-by: Alice Mikityanska <alice@isovalent.com> Link: https://patch.msgid.link/20260822120117.1163423-3-alice.kernel@fastmail.im Signed-off-by: Paolo Abeni <pabeni@redhat.com>
46 hoursnetfilter: conncount: use DEBUG_NET_WARN_ON_ONCE on reaching count limitFernando Fernandez Mancera
Replace WARN_ON_ONCE with DEBUG_NET_WARN_ON_ONCE in __nf_conncount_add. The function handles count limit breaches safely by returning -EOVERFLOW, so a production backtrace is not needed. This prevents unnecessary system panics when panic_on_warn=1 is enabled in production systems. Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
46 hoursnetfilter: 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>
2 daystcp: fix AO info use-after-free in tcp_ao_connect_init()Qing Ming
tcp_v4_connect() adds a SYN-SENT socket to the ehash before calling tcp_connect(). If TCP-AO is configured, tcp_connect() first verifies that a key matches the peer and the bound device's current L3 master. tcp_ao_connect_init() later resolves the L3 master again and removes keys which do not match it. The socket lock does not stabilize the bound device's VRF membership. Detaching the device from its VRF between the initial validation and the L3-master calculation in tcp_ao_connect_init() can therefore make the validation succeed while initialization observes the default L3 domain and removes the only key. The subsequent AO lookup then fails, so the no-key path clears tp->ao_info and frees it directly. The receive path can find the socket in the ehash and load tp->ao_info under RCU before acquiring the socket lock. A reader which loaded the old pointer can thus continue into tcp_inbound_ao_hash() after the direct free. The issue was found during a static audit of TCP-AO object lifetime. An unprivileged reproducer in self-created user and network namespaces raced connect() with detaching a veth from its VRF while sending TCP-AO segments. It triggered the same KASAN report on two fresh boots: BUG: KASAN: slab-use-after-free in tcp_inbound_ao_hash+0x585/0x19f0 Write of size 8 at addr ffff88800bf88128 by task tcp_ao_vrf_race/232 Call Trace: tcp_inbound_ao_hash+0x585/0x19f0 tcp_inbound_hash+0x677/0xa80 tcp_v4_rcv+0x1c3e/0x3ab0 Allocated by task 235: tcp_ao_alloc_info+0x43/0xf0 tcp_ao_add_cmd+0xdf7/0x13b0 do_tcp_setsockopt+0x168c/0x2640 Freed by task 235: kfree+0x1b8/0x550 tcp_connect+0x252/0x4f00 tcp_v4_connect+0x1114/0x1720 The bad address is 40 bytes inside the freed 128-byte object, matching the tcp_ao_info counters.key_not_found field. The two runs used 1000 attempts each, reached the no-key path 366 and 411 times, and produced one and two KASAN reports respectively. With this change, the same reproducer reached the no-key path 366 times in 1000 attempts without a KASAN report or oops. Use tcp_ao_destroy_sock() for the no-key path. It unpublishes the AO info, updates the socket memory and static-key accounting, and defers the free until after an RCU grace period. Also drop the WARN_ON_ONCE() and its stale comment. The VRF detach race makes the no-key state reachable during normal operation, so it is a handled condition rather than an impossible assertion. On panic_on_warn kernels the WARN would turn this handled race into a kernel panic. Fixes: 248411b8cb89 ("net/tcp: Wire up l3index to TCP-AO") Cc: stable@vger.kernel.org Assisted-by: Codex:gpt-5 Signed-off-by: Qing Ming <a0yami@mailbox.org> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260825072033.6921-1-a0yami@mailbox.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2 daysnet/tcp: fix TCP-AO key deletion in VRFsRastislav Szabo
TCP-AO keys with TCP_AO_KEYF_IFINDEX store the VRF L3 interface index in l3index. tcp_ao_del_cmd() validates the supplied ifindex, but does not assign it to its local l3index before matching keys. As a result, deleting a key scoped to a non-default VRF always fails with ENOENT because it is matched against l3index 0. Fixes: 248411b8cb89 ("net/tcp: Wire up l3index to TCP-AO") Cc: stable@vger.kernel.org Signed-off-by: Rastislav Szabo <rastislav.szabo@isovalent.com> Reviewed-by: David Ahern <dsahern@kernel.org> Acked-by: Dmitry Safonov <0x7f454c46@gmail.com> Link: https://patch.msgid.link/20260822201119.272269-1-rastislav.szabo@isovalent.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2 daysnet/smc: release the internal TCP sock on IPPROTO_SMC socket creation failureYifei Chu
IPPROTO_SMC sockets create an internal TCP sock ("clcsock") from the proto->init hook. When socket creation fails after proto->init has run - e.g. a cgroup BPF program attached to BPF_CGROUP_INET_SOCK_CREATE denies the socket - sk_common_release() only invokes sk_prot->destroy if it is set, but neither smc_inet_prot nor smc_inet6_prot defines it, and smc_destruct() returns early unless sk_state is SMC_CLOSED. As a result, every failing socket(AF_INET, SOCK_STREAM, IPPROTO_SMC) call leaks one tcp_sock, so an unprivileged task able to attach a deny-all BPF_CGROUP_INET_SOCK_CREATE program to its own cgroup can grow kernel memory unboundedly. Add a .destroy hook to both protos that releases the clcsock via smc_clcsock_release(). smc_sk_init() hashes the sock into the smc hashinfo before the clcsock is created, and smc_diag dumps walk that hash dereferencing smc->clcsock without taking clcsock_release_lock, while sk_common_release() calls .destroy before .unhash. Unhash the sock before releasing the clcsock, as __smc_release() does, so a concurrent dump cannot observe the release; the second unhash in sk_common_release() is a no-op. Fixes: d25a92ccae6b ("net/smc: Introduce IPPROTO_SMC") Reported-by: Abaci <abaci@linux.alibaba.com> Assisted-by: abaci:qwen3.8-max Signed-off-by: Yifei Chu <Chuyf26@linux.alibaba.com> Reviewed-by: Dust Li <dust.li@linux.alibaba.com> Link: https://patch.msgid.link/178753843966.342810.566471390946765094@linux.alibaba.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2 daysnet: fix spurious TX timeout after dev_activate()Breno Leitao
While debugging another issue today, I found out that my TX queue is reported as stopped for 4294907392 ms (49.7 days), on a machine that had been up for four minutes. bnxt_en 0002:01:00.0 eth0: NETDEV WATCHDOG: CPU: 28: transmit queue 23 timed out 4294907392 ms 4294907392 is not an elapsed time. It is the value of jiffies at that moment: INITIAL_JIFFIES is 4294667296, which leaves jiffies 59 seconds short of wrapping. dev_activate() runs transition_one_qdisc() over every TX queue, which resets trans_start to 0, and then stamps only queue 0 through netif_trans_update(). Stamp jiffies instead. A queue stopped across dev_activate() now gets a full watchdog_timeo of grace, and is still reported if it is stopped that long. Fixes: 9b36627acecd ("net: remove dev->trans_start") Cc: stable@vger.kernel.org Signed-off-by: Breno Leitao <leitao@debian.org> Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de> Reviewed-by: Jason Xing <kerneljasonxing@gmail.com> Link: https://patch.msgid.link/20260825-trans_start-v2-1-286b4d6d70cb@debian.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2 daysMerge tag 'hyperv-next-signed-20260826' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux Pull hyperv updates from Wei Liu: - Decrypt netvsc buffer on contiguous direct-map addresses (Kameron Carr) - Drop WS2012/2012R2 & Win8/8.1 Hyper-V support (Michael Kelley) - Use more meaningful errnos for hypercall status code (Hardik Garg) - Fix lost interrupts on CPU hot-unplug for Hyper-V PCI/MSI (Naman Jain) - Reserve more MSHV vectors for Linux root partition (Wei Liu) * tag 'hyperv-next-signed-20260826' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux: clocksource: hyper-v: Remove support for stimer interrupts in message mode scsi: storvsc: Remove support for storvsc protocol of old Hyper-V hosts hv_netvsc: Remove GPADL teardown special case for old Hyper-V hosts hv_sock: Remove check for old Hyper-V hosts Drivers: hv: Remove support for WS2012/2012R2 & Win8/8.1 version of Hyper-V hv_netvsc: Allocate send/receive buffers using vmbus_alloc_buffer() Drivers: hv: vmbus: Add vmbus_alloc_buffer()/vmbus_free_buffer() for CoCo VMs Drivers: hv: vmbus: add vmbus_establish_gpadl_caller_decrypted() Drivers: hv: vmbus: Skip VMBus module cleanup for non-nested root partition x86/hyperv: reserve more vectors PCI: hv: Set irq_retrigger callback for the Hyper-V PCI MSI irqchip Drivers: hv: Use meaningful errnos for hypercall status codes
3 daysMerge tag 'nfs-for-7.3-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfsLinus Torvalds
Pull NFS client updates from Trond Myklebust: "Highlights include: Stable fixes: - Use-after-free fixes for the sunrpc client code - Delegation hash table leak - NULL dereference on lockowner allocation failure - Fix a handshake completion race in the TLS code - Fix an error sign checking issue when deciding whether the pNFS layout is still in use, or can be returned - Fix a layout segment leak in pnfs_layout_process() Other bugfixes: - Fix a missing NULL check in the rpcbind client - annotate shared socket callbacks with READ_ONCE/WRITE_ONCE - nfs_inode_set_delegation() error paths should return the delegation - Use clear_and_wake_up_bit() in nfs_clear_invalid_mapping() and the pNFS code. - Fix the nfs4_alloc_client() error paths to free the IDR allocation - fix folio dereference before NULL check in nfs_inode_remove_request() - Fix delayed delegation return - Fix another state manager race with umount - Fix device leaks on parse failure - Avoid cancelling in-flight I/O during a layout recall if the server doesn't require it - flexfiles: report cancelled I/O as a layout error - flexfiles: fix NULL dereference for NFSv4.0 data servers - Fix incorrect argument passed to nfs4_delete_lease() - Fix several symlink issues resulting from nfs_atomic_open_v23() - Fix an uninitialised variable issue in the NFSv4.1 callback code - fix LAYOUTSTATS send buffer exhaustion Features and cleanups: - NFSv4.2: Allow the server to specify that file data may not be cached - localio: optimise I/O submission when when not doing memory reclaim - localio: Remove duplicate wait code in nfs_local_commit - flexfiles: support loosely coupled NFSv4.x data servers - pNFS: key the data server cache on the NFS version" * tag 'nfs-for-7.3-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (33 commits) NFSv4.1: fix layout segment leak on the pnfs_layout_process() forget path NFSv4/pnfs: key the data server cache on the NFS version NFSv4.2: fix LAYOUTSTATS send buffer exhaustion pNFS: Fix EBUSY check in pnfs_layout_need_return NFSv4.1: zero referring call lists before decoding nfs: fix ENXIO on O_CREAT open of existing symlink over NFSv3 SUNRPC: wait for in-flight client TLS handshake callback NFSv4: Fix incorrect argument passed to nfs4_delete_lease() in nfs4_add_lease() lockd: fix NULL dereference on lockowner allocation failure NFS: fix delegation_hash_table leak when nfs4_server_common_setup() fails NFSv4/flexfiles: support loosely coupled data servers NFSv4/flexfiles: fix NULL dereference for NFSv4.0 data servers NFSv4: pin the superblock for active state owners sunrpc: fix use-after-free in __rpc_clnt_handle_event and __rpc_clnt_remove_pipedir NFS/localio: issue commit inline when not in a memory-reclaim context NFS/localio: remove dead FLUSH_SYNC handling from nfs_local_commit NFS/localio: issue IO inline when not in a memory-reclaim context NFS: Fix delayed delegation return list handling NFS: Verify symlink inode before caching target NFS: fix folio dereference before NULL check in nfs_inode_remove_request() ...
3 dayslibceph: reject buckets with mismatched CRUSH idsJérémy Jean
crush_decode() stores bucket data by array slot, and the mapper later derives the per-bucket workspace index from the decoded bucket id. A malformed map can therefore make one bucket reuse another bucket's workspace by encoding an id different from -1 - slot. For uniform buckets, the second replica selection expands the source bucket's permutation into that aliased workspace buffer. If the source bucket is larger than the aliased bucket, the write runs past the smaller permutation array and can escape the kvmalloc'd CRUSH workspace. KASAN reports a slab OOB write of 4 bytes in bucket_perm_choose(). Reject buckets whose encoded id does not match their array slot. Valid CRUSH maps already use the canonical negative id corresponding to the bucket slot, so this restores the invariant expected by work->work[-1 - in->id] without changing valid map behavior. Cc: stable@vger.kernel.org Fixes: 66a0e2d579db ("crush: remove mutable part of CRUSH map") Assisted-by: Codex:gpt-5 Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
3 dayslibceph: remove ceph_put_page_vector()Tal Zussman
ceph_put_page_vector() was paired with ceph_get_direct_page_vector(), which was removed in commit 97a385e55829 ("libceph: remove ceph_get_direct_page_vector()"). Its only remaining caller, finish_netfs_read(), uses it to put a page vector allocated with iov_iter_get_pages_alloc2(), which is confusing. Open-code the put_page() loop and kvfree() there instead. The caller passed dirty = false, so this also removes the dead dirty branch and with it a call to the deprecated set_page_dirty_lock(). Signed-off-by: Tal Zussman <tz2294@columbia.edu> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
3 dayslibceph: validate banner payload lengthAleksandr Nogikh
When parsing the Ceph messenger v2 protocol banner, the `payload_len` field is decoded from the banner prefix. If a client sends a banner with a `payload_len` of 0, the kernel sets up a 0-length socket read. This violates an invariant in the state machine, triggering a warning in `populate_in_iter()`: ------------[ cut here ]------------ !iov_iter_count(&con->v2.in_iter) WARNING: net/ceph/messenger_v2.c:3129 at populate_in_iter net/ceph/messenger_v2.c:3129 [inline], CPU#1: kworker/1:3/5070 WARNING: net/ceph/messenger_v2.c:3129 at ceph_con_v2_try_read+0x6634/0x6810 net/ceph/messenger_v2.c:3159, CPU#1: kworker/1:3/5070 ... Call Trace: <TASK> ceph_con_workfn+0x1f5/0x14a0 net/ceph/messenger.c:1575 process_one_work kernel/workqueue.c:3322 [inline] process_scheduled_works+0xa8e/0x14e0 kernel/workqueue.c:3405 worker_thread+0xa47/0xfb0 kernel/workqueue.c:3486 kthread+0x388/0x470 kernel/kthread.c:436 ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 </TASK> According to the msgr2 protocol specification, the banner payload is expected to contain at least two 64-bit integers (`server_feat` and `server_req_feat`). Therefore, `payload_len` must be at least 16 bytes. Fix this by adding a check in `process_banner_prefix()` to reject a `payload_len` smaller than 16 bytes. This prevents the 0-length read and correctly aborts the connection with a protocol error. Fixes: cd1a677cad99 ("libceph, ceph: implement msgr2.1 protocol (crc and secure modes)") Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot Reported-by: syzbot+87c7c2d63c44e41c77a3@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=87c7c2d63c44e41c77a3 Link: https://syzkaller.appspot.com/ai_job?id=c8ca3d63-717a-4933-89ec-f3d761b8690d Signed-off-by: Aleksandr Nogikh <nogikh@google.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
3 dayslibceph: validate OSD extent maps before cursor advanceMichael Bommarito
net/ceph/osd_client.c:osd_sparse_read() validates that the sparse-read data length matches the summed extent lengths, but it does not validate that each OSD-supplied extent is monotonic and lies inside the original request range. A malformed authenticated OSD reply can advertise a far-forward nonzero extent offset with a matching data length and make the client advance the message-data cursor beyond the request buffer. This reaches the BUG_ON(!*length) assertion in ceph_msg_data_next() from the client receive path. Impact: A malicious or compromised authenticated Ceph OSD peer can crash a kernel Ceph client via a malformed sparse-read reply. Reject sparse extent maps that overflow, move backwards, overlap, or extend outside the original sparse-read request before advancing the cursor. [ idryomov: perform sparse_extent_map_valid() check a bit earlier, in CEPH_SPARSE_READ_DATA_LEN instead of CEPH_SPARSE_READ_DATA_PRE state ] Cc: stable@vger.kernel.org Fixes: f628d7999727 ("libceph: add sparse read support to OSD client") Assisted-by: Codex:gpt-5-5-xhigh Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
3 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>
4 daysnet/sched: sch_teql: restore skb->dev on the slave failure pathVictor Nogueira
teql_master_xmit() sets skb->dev = slave before calling the slave's ndo_start_xmit(), but never restores it when that transmit fails. The skb then walks on to the next slave still pointing at the previous one. If a later slave has no resolved neighbour, teql_resolve() hands the skb to neigh_event_send(), which queues it on that neighbour's arp_queue with the stale skb->dev. skb->dev holds no reference, so deleting the previous slave frees the net_device while the skb is still queued. Whatever runs next on that skb - arp_error_report() on timeout, or neigh_direct_output() -> dev_queue_xmit() once the neighbour resolves - causes a UAF like the one below: BUG: KASAN: slab-use-after-free in __icmp_send (net/ipv4/icmp.c:914 (discriminator 2)) Read of size 4 at addr ffff888106e100b0 by task flood_packet/527 CPU: 0 UID: 0 PID: 527 Comm: flood_packet Not tainted 7.2.0-rc6-g594d90519502 #1 PREEMPT(lazy) Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Call Trace: <IRQ> dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120) print_report (mm/kasan/report.c:378 mm/kasan/report.c:482) ? __pfx__raw_spin_lock_irqsave (./include/asm-generic/qrwlock.h:122 (discriminator 4)) ? __icmp_send (net/ipv4/icmp.c:914 (discriminator 2)) kasan_report (mm/kasan/report.c:595) ? __icmp_send (net/ipv4/icmp.c:914 (discriminator 2)) __icmp_send (net/ipv4/icmp.c:914 (discriminator 2)) [...] ipv4_link_failure (net/ipv4/route.c:1251 net/ipv4/route.c:1258) ? __pfx_ipv4_link_failure (./include/linux/skbuff.h:4327) ? _raw_write_lock (./include/linux/instrumented.h:55 ./include/linux/atomic/atomic-instrumented.h:1301 ./include/asm-generic/qrwlock.h:98 ./include/linux/rwlock_api_smp.h:230 kernel/locking/spinlock.c:304) ? __pfx__raw_write_lock (kernel/locking/spinlock.c:175) arp_error_report (./include/net/dst.h:438 net/ipv4/arp.c:296) neigh_invalidate (net/core/neighbour.c:1077) neigh_timer_handler (net/core/neighbour.c:1169) [...] Allocated by task 505: kasan_save_stack (mm/kasan/common.c:57) kasan_save_track (mm/kasan/common.c:78) __kasan_kmalloc (mm/kasan/common.c:398 mm/kasan/common.c:415) __kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5334 mm/slub.c:6905) alloc_netdev_mqs (net/core/dev.c:12055 (discriminator 2)) rtnl_create_link (net/core/rtnetlink.c:3721) rtnl_newlink (net/core/rtnetlink.c:3903 net/core/rtnetlink.c:4044 net/core/rtnetlink.c:4159) rtnetlink_rcv_msg (net/core/rtnetlink.c:7076) [...] Freed by task 536: kasan_save_stack (mm/kasan/common.c:57) kasan_save_track (mm/kasan/common.c:78) kasan_save_free_info (mm/kasan/generic.c:584) __kasan_slab_free (mm/kasan/common.c:253 mm/kasan/common.c:285) kfree (./include/linux/kasan.h:235 mm/slub.c:2677 mm/slub.c:6377 mm/slub.c:6692) device_release (drivers/base/core.c:2636) kobject_put (lib/kobject.c:689 lib/kobject.c:720 ./include/linux/kref.h:65 lib/kobject.c:737) netdev_run_todo (net/core/dev.c:11756) rtnl_dellink (net/core/rtnetlink.c:157 ./include/linux/rtnetlink.h:135 net/core/rtnetlink.c:3651) rtnetlink_rcv_msg (net/core/rtnetlink.c:7076) [...] Fix this by restoring skb->dev to the master at the end of each slave's iteration. Fixes: 0cc0c2e661af ("net/sched: teql: fix NULL pointer dereference in iptunnel_xmit on TEQL slave xmit") Reported-by: Vega <vega@nebusec.ai> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: Victor Nogueira <victor@mojatatu.com> Link: https://patch.msgid.link/20260824115928.4099988-1-victor@mojatatu.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 dayssctp: fix stream->outcnt underflow on duplicate RECONF responsesJun Yang
A cached RECONF chunk may contain more than one request parameter. A duplicate response can therefore find and process the same ADD_OUT request again while another parameter is still outstanding, rolling back outcnt twice and possibly underflowing it. Track outstanding request types as bits and clear each bit after its first response. Later responses for the same request are then ignored. Fixes: 11ae76e67a17 ("sctp: implement receiver-side procedures for the Reconf Response Parameter") Cc: stable@kernel.org Reported-by: TencentOS Corvus AI <corvus@tencent.com> Link: https://lore.kernel.org/netdev/20260730110225.37371-1-juny24602@gmail.com/ Suggested-by: Xin Long <lucien.xin@gmail.com> Assisted-by: tencentos-corvus-ai:kimi-k3 Signed-off-by: Jun Yang <junvyyang@tencent.com> Link: https://patch.msgid.link/20260824081832.98717-3-juny24602@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 dayssctp: distinguish sequence zero from wildcard in reconf lookupJun Yang
Zero is a valid response sequence after strreset_outseq wraps, but sctp_chunk_lookup_strreset_param() currently treats it as a wildcard. Add match_seq so response lookups match zero exactly while the one type-only lookup can still ignore the sequence. Fixes: 50a41591f110 ("sctp: implement receiver-side procedures for the Add Outgoing Streams Request Parameter") Cc: stable@kernel.org Suggested-by: Simon Horman <horms@kernel.org> Acked-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: Jun Yang <junvyyang@tencent.com> Link: https://patch.msgid.link/20260824081832.98717-2-juny24602@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet/sched: sfq: clamp quantum to avoid signed overflow soft lockupJamal Hadi Salim
sfq_init() sets q->quantum = psched_mtu(qdisc_dev(sch)) (unsigned). A device with a huge MTU (e.g. dummy with max_mtu == 0 accepting MTU 2147483634) makes psched_mtu() return 0x80000000, so slot->allot = INT_MIN and INT_MIN + INT_MIN toggles between INT_MIN and 0 forever, spinning sfq_dequeue() under the qdisc lock. Clamp the quantum to [256, 1 << 20] so the refill loop terminates. The lower bound also covers q->quantum == 0 (psched_mtu() returning 0), which spins sfq_dequeue() identically. sfq_change() already rejects a negative quantum, so only the init path was exposed. Conditions to recreate the bug: a device whose MTU (plus hard_header_len) wraps psched_mtu() into the sign bit (e.g. a dummy device with max_mtu == 0 accepting MTU 2147483634). Requires CAP_NET_ADMIN in a user namespace. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: vega@nebusec.ai Tested-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/20260822195509.112717-7-jhs@mojatatu.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet/sched: hhf: clamp quantum before hhf_change() to avoid overflowJamal Hadi Salim
hhf_init() sets q->quantum = psched_mtu(qdisc_dev(sch)) with no overflow check. A device with a huge MTU (e.g. dummy with max_mtu == 0 accepting MTU 2147483634) makes weight * quantum overflow the signed deficit in hhf_dequeue(), spinning forever. Clamp q->quantum before hhf_change() so both the opt and !opt paths see a sane quantum. Without this, bare "tc qdisc add ... hhf" succeeds with a clamped quantum but "tc qdisc add ... hhf limit 1000" (any option present) fails with -EINVAL because hhf_change() re-validates the unclamped default (sch_hhf.c:559). 256 matches fq_codel's floor and is a sane minimum for a DRR quantum. Conditions to recreate the bug: a device whose MTU (plus hard_header_len) wraps psched_mtu() into the sign bit (e.g. a dummy device with max_mtu == 0 accepting MTU 2147483634). Requires CAP_NET_ADMIN in a user namespace. Fixes: 10239edf86f1 ("net-qdisc-hhf: Heavy-Hitter Filter (HHF) qdisc") Reported-by: vega@nebusec.ai Tested-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/20260822195509.112717-6-jhs@mojatatu.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet/sched: fq_pie: clamp default quantum to avoid signed overflowJamal Hadi Salim
fq_pie_init() sets q->quantum = psched_mtu(qdisc_dev(sch)) without clamping. A device with a huge MTU (e.g. dummy with max_mtu == 0 accepting MTU 2147483634) makes psched_mtu() return 0x80000000, which overflows the signed flow->deficit to INT_MIN in fq_pie_qdisc_dequeue(), causing an infinite loop and soft lockup. Emulate fq_pie_policy which is already bounded to [1, 1 << 20]; clamp the default to [256, 1 << 20]. 256 matches fq_codel's floor and is a sane minimum for a DRR quantum. Conditions to recreate the bug: a device whose MTU (plus hard_header_len) wraps psched_mtu() into the sign bit (e.g. a dummy device with max_mtu == 0 accepting MTU 2147483634). Requires CAP_NET_ADMIN in a user namespace. Fixes: ec97ecf1ebe4 ("net: sched: add Flow Queue PIE packet scheduler") Reported-by: vega@nebusec.ai Tested-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/20260822195509.112717-5-jhs@mojatatu.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet/sched: sch_codel: clamp default mtu to avoid disabling CoDelJamal Hadi Salim
codel_init() sets q->params.mtu = psched_mtu(qdisc_dev(sch)) without clamping. A device with a huge MTU (e.g. dummy with max_mtu == 0 accepting MTU 2147483634) makes psched_mtu() return 0x80000000. In codel_should_drop() the test "*backlog <= params->mtu" then compares the backlog against ~2 GiB; with the default sch->limit of DEFAULT_CODEL_LIMIT (1000) packets the backlog can never reach it, so the test is always true and CoDel is silently and completely disabled i.e no drops, no ECN marking, codel degrades to a tail-drop FIFO. codel_change() never updates params.mtu, so the init path is the only place to clamp it. Constrain to [256, 1 << 20], matching the fq_codel bound; 256 is a sane floor that only makes CoDel slightly more willing to act on very small queues, which is the safe direction. Conditions to recreate the bug: a device whose MTU (plus hard_header_len) wraps psched_mtu() into the sign bit (e.g. a dummy device with max_mtu == 0 accepting MTU 2147483634). Requires CAP_NET_ADMIN in a user namespace. Fixes: 76e3cc126bb2 ("codel: Controlled Delay AQM") Reported-by: vega@nebusec.ai Tested-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/20260822195509.112717-4-jhs@mojatatu.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet/sched: fq_codel: clamp default quantum and mtuJamal Hadi Salim
fq_codel_init() sets q->quantum = psched_mtu(qdisc_dev(sch)) without clamping. A device with a huge MTU (e.g. dummy with max_mtu == 0 accepting MTU 2147483634) makes psched_mtu() return 0x80000000, which overflows the signed flow->deficit to INT_MIN in fq_codel_dequeue(), causing an infinite loop and soft lockup. Emulate fq_codel_change() and constrain to [256, FQ_CODEL_QUANTUM_MAX]. The same unclamped psched_mtu() is assigned to q->cparams.mtu a bit below, and fq_codel_change() never updates it. codel_should_drop() tests "*backlog <= params->mtu"; with mtu == 0x80000000 (~2 GiB) and the default 32 MiB memory_limit, the test is always true, so CoDel is silently and completely disabled (no drops, no ECN). Declare a single clamped mtu and assign both q->quantum and q->cparams.mtu from it, which also removes the double psched_mtu() call. Conditions to recreate the bug: a device whose MTU (plus hard_header_len) wraps psched_mtu() into the sign bit (e.g. a dummy device with max_mtu == 0 accepting MTU 2147483634). Requires CAP_NET_ADMIN in a user namespace. Fixes: 4b549a2ef4be ("fq_codel: Fair Queue Codel AQM") Reported-by: vega@nebusec.ai Tested-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/20260822195509.112717-3-jhs@mojatatu.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet/sched: fq: add overflow bounds to quantum and initial quantumJamal Hadi Salim
fq_init() computes quantum = 2 * psched_mtu() and initial_quantum = 10 * psched_mtu() with no overflow check. A device with a huge MTU (e.g. dummy with max_mtu == 0 accepting MTU 2147483634) makes psched_mtu() return 0x80000000; the 2 * and 10 * multiplications wrap to 0 in 32-bit arithmetic, so q->quantum == 0. Then in fq_dequeue() the credit-refill loop adds 0 to f->credit (which stays <= 0) and goto begin loops forever under the qdisc lock, creating a soft lockup. Clamp psched_mtu() to [1, 1 << 20] before multiplying so the product cannot wrap, then cap the result at 1 << 20, matching the bound already enforced on TCA_FQ_QUANTUM in fq_change(). Conditions to recreate the bug: a device whose MTU (plus hard_header_len) is large enough that 2 * psched_mtu() wraps (e.g. a dummy device with max_mtu == 0 accepting MTU 2147483634). Requires CAP_NET_ADMIN in a user namespace. Fixes: afe4fd062416 ("pkt_sched: fq: Fair Queue packet scheduler") Reported-by: vega@nebusec.ai Tested-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/20260822195509.112717-2-jhs@mojatatu.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysvsock/virtio: flush works in dependency orderChengfeng Ye
virtio_vsock_remove() stops the virtqueues and then flushes each work item before freeing the enclosing virtio_vsock. The current order does not account for dependencies between those items: tx_work may queue send_pkt_work, and send_pkt_work may queue rx_work. In particular, send_pkt_work can set restart_rx and release tx_lock. The remove path can then stop the queues and flush rx_work before send_pkt_work queues it. Although the later send_pkt_work flush waits for that producer to finish, nothing waits for the newly queued rx_work, so kfree(vsock) can race with it. KASAN reported: BUG: KASAN: slab-use-after-free in virtio_transport_rx_work+0x487/0x4b0 Read of size 8 at addr ffff888114c2b008 by task kworker/1:1/47 Workqueue: virtio_vsock virtio_transport_rx_work Call Trace: virtio_transport_rx_work+0x487/0x4b0 process_one_work+0x688/0x1120 worker_thread+0x45b/0xd10 Allocated by task 1: virtio_vsock_probe+0xef/0x6b0 Freed by task 84: kfree+0x131/0x3c0 virtio_vsock_remove+0xd1/0x100 Flush the works in producer-to-consumer order. virtio_vsock_vqs_del() has already disabled the queue callbacks and cleared the run flags, so after tx_work and send_pkt_work are drained, no source remains that can queue rx_work after its flush. Fixes: 0ea9e1d3a9e3 ("VSOCK: Introduce virtio_transport.ko") Cc: stable@vger.kernel.org Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com> Link: https://patch.msgid.link/20260822164556.3750959-1-nicoyip.dev@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet: fix a resource leak in copy_net_ns() error handling pathTetsuo Handa
Currently, preinit_net() does two things: (1) call ns_common_init() which might fail (2) initialize resources which does not fail However, preinit_net() is returning early when (1) fails, and copy_net_ns() is jumping to the dec_ucounts: label. As a result, resources allocated by net_alloc() are leaking. We need to call key_remove_domain() and net_passive_dec() in order to release resources allocated by net_alloc(). We cannot simply jump to the put_userns: label when preinit_net() failed, for (2) is not yet done. But we can reorder (1) and (2), for there is no dependency between (1) and (2). Therefore, this patch decouples (1) from preinit_net() and changes preinit_net() back to a void function, and calls ns_common_init() after preinit_net() succeeded. Then, we can jump to immediately after ns_common_free() of the put_userns: label. Reported-by: sashiko (no mail address) Closes: https://sashiko.dev/#/patchset/af7dabf3-d0d7-46dc-a878-e1715b3c9ac6%40I-love.SAKURA.ne.jp Fixes: 08027f6b790b ("net: use ns_common_init()") Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Link: https://patch.msgid.link/c182cf90-1ed7-435b-88f7-9f00e88a0487@I-love.SAKURA.ne.jp Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet: core: fix head-page leak in skb_zerocopyMina Almasry
When skb_orphan_frags() throws -ENOMEM, skb_copy_ubufs() may have already reallocated and replaced 'from->head'. Accessing from->head to drop the old refcount leaks the original head page, and erroneously puts an unrelated new buffer. Use the local 'page' tracker variable instead to drop the reference properly. Fixes: 36d5fe6a0007 ("core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors") Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20260823183602.1051453-2-almasrymina@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet: core: check skb_frags_readable before uncloning in skb_copy_ubufsMina Almasry
skb_copy_ubufs drops clones and modifies the SKB via pskb_expand_head() before checking for !skb_frags_readable(skb). This alters the SKB geometry prior to throwing an -EFAULT on an invalid SKB. Check readability first. Fixes: 65249feb6b3d ("net: add support for skbs with unreadable frags") Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20260823183602.1051453-1-almasrymina@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 dayssctp: fix NULL deref on untransmitted RECONF completionWeiming Shi
sctp_process_strreset_outreq(), sctp_process_strreset_addstrm_out() and sctp_process_strreset_resp() complete a pending stream reconfiguration request by stopping the reconf timer on the transport it was sent on: t = asoc->strreset_chunk->transport; if (timer_delete(&t->reconf_timer)) sctp_transport_put(t); chunk->transport is assigned by __sctp_packet_append_chunk() when the chunk is appended to an outbound packet, and sctp_outq_flush_ctrl() arms the reconf timer at that same point. A request already published in asoc->strreset_chunk but not yet transmitted has neither, so completing it dereferences NULL. Two ways to get there. sctp_send_asconf_del_ip() sets asoc->src_out_of_asoc_ok without sending anything when the address being removed is the association's last one, and sctp_outq_flush_ctrl() then leaves every non-ASCONF control chunk queued; as only sctp_process_asconf_ack() clears that flag, it persists. An unprivileged process that removes such an address and then asks for a stream reset panics the kernel from softirq. A peer needs neither ASCONF nor local help: sctp_cmd_interpreter() uncorks the outqueue only once the whole packet has been processed, so a reply built while walking a RECONF chunk stays untransmitted for the rest of that walk, and one RECONF chunk carrying [Incoming SSN Reset Request, Outgoing SSN Reset Request, Response] -- or two RECONF chunks in one packet -- reaches the same dereference. KASAN: null-ptr-deref in range [0x00000000000001e8-0x00000000000001ef] RIP: 0010:timer_delete+0x67/0x110 Call Trace: <IRQ> sctp_process_strreset_addstrm_out (net/sctp/stream.c:832) sctp_sf_do_reconf (net/sctp/sm_statefuns.c:4212) sctp_do_sm (net/sctp/sm_sideeffect.c:1172) sctp_assoc_bh_rcv (net/sctp/associola.c:1044) sctp_rcv (net/sctp/input.c:243) ip_local_deliver (net/ipv4/ip_input.c:262) process_backlog (net/core/dev.c:6680) </IRQ> A response can only acknowledge a request that was actually sent, so do not match asoc->strreset_chunk while chunk->transport is NULL. Guarding the lookup covers all three completion sites. Fixes: 810544764536 ("sctp: implement receiver-side procedures for the Outgoing SSN Reset Request Parameter") Cc: stable@vger.kernel.org Reported-by: Xiang Mei <xmei5@asu.edu> Suggested-by: Xin Long <lucien.xin@gmail.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Weiming Shi <bestswngs@gmail.com> Acked-by: Xin Long <lucien.xin@gmail.com> Link: https://patch.msgid.link/20260823172857.896146-2-bestswngs@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet/sched: act_skbmod: fix length calculations and avoid invalid header warningsEric Dumazet
syzbot reported a warning in skb_network_header_len() triggered by tcf_skbmod_act(): !skb_transport_header_was_set(skb) WARNING: CPU: 0 PID: 14949 at include/linux/skbuff.h:3243 skb_network_header_len include/linux/skbuff.h:3243 [inline] WARNING: CPU: 0 PID: 14949 at net/sched/act_skbmod.c:55 tcf_skbmod_act+0xfe8/0x1810 net/sched/act_skbmod.c:55 There are a few issues in tcf_skbmod_act(): 1. Calling skb_network_header_len() assumes skb->transport_header is set, which is not guaranteed when tcf_skbmod_act() runs at TC ingress. 2. Unconditionally calling skb_mac_header_len() at the beginning of tcf_skbmod_act() triggers a warning on L3 devices (e.g. TUN) where the MAC header is unset, evaluating to an underflowed garbage length. 3. On TC ingress, skb->data points to the network header. Adding the MAC header length to the IP header length causes skb_ensure_writable() to request more bytes than the actual IP packet length, dropping valid short packets (e.g. 28-byte UDP/IPv4 packets). Fix these by: - Using skb_network_offset(skb) + sizeof(struct iphdr/ipv6hdr) for SKBMOD_F_ECN so that the required length is correctly calculated on both ingress (offset == 0) and egress (offset == mac_len). - Setting max_edit_len to ETH_HLEN for Ethernet header modifications after validating ARPHRD_ETHER. Fixes: 56af5e749f20 ("net/sched: act_skbmod: Add SKBMOD_F_ECN option support") Reported-by: syzbot+1d56f14f95c0480cfdc9@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6a8b39c0.dbb3a75c.13dd47.0051.GAE@google.com/T/#u Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260823182241.1958695-1-edumazet@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daystls: device: fix out-of-bounds write in tls_append_frag()Jiayuan Chen
Found with syzkaller and a local syzbot instance running on top of a netdevsim TLS offload emulation; tls_device.c is otherwise only reachable on a machine with a NIC that implements the offload. tls_push_data() only checks whether the open record still has room for another frag at the bottom of its loop, and the MSG_MORE early break skips that check. The record survives to the next syscall with the frag count it already had, and tls_append_frag() does not check either, so with TLS_TX_ZEROCOPY_RO every splice(SPLICE_F_MORE) of a byte or two adds a non-coalescing pipe page and num_frags walks off the end of tls_record_info.frags[MAX_SKB_FRAGS]. Once the record is pushed, tls_push_record() runs the same index over sg_tx_data[MAX_SKB_FRAGS] and the sg_set_page() writes land on the destruct_work that follows it, which the workqueue then calls. The byte limit is fine because copy drops to 0 and the loop falls through to the same check; the frag count has no such feedback. Push the record rather than keep a full one open, which is what a plain TCP socket does - tcp_sendmsg_locked() uses tcp_mark_push() and new_segment in both the copy and the MSG_SPLICE_PAGES paths, and tls_sw already sets full_record when the sk_msg ring fills up, MSG_MORE or not. BUG: KASAN: slab-out-of-bounds in tls_append_frag ( net/tls/tls_device.c:269) Write of size 8 at addr ffff8881104d1530 by task tls_oob/450 CPU: 2 UID: 0 PID: 450 Comm: tls_oob Not tainted 7.2.0-rc7+ #329 PREEMPT Call Trace: <TASK> dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120) print_report (mm/kasan/report.c:378 mm/kasan/report.c:482) kasan_report (mm/kasan/report.c:595) tls_append_frag (net/tls/tls_device.c:269) tls_push_data (net/tls/tls_device.c:518) tls_device_sendmsg (net/tls/tls_device.c:583) inet_sendmsg (net/ipv4/af_inet.c:865) sock_sendmsg (net/socket.c:775 net/socket.c:790 net/socket.c:813) splice_to_socket (fs/splice.c:884) do_splice (fs/splice.c:936 fs/splice.c:1349) __do_splice (fs/splice.c:1431) __x64_sys_splice (fs/splice.c:1634 fs/splice.c:1616) do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121) </TASK> and, once the record is pushed: UBSAN: array-index-out-of-bounds in net/tls/tls_device.c:300:24 index 18 is out of range for type 'skb_frag_t [17]' UBSAN: array-index-out-of-bounds in net/tls/tls_device.c:301:41 index 18 is out of range for type 'scatterlist [17]' UBSAN: array-index-out-of-bounds in net/tls/tls_device.c:302:39 index 18 is out of range for type 'scatterlist [17]' UBSAN: array-index-out-of-bounds in net/tls/tls_device.c:307:38 index 26 is out of range for type 'scatterlist [17]' kernel tried to execute NX-protected page - exploit attempt? (uid: 0) BUG: unable to handle page fault for address: ffffea000411a680 #PF: supervisor instruction fetch in kernel mode #PF: error_code(0x0011) - permissions violation Oops: Oops: 0011 [#1] SMP KASAN PTI Workqueue: ktls_device_destruct 0xffffea000411a680 RIP: 0010:0xffffea000411a680 Call Trace: <TASK> worker_thread (kernel/workqueue.c:3405 kernel/workqueue.c:3486) 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: e8f69799810c ("net/tls: Add generic NIC offload infrastructure") Cc: stable@vger.kernel.org Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev> Link: https://patch.msgid.link/20260823084758.20936-1-jiayuan.chen@linux.dev Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet: skbuff: don't touch shared zerocopy state in skb_tx_error()Norbert Szetei
skb_tx_error() completes the zerocopy uarg and clears SKBFL_ALL_ZEROCOPY, and skb_zcopy_downgrade_managed() clears SKBFL_MANAGED_FRAG_REFS. Both live in skb_shinfo(), which every clone shares, while the caller only owns the reference it is about to drop. Through a clone it tells the producer its pages are free and drops SKBFL_SHARED_FRAG for an skb that is still in flight. Open vSwitch reaches this with a non-last OVS_ACTION_ATTR_RECIRC: clone_execute() sends a skb_clone() into ovs_dp_process_packet() while do_execute_actions() keeps forwarding the original, and skb_clone() does not privatise the frags here -- skb_orphan_frags() returns early on SKBFL_DONT_ORPHAN. A flow miss on the clone then strips the marker from the packet still being forwarded, and a later local ESP delivery decrypts in place over frags it does not own privately. Skip it for a cloned skb. Nothing is lost: skb_release_data() clears the zerocopy state once the last reference to the shared data goes. Fixes: 25121173f7b1 ("skb: api to report errors for zero copy skbs") Cc: stable@vger.kernel.org Suggested-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Norbert Szetei <norbert@doyensec.com> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Tested-by: Jongmin Jang <payload.jang@gmail.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/CFAB292A-674B-4C14-BB2C-BB8830AD5659@doyensec.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet: skbuff: don't skb_tx_error() the source skb in skb_zerocopy()Norbert Szetei
skb_zerocopy() copies frags from @from into @to. On an skb_orphan_frags() failure it calls skb_tx_error(@from), a destructive operation on the source skb the copy helper does not own. That completes @from's zerocopy uarg and clears SKBFL_ALL_ZEROCOPY, including the SKBFL_SHARED_FRAG page-ownership marker. Both callers already report the failure on their own drop path. nfnetlink_queue does it at nla_put_failure, and Open vSwitch does it in the flow-miss drop arm of ovs_dp_process_packet(), so nothing is lost by dropping it here. On Open vSwitch's OVS_ACTION_ATTR_USERSPACE path the skb is not freed on this error: do_execute_actions() ignores output_userspace()'s return value and, unless the upcall was the last action, keeps forwarding the same skb through the flow's remaining actions. The uarg is completed while that skb is still in flight, telling the producer its buffers are free, and SKBFL_SHARED_FRAG is cleared on an skb the rest of the stack still handles. That flag is what makes esp_input() call skb_cow_data() instead of decrypting in place, so a later local ESP delivery can decrypt over frags the skb does not own privately. Leave error reporting to the callers. Fixes: 36d5fe6a0007 ("core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors") Cc: stable@vger.kernel.org Suggested-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Norbert Szetei <norbert@doyensec.com> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/6E3A780D-FB87-421F-9964-B1D457D7D106@doyensec.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysopenvswitch: only skb_tx_error() a packet we are about to dropNorbert Szetei
queue_userspace_packet() borrows the packet skb -- it only copies it into a private netlink message (user_skb) and does not own it; on return do_execute_actions() keeps forwarding it through the flow's remaining actions. Its error path nevertheless calls skb_tx_error(skb), which via skb_zcopy_clear() does skb_shinfo(skb)->flags &= ~SKBFL_ALL_ZEROCOPY, stripping SKBFL_SHARED_FRAG from that live skb (skb_tx_error()'s kerneldoc says "skb must be freed afterwards"). For a MSG_ZEROCOPY skb carrying page-cache frags, SKBFL_SHARED_FRAG is what makes esp_input() skb_cow_data() before in-place AEAD; once it is stripped a later local ESP-in-UDP delivery decrypts in place over pages the sender does not own -- an unprivileged page-cache write (the "Fragnesia" primitive). do_execute_actions() ignores output_userspace()'s return value, so any action after a failed USERSPACE upcall inherits the stripped skb. Move the skb_tx_error() to the flow-miss drop path - the "default" branch of ovs_dp_process_packet()'s switch(error), before kfree_skb(). The call has been here since commit 36d5fe6a0007 ("core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors") but was harmless until esp_input() began relying on SKBFL_SHARED_FRAG to gate in-place decrypt; only then did stripping it on a still-forwarded skb become a page-cache write primitive. Fixes: 36d5fe6a0007 ("core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors") Fixes: f4c50a4034e6 ("xfrm: esp: avoid in-place decrypt on shared skb frags") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-5 Signed-off-by: Norbert Szetei <norbert@doyensec.com> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Tested-by: Jongmin Jang <payload.jang@gmail.com> Link: https://patch.msgid.link/55A52703-7548-4A55-A9CE-2A37145BDCAD@doyensec.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysMerge tag 'for-net-2026-08-24' of ↵Jakub Kicinski
git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: Core: - hci_core: use skb_get() instead of skb_clone() for req_skb - hci_conn: re-enable advertising only for peripheral role - hci_event: clear HCI_LE_ADV only on a created connection - hci_sync: Clear HCI_CMD_PENDING when dropping the last request - hci_sync: add conditional locking annotations - hci_sync: do not leak an hci_conn when a second LE connect is rejected - eir: Fix OOB read in eir_get_service_data() - mgmt: fix 'hdev->discovery.uuids' NULL dereference - L2CAP: access chan->conn safely in get/setsockopt - L2CAP: reject accept queue add unless BT_LISTEN - L2CAP: fix race l2cap_sock_cleanup_listen() vs. put_chan - RFCOMM: serialize security confirmation handling - RFCOMM: serialize session teardown - RFCOMM: Validate MTU in rfcomm_apply_pn() to prevent infinite loop - ISO: fix use-after-free of listener socket in iso_conn_ready Drivers: - btnxpuart: Validate the FW dump header length - btnxpuart: Check remote M.2 connector availability before pwrseq - btmtksdio: Take exclusive ownership of the SKB before TX - btmtksdio: Fix out-of-bounds DMA read in the TX path - hci_uart: Fix false success return in hci_uart_setup() - hci_bcm: fix usage_count leak when autosuspend_delay is negative - hci_h5: fix usage_count leak when autosuspend_delay is negative - hci_intel: fix usage_count leak when autosuspend_delay is negative - btmtk: Do not report success when subsys reset fails - btmtk: Do not discard the subsystem reset timeout - btusb: limit RTL8761B BROKEN_EXT_SCAN quirk to 0bda:a728 - hci_bcm4377: Ignore reserved PHY in ext adv reports on BCM4378 * tag 'for-net-2026-08-24' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: (27 commits) Bluetooth: RFCOMM: serialize session teardown Bluetooth: do not leak an hci_conn when a second LE connect is rejected Bluetooth: RFCOMM: serialize security confirmation handling Bluetooth: btusb: limit RTL8761B BROKEN_EXT_SCAN quirk to 0bda:a728 Bluetooth: hci_uart: Fix false success return in hci_uart_setup() Bluetooth: RFCOMM: Validate MTU in rfcomm_apply_pn() to prevent infinite loop Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready Bluetooth: hci_core: use skb_get() instead of skb_clone() for req_skb Bluetooth: hci_event: clear HCI_LE_ADV only on a created connection Bluetooth: hci_conn: re-enable advertising only for peripheral role Bluetooth: hci_bcm4377: Ignore reserved PHY in ext adv reports on BCM4378 Bluetooth: eir: Fix OOB read in eir_get_service_data() Bluetooth: btnxpuart: Validate the FW dump header length Bluetooth: hci_sync: add conditional locking annotations Bluetooth: btnxpuart: Check remote M.2 connector availability before pwrseq Bluetooth: btmtksdio: Fix out-of-bounds DMA read in the TX path Bluetooth: btmtksdio: Take exclusive ownership of the SKB before TX Bluetooth: btmtk: Do not discard the subsystem reset timeout Bluetooth: btmtk: Do not report success when subsys reset fails Bluetooth: L2CAP: fix race l2cap_sock_cleanup_listen() vs. put_chan ... ==================== Link: https://patch.msgid.link/20260824180639.3570348-1-luiz.dentz@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
5 daysnet/iucv: filter frames in afiucv_hs_rcv() by ingress deviceAlexandra Winter
afiucv_hs_rcv() selects a socket from iucv_sk_list by matching four 8-byte name fields in the transport header alone. No check is made against the net_device the frame arrived on. This can cause a frame arriving on any netdev to be delivered to an AF_IUCV socket. Three problems follow. First, a frame arriving over HiperSockets can be delivered to a socket bound to the classic z/VM IUCV transport, which has iucv->hs_dev == NULL. iucv_sock_bind() takes the classic path whenever the requested userid matches iucv_userid, even on a guest that also has a HiperSockets device carrying the same identifier. The child socket created by afiucv_hs_callback_syn() for such a match inherits hs_dev = NULL and transport = AF_IUCV_TRANS_HIPER, so the first send() on it returns -ENODEV. The socket delivered to accept() is unusable. Second, a frame arriving on one netdev can be delivered to a socket bound to a different IQD device. Which can lead to - Accept-queue exhaustion (DoS) - Attacker-controlled peer identity in the child socket - Data injection into existing sockets - Fabric noise on the IQD fabric, where bogus replies are sent - killing established connections Third, all AF_IUCV sockets live in init_net, as iucv_sock_alloc() calls sk_alloc(&init_net, ...). But even frames arriving on netdev devices in a namespace can be delivered to an IUCV socket. So a process in an unprivileged user and network namespace holding only the CAP_NET_RAW capability valid within that namespace can send a raw ETH_P_AF_IUCV frame on its own lo device and have it matched against init_net sockets. Fix all three by skipping any socket whose hs_dev does not match the ingress device. A classic z/VM IUCV socket has hs_dev == NULL; the ingress dev is never NULL, so classic sockets are skipped automatically. An unbound HIPER socket also has hs_dev == NULL and is skipped. A bound HIPER socket is only reachable from the exact IQD device it was bound to. Because hs_dev is always a device in init_net (iucv_sock_bind() scans for_each_netdev_rcu(&init_net, ...) exclusively), a frame whose ingress device belongs to another namespace never matches any socket. Note that AF_IUCV over HiperSockets provides no per-connection authentication: no sequence numbers, no TLS, no nonce. The four name fields identifying a connection are exchanged in plaintext on the shared HiperSockets segment (VCHID). Any host on the same HiperSockets segment could spoof any frame type against an existing connection. That is a protocol-level property unchanged by this patch. The fix reduces the attack surface to peers present on the same HiperSockets segment. Fixes: 3881ac441f64 ("af_iucv: add HiperSockets transport") Cc: stable@vger.kernel.org Co-developed-by: Bryam Vargas <hexlabsecurity@proton.me> Signed-off-by: Alexandra Winter <wintera@linux.ibm.com> Link: https://patch.msgid.link/20260821125501.3718748-1-wintera@linux.ibm.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>