--- /dev/null
+From d7db62891616fca8cbf86b39553cec4fce195f99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 16:46:13 +0000
+Subject: ip6_vti: fix incorrect tunnel matching in vti6_tnl_lookup()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit a5c0359f5cbc51a2e2b114d6041e0f3c73f903e9 ]
+
+In vti6_tnl_lookup(), when an exact match for a tunnel fails,
+the code falls back to searching for wildcard tunnels:
+
+- Tunnels matching the packet's local address, with any remote address
+ wildcard remote).
+
+- Tunnels matching the packet's remote address, with any local address
+ (wildcard local).
+
+However, vti6 stores all these different types of tunnels in the same
+hash table (ip6n->tnls_r_l) prone to hash collisions.
+
+The bug is that the fallback search loops in vti6_tnl_lookup() were
+missing checks to ensure that the candidate tunnel actually has
+a wildcard address.
+
+Fixes: fbe68ee87522 ("vti6: Add a lookup method for tunnels with wildcard endpoints.")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260608164613.933023-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_vti.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
+index 241e5191f43c15..e471a5821b0de5 100644
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -105,6 +105,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(&any, local);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(local, &t->parms.laddr) &&
++ ipv6_addr_any(&t->parms.raddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+@@ -112,6 +113,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(remote, &any);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(remote, &t->parms.raddr) &&
++ ipv6_addr_any(&t->parms.laddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+--
+2.53.0
+
--- /dev/null
+From 4779f49fbd08993627b7a084cb433d199a07abb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 00:34:48 -0700
+Subject: ipv6: sit: reload inner IPv6 header after GSO offloads
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f0e42f0c4337b1f220de1ddd63f47197c7dee4de ]
+
+ipip6_tunnel_xmit() caches the inner IPv6 header pointer at function
+entry and continues using it after iptunnel_handle_offloads().
+
+For GSO skbs, iptunnel_handle_offloads() calls skb_header_unclone().
+When the skb header is cloned, skb_header_unclone() can call
+pskb_expand_head(), which may move the skb head. The pskb_expand_head()
+contract requires pointers into the skb header to be reloaded after the
+call.
+
+If the later skb_realloc_headroom() branch is not taken, SIT uses the
+stale iph6 pointer to read the inner hop limit and DS field. That can
+read from a freed skb head after the old head's remaining clone is
+released.
+
+Reload iph6 after the offload helper succeeds and before subsequent
+reads from the inner IPv6 header. Keep the existing reload after
+skb_realloc_headroom(), since that branch can also replace the skb.
+
+Fixes: 14909664e4e1 ("sit: Setup and TX path for sit/UDP foo-over-udp encapsulation")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot+6eb9ca986d80f6f88cf9@syzkaller.appspotmail.com
+Link: https://patch.msgid.link/20260605073448.6524-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/sit.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index 9806bd56b95f12..387b48ba4aac71 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -964,6 +964,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ ip_rt_put(rt);
+ goto tx_error;
+ }
++ iph6 = ipv6_hdr(skb);
+
+ if (df) {
+ mtu = dst_mtu(&rt->dst) - t_hlen;
+--
+2.53.0
+
--- /dev/null
+From ec9b38617987261e634b36d1141217443774a149 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 19:18:19 -0700
+Subject: net: guard timestamp cmsgs to real error queue skbs
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit 1ee90b77b727df903033db873c75caac5c27ec98 ]
+
+skb_is_err_queue() treats PACKET_OUTGOING as the sole marker for an skb
+from sk_error_queue. That assumption is not true for AF_PACKET sockets:
+outgoing packet taps are also delivered to packet sockets with
+skb->pkt_type == PACKET_OUTGOING, but their skb->cb is owned by AF_PACKET
+instead of struct sock_exterr_skb.
+
+If such an skb is received with timestamping enabled, the generic
+timestamp cmsg path can read AF_PACKET control-buffer state as
+sock_exterr_skb::opt_stats. With SO_RXQ_OVFL enabled, the packet drop
+counter overlaps opt_stats. An odd drop count makes the path emit
+SCM_TIMESTAMPING_OPT_STATS with skb->len and skb->data. For non-linear
+skbs this copies past the linear head and can trigger hardened usercopy or
+disclose adjacent heap contents.
+
+Keep skb_is_err_queue() local to net/socket.c, but make it verify that
+the PACKET_OUTGOING marker is paired with the sock_rmem_free destructor
+installed by sock_queue_err_skb(). AF_PACKET receive skbs use normal
+receive ownership and no longer pass as error-queue skbs, while legitimate
+sk_error_queue entries keep the PACKET_OUTGOING marker and sock_rmem_free
+ownership.
+
+Fixes: 8605330aac5a ("tcp: fix SCM_TIMESTAMPING_OPT_STATS for normal skbs")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260607021819.49698-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 1 +
+ net/core/skbuff.c | 6 +++---
+ net/socket.c | 11 ++++++-----
+ 3 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 4e5386cdb09cd5..f0e391afb511d2 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1779,6 +1779,7 @@ struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size,
+ gfp_t priority);
+ void skb_orphan_partial(struct sk_buff *skb);
+ void sock_rfree(struct sk_buff *skb);
++void sock_rmem_free(struct sk_buff *skb);
+ void sock_efree(struct sk_buff *skb);
+ #ifdef CONFIG_INET
+ void sock_edemux(struct sk_buff *skb);
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index f7100f5af37ca7..b2cd853ecb7e7b 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -4633,7 +4633,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
+ }
+ EXPORT_SYMBOL_GPL(skb_cow_data);
+
+-static void sock_rmem_free(struct sk_buff *skb)
++void sock_rmem_free(struct sk_buff *skb)
+ {
+ struct sock *sk = skb->sk;
+
+@@ -4642,8 +4642,8 @@ static void sock_rmem_free(struct sk_buff *skb)
+
+ static void skb_set_err_queue(struct sk_buff *skb)
+ {
+- /* pkt_type of skbs received on local sockets is never PACKET_OUTGOING.
+- * So, it is safe to (mis)use it to mark skbs on the error queue.
++ /* The error-queue test in skb_is_err_queue() matches this marker
++ * with the sock_rmem_free destructor installed by sock_queue_err_skb().
+ */
+ skb->pkt_type = PACKET_OUTGOING;
+ BUILD_BUG_ON(PACKET_OUTGOING == 0);
+diff --git a/net/socket.c b/net/socket.c
+index 2a48aa89c035b6..d105beeb15e118 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -740,12 +740,13 @@ EXPORT_SYMBOL(kernel_sendmsg_locked);
+
+ static bool skb_is_err_queue(const struct sk_buff *skb)
+ {
+- /* pkt_type of skbs enqueued on the error queue are set to
+- * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
+- * in recvmsg, since skbs received on a local socket will never
+- * have a pkt_type of PACKET_OUTGOING.
++ /* Error-queue skbs are marked as PACKET_OUTGOING in
++ * skb_set_err_queue() and use the destructor installed by
++ * sock_queue_err_skb(). PACKET_OUTGOING alone is not unique:
++ * AF_PACKET outgoing taps use the same pkt_type.
+ */
+- return skb->pkt_type == PACKET_OUTGOING;
++ return skb->pkt_type == PACKET_OUTGOING &&
++ skb->destructor == sock_rmem_free;
+ }
+
+ /* On transmit, software and hardware timestamps are returned independently.
+--
+2.53.0
+
--- /dev/null
+From 50826ba8a003340e7f6cd5f3a45f0f76c7f37645 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:40 +0200
+Subject: net: mvpp2: sync RX data at the hardware packet offset
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 180235600934bef6add3be637c296d6cf3272e67 ]
+
+mvpp2 programs the RX queue packet offset, so hardware writes received
+data at dma_addr + MVPP2_SKB_HEADROOM. The current CPU sync starts at
+dma_addr and only covers rx_bytes + MVPP2_MH_SIZE bytes, which syncs the
+unused headroom and misses the same number of bytes at the packet tail.
+
+On non-coherent DMA systems this can leave the CPU reading stale cache
+contents for the end of the received frame.
+
+Use dma_sync_single_range_for_cpu() with MVPP2_SKB_HEADROOM as the range
+offset so the sync covers the Marvell header and packet data actually
+written by hardware.
+
+Fixes: e1921168bbd4 ("mvpp2: sync only the received frame")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-2-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index e4e80c2b1ce400..6d672afc73d500 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3588,9 +3588,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ dma_dir = DMA_FROM_DEVICE;
+ }
+
+- dma_sync_single_for_cpu(dev->dev.parent, dma_addr,
+- rx_bytes + MVPP2_MH_SIZE,
+- dma_dir);
++ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
++ MVPP2_SKB_HEADROOM,
++ rx_bytes + MVPP2_MH_SIZE,
++ dma_dir);
+
+ /* Buffer header not supported */
+ if (rx_status & MVPP2_RXD_BUF_HDR)
+--
+2.53.0
+
--- /dev/null
+From 85949cef1cfe4c6d979a696417e34af79dbdd9ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:19:46 +0200
+Subject: net: openvswitch: fix possible kfree_skb of ERR_PTR
+
+From: Adrian Moreno <amorenoz@redhat.com>
+
+[ Upstream commit ee30dd2909d8b98619f4341c70ec8dc8e155ab02 ]
+
+After the patch in the "Fixes" tag, the allocation of the "reply" skb
+can happen either before or after locking the ovs_mutex.
+
+However, error cleanups still follow the classical reversed order,
+assuming "reply" is allocated before locking: it is freed after unlocking.
+
+If "reply" allocation happens after locking the mutex and it fails,
+"reply" is left with an ERR_PTR, and execution jumps to the correspondent
+cleanup stage which will try to free an invalid pointer.
+
+Fix this by setting the pointer to NULL after having saved its error
+value.
+
+Fixes: 893f139b9a6c ("openvswitch: Minimize ovs_flow_cmd_new|set critical sections.")
+Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Acked-by: Eelco Chaudron <echaudro@redhat.com>
+Link: https://patch.msgid.link/20260604121946.942164-1-amorenoz@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/datapath.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 1c69aa986633af..5fb74fbcb2f382 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -1248,6 +1248,7 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
+
+ if (IS_ERR(reply)) {
+ error = PTR_ERR(reply);
++ reply = NULL;
+ goto err_unlock_ovs;
+ }
+ }
+--
+2.53.0
+
--- /dev/null
+From 7c5728490616aa7ba54fbca3e7c6aaa1723e37d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:48:01 +0800
+Subject: net: qrtr: fix refcount saturation and potential UAF in
+ qrtr_port_remove
+
+From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+
+[ Upstream commit a2171131ecda1ed61a594a1eb715e75fdad0fef5 ]
+
+In qrtr_port_remove(), the socket reference count is decremented via
+__sock_put() before the port is removed from the qrtr_ports XArray and
+before the RCU grace period elapses.
+
+This breaks the fundamental RCU update paradigm. It exposes a race
+window where a concurrent RCU reader (such as qrtr_reset_ports() or
+qrtr_port_lookup()) can obtain a pointer to the socket from the XArray,
+and attempt to call sock_hold() on a socket whose reference count has
+already dropped to zero.
+
+This exact race condition was hit during syzkaller fuzzing, leading to
+the following refcount saturation warning and a potential Use-After-Free:
+
+ refcount_t: saturated; leaking memory.
+ WARNING: CPU: 3 PID: 1273 at lib/refcount.c:22 refcount_warn_saturate+0xae/0x1d0
+ Modules linked in: qrtr(+) bochs drm_shmem_helper ...
+ Call Trace:
+ <TASK>
+ qrtr_reset_ports net/qrtr/af_qrtr.c:768 [inline] [qrtr]
+ __qrtr_bind.isra.0+0x48b/0x570 net/qrtr/af_qrtr.c:805 [qrtr]
+ qrtr_bind+0x17d/0x210 net/qrtr/af_qrtr.c:901 [qrtr]
+ kernel_bind+0xe4/0x120 net/socket.c:3592
+ qrtr_ns_init+0x1a6/0x380 net/qrtr/ns.c:715 [qrtr]
+ qrtr_proto_init+0x3b/0xff0 net/qrtr/af_qrtr.c:169 [qrtr]
+ do_one_initcall+0xf5/0x5e0 init/main.c:1283
+ ...
+ </TASK>
+
+Fix this by deferring the reference count decrement until after the
+xa_erase() and the synchronize_rcu() complete.
+
+(Note: The v1 of this patch incorrectly replaced __sock_put() with
+sock_put(). As Simon Horman pointed out, the callers of qrtr_port_remove()
+still hold a reference to the socket, so freeing the socket memory here
+would lead to a subsequent UAF in the caller. Thus, the __sock_put() is
+kept, but only repositioned to close the RCU race.)
+
+Fixes: bdabad3e363d ("net: Add Qualcomm IPC router")
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260604064801.1180388-1-w15303746062@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/af_qrtr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c
+index fdb7a5a12f0358..fb0398903e4f36 100644
+--- a/net/qrtr/af_qrtr.c
++++ b/net/qrtr/af_qrtr.c
+@@ -701,13 +701,13 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
+ if (port == QRTR_PORT_CTRL)
+ port = 0;
+
+- __sock_put(&ipc->sk);
+-
+ xa_erase(&qrtr_ports, port);
+
+ /* Ensure that if qrtr_port_lookup() did enter the RCU read section we
+ * wait for it to up increment the refcount */
+ synchronize_rcu();
++
++ __sock_put(&ipc->sk);
+ }
+
+ /* Assign port number to socket.
+--
+2.53.0
+
--- /dev/null
+From 68ed42e17436571b7eaa176efb626ae184e75db4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 12:24:48 -0700
+Subject: net/rds: fix NULL deref in rds_ib_send_cqe_handler() on masked atomic
+ completion
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 34080db3e70ddf94c38512ad2331e3c3afca6cc1 ]
+
+rds_ib_xmit_atomic() always programs a masked atomic opcode
+(IB_WR_MASKED_ATOMIC_CMP_AND_SWP or IB_WR_MASKED_ATOMIC_FETCH_AND_ADD)
+for every RDS atomic cmsg. But the completion-side switch in
+rds_ib_send_unmap_op() only handles the non-masked opcodes, so a masked
+atomic completion falls through to default and returns rm == NULL while
+send->s_op is left set. rds_ib_send_cqe_handler() then dereferences the
+NULL rm via rm->m_final_op, oopsing in softirq context. An unprivileged
+AF_RDS sendmsg() of an atomic cmsg over an active RDS/IB connection
+triggers it; on hardware that natively accepts masked atomics (mlx4,
+mlx5) no extra setup is needed.
+
+ RDS/IB: rds_ib_send_unmap_op: unexpected opcode 0xd in WR!
+ Oops: general protection fault [#1] SMP KASAN
+ KASAN: null-ptr-deref in range [0x0000000000000190-0x0000000000000197]
+ RIP: rds_ib_send_cqe_handler+0x25c/0xb10 (net/rds/ib_send.c:282)
+ Call Trace:
+ <IRQ>
+ rds_ib_send_cqe_handler (net/rds/ib_send.c:282)
+ poll_scq (net/rds/ib_cm.c:274)
+ rds_ib_tasklet_fn_send (net/rds/ib_cm.c:294)
+ tasklet_action_common (kernel/softirq.c:943)
+ handle_softirqs (kernel/softirq.c:573)
+ run_ksoftirqd (kernel/softirq.c:479)
+ </IRQ>
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Handle the masked atomic opcodes in the same case as the non-masked
+ones: they map to the same struct rds_message.atomic union member, so
+the existing container_of()/rds_ib_send_unmap_atomic() body is correct
+for them.
+
+Fixes: 20c72bd5f5f9 ("RDS: Implement masked atomic operations")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260606192447.1179255-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/ib_send.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
+index 92b4a8689aae7a..6c20526f71a1e2 100644
+--- a/net/rds/ib_send.c
++++ b/net/rds/ib_send.c
+@@ -170,6 +170,8 @@ static struct rds_message *rds_ib_send_unmap_op(struct rds_ib_connection *ic,
+ break;
+ case IB_WR_ATOMIC_FETCH_AND_ADD:
+ case IB_WR_ATOMIC_CMP_AND_SWP:
++ case IB_WR_MASKED_ATOMIC_FETCH_AND_ADD:
++ case IB_WR_MASKED_ATOMIC_CMP_AND_SWP:
+ if (send->s_op) {
+ rm = container_of(send->s_op, struct rds_message, atomic);
+ rds_ib_send_unmap_atomic(ic, send->s_op, wc_status);
+--
+2.53.0
+
--- /dev/null
+From efe34074cd484539e65fd5ca60b1073778a0ee96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 21:28:09 +0200
+Subject: netfilter: nft_exthdr: fix register tracking for F_PRESENT flag
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 772cecf198da732faebb5dcfc46d66a505be8495 ]
+
+nft_exthdr_init() passes user-controlled priv->len to
+nft_parse_register_store(), which marks that many bytes in the
+register bitmap as initialized. However, when NFT_EXTHDR_F_PRESENT
+is set, the eval paths write only 1 byte (nft_reg_store8) or
+4 bytes (*dest = 0 on TCP/DCCP error path). When len > 4,
+registers beyond the first are never written, retaining
+uninitialized stack data from nft_regs.
+
+Bail out if userspace requests too much data when F_PRESENT is set.
+
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Fixes: c078ca3b0c5b ("netfilter: nft_exthdr: Add support for existence check")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_exthdr.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
+index 5bde436b875485..be8ff8b5355721 100644
+--- a/net/netfilter/nft_exthdr.c
++++ b/net/netfilter/nft_exthdr.c
+@@ -454,6 +454,9 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
+ return err;
+ }
+
++ if ((flags & NFT_EXTHDR_F_PRESENT) && len != 1)
++ return -EINVAL;
++
+ priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
+ priv->offset = offset;
+ priv->len = len;
+--
+2.53.0
+
--- /dev/null
+From 3145492aabee802c365769d1761df28c6947915b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 01:10:31 -0700
+Subject: netfilter: x_tables: avoid leaking percpu counter pointers
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f7f2fbb0e893a0238dc464f8d8c0f5609bec584f ]
+
+The native and compat get-entries paths copy the fixed rule entry header
+from the kernelized rule blob to userspace before overwriting the entry's
+counter fields with a sanitized counter snapshot.
+
+On SMP kernels, entry->counters.pcnt contains the percpu allocation
+address used by x_tables rule counters. A caller can provide a userspace
+buffer that faults during the initial fixed-header copy after pcnt has
+been copied but before the later sanitized counter copy runs. The syscall
+then returns -EFAULT while leaving the raw percpu pointer in userspace.
+
+Copy only the fixed entry prefix before counters from the kernelized rule
+blob, then copy the sanitized counter snapshot into the counter field.
+Apply this ordering to the IPv4, IPv6, and ARP native and compat
+get-entries implementations so a fault cannot expose the internal percpu
+counter pointer.
+
+Fixes: 71ae0dff02d7 ("netfilter: xtables: use percpu rule counters")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/netfilter/arp_tables.c | 15 ++++++---------
+ net/ipv4/netfilter/ip_tables.c | 15 ++++++---------
+ net/ipv6/netfilter/ip6_tables.c | 15 ++++++---------
+ 3 files changed, 18 insertions(+), 27 deletions(-)
+
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+index d5f3b6260da0cf..bc8a5b6eccc336 100644
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -701,14 +701,12 @@ static int copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct arpt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct arpt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1326,9 +1324,8 @@ static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct arpt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_arpt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_arpt_entry);
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
+index 22e9ff592cd75f..55798e12fb3745 100644
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -833,14 +833,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ipt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ipt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1229,9 +1227,8 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ipt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ipt_entry);
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+index df7cd3d285e4f0..da136d25701a9e 100644
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -850,14 +850,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ip6t_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ip6t_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1246,9 +1244,8 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ip6t_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ip6t_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ip6t_entry);
+--
+2.53.0
+
--- /dev/null
+From 7b3200b343e5c199b0290fe018158edc4d414ce6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 09:13:53 +0800
+Subject: netlabel: validate unlabeled address and mask attribute lengths
+
+From: Chenguang Zhao <zhaochenguang@kylinos.cn>
+
+[ Upstream commit 9772589b57e44aedc240211c5c3f7a684a034d3a ]
+
+netlbl_unlabel_addrinfo_get() used the address attribute length to
+determine whether the attribute data could be read as an IPv4 or IPv6
+address, but did not independently validate the corresponding mask
+attribute length. A crafted Generic Netlink request could therefore
+provide a valid IPv4/IPv6 address attribute with a shorter mask
+attribute, which would later be read as a full struct in_addr or
+struct in6_addr.
+
+NLA_BINARY policy lengths are maximum lengths by default, so use
+NLA_POLICY_EXACT_LEN() for the unlabeled IPv4/IPv6 address and mask
+attributes. This rejects short attributes during policy validation and
+also exposes the exact length requirements through policy introspection.
+
+Fixes: 8cc44579d1bd ("NetLabel: Introduce static network labels for unlabeled connections")
+Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlabel/netlabel_unlabeled.c | 30 ++++++++++--------------------
+ 1 file changed, 10 insertions(+), 20 deletions(-)
+
+diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
+index 3049fff0b7f864..7bfccedbffe5aa 100644
+--- a/net/netlabel/netlabel_unlabeled.c
++++ b/net/netlabel/netlabel_unlabeled.c
+@@ -114,14 +114,14 @@ static struct genl_family netlbl_unlabel_gnl_family;
+ /* NetLabel Netlink attribute policy */
+ static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
+ [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
+- [NLBL_UNLABEL_A_IPV6ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV6MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV4ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
+- [NLBL_UNLABEL_A_IPV4MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
++ [NLBL_UNLABEL_A_IPV6ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV6MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV4ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
++ [NLBL_UNLABEL_A_IPV4MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
+ [NLBL_UNLABEL_A_IFACE] = { .type = NLA_NUL_STRING,
+ .len = IFNAMSIZ - 1 },
+ [NLBL_UNLABEL_A_SECCTX] = { .type = NLA_BINARY }
+@@ -766,24 +766,14 @@ static int netlbl_unlabel_addrinfo_get(struct genl_info *info,
+ void **mask,
+ u32 *len)
+ {
+- u32 addr_len;
+-
+ if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR] &&
+ info->attrs[NLBL_UNLABEL_A_IPV4MASK]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+- if (addr_len != sizeof(struct in_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV4MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4MASK]);
+ return 0;
+ } else if (info->attrs[NLBL_UNLABEL_A_IPV6ADDR]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+- if (addr_len != sizeof(struct in6_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV6MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in6_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6MASK]);
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From 292e4623e2cb91973d222968c0420b92d4bb6067 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 02:32:05 -0700
+Subject: rds: mark snapshot pages dirty in rds_info_getsockopt()
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 512db8267b73a220a64180d95ab5eebe7c4964a8 ]
+
+rds_info_getsockopt() pins the destination user pages with FOLL_WRITE and
+the RDS_INFO_* producers memcpy the snapshot into them through
+kmap_atomic(). Because that copy goes through the kernel direct map, the
+dirty bit on the user PTE is never set, so unpin_user_pages() releases the
+pages without marking them dirty. A file-backed destination page can then
+be reclaimed without writeback, silently discarding the copied data.
+
+Use unpin_user_pages_dirty_lock() with make_dirty=true so the modified
+pages are marked dirty before they are unpinned.
+
+Fixes: a8c879a7ee98 ("RDS: Info and stats")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260608-rds_fix-v1-1-006c88543408@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/info.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/rds/info.c b/net/rds/info.c
+index b6b46a8214a0a5..b3ee5f8238c44d 100644
+--- a/net/rds/info.c
++++ b/net/rds/info.c
+@@ -235,7 +235,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
+
+ out:
+ if (pages)
+- unpin_user_pages(pages, nr_pages);
++ unpin_user_pages_dirty_lock(pages, nr_pages, true);
+ kfree(pages);
+
+ return ret;
+--
+2.53.0
+
--- /dev/null
+From 3339fec14802e88725413a070f5c500ce8915672 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 08:22:34 -0400
+Subject: sctp: fix uninit-value in __sctp_rcv_asconf_lookup()
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit f8373d7090b745728de66308deeecc67e8d319ce ]
+
+__sctp_rcv_asconf_lookup() in net/sctp/input.c only checks that the ASCONF
+chunk can hold the ADDIP header and a parameter header, then calls
+af->from_addr_param(), which reads the full address (16 bytes for IPv6)
+trusting the parameter's declared length.
+
+An unauthenticated peer can send a truncated trailing ASCONF chunk that
+declares an IPv6 address parameter but stops after the 4-byte parameter
+header; reached from the no-association lookup path, from_addr_param() then
+reads uninitialized bytes past the parameter.
+
+Impact: an unauthenticated SCTP peer makes the receive path read up to 16
+bytes of uninitialized memory past a truncated ASCONF address parameter.
+
+The sibling __sctp_rcv_init_lookup() bounds parameters with
+sctp_walk_params(); this path open-codes the fetch and omits the bound.
+Verify the whole address parameter lies within the chunk before
+from_addr_param() reads it, the same class of fix as commit 51e5ad549c43
+("net: sctp: fix KMSAN uninit-value in sctp_inq_pop").
+
+Fixes: df2185771439 ("[SCTP]: Update association lookup to look at ASCONF chunks as well")
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260608122234.459098-1-michael.bommarito@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/input.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/sctp/input.c b/net/sctp/input.c
+index 079b1bfc7d3106..3c7761199f200b 100644
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -1172,6 +1172,14 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
+ /* Skip over the ADDIP header and find the Address parameter */
+ param = (union sctp_addr_param *)(asconf + 1);
+
++ /* The whole address parameter must lie within the chunk before
++ * af->from_addr_param() reads the variable-length address; otherwise a
++ * truncated trailing ASCONF chunk lets it read uninitialized bytes past
++ * the parameter.
++ */
++ if (sizeof(*asconf) + ntohs(param->p.length) > ntohs(ch->length))
++ return NULL;
++
+ af = sctp_get_af_specific(param_type2af(param->p.type));
+ if (unlikely(!af))
+ return NULL;
+--
+2.53.0
+
kvm-arm64-remove-vpipt-i-cache-handling.patch
arm64-tlb-allow-xzr-argument-to-tlbi-ops.patch
arm64-tlb-optimize-arm64_workaround_repeat_tlbi.patch
+xfrm-policy-fix-use-after-free-on-inexact-bin-in-xfr.patch
+netlabel-validate-unlabeled-address-and-mask-attribu.patch
+net-qrtr-fix-refcount-saturation-and-potential-uaf-i.patch
+ipv6-sit-reload-inner-ipv6-header-after-gso-offloads.patch
+net-openvswitch-fix-possible-kfree_skb-of-err_ptr.patch
+sctp-fix-uninit-value-in-__sctp_rcv_asconf_lookup.patch
+net-guard-timestamp-cmsgs-to-real-error-queue-skbs.patch
+net-rds-fix-null-deref-in-rds_ib_send_cqe_handler-on.patch
+ip6_vti-fix-incorrect-tunnel-matching-in-vti6_tnl_lo.patch
+rds-mark-snapshot-pages-dirty-in-rds_info_getsockopt.patch
+netfilter-x_tables-avoid-leaking-percpu-counter-poin.patch
+netfilter-nft_exthdr-fix-register-tracking-for-f_pre.patch
+net-mvpp2-sync-rx-data-at-the-hardware-packet-offset.patch
--- /dev/null
+From 248f2e82958ac419b70e8412d131b08734b199a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 18:49:05 +0900
+Subject: xfrm: policy: fix use-after-free on inexact bin in
+ xfrm_policy_bysel_ctx()
+
+From: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+
+[ Upstream commit 7f2d76c9c03257c0782afef9d95321fa04096f60 ]
+
+Fix the race by pruning the bin while still holding xfrm_policy_lock,
+before dropping it. Use __xfrm_policy_inexact_prune_bin() directly since
+the lock is already held. The wrapper xfrm_policy_inexact_prune_bin()
+becomes unused and is removed.
+
+Race:
+
+ CPU0 (XFRM_MSG_DELPOLICY) CPU1 (XFRM_MSG_NEWSPDINFO)
+ ========================== ==========================
+ xfrm_policy_bysel_ctx():
+ spin_lock_bh(xfrm_policy_lock)
+ bin = xfrm_policy_inexact_lookup()
+ __xfrm_policy_unlink(pol)
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_kill(ret)
+ // wide window, lock not held
+ xfrm_hash_rebuild():
+ spin_lock_bh(xfrm_policy_lock)
+ __xfrm_policy_inexact_flush():
+ kfree_rcu(bin) // bin freed
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_inexact_prune_bin(bin)
+ // UAF: bin is freed
+
+Fixes: 6be3b0db6db8 ("xfrm: policy: add inexact policy search tree infrastructure")
+Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 5bcc5642ccf067..e17faf51f32553 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1124,15 +1124,6 @@ static void __xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b, bool
+ }
+ }
+
+-static void xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b)
+-{
+- struct net *net = read_pnet(&b->k.net);
+-
+- spin_lock_bh(&net->xfrm.xfrm_policy_lock);
+- __xfrm_policy_inexact_prune_bin(b, false);
+- spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+-}
+-
+ static void __xfrm_policy_inexact_flush(struct net *net)
+ {
+ struct xfrm_pol_inexact_bin *bin, *t;
+@@ -1720,12 +1711,12 @@ xfrm_policy_bysel_ctx(struct net *net, const struct xfrm_mark *mark, u32 if_id,
+ }
+ ret = pol;
+ }
++ if (bin && delete)
++ __xfrm_policy_inexact_prune_bin(bin, false);
+ spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+
+ if (ret && delete)
+ xfrm_policy_kill(ret);
+- if (bin && delete)
+- xfrm_policy_inexact_prune_bin(bin);
+ return ret;
+ }
+ EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
+--
+2.53.0
+
--- /dev/null
+From 0bced9baeb701c8ec86a4edc8867740dbcb6002c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 16:46:13 +0000
+Subject: ip6_vti: fix incorrect tunnel matching in vti6_tnl_lookup()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit a5c0359f5cbc51a2e2b114d6041e0f3c73f903e9 ]
+
+In vti6_tnl_lookup(), when an exact match for a tunnel fails,
+the code falls back to searching for wildcard tunnels:
+
+- Tunnels matching the packet's local address, with any remote address
+ wildcard remote).
+
+- Tunnels matching the packet's remote address, with any local address
+ (wildcard local).
+
+However, vti6 stores all these different types of tunnels in the same
+hash table (ip6n->tnls_r_l) prone to hash collisions.
+
+The bug is that the fallback search loops in vti6_tnl_lookup() were
+missing checks to ensure that the candidate tunnel actually has
+a wildcard address.
+
+Fixes: fbe68ee87522 ("vti6: Add a lookup method for tunnels with wildcard endpoints.")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260608164613.933023-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_vti.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
+index 4f5093b36b3e36..077aae4b1bb332 100644
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -105,6 +105,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(&any, local);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(local, &t->parms.laddr) &&
++ ipv6_addr_any(&t->parms.raddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+@@ -112,6 +113,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(remote, &any);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(remote, &t->parms.raddr) &&
++ ipv6_addr_any(&t->parms.laddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+--
+2.53.0
+
--- /dev/null
+From 1d42a4f815b49f74e2a7b06dd82f55430c056653 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 00:34:48 -0700
+Subject: ipv6: sit: reload inner IPv6 header after GSO offloads
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f0e42f0c4337b1f220de1ddd63f47197c7dee4de ]
+
+ipip6_tunnel_xmit() caches the inner IPv6 header pointer at function
+entry and continues using it after iptunnel_handle_offloads().
+
+For GSO skbs, iptunnel_handle_offloads() calls skb_header_unclone().
+When the skb header is cloned, skb_header_unclone() can call
+pskb_expand_head(), which may move the skb head. The pskb_expand_head()
+contract requires pointers into the skb header to be reloaded after the
+call.
+
+If the later skb_realloc_headroom() branch is not taken, SIT uses the
+stale iph6 pointer to read the inner hop limit and DS field. That can
+read from a freed skb head after the old head's remaining clone is
+released.
+
+Reload iph6 after the offload helper succeeds and before subsequent
+reads from the inner IPv6 header. Keep the existing reload after
+skb_realloc_headroom(), since that branch can also replace the skb.
+
+Fixes: 14909664e4e1 ("sit: Setup and TX path for sit/UDP foo-over-udp encapsulation")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot+6eb9ca986d80f6f88cf9@syzkaller.appspotmail.com
+Link: https://patch.msgid.link/20260605073448.6524-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/sit.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index 3bc02ab9ceaca0..bc5db4a9dbfaf1 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -971,6 +971,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ ip_rt_put(rt);
+ goto tx_error;
+ }
++ iph6 = ipv6_hdr(skb);
+
+ if (df) {
+ mtu = dst_mtu(&rt->dst) - t_hlen;
+--
+2.53.0
+
--- /dev/null
+From 267c75b24337ced877d6fb15332581886a806600 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 19:18:19 -0700
+Subject: net: guard timestamp cmsgs to real error queue skbs
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit 1ee90b77b727df903033db873c75caac5c27ec98 ]
+
+skb_is_err_queue() treats PACKET_OUTGOING as the sole marker for an skb
+from sk_error_queue. That assumption is not true for AF_PACKET sockets:
+outgoing packet taps are also delivered to packet sockets with
+skb->pkt_type == PACKET_OUTGOING, but their skb->cb is owned by AF_PACKET
+instead of struct sock_exterr_skb.
+
+If such an skb is received with timestamping enabled, the generic
+timestamp cmsg path can read AF_PACKET control-buffer state as
+sock_exterr_skb::opt_stats. With SO_RXQ_OVFL enabled, the packet drop
+counter overlaps opt_stats. An odd drop count makes the path emit
+SCM_TIMESTAMPING_OPT_STATS with skb->len and skb->data. For non-linear
+skbs this copies past the linear head and can trigger hardened usercopy or
+disclose adjacent heap contents.
+
+Keep skb_is_err_queue() local to net/socket.c, but make it verify that
+the PACKET_OUTGOING marker is paired with the sock_rmem_free destructor
+installed by sock_queue_err_skb(). AF_PACKET receive skbs use normal
+receive ownership and no longer pass as error-queue skbs, while legitimate
+sk_error_queue entries keep the PACKET_OUTGOING marker and sock_rmem_free
+ownership.
+
+Fixes: 8605330aac5a ("tcp: fix SCM_TIMESTAMPING_OPT_STATS for normal skbs")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260607021819.49698-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 1 +
+ net/core/skbuff.c | 6 +++---
+ net/socket.c | 11 ++++++-----
+ 3 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index ee9c398dd8f25e..962acf4a644da9 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1868,6 +1868,7 @@ struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size,
+ gfp_t priority);
+ void skb_orphan_partial(struct sk_buff *skb);
+ void sock_rfree(struct sk_buff *skb);
++void sock_rmem_free(struct sk_buff *skb);
+ void sock_efree(struct sk_buff *skb);
+ #ifdef CONFIG_INET
+ void sock_edemux(struct sk_buff *skb);
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index a8d09eff26f11c..1d3784480834bb 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -4814,7 +4814,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
+ }
+ EXPORT_SYMBOL_GPL(skb_cow_data);
+
+-static void sock_rmem_free(struct sk_buff *skb)
++void sock_rmem_free(struct sk_buff *skb)
+ {
+ struct sock *sk = skb->sk;
+
+@@ -4823,8 +4823,8 @@ static void sock_rmem_free(struct sk_buff *skb)
+
+ static void skb_set_err_queue(struct sk_buff *skb)
+ {
+- /* pkt_type of skbs received on local sockets is never PACKET_OUTGOING.
+- * So, it is safe to (mis)use it to mark skbs on the error queue.
++ /* The error-queue test in skb_is_err_queue() matches this marker
++ * with the sock_rmem_free destructor installed by sock_queue_err_skb().
+ */
+ skb->pkt_type = PACKET_OUTGOING;
+ BUILD_BUG_ON(PACKET_OUTGOING == 0);
+diff --git a/net/socket.c b/net/socket.c
+index f3d0a8d66cceee..cc7ba4702d1380 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -795,12 +795,13 @@ EXPORT_SYMBOL(kernel_sendmsg_locked);
+
+ static bool skb_is_err_queue(const struct sk_buff *skb)
+ {
+- /* pkt_type of skbs enqueued on the error queue are set to
+- * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
+- * in recvmsg, since skbs received on a local socket will never
+- * have a pkt_type of PACKET_OUTGOING.
++ /* Error-queue skbs are marked as PACKET_OUTGOING in
++ * skb_set_err_queue() and use the destructor installed by
++ * sock_queue_err_skb(). PACKET_OUTGOING alone is not unique:
++ * AF_PACKET outgoing taps use the same pkt_type.
+ */
+- return skb->pkt_type == PACKET_OUTGOING;
++ return skb->pkt_type == PACKET_OUTGOING &&
++ skb->destructor == sock_rmem_free;
+ }
+
+ /* On transmit, software and hardware timestamps are returned independently.
+--
+2.53.0
+
--- /dev/null
+From 71a7cd84bd6f6d79af00c3a4520663106210b96f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 12:46:06 +0100
+Subject: net: mvpp2: Add metadata support for xdp mode
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 9a45e193c88a55a536d7fd0ebfa29823d588c2cf ]
+
+Set metadata size building the skb from xdp_buff in mvpp2 driver
+mvpp2 driver sets xdp headroom to:
+
+MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM
+
+where
+
+MVPP2_MH_SIZE 2
+MVPP2_SKB_HEADROOM min(max(XDP_PACKET_HEADROOM, NET_SKB_PAD), 224)
+
+so the headroom is large enough to contain xdp_frame and xdp metadata.
+Please note this patch is just compiled tested.
+
+Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20250318-mvneta-xdp-meta-v2-2-b6075778f61f@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 77a6b90ce56b ("net: mvpp2: build skb from XDP-adjusted data on XDP_PASS")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index d8a2268b88187a..d55c3f1526c38b 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3912,13 +3912,13 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ while (rx_done < rx_todo) {
+ struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq);
++ u32 rx_status, timestamp, metasize = 0;
+ struct mvpp2_bm_pool *bm_pool;
+ struct page_pool *pp = NULL;
+ struct sk_buff *skb;
+ unsigned int frag_size;
+ dma_addr_t dma_addr;
+ phys_addr_t phys_addr;
+- u32 rx_status, timestamp;
+ int pool, rx_bytes, err, ret;
+ struct page *page;
+ void *data;
+@@ -3981,7 +3981,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ xdp_init_buff(&xdp, bm_pool->frag_size, xdp_rxq);
+ xdp_prepare_buff(&xdp, data,
+ MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM,
+- rx_bytes, false);
++ rx_bytes, true);
+
+ ret = mvpp2_run_xdp(port, xdp_prog, &xdp, pp, &ps);
+
+@@ -3997,6 +3997,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ ps.rx_bytes += rx_bytes;
+ continue;
+ }
++
++ metasize = xdp.data - xdp.data_meta;
+ }
+
+ skb = build_skb(data, frag_size);
+@@ -4033,6 +4035,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);
+ skb_put(skb, rx_bytes);
++ if (metasize)
++ skb_metadata_set(skb, metasize);
+ skb->ip_summed = mvpp2_rx_csum(port, rx_status);
+ skb->protocol = eth_type_trans(skb, dev);
+
+--
+2.53.0
+
--- /dev/null
+From 61455619f170d82a8029b062f11cd1d5e3e4e088 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:43 +0200
+Subject: net: mvpp2: build skb from XDP-adjusted data on XDP_PASS
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 77a6b90ce56bc982dcfa94229b8e28e6abb16e95 ]
+
+When an XDP program uses bpf_xdp_adjust_head() or bpf_xdp_adjust_tail()
+and then returns XDP_PASS, mvpp2 still builds the skb from fixed offsets
+derived from the original RX descriptor. Packet geometry changes made by
+the XDP program are therefore discarded before the skb reaches the stack.
+
+Update rx_offset and rx_bytes from xdp.data and xdp.data_end for
+XDP_PASS. This makes skb_reserve() and skb_put() reflect the packet seen
+by XDP, and makes RX byte accounting for XDP_PASS follow the length of the
+skb passed to the network stack.
+
+Keep a separate rx_sync_size for page-pool recycling on skb allocation
+failure, which must stay tied to the received buffer range.
+
+Non-PASS verdicts continue to account the descriptor length because no skb
+is passed up in those cases.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-5-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 21 +++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 04002548a46327..c4951eb88241b0 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3916,10 +3916,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ struct mvpp2_bm_pool *bm_pool;
+ struct page_pool *pp = NULL;
+ struct sk_buff *skb;
+- unsigned int frag_size;
++ unsigned int frag_size, rx_sync_size;
+ dma_addr_t dma_addr;
+ phys_addr_t phys_addr;
+- int pool, rx_bytes, err, ret;
++ int pool, rx_bytes, rx_offset, err, ret;
+ struct page *page;
+ void *data;
+
+@@ -3932,6 +3932,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ rx_status = mvpp2_rxdesc_status_get(port, rx_desc);
+ rx_bytes = mvpp2_rxdesc_size_get(port, rx_desc);
+ rx_bytes -= MVPP2_MH_SIZE;
++ rx_sync_size = rx_bytes + MVPP2_MH_SIZE;
++ rx_offset = MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM;
+ dma_addr = mvpp2_rxdesc_dma_addr_get(port, rx_desc);
+
+ pool = (rx_status & MVPP2_RXD_BM_POOL_ID_MASK) >>
+@@ -3947,7 +3949,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
+ MVPP2_SKB_HEADROOM,
+- rx_bytes + MVPP2_MH_SIZE,
++ rx_sync_size,
+ dma_dir);
+
+ /* Buffer header not supported */
+@@ -3998,6 +4000,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ continue;
+ }
+
++ rx_sync_size = max_t(unsigned int, rx_sync_size,
++ xdp.data_end - xdp.data_hard_start -
++ MVPP2_SKB_HEADROOM);
++
++ /* Update offset and length to reflect any XDP adjustments. */
++ rx_offset = xdp.data - data;
++ rx_bytes = xdp.data_end - xdp.data;
++
+ metasize = xdp.data - xdp.data_meta;
+ }
+
+@@ -4006,8 +4016,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ netdev_warn(port->dev, "skb build failed\n");
+ if (pp) {
+ page_pool_put_page(pp, virt_to_head_page(data),
+- rx_bytes + MVPP2_MH_SIZE,
+- true);
++ rx_sync_size, true);
+ } else {
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size,
+@@ -4037,7 +4046,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
+
+- skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);
++ skb_reserve(skb, rx_offset);
+ skb_put(skb, rx_bytes);
+ if (metasize)
+ skb_metadata_set(skb, metasize);
+--
+2.53.0
+
--- /dev/null
+From a7374a3523c2b59d67825e86ffb4d4bbfbd87c6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:41 +0200
+Subject: net: mvpp2: limit XDP frame size to the RX buffer
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit f3c6aa078927e6fe8121c9c591ddee8716c5305a ]
+
+mvpp2 has short and long BM pools, and short pool buffers can be smaller
+than PAGE_SIZE. The XDP path nevertheless initializes every xdp_buff with
+PAGE_SIZE as frame size.
+
+XDP helpers use frame_sz to validate tail growth and to derive the hard
+end of the data area. Advertising PAGE_SIZE for short buffers can let
+bpf_xdp_adjust_tail() grow a packet past the real allocation, corrupting
+memory or later tripping skb tailroom checks.
+
+Initialize the XDP buffer with bm_pool->frag_size so XDP tailroom matches
+the actual buffer backing the packet.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-3-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index ad6325c80f9868..d8a2268b88187a 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3978,7 +3978,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ else
+ xdp_rxq = &rxq->xdp_rxq_long;
+
+- xdp_init_buff(&xdp, PAGE_SIZE, xdp_rxq);
++ xdp_init_buff(&xdp, bm_pool->frag_size, xdp_rxq);
+ xdp_prepare_buff(&xdp, data,
+ MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM,
+ rx_bytes, false);
+--
+2.53.0
+
--- /dev/null
+From 140d90ef1f63f7f3f490323e8f4f44459212fe5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:42 +0200
+Subject: net: mvpp2: refill RX buffers before XDP or skb use
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 5e8e2a9624df72fca7c736b2966b2cbf6c9c3ff6 ]
+
+The RX error path returns the current descriptor buffer to the hardware
+BM pool. That is only valid while the driver still owns the buffer.
+
+mvpp2_rx_refill() can fail after the current buffer has been handed to
+XDP or attached to an skb. In those cases mvpp2_run_xdp() may have
+recycled, redirected, or queued the page for XDP_TX, and an skb free also
+retires the data buffer. Returning such a buffer to BM lets hardware DMA
+into memory that is no longer owned by the RX ring.
+
+Refill the BM pool before handing the current buffer to XDP or to the
+skb. If the allocation fails there, drop the packet and return the
+still-owned current buffer to BM, preserving the pool depth. Once the
+refill succeeds, later local drops retire/free the current buffer instead
+of returning it to BM.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Fixes: d6526926de73 ("net: mvpp2: fix memory leak in mvpp2_rx")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-4-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 77a6b90ce56b ("net: mvpp2: build skb from XDP-adjusted data on XDP_PASS")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 43 +++++++++++--------
+ 1 file changed, 24 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index d55c3f1526c38b..04002548a46327 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3970,6 +3970,12 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ else
+ frag_size = bm_pool->frag_size;
+
++ err = mvpp2_rx_refill(port, bm_pool, pp, pool);
++ if (err) {
++ netdev_err(port->dev, "failed to refill BM pools\n");
++ goto err_drop_frame;
++ }
++
+ if (xdp_prog) {
+ struct xdp_rxq_info *xdp_rxq;
+
+@@ -3987,12 +3993,6 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ if (ret) {
+ xdp_ret |= ret;
+- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+- if (err) {
+- netdev_err(port->dev, "failed to refill BM pools\n");
+- goto err_drop_frame;
+- }
+-
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
+ continue;
+@@ -4004,8 +4004,21 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ skb = build_skb(data, frag_size);
+ if (!skb) {
+ netdev_warn(port->dev, "skb build failed\n");
+- goto err_drop_frame;
++ if (pp) {
++ page_pool_put_page(pp, virt_to_head_page(data),
++ rx_bytes + MVPP2_MH_SIZE,
++ true);
++ } else {
++ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
++ bm_pool->buf_size,
++ DMA_FROM_DEVICE,
++ DMA_ATTR_SKIP_CPU_SYNC);
++ mvpp2_frag_free(bm_pool, pp, data);
++ }
++ goto err_drop_frame_retired;
+ }
++ if (pp)
++ skb_mark_for_recycle(skb);
+
+ /* If we have RX hardware timestamping enabled, grab the
+ * timestamp from the queue and convert.
+@@ -4016,16 +4029,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ skb_hwtstamps(skb));
+ }
+
+- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+- if (err) {
+- netdev_err(port->dev, "failed to refill BM pools\n");
+- dev_kfree_skb_any(skb);
+- goto err_drop_frame;
+- }
+-
+- if (pp)
+- skb_mark_for_recycle(skb);
+- else
++ if (!pp)
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size, DMA_FROM_DEVICE,
+ DMA_ATTR_SKIP_CPU_SYNC);
+@@ -4044,13 +4048,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ continue;
+
+ err_drop_frame:
+- dev->stats.rx_errors++;
+- mvpp2_rx_error(port, rx_desc);
+ /* Return the buffer to the pool */
+ if (rx_status & MVPP2_RXD_BUF_HDR)
+ mvpp2_buff_hdr_pool_put(port, rx_desc, pool, rx_status);
+ else
+ mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);
++err_drop_frame_retired:
++ dev->stats.rx_errors++;
++ mvpp2_rx_error(port, rx_desc);
+ }
+
+ if (xdp_ret & MVPP2_XDP_REDIR)
+--
+2.53.0
+
--- /dev/null
+From 66e38a95cf22fb4e71c45cf03217a4766ef5d58f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:40 +0200
+Subject: net: mvpp2: sync RX data at the hardware packet offset
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 180235600934bef6add3be637c296d6cf3272e67 ]
+
+mvpp2 programs the RX queue packet offset, so hardware writes received
+data at dma_addr + MVPP2_SKB_HEADROOM. The current CPU sync starts at
+dma_addr and only covers rx_bytes + MVPP2_MH_SIZE bytes, which syncs the
+unused headroom and misses the same number of bytes at the packet tail.
+
+On non-coherent DMA systems this can leave the CPU reading stale cache
+contents for the end of the received frame.
+
+Use dma_sync_single_range_for_cpu() with MVPP2_SKB_HEADROOM as the range
+offset so the sync covers the Marvell header and packet data actually
+written by hardware.
+
+Fixes: e1921168bbd4 ("mvpp2: sync only the received frame")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-2-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index fdfdd55fdb1dcf..ad6325c80f9868 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3945,9 +3945,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ dma_dir = DMA_FROM_DEVICE;
+ }
+
+- dma_sync_single_for_cpu(dev->dev.parent, dma_addr,
+- rx_bytes + MVPP2_MH_SIZE,
+- dma_dir);
++ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
++ MVPP2_SKB_HEADROOM,
++ rx_bytes + MVPP2_MH_SIZE,
++ dma_dir);
+
+ /* Buffer header not supported */
+ if (rx_status & MVPP2_RXD_BUF_HDR)
+--
+2.53.0
+
--- /dev/null
+From a4faecb8eb6c80d91a81fce3b764b9ab08b12b16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:19:46 +0200
+Subject: net: openvswitch: fix possible kfree_skb of ERR_PTR
+
+From: Adrian Moreno <amorenoz@redhat.com>
+
+[ Upstream commit ee30dd2909d8b98619f4341c70ec8dc8e155ab02 ]
+
+After the patch in the "Fixes" tag, the allocation of the "reply" skb
+can happen either before or after locking the ovs_mutex.
+
+However, error cleanups still follow the classical reversed order,
+assuming "reply" is allocated before locking: it is freed after unlocking.
+
+If "reply" allocation happens after locking the mutex and it fails,
+"reply" is left with an ERR_PTR, and execution jumps to the correspondent
+cleanup stage which will try to free an invalid pointer.
+
+Fix this by setting the pointer to NULL after having saved its error
+value.
+
+Fixes: 893f139b9a6c ("openvswitch: Minimize ovs_flow_cmd_new|set critical sections.")
+Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Acked-by: Eelco Chaudron <echaudro@redhat.com>
+Link: https://patch.msgid.link/20260604121946.942164-1-amorenoz@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/datapath.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 16ee704bab04db..0202111cda3531 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -1261,6 +1261,7 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
+
+ if (IS_ERR(reply)) {
+ error = PTR_ERR(reply);
++ reply = NULL;
+ goto err_unlock_ovs;
+ }
+ }
+--
+2.53.0
+
--- /dev/null
+From 8f4d2989cbae29554c25cabdb0f015f8ef48f0c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:48:01 +0800
+Subject: net: qrtr: fix refcount saturation and potential UAF in
+ qrtr_port_remove
+
+From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+
+[ Upstream commit a2171131ecda1ed61a594a1eb715e75fdad0fef5 ]
+
+In qrtr_port_remove(), the socket reference count is decremented via
+__sock_put() before the port is removed from the qrtr_ports XArray and
+before the RCU grace period elapses.
+
+This breaks the fundamental RCU update paradigm. It exposes a race
+window where a concurrent RCU reader (such as qrtr_reset_ports() or
+qrtr_port_lookup()) can obtain a pointer to the socket from the XArray,
+and attempt to call sock_hold() on a socket whose reference count has
+already dropped to zero.
+
+This exact race condition was hit during syzkaller fuzzing, leading to
+the following refcount saturation warning and a potential Use-After-Free:
+
+ refcount_t: saturated; leaking memory.
+ WARNING: CPU: 3 PID: 1273 at lib/refcount.c:22 refcount_warn_saturate+0xae/0x1d0
+ Modules linked in: qrtr(+) bochs drm_shmem_helper ...
+ Call Trace:
+ <TASK>
+ qrtr_reset_ports net/qrtr/af_qrtr.c:768 [inline] [qrtr]
+ __qrtr_bind.isra.0+0x48b/0x570 net/qrtr/af_qrtr.c:805 [qrtr]
+ qrtr_bind+0x17d/0x210 net/qrtr/af_qrtr.c:901 [qrtr]
+ kernel_bind+0xe4/0x120 net/socket.c:3592
+ qrtr_ns_init+0x1a6/0x380 net/qrtr/ns.c:715 [qrtr]
+ qrtr_proto_init+0x3b/0xff0 net/qrtr/af_qrtr.c:169 [qrtr]
+ do_one_initcall+0xf5/0x5e0 init/main.c:1283
+ ...
+ </TASK>
+
+Fix this by deferring the reference count decrement until after the
+xa_erase() and the synchronize_rcu() complete.
+
+(Note: The v1 of this patch incorrectly replaced __sock_put() with
+sock_put(). As Simon Horman pointed out, the callers of qrtr_port_remove()
+still hold a reference to the socket, so freeing the socket memory here
+would lead to a subsequent UAF in the caller. Thus, the __sock_put() is
+kept, but only repositioned to close the RCU race.)
+
+Fixes: bdabad3e363d ("net: Add Qualcomm IPC router")
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260604064801.1180388-1-w15303746062@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/af_qrtr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c
+index 431fd1f2b80c18..6f4b901afc330c 100644
+--- a/net/qrtr/af_qrtr.c
++++ b/net/qrtr/af_qrtr.c
+@@ -702,13 +702,13 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
+ if (port == QRTR_PORT_CTRL)
+ port = 0;
+
+- __sock_put(&ipc->sk);
+-
+ xa_erase(&qrtr_ports, port);
+
+ /* Ensure that if qrtr_port_lookup() did enter the RCU read section we
+ * wait for it to up increment the refcount */
+ synchronize_rcu();
++
++ __sock_put(&ipc->sk);
+ }
+
+ /* Assign port number to socket.
+--
+2.53.0
+
--- /dev/null
+From ecbf267876e4dd48e30965ed4014312b4c8a4d53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 12:24:48 -0700
+Subject: net/rds: fix NULL deref in rds_ib_send_cqe_handler() on masked atomic
+ completion
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 34080db3e70ddf94c38512ad2331e3c3afca6cc1 ]
+
+rds_ib_xmit_atomic() always programs a masked atomic opcode
+(IB_WR_MASKED_ATOMIC_CMP_AND_SWP or IB_WR_MASKED_ATOMIC_FETCH_AND_ADD)
+for every RDS atomic cmsg. But the completion-side switch in
+rds_ib_send_unmap_op() only handles the non-masked opcodes, so a masked
+atomic completion falls through to default and returns rm == NULL while
+send->s_op is left set. rds_ib_send_cqe_handler() then dereferences the
+NULL rm via rm->m_final_op, oopsing in softirq context. An unprivileged
+AF_RDS sendmsg() of an atomic cmsg over an active RDS/IB connection
+triggers it; on hardware that natively accepts masked atomics (mlx4,
+mlx5) no extra setup is needed.
+
+ RDS/IB: rds_ib_send_unmap_op: unexpected opcode 0xd in WR!
+ Oops: general protection fault [#1] SMP KASAN
+ KASAN: null-ptr-deref in range [0x0000000000000190-0x0000000000000197]
+ RIP: rds_ib_send_cqe_handler+0x25c/0xb10 (net/rds/ib_send.c:282)
+ Call Trace:
+ <IRQ>
+ rds_ib_send_cqe_handler (net/rds/ib_send.c:282)
+ poll_scq (net/rds/ib_cm.c:274)
+ rds_ib_tasklet_fn_send (net/rds/ib_cm.c:294)
+ tasklet_action_common (kernel/softirq.c:943)
+ handle_softirqs (kernel/softirq.c:573)
+ run_ksoftirqd (kernel/softirq.c:479)
+ </IRQ>
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Handle the masked atomic opcodes in the same case as the non-masked
+ones: they map to the same struct rds_message.atomic union member, so
+the existing container_of()/rds_ib_send_unmap_atomic() body is correct
+for them.
+
+Fixes: 20c72bd5f5f9 ("RDS: Implement masked atomic operations")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260606192447.1179255-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/ib_send.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
+index 4190b90ff3b18a..1909cd440a4b66 100644
+--- a/net/rds/ib_send.c
++++ b/net/rds/ib_send.c
+@@ -170,6 +170,8 @@ static struct rds_message *rds_ib_send_unmap_op(struct rds_ib_connection *ic,
+ break;
+ case IB_WR_ATOMIC_FETCH_AND_ADD:
+ case IB_WR_ATOMIC_CMP_AND_SWP:
++ case IB_WR_MASKED_ATOMIC_FETCH_AND_ADD:
++ case IB_WR_MASKED_ATOMIC_CMP_AND_SWP:
+ if (send->s_op) {
+ rm = container_of(send->s_op, struct rds_message, atomic);
+ rds_ib_send_unmap_atomic(ic, send->s_op, wc_status);
+--
+2.53.0
+
--- /dev/null
+From b885b3d9b504d2d8f2b649cbb5499054775267d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 15:55:02 -0700
+Subject: netfilter: nf_log: validate MAC header was set before dumping it
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit a84b6fedbc97078788be78dbdd7517d143ad1a77 ]
+
+The fallback path of dump_mac_header() guards the MAC header access
+only with "skb->mac_header != skb->network_header", without checking
+skb_mac_header_was_set(). When the MAC header is unset, mac_header is
+0xffff, so the test passes and skb_mac_header(skb) returns
+skb->head + 0xffff, ~64 KiB past the buffer; the loop then reads
+dev->hard_header_len bytes out of bounds into the kernel log.
+
+This is reachable via the netdev logger: nf_log_unknown_packet() calls
+dump_mac_header() unconditionally, and an skb sent through AF_PACKET
+with PACKET_QDISC_BYPASS reaches the egress hook with mac_header still
+unset (__dev_queue_xmit(), which would reset it, is bypassed).
+
+Add the skb_mac_header_was_set() check the ARPHRD_ETHER path already
+uses, and replace the open-coded MAC header length test with
+skb_mac_header_len(). Only skbs with an unset MAC header are affected;
+valid ones are dumped as before.
+
+ BUG: KASAN: slab-out-of-bounds in dump_mac_header (net/netfilter/nf_log_syslog.c:831)
+ Read of size 1 at addr ffff88800ea49d3f by task exploit/148
+ Call Trace:
+ kasan_report (mm/kasan/report.c:595)
+ dump_mac_header (net/netfilter/nf_log_syslog.c:831)
+ nf_log_netdev_packet (net/netfilter/nf_log_syslog.c:938 net/netfilter/nf_log_syslog.c:963)
+ nf_log_packet (net/netfilter/nf_log.c:260)
+ nft_log_eval (net/netfilter/nft_log.c:60)
+ nft_do_chain (net/netfilter/nf_tables_core.c:285)
+ nft_do_chain_netdev (net/netfilter/nft_chain_filter.c:307)
+ nf_hook_slow (net/netfilter/core.c:619)
+ nf_hook_direct_egress (net/packet/af_packet.c:257)
+ packet_xmit (net/packet/af_packet.c:280)
+ packet_sendmsg (net/packet/af_packet.c:3114)
+ __sys_sendto (net/socket.c:2265)
+
+Fixes: 7eb9282cd0ef ("netfilter: ipt_LOG/ip6t_LOG: add option to print decoded MAC header")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_log_syslog.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
+index 7000e069bc0760..2b0edb22ba511b 100644
+--- a/net/netfilter/nf_log_syslog.c
++++ b/net/netfilter/nf_log_syslog.c
+@@ -793,8 +793,8 @@ static void dump_ipv4_mac_header(struct nf_log_buf *m,
+
+ fallback:
+ nf_log_buf_add(m, "MAC=");
+- if (dev->hard_header_len &&
+- skb->mac_header != skb->network_header) {
++ if (dev->hard_header_len && skb_mac_header_was_set(skb) &&
++ skb_mac_header_len(skb) != 0) {
+ const unsigned char *p = skb_mac_header(skb);
+ unsigned int i;
+
+--
+2.53.0
+
--- /dev/null
+From 5441fe681499189272b2aa331798743770a78963 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 21:28:09 +0200
+Subject: netfilter: nft_exthdr: fix register tracking for F_PRESENT flag
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 772cecf198da732faebb5dcfc46d66a505be8495 ]
+
+nft_exthdr_init() passes user-controlled priv->len to
+nft_parse_register_store(), which marks that many bytes in the
+register bitmap as initialized. However, when NFT_EXTHDR_F_PRESENT
+is set, the eval paths write only 1 byte (nft_reg_store8) or
+4 bytes (*dest = 0 on TCP/DCCP error path). When len > 4,
+registers beyond the first are never written, retaining
+uninitialized stack data from nft_regs.
+
+Bail out if userspace requests too much data when F_PRESENT is set.
+
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Fixes: c078ca3b0c5b ("netfilter: nft_exthdr: Add support for existence check")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_exthdr.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
+index 7c2931e024bb05..e8978a0aa7408f 100644
+--- a/net/netfilter/nft_exthdr.c
++++ b/net/netfilter/nft_exthdr.c
+@@ -454,6 +454,9 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
+ return err;
+ }
+
++ if ((flags & NFT_EXTHDR_F_PRESENT) && len != 1)
++ return -EINVAL;
++
+ priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
+ priv->offset = offset;
+ priv->len = len;
+--
+2.53.0
+
--- /dev/null
+From d476e361edf80b4abe1bd3c335b2f148db253f47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 01:10:31 -0700
+Subject: netfilter: x_tables: avoid leaking percpu counter pointers
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f7f2fbb0e893a0238dc464f8d8c0f5609bec584f ]
+
+The native and compat get-entries paths copy the fixed rule entry header
+from the kernelized rule blob to userspace before overwriting the entry's
+counter fields with a sanitized counter snapshot.
+
+On SMP kernels, entry->counters.pcnt contains the percpu allocation
+address used by x_tables rule counters. A caller can provide a userspace
+buffer that faults during the initial fixed-header copy after pcnt has
+been copied but before the later sanitized counter copy runs. The syscall
+then returns -EFAULT while leaving the raw percpu pointer in userspace.
+
+Copy only the fixed entry prefix before counters from the kernelized rule
+blob, then copy the sanitized counter snapshot into the counter field.
+Apply this ordering to the IPv4, IPv6, and ARP native and compat
+get-entries implementations so a fault cannot expose the internal percpu
+counter pointer.
+
+Fixes: 71ae0dff02d7 ("netfilter: xtables: use percpu rule counters")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/netfilter/arp_tables.c | 15 ++++++---------
+ net/ipv4/netfilter/ip_tables.c | 15 ++++++---------
+ net/ipv6/netfilter/ip6_tables.c | 15 ++++++---------
+ 3 files changed, 18 insertions(+), 27 deletions(-)
+
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+index 92bc90ee767484..2c39529769f19a 100644
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -701,14 +701,12 @@ static int copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct arpt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct arpt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1326,9 +1324,8 @@ static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct arpt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_arpt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_arpt_entry);
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
+index aee7cd584c9262..15a9e303a15317 100644
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -833,14 +833,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ipt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ipt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1229,9 +1227,8 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ipt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ipt_entry);
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+index afd22ea9f555ba..f2de34f0de239c 100644
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -850,14 +850,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ip6t_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ip6t_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1246,9 +1244,8 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ip6t_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ip6t_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ip6t_entry);
+--
+2.53.0
+
--- /dev/null
+From e54bf64f9c25d4ea7cbd93c65a4e5dc922425d29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 09:13:53 +0800
+Subject: netlabel: validate unlabeled address and mask attribute lengths
+
+From: Chenguang Zhao <zhaochenguang@kylinos.cn>
+
+[ Upstream commit 9772589b57e44aedc240211c5c3f7a684a034d3a ]
+
+netlbl_unlabel_addrinfo_get() used the address attribute length to
+determine whether the attribute data could be read as an IPv4 or IPv6
+address, but did not independently validate the corresponding mask
+attribute length. A crafted Generic Netlink request could therefore
+provide a valid IPv4/IPv6 address attribute with a shorter mask
+attribute, which would later be read as a full struct in_addr or
+struct in6_addr.
+
+NLA_BINARY policy lengths are maximum lengths by default, so use
+NLA_POLICY_EXACT_LEN() for the unlabeled IPv4/IPv6 address and mask
+attributes. This rejects short attributes during policy validation and
+also exposes the exact length requirements through policy introspection.
+
+Fixes: 8cc44579d1bd ("NetLabel: Introduce static network labels for unlabeled connections")
+Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlabel/netlabel_unlabeled.c | 30 ++++++++++--------------------
+ 1 file changed, 10 insertions(+), 20 deletions(-)
+
+diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
+index 566ba4397ee400..4c4b91ce446dfa 100644
+--- a/net/netlabel/netlabel_unlabeled.c
++++ b/net/netlabel/netlabel_unlabeled.c
+@@ -114,14 +114,14 @@ static struct genl_family netlbl_unlabel_gnl_family;
+ /* NetLabel Netlink attribute policy */
+ static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
+ [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
+- [NLBL_UNLABEL_A_IPV6ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV6MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV4ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
+- [NLBL_UNLABEL_A_IPV4MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
++ [NLBL_UNLABEL_A_IPV6ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV6MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV4ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
++ [NLBL_UNLABEL_A_IPV4MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
+ [NLBL_UNLABEL_A_IFACE] = { .type = NLA_NUL_STRING,
+ .len = IFNAMSIZ - 1 },
+ [NLBL_UNLABEL_A_SECCTX] = { .type = NLA_BINARY }
+@@ -764,24 +764,14 @@ static int netlbl_unlabel_addrinfo_get(struct genl_info *info,
+ void **mask,
+ u32 *len)
+ {
+- u32 addr_len;
+-
+ if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR] &&
+ info->attrs[NLBL_UNLABEL_A_IPV4MASK]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+- if (addr_len != sizeof(struct in_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV4MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4MASK]);
+ return 0;
+ } else if (info->attrs[NLBL_UNLABEL_A_IPV6ADDR]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+- if (addr_len != sizeof(struct in6_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV6MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in6_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6MASK]);
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From 9fc065cb461f330c97e2d33c0f96a35de41dd190 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 02:32:05 -0700
+Subject: rds: mark snapshot pages dirty in rds_info_getsockopt()
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 512db8267b73a220a64180d95ab5eebe7c4964a8 ]
+
+rds_info_getsockopt() pins the destination user pages with FOLL_WRITE and
+the RDS_INFO_* producers memcpy the snapshot into them through
+kmap_atomic(). Because that copy goes through the kernel direct map, the
+dirty bit on the user PTE is never set, so unpin_user_pages() releases the
+pages without marking them dirty. A file-backed destination page can then
+be reclaimed without writeback, silently discarding the copied data.
+
+Use unpin_user_pages_dirty_lock() with make_dirty=true so the modified
+pages are marked dirty before they are unpinned.
+
+Fixes: a8c879a7ee98 ("RDS: Info and stats")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260608-rds_fix-v1-1-006c88543408@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/info.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/rds/info.c b/net/rds/info.c
+index b6b46a8214a0a5..b3ee5f8238c44d 100644
+--- a/net/rds/info.c
++++ b/net/rds/info.c
+@@ -235,7 +235,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
+
+ out:
+ if (pages)
+- unpin_user_pages(pages, nr_pages);
++ unpin_user_pages_dirty_lock(pages, nr_pages, true);
+ kfree(pages);
+
+ return ret;
+--
+2.53.0
+
--- /dev/null
+From a710c9f54c25cd74a2aa0a7b4e751a04679fbc6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 08:22:34 -0400
+Subject: sctp: fix uninit-value in __sctp_rcv_asconf_lookup()
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit f8373d7090b745728de66308deeecc67e8d319ce ]
+
+__sctp_rcv_asconf_lookup() in net/sctp/input.c only checks that the ASCONF
+chunk can hold the ADDIP header and a parameter header, then calls
+af->from_addr_param(), which reads the full address (16 bytes for IPv6)
+trusting the parameter's declared length.
+
+An unauthenticated peer can send a truncated trailing ASCONF chunk that
+declares an IPv6 address parameter but stops after the 4-byte parameter
+header; reached from the no-association lookup path, from_addr_param() then
+reads uninitialized bytes past the parameter.
+
+Impact: an unauthenticated SCTP peer makes the receive path read up to 16
+bytes of uninitialized memory past a truncated ASCONF address parameter.
+
+The sibling __sctp_rcv_init_lookup() bounds parameters with
+sctp_walk_params(); this path open-codes the fetch and omits the bound.
+Verify the whole address parameter lies within the chunk before
+from_addr_param() reads it, the same class of fix as commit 51e5ad549c43
+("net: sctp: fix KMSAN uninit-value in sctp_inq_pop").
+
+Fixes: df2185771439 ("[SCTP]: Update association lookup to look at ASCONF chunks as well")
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260608122234.459098-1-michael.bommarito@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/input.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/sctp/input.c b/net/sctp/input.c
+index 182898cb754a52..70530cbe57d0a7 100644
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -1197,6 +1197,14 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
+ /* Skip over the ADDIP header and find the Address parameter */
+ param = (union sctp_addr_param *)(asconf + 1);
+
++ /* The whole address parameter must lie within the chunk before
++ * af->from_addr_param() reads the variable-length address; otherwise a
++ * truncated trailing ASCONF chunk lets it read uninitialized bytes past
++ * the parameter.
++ */
++ if (sizeof(*asconf) + ntohs(param->p.length) > ntohs(ch->length))
++ return NULL;
++
+ af = sctp_get_af_specific(param_type2af(param->p.type));
+ if (unlikely(!af))
+ return NULL;
+--
+2.53.0
+
kvm-arm64-remove-vpipt-i-cache-handling.patch
arm64-tlb-allow-xzr-argument-to-tlbi-ops.patch
arm64-tlb-optimize-arm64_workaround_repeat_tlbi.patch
+xfrm-policy-fix-use-after-free-on-inexact-bin-in-xfr.patch
+netlabel-validate-unlabeled-address-and-mask-attribu.patch
+net-qrtr-fix-refcount-saturation-and-potential-uaf-i.patch
+ipv6-sit-reload-inner-ipv6-header-after-gso-offloads.patch
+net-openvswitch-fix-possible-kfree_skb-of-err_ptr.patch
+sctp-fix-uninit-value-in-__sctp_rcv_asconf_lookup.patch
+net-guard-timestamp-cmsgs-to-real-error-queue-skbs.patch
+net-rds-fix-null-deref-in-rds_ib_send_cqe_handler-on.patch
+ip6_vti-fix-incorrect-tunnel-matching-in-vti6_tnl_lo.patch
+rds-mark-snapshot-pages-dirty-in-rds_info_getsockopt.patch
+netfilter-x_tables-avoid-leaking-percpu-counter-poin.patch
+netfilter-nf_log-validate-mac-header-was-set-before-.patch
+netfilter-nft_exthdr-fix-register-tracking-for-f_pre.patch
+net-mvpp2-sync-rx-data-at-the-hardware-packet-offset.patch
+net-mvpp2-limit-xdp-frame-size-to-the-rx-buffer.patch
+net-mvpp2-add-metadata-support-for-xdp-mode.patch
+net-mvpp2-refill-rx-buffers-before-xdp-or-skb-use.patch
+net-mvpp2-build-skb-from-xdp-adjusted-data-on-xdp_pa.patch
--- /dev/null
+From 3db0021eb5bb898a520fc8d8c37cba8219be0d3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 18:49:05 +0900
+Subject: xfrm: policy: fix use-after-free on inexact bin in
+ xfrm_policy_bysel_ctx()
+
+From: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+
+[ Upstream commit 7f2d76c9c03257c0782afef9d95321fa04096f60 ]
+
+Fix the race by pruning the bin while still holding xfrm_policy_lock,
+before dropping it. Use __xfrm_policy_inexact_prune_bin() directly since
+the lock is already held. The wrapper xfrm_policy_inexact_prune_bin()
+becomes unused and is removed.
+
+Race:
+
+ CPU0 (XFRM_MSG_DELPOLICY) CPU1 (XFRM_MSG_NEWSPDINFO)
+ ========================== ==========================
+ xfrm_policy_bysel_ctx():
+ spin_lock_bh(xfrm_policy_lock)
+ bin = xfrm_policy_inexact_lookup()
+ __xfrm_policy_unlink(pol)
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_kill(ret)
+ // wide window, lock not held
+ xfrm_hash_rebuild():
+ spin_lock_bh(xfrm_policy_lock)
+ __xfrm_policy_inexact_flush():
+ kfree_rcu(bin) // bin freed
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_inexact_prune_bin(bin)
+ // UAF: bin is freed
+
+Fixes: 6be3b0db6db8 ("xfrm: policy: add inexact policy search tree infrastructure")
+Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 6c52ba6cbb5b7e..d8348730e2d0e6 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1124,15 +1124,6 @@ static void __xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b, bool
+ }
+ }
+
+-static void xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b)
+-{
+- struct net *net = read_pnet(&b->k.net);
+-
+- spin_lock_bh(&net->xfrm.xfrm_policy_lock);
+- __xfrm_policy_inexact_prune_bin(b, false);
+- spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+-}
+-
+ static void __xfrm_policy_inexact_flush(struct net *net)
+ {
+ struct xfrm_pol_inexact_bin *bin, *t;
+@@ -1720,12 +1711,12 @@ xfrm_policy_bysel_ctx(struct net *net, const struct xfrm_mark *mark, u32 if_id,
+ }
+ ret = pol;
+ }
++ if (bin && delete)
++ __xfrm_policy_inexact_prune_bin(bin, false);
+ spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+
+ if (ret && delete)
+ xfrm_policy_kill(ret);
+- if (bin && delete)
+- xfrm_policy_inexact_prune_bin(bin);
+ return ret;
+ }
+ EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
+--
+2.53.0
+
--- /dev/null
+From 9fd752a8bc740a0a4ac0f9010065ff0030c9061c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 11:12:44 +0100
+Subject: ASoC: wm_adsp: Fix NULL dereference when removing firmware controls
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 7d3fb78b550301e43fdc60312aed733069694426 ]
+
+In wm_adsp_control_remove() check that the priv pointer is not NULL
+before attempting to cleanup what it points to.
+
+When cs_dsp creates a control it calls wm_adsp_control_add_cb() so that
+wm_adsp can create its own private control data. There are two cases
+where private data is not created:
+
+1. The control is a SYSTEM control, so an ALSA control is not created.
+
+2. The codec driver has registered a control_add() callback that
+ hides the control, so wm_adsp_control_add() is not called.
+
+When cs_dsp_remove destroys its control list it calls
+wm_adsp_control_remove() for each control. But wm_adsp_control_remove()
+was attempting to cleanup the private data pointed to by cs_ctl->priv
+without checking the pointer for NULL.
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Fixes: 0700bc2fb94c ("ASoC: wm_adsp: Separate generic cs_dsp_coeff_ctl handling")
+Link: https://patch.msgid.link/20260604101244.1402862-1-rf@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/wm_adsp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
+index 47a4c363227ccd..bc9798ea5a25e2 100644
+--- a/sound/soc/codecs/wm_adsp.c
++++ b/sound/soc/codecs/wm_adsp.c
+@@ -666,6 +666,9 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl)
+ {
+ struct wm_coeff_ctl *ctl = cs_ctl->priv;
+
++ if (!ctl)
++ return;
++
+ cancel_work_sync(&ctl->work);
+
+ kfree(ctl->name);
+--
+2.53.0
+
--- /dev/null
+From eee00014b084e23b43276c79b649cfe10f5e49b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 08:10:47 -0400
+Subject: iomap: don't revert iov_iter on partially completed buffered writes
+
+From: Brian Foster <bfoster@redhat.com>
+
+Gregg reports that the iomap retry behavior for nonblocking (nowait)
+append writes is broken. The problem occurs when an append write is
+first submitted in non-blocking mode (i.e. via io_uring), partially
+completes before hitting -EAGAIN, and then is resubmitted from
+blocking context.
+
+The specific problem is that at least one iteration of the loop in
+iomap_write_iter() completes in non-blocking context and thus has
+bumped i_size. The next iteration hits -EAGAIN, reverts the iov_iter
+and returns. io_uring retries the entire append write from blocking
+context, but since i_size has already been increased, the data that
+was partially written on the first attempt is rewritten at the new
+i_size. This is essentially an intra-write data corruption since the
+data written to the file does not reflect the write from userspace.
+
+This problem is already fixed on master as of commit 1a1a3b574b97
+("iomap: advance the iter directly on buffered writes"). That commit
+was primarily intended to clean up iomap iter state tracking, but it
+also happened to remove the iov_iter revert and thus accidentally
+fix this problem as well. Without the revert, iomap will commit
+partial progress internally and loop once more before it more than
+likely hits -EAGAIN and returns partial progress consistent with the
+inode updates. This means the blocking retry from io_uring will pick
+up where the first attempt left off at the current i_size and
+perform the remainder of the write correctly.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 18e419f6e80a ("iomap: Return -EAGAIN from iomap_write_iter()")
+Reported-by: Gregg Leventhal <gleventhal@janestreet.com>
+Reported-by: Eric Hagberg <ehagberg@janestreet.com>
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/iomap/buffered-io.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
+index c3408ba636632a..243cb2ec76ed2e 100644
+--- a/fs/iomap/buffered-io.c
++++ b/fs/iomap/buffered-io.c
+@@ -821,10 +821,6 @@ static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
+ length -= status;
+ } while (iov_iter_count(i) && length);
+
+- if (status == -EAGAIN) {
+- iov_iter_revert(i, written);
+- return -EAGAIN;
+- }
+ return written ? written : status;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From c3461d0c67643eba2fb2fc290a1d4eb0fbd5674c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 16:46:13 +0000
+Subject: ip6_vti: fix incorrect tunnel matching in vti6_tnl_lookup()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit a5c0359f5cbc51a2e2b114d6041e0f3c73f903e9 ]
+
+In vti6_tnl_lookup(), when an exact match for a tunnel fails,
+the code falls back to searching for wildcard tunnels:
+
+- Tunnels matching the packet's local address, with any remote address
+ wildcard remote).
+
+- Tunnels matching the packet's remote address, with any local address
+ (wildcard local).
+
+However, vti6 stores all these different types of tunnels in the same
+hash table (ip6n->tnls_r_l) prone to hash collisions.
+
+The bug is that the fallback search loops in vti6_tnl_lookup() were
+missing checks to ensure that the candidate tunnel actually has
+a wildcard address.
+
+Fixes: fbe68ee87522 ("vti6: Add a lookup method for tunnels with wildcard endpoints.")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260608164613.933023-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_vti.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
+index ead8f1ecd8271b..8808067df5168c 100644
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -105,6 +105,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(&any, local);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(local, &t->parms.laddr) &&
++ ipv6_addr_any(&t->parms.raddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+@@ -112,6 +113,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(remote, &any);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(remote, &t->parms.raddr) &&
++ ipv6_addr_any(&t->parms.laddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+--
+2.53.0
+
--- /dev/null
+From e9e9067dfcd4f9247b7c3b5098e553ed6da206fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 00:34:48 -0700
+Subject: ipv6: sit: reload inner IPv6 header after GSO offloads
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f0e42f0c4337b1f220de1ddd63f47197c7dee4de ]
+
+ipip6_tunnel_xmit() caches the inner IPv6 header pointer at function
+entry and continues using it after iptunnel_handle_offloads().
+
+For GSO skbs, iptunnel_handle_offloads() calls skb_header_unclone().
+When the skb header is cloned, skb_header_unclone() can call
+pskb_expand_head(), which may move the skb head. The pskb_expand_head()
+contract requires pointers into the skb header to be reloaded after the
+call.
+
+If the later skb_realloc_headroom() branch is not taken, SIT uses the
+stale iph6 pointer to read the inner hop limit and DS field. That can
+read from a freed skb head after the old head's remaining clone is
+released.
+
+Reload iph6 after the offload helper succeeds and before subsequent
+reads from the inner IPv6 header. Keep the existing reload after
+skb_realloc_headroom(), since that branch can also replace the skb.
+
+Fixes: 14909664e4e1 ("sit: Setup and TX path for sit/UDP foo-over-udp encapsulation")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot+6eb9ca986d80f6f88cf9@syzkaller.appspotmail.com
+Link: https://patch.msgid.link/20260605073448.6524-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/sit.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index eb4c8e2a2b12e0..aa88a41034d920 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -965,6 +965,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ ip_rt_put(rt);
+ goto tx_error;
+ }
++ iph6 = ipv6_hdr(skb);
+
+ if (df) {
+ mtu = dst_mtu(&rt->dst) - t_hlen;
+--
+2.53.0
+
--- /dev/null
+From 5596e4c6b61d8c59ef1e9823b05b9b982bcaf653 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 19:18:19 -0700
+Subject: net: guard timestamp cmsgs to real error queue skbs
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit 1ee90b77b727df903033db873c75caac5c27ec98 ]
+
+skb_is_err_queue() treats PACKET_OUTGOING as the sole marker for an skb
+from sk_error_queue. That assumption is not true for AF_PACKET sockets:
+outgoing packet taps are also delivered to packet sockets with
+skb->pkt_type == PACKET_OUTGOING, but their skb->cb is owned by AF_PACKET
+instead of struct sock_exterr_skb.
+
+If such an skb is received with timestamping enabled, the generic
+timestamp cmsg path can read AF_PACKET control-buffer state as
+sock_exterr_skb::opt_stats. With SO_RXQ_OVFL enabled, the packet drop
+counter overlaps opt_stats. An odd drop count makes the path emit
+SCM_TIMESTAMPING_OPT_STATS with skb->len and skb->data. For non-linear
+skbs this copies past the linear head and can trigger hardened usercopy or
+disclose adjacent heap contents.
+
+Keep skb_is_err_queue() local to net/socket.c, but make it verify that
+the PACKET_OUTGOING marker is paired with the sock_rmem_free destructor
+installed by sock_queue_err_skb(). AF_PACKET receive skbs use normal
+receive ownership and no longer pass as error-queue skbs, while legitimate
+sk_error_queue entries keep the PACKET_OUTGOING marker and sock_rmem_free
+ownership.
+
+Fixes: 8605330aac5a ("tcp: fix SCM_TIMESTAMPING_OPT_STATS for normal skbs")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260607021819.49698-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 1 +
+ net/core/skbuff.c | 6 +++---
+ net/socket.c | 11 ++++++-----
+ 3 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 2d34dd5941e795..1e7096e9bc4842 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1945,6 +1945,7 @@ struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size,
+ gfp_t priority);
+ void skb_orphan_partial(struct sk_buff *skb);
+ void sock_rfree(struct sk_buff *skb);
++void sock_rmem_free(struct sk_buff *skb);
+ void sock_efree(struct sk_buff *skb);
+ #ifdef CONFIG_INET
+ void sock_edemux(struct sk_buff *skb);
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index f1f5b2b25f8522..f41dd20991c3df 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -4810,7 +4810,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
+ }
+ EXPORT_SYMBOL_GPL(skb_cow_data);
+
+-static void sock_rmem_free(struct sk_buff *skb)
++void sock_rmem_free(struct sk_buff *skb)
+ {
+ struct sock *sk = skb->sk;
+
+@@ -4819,8 +4819,8 @@ static void sock_rmem_free(struct sk_buff *skb)
+
+ static void skb_set_err_queue(struct sk_buff *skb)
+ {
+- /* pkt_type of skbs received on local sockets is never PACKET_OUTGOING.
+- * So, it is safe to (mis)use it to mark skbs on the error queue.
++ /* The error-queue test in skb_is_err_queue() matches this marker
++ * with the sock_rmem_free destructor installed by sock_queue_err_skb().
+ */
+ skb->pkt_type = PACKET_OUTGOING;
+ BUILD_BUG_ON(PACKET_OUTGOING == 0);
+diff --git a/net/socket.c b/net/socket.c
+index 701389e2f22b3a..f2b4cf9b09a322 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -807,12 +807,13 @@ EXPORT_SYMBOL(kernel_sendmsg_locked);
+
+ static bool skb_is_err_queue(const struct sk_buff *skb)
+ {
+- /* pkt_type of skbs enqueued on the error queue are set to
+- * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
+- * in recvmsg, since skbs received on a local socket will never
+- * have a pkt_type of PACKET_OUTGOING.
++ /* Error-queue skbs are marked as PACKET_OUTGOING in
++ * skb_set_err_queue() and use the destructor installed by
++ * sock_queue_err_skb(). PACKET_OUTGOING alone is not unique:
++ * AF_PACKET outgoing taps use the same pkt_type.
+ */
+- return skb->pkt_type == PACKET_OUTGOING;
++ return skb->pkt_type == PACKET_OUTGOING &&
++ skb->destructor == sock_rmem_free;
+ }
+
+ /* On transmit, software and hardware timestamps are returned independently.
+--
+2.53.0
+
--- /dev/null
+From a88f4a07384e27b78fd94cc9719dd82c082c3b9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 14:10:44 +0800
+Subject: net/mlx4: avoid GCC 10 __bad_copy_from() false positive
+
+From: Yao Sang <sangyao@kylinos.cn>
+
+[ Upstream commit 2365343f4aad3e1b1e7a2e87e98cf66d5e590589 ]
+
+mlx4_init_user_cqes() fills a scratch buffer with the CQE
+initialization pattern and then copies from that buffer to userspace.
+
+In the single-copy path, the copy length is array_size(entries,
+cqe_size), but the scratch buffer is allocated with PAGE_SIZE. GCC 10
+does not carry the branch invariant strongly enough through the object
+size checks and falsely triggers __bad_copy_from().
+
+Size the scratch buffer to the actual copy length for the active path,
+keep array_size() for the single-copy case, and retain a WARN_ON_ONCE()
+guard for the PAGE_SIZE invariant before allocating the buffer.
+
+Fixes: f69bf5dee7ef ("net/mlx4: Use array_size() helper in copy_to_user()")
+Signed-off-by: Yao Sang <sangyao@kylinos.cn>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx4/cq.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c
+index 4d4f9cf9facb87..fb83d8af8dcb9c 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
++++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
+@@ -290,6 +290,7 @@ static void mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
+ static int mlx4_init_user_cqes(void *buf, int entries, int cqe_size)
+ {
+ int entries_per_copy = PAGE_SIZE / cqe_size;
++ size_t copy_bytes;
+ void *init_ents;
+ int err = 0;
+ int i;
+@@ -314,8 +315,14 @@ static int mlx4_init_user_cqes(void *buf, int entries, int cqe_size)
+ buf += PAGE_SIZE;
+ }
+ } else {
++ copy_bytes = array_size(entries, cqe_size);
++ if (WARN_ON_ONCE(copy_bytes > PAGE_SIZE)) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ err = copy_to_user((void __user *)buf, init_ents,
+- array_size(entries, cqe_size)) ?
++ copy_bytes) ?
+ -EFAULT : 0;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From ae9fafa2bc96aa2e28cd46e941de3daac4045471 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 12:46:06 +0100
+Subject: net: mvpp2: Add metadata support for xdp mode
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 9a45e193c88a55a536d7fd0ebfa29823d588c2cf ]
+
+Set metadata size building the skb from xdp_buff in mvpp2 driver
+mvpp2 driver sets xdp headroom to:
+
+MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM
+
+where
+
+MVPP2_MH_SIZE 2
+MVPP2_SKB_HEADROOM min(max(XDP_PACKET_HEADROOM, NET_SKB_PAD), 224)
+
+so the headroom is large enough to contain xdp_frame and xdp metadata.
+Please note this patch is just compiled tested.
+
+Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20250318-mvneta-xdp-meta-v2-2-b6075778f61f@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 77a6b90ce56b ("net: mvpp2: build skb from XDP-adjusted data on XDP_PASS")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 8403fc4e9e7176..4c299d8bb2392c 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3915,13 +3915,13 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ while (rx_done < rx_todo) {
+ struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq);
++ u32 rx_status, timestamp, metasize = 0;
+ struct mvpp2_bm_pool *bm_pool;
+ struct page_pool *pp = NULL;
+ struct sk_buff *skb;
+ unsigned int frag_size;
+ dma_addr_t dma_addr;
+ phys_addr_t phys_addr;
+- u32 rx_status, timestamp;
+ int pool, rx_bytes, err, ret;
+ struct page *page;
+ void *data;
+@@ -3984,7 +3984,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ xdp_init_buff(&xdp, bm_pool->frag_size, xdp_rxq);
+ xdp_prepare_buff(&xdp, data,
+ MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM,
+- rx_bytes, false);
++ rx_bytes, true);
+
+ ret = mvpp2_run_xdp(port, xdp_prog, &xdp, pp, &ps);
+
+@@ -4000,6 +4000,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ ps.rx_bytes += rx_bytes;
+ continue;
+ }
++
++ metasize = xdp.data - xdp.data_meta;
+ }
+
+ skb = build_skb(data, frag_size);
+@@ -4036,6 +4038,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);
+ skb_put(skb, rx_bytes);
++ if (metasize)
++ skb_metadata_set(skb, metasize);
+ skb->ip_summed = mvpp2_rx_csum(port, rx_status);
+ skb->protocol = eth_type_trans(skb, dev);
+
+--
+2.53.0
+
--- /dev/null
+From 70ddb1c77b65308662aa36d0578c3afe49d38308 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:43 +0200
+Subject: net: mvpp2: build skb from XDP-adjusted data on XDP_PASS
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 77a6b90ce56bc982dcfa94229b8e28e6abb16e95 ]
+
+When an XDP program uses bpf_xdp_adjust_head() or bpf_xdp_adjust_tail()
+and then returns XDP_PASS, mvpp2 still builds the skb from fixed offsets
+derived from the original RX descriptor. Packet geometry changes made by
+the XDP program are therefore discarded before the skb reaches the stack.
+
+Update rx_offset and rx_bytes from xdp.data and xdp.data_end for
+XDP_PASS. This makes skb_reserve() and skb_put() reflect the packet seen
+by XDP, and makes RX byte accounting for XDP_PASS follow the length of the
+skb passed to the network stack.
+
+Keep a separate rx_sync_size for page-pool recycling on skb allocation
+failure, which must stay tied to the received buffer range.
+
+Non-PASS verdicts continue to account the descriptor length because no skb
+is passed up in those cases.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-5-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 21 +++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index fc16e577a10376..675616142c4f47 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3919,10 +3919,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ struct mvpp2_bm_pool *bm_pool;
+ struct page_pool *pp = NULL;
+ struct sk_buff *skb;
+- unsigned int frag_size;
++ unsigned int frag_size, rx_sync_size;
+ dma_addr_t dma_addr;
+ phys_addr_t phys_addr;
+- int pool, rx_bytes, err, ret;
++ int pool, rx_bytes, rx_offset, err, ret;
+ struct page *page;
+ void *data;
+
+@@ -3935,6 +3935,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ rx_status = mvpp2_rxdesc_status_get(port, rx_desc);
+ rx_bytes = mvpp2_rxdesc_size_get(port, rx_desc);
+ rx_bytes -= MVPP2_MH_SIZE;
++ rx_sync_size = rx_bytes + MVPP2_MH_SIZE;
++ rx_offset = MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM;
+ dma_addr = mvpp2_rxdesc_dma_addr_get(port, rx_desc);
+
+ pool = (rx_status & MVPP2_RXD_BM_POOL_ID_MASK) >>
+@@ -3950,7 +3952,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
+ MVPP2_SKB_HEADROOM,
+- rx_bytes + MVPP2_MH_SIZE,
++ rx_sync_size,
+ dma_dir);
+
+ /* Buffer header not supported */
+@@ -4001,6 +4003,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ continue;
+ }
+
++ rx_sync_size = max_t(unsigned int, rx_sync_size,
++ xdp.data_end - xdp.data_hard_start -
++ MVPP2_SKB_HEADROOM);
++
++ /* Update offset and length to reflect any XDP adjustments. */
++ rx_offset = xdp.data - data;
++ rx_bytes = xdp.data_end - xdp.data;
++
+ metasize = xdp.data - xdp.data_meta;
+ }
+
+@@ -4009,8 +4019,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ netdev_warn(port->dev, "skb build failed\n");
+ if (pp) {
+ page_pool_put_page(pp, virt_to_head_page(data),
+- rx_bytes + MVPP2_MH_SIZE,
+- true);
++ rx_sync_size, true);
+ } else {
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size,
+@@ -4040,7 +4049,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
+
+- skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);
++ skb_reserve(skb, rx_offset);
+ skb_put(skb, rx_bytes);
+ if (metasize)
+ skb_metadata_set(skb, metasize);
+--
+2.53.0
+
--- /dev/null
+From 6919a53c7d4cfc5f5e91b59206a2e12880a7384d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:41 +0200
+Subject: net: mvpp2: limit XDP frame size to the RX buffer
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit f3c6aa078927e6fe8121c9c591ddee8716c5305a ]
+
+mvpp2 has short and long BM pools, and short pool buffers can be smaller
+than PAGE_SIZE. The XDP path nevertheless initializes every xdp_buff with
+PAGE_SIZE as frame size.
+
+XDP helpers use frame_sz to validate tail growth and to derive the hard
+end of the data area. Advertising PAGE_SIZE for short buffers can let
+bpf_xdp_adjust_tail() grow a packet past the real allocation, corrupting
+memory or later tripping skb tailroom checks.
+
+Initialize the XDP buffer with bm_pool->frag_size so XDP tailroom matches
+the actual buffer backing the packet.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-3-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 62d72f5ed01295..8403fc4e9e7176 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3981,7 +3981,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ else
+ xdp_rxq = &rxq->xdp_rxq_long;
+
+- xdp_init_buff(&xdp, PAGE_SIZE, xdp_rxq);
++ xdp_init_buff(&xdp, bm_pool->frag_size, xdp_rxq);
+ xdp_prepare_buff(&xdp, data,
+ MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM,
+ rx_bytes, false);
+--
+2.53.0
+
--- /dev/null
+From 00b2a5060375b7f736833890604d4ec33fab30f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:42 +0200
+Subject: net: mvpp2: refill RX buffers before XDP or skb use
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 5e8e2a9624df72fca7c736b2966b2cbf6c9c3ff6 ]
+
+The RX error path returns the current descriptor buffer to the hardware
+BM pool. That is only valid while the driver still owns the buffer.
+
+mvpp2_rx_refill() can fail after the current buffer has been handed to
+XDP or attached to an skb. In those cases mvpp2_run_xdp() may have
+recycled, redirected, or queued the page for XDP_TX, and an skb free also
+retires the data buffer. Returning such a buffer to BM lets hardware DMA
+into memory that is no longer owned by the RX ring.
+
+Refill the BM pool before handing the current buffer to XDP or to the
+skb. If the allocation fails there, drop the packet and return the
+still-owned current buffer to BM, preserving the pool depth. Once the
+refill succeeds, later local drops retire/free the current buffer instead
+of returning it to BM.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Fixes: d6526926de73 ("net: mvpp2: fix memory leak in mvpp2_rx")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-4-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 77a6b90ce56b ("net: mvpp2: build skb from XDP-adjusted data on XDP_PASS")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 43 +++++++++++--------
+ 1 file changed, 24 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 4c299d8bb2392c..fc16e577a10376 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3973,6 +3973,12 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ else
+ frag_size = bm_pool->frag_size;
+
++ err = mvpp2_rx_refill(port, bm_pool, pp, pool);
++ if (err) {
++ netdev_err(port->dev, "failed to refill BM pools\n");
++ goto err_drop_frame;
++ }
++
+ if (xdp_prog) {
+ struct xdp_rxq_info *xdp_rxq;
+
+@@ -3990,12 +3996,6 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ if (ret) {
+ xdp_ret |= ret;
+- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+- if (err) {
+- netdev_err(port->dev, "failed to refill BM pools\n");
+- goto err_drop_frame;
+- }
+-
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
+ continue;
+@@ -4007,8 +4007,21 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ skb = build_skb(data, frag_size);
+ if (!skb) {
+ netdev_warn(port->dev, "skb build failed\n");
+- goto err_drop_frame;
++ if (pp) {
++ page_pool_put_page(pp, virt_to_head_page(data),
++ rx_bytes + MVPP2_MH_SIZE,
++ true);
++ } else {
++ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
++ bm_pool->buf_size,
++ DMA_FROM_DEVICE,
++ DMA_ATTR_SKIP_CPU_SYNC);
++ mvpp2_frag_free(bm_pool, pp, data);
++ }
++ goto err_drop_frame_retired;
+ }
++ if (pp)
++ skb_mark_for_recycle(skb);
+
+ /* If we have RX hardware timestamping enabled, grab the
+ * timestamp from the queue and convert.
+@@ -4019,16 +4032,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ skb_hwtstamps(skb));
+ }
+
+- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+- if (err) {
+- netdev_err(port->dev, "failed to refill BM pools\n");
+- dev_kfree_skb_any(skb);
+- goto err_drop_frame;
+- }
+-
+- if (pp)
+- skb_mark_for_recycle(skb);
+- else
++ if (!pp)
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size, DMA_FROM_DEVICE,
+ DMA_ATTR_SKIP_CPU_SYNC);
+@@ -4047,13 +4051,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ continue;
+
+ err_drop_frame:
+- dev->stats.rx_errors++;
+- mvpp2_rx_error(port, rx_desc);
+ /* Return the buffer to the pool */
+ if (rx_status & MVPP2_RXD_BUF_HDR)
+ mvpp2_buff_hdr_pool_put(port, rx_desc, pool, rx_status);
+ else
+ mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);
++err_drop_frame_retired:
++ dev->stats.rx_errors++;
++ mvpp2_rx_error(port, rx_desc);
+ }
+
+ if (xdp_ret & MVPP2_XDP_REDIR)
+--
+2.53.0
+
--- /dev/null
+From 571d3846ba606a9a4f508e02fc5525acee972cd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:40 +0200
+Subject: net: mvpp2: sync RX data at the hardware packet offset
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 180235600934bef6add3be637c296d6cf3272e67 ]
+
+mvpp2 programs the RX queue packet offset, so hardware writes received
+data at dma_addr + MVPP2_SKB_HEADROOM. The current CPU sync starts at
+dma_addr and only covers rx_bytes + MVPP2_MH_SIZE bytes, which syncs the
+unused headroom and misses the same number of bytes at the packet tail.
+
+On non-coherent DMA systems this can leave the CPU reading stale cache
+contents for the end of the received frame.
+
+Use dma_sync_single_range_for_cpu() with MVPP2_SKB_HEADROOM as the range
+offset so the sync covers the Marvell header and packet data actually
+written by hardware.
+
+Fixes: e1921168bbd4 ("mvpp2: sync only the received frame")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-2-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index b42c2c498faa2e..62d72f5ed01295 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3948,9 +3948,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ dma_dir = DMA_FROM_DEVICE;
+ }
+
+- dma_sync_single_for_cpu(dev->dev.parent, dma_addr,
+- rx_bytes + MVPP2_MH_SIZE,
+- dma_dir);
++ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
++ MVPP2_SKB_HEADROOM,
++ rx_bytes + MVPP2_MH_SIZE,
++ dma_dir);
+
+ /* Buffer header not supported */
+ if (rx_status & MVPP2_RXD_BUF_HDR)
+--
+2.53.0
+
--- /dev/null
+From a31eab113ac2c300d3cf21c31fa74577e9f042f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:19:46 +0200
+Subject: net: openvswitch: fix possible kfree_skb of ERR_PTR
+
+From: Adrian Moreno <amorenoz@redhat.com>
+
+[ Upstream commit ee30dd2909d8b98619f4341c70ec8dc8e155ab02 ]
+
+After the patch in the "Fixes" tag, the allocation of the "reply" skb
+can happen either before or after locking the ovs_mutex.
+
+However, error cleanups still follow the classical reversed order,
+assuming "reply" is allocated before locking: it is freed after unlocking.
+
+If "reply" allocation happens after locking the mutex and it fails,
+"reply" is left with an ERR_PTR, and execution jumps to the correspondent
+cleanup stage which will try to free an invalid pointer.
+
+Fix this by setting the pointer to NULL after having saved its error
+value.
+
+Fixes: 893f139b9a6c ("openvswitch: Minimize ovs_flow_cmd_new|set critical sections.")
+Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Acked-by: Eelco Chaudron <echaudro@redhat.com>
+Link: https://patch.msgid.link/20260604121946.942164-1-amorenoz@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/datapath.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index c751d6b36febd1..0c0d89470145a1 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -1263,6 +1263,7 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
+
+ if (IS_ERR(reply)) {
+ error = PTR_ERR(reply);
++ reply = NULL;
+ goto err_unlock_ovs;
+ }
+ }
+--
+2.53.0
+
--- /dev/null
+From 8a33c0cfd0df7e96d9d8f6f72f9cccb14b181cc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:48:01 +0800
+Subject: net: qrtr: fix refcount saturation and potential UAF in
+ qrtr_port_remove
+
+From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+
+[ Upstream commit a2171131ecda1ed61a594a1eb715e75fdad0fef5 ]
+
+In qrtr_port_remove(), the socket reference count is decremented via
+__sock_put() before the port is removed from the qrtr_ports XArray and
+before the RCU grace period elapses.
+
+This breaks the fundamental RCU update paradigm. It exposes a race
+window where a concurrent RCU reader (such as qrtr_reset_ports() or
+qrtr_port_lookup()) can obtain a pointer to the socket from the XArray,
+and attempt to call sock_hold() on a socket whose reference count has
+already dropped to zero.
+
+This exact race condition was hit during syzkaller fuzzing, leading to
+the following refcount saturation warning and a potential Use-After-Free:
+
+ refcount_t: saturated; leaking memory.
+ WARNING: CPU: 3 PID: 1273 at lib/refcount.c:22 refcount_warn_saturate+0xae/0x1d0
+ Modules linked in: qrtr(+) bochs drm_shmem_helper ...
+ Call Trace:
+ <TASK>
+ qrtr_reset_ports net/qrtr/af_qrtr.c:768 [inline] [qrtr]
+ __qrtr_bind.isra.0+0x48b/0x570 net/qrtr/af_qrtr.c:805 [qrtr]
+ qrtr_bind+0x17d/0x210 net/qrtr/af_qrtr.c:901 [qrtr]
+ kernel_bind+0xe4/0x120 net/socket.c:3592
+ qrtr_ns_init+0x1a6/0x380 net/qrtr/ns.c:715 [qrtr]
+ qrtr_proto_init+0x3b/0xff0 net/qrtr/af_qrtr.c:169 [qrtr]
+ do_one_initcall+0xf5/0x5e0 init/main.c:1283
+ ...
+ </TASK>
+
+Fix this by deferring the reference count decrement until after the
+xa_erase() and the synchronize_rcu() complete.
+
+(Note: The v1 of this patch incorrectly replaced __sock_put() with
+sock_put(). As Simon Horman pointed out, the callers of qrtr_port_remove()
+still hold a reference to the socket, so freeing the socket memory here
+would lead to a subsequent UAF in the caller. Thus, the __sock_put() is
+kept, but only repositioned to close the RCU race.)
+
+Fixes: bdabad3e363d ("net: Add Qualcomm IPC router")
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260604064801.1180388-1-w15303746062@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/af_qrtr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c
+index 3831eb25e240ae..8cedf26d78ee02 100644
+--- a/net/qrtr/af_qrtr.c
++++ b/net/qrtr/af_qrtr.c
+@@ -702,13 +702,13 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
+ if (port == QRTR_PORT_CTRL)
+ port = 0;
+
+- __sock_put(&ipc->sk);
+-
+ xa_erase(&qrtr_ports, port);
+
+ /* Ensure that if qrtr_port_lookup() did enter the RCU read section we
+ * wait for it to up increment the refcount */
+ synchronize_rcu();
++
++ __sock_put(&ipc->sk);
+ }
+
+ /* Assign port number to socket.
+--
+2.53.0
+
--- /dev/null
+From 83eee2a46bc2b026bdfec6b4ca51e718a139d6b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 12:24:48 -0700
+Subject: net/rds: fix NULL deref in rds_ib_send_cqe_handler() on masked atomic
+ completion
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 34080db3e70ddf94c38512ad2331e3c3afca6cc1 ]
+
+rds_ib_xmit_atomic() always programs a masked atomic opcode
+(IB_WR_MASKED_ATOMIC_CMP_AND_SWP or IB_WR_MASKED_ATOMIC_FETCH_AND_ADD)
+for every RDS atomic cmsg. But the completion-side switch in
+rds_ib_send_unmap_op() only handles the non-masked opcodes, so a masked
+atomic completion falls through to default and returns rm == NULL while
+send->s_op is left set. rds_ib_send_cqe_handler() then dereferences the
+NULL rm via rm->m_final_op, oopsing in softirq context. An unprivileged
+AF_RDS sendmsg() of an atomic cmsg over an active RDS/IB connection
+triggers it; on hardware that natively accepts masked atomics (mlx4,
+mlx5) no extra setup is needed.
+
+ RDS/IB: rds_ib_send_unmap_op: unexpected opcode 0xd in WR!
+ Oops: general protection fault [#1] SMP KASAN
+ KASAN: null-ptr-deref in range [0x0000000000000190-0x0000000000000197]
+ RIP: rds_ib_send_cqe_handler+0x25c/0xb10 (net/rds/ib_send.c:282)
+ Call Trace:
+ <IRQ>
+ rds_ib_send_cqe_handler (net/rds/ib_send.c:282)
+ poll_scq (net/rds/ib_cm.c:274)
+ rds_ib_tasklet_fn_send (net/rds/ib_cm.c:294)
+ tasklet_action_common (kernel/softirq.c:943)
+ handle_softirqs (kernel/softirq.c:573)
+ run_ksoftirqd (kernel/softirq.c:479)
+ </IRQ>
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Handle the masked atomic opcodes in the same case as the non-masked
+ones: they map to the same struct rds_message.atomic union member, so
+the existing container_of()/rds_ib_send_unmap_atomic() body is correct
+for them.
+
+Fixes: 20c72bd5f5f9 ("RDS: Implement masked atomic operations")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260606192447.1179255-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/ib_send.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
+index 4190b90ff3b18a..1909cd440a4b66 100644
+--- a/net/rds/ib_send.c
++++ b/net/rds/ib_send.c
+@@ -170,6 +170,8 @@ static struct rds_message *rds_ib_send_unmap_op(struct rds_ib_connection *ic,
+ break;
+ case IB_WR_ATOMIC_FETCH_AND_ADD:
+ case IB_WR_ATOMIC_CMP_AND_SWP:
++ case IB_WR_MASKED_ATOMIC_FETCH_AND_ADD:
++ case IB_WR_MASKED_ATOMIC_CMP_AND_SWP:
+ if (send->s_op) {
+ rm = container_of(send->s_op, struct rds_message, atomic);
+ rds_ib_send_unmap_atomic(ic, send->s_op, wc_status);
+--
+2.53.0
+
--- /dev/null
+From a93803048fade3b7afd9ec7aa176ecd175ac2831 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 00:38:17 -0700
+Subject: netfilter: nf_conntrack: destroy stale expectfn expectations on
+ unregister
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit c3009418f9fa1dcb3eb86f4d8c92583537b5faa3 ]
+
+NAT helpers such as nf_nat_h323 store a raw pointer to module text in
+exp->expectfn (e.g. ip_nat_q931_expect). nf_ct_helper_expectfn_unregister()
+only unlinks the callback descriptor and never walks the expectation table,
+so an expectation pending at module removal survives with a dangling
+exp->expectfn into freed module text.
+
+When the expected connection arrives, init_conntrack() invokes
+exp->expectfn(), now a stale pointer into the unloaded module. Reproduced
+on a KASAN build by loading the H.323 helpers, creating a Q.931
+expectation, unloading nf_nat_h323, then connecting to the expected port:
+
+ Oops: int3: 0000 [#1] SMP KASAN NOPTI
+ RIP: 0010:0xffffffffa06102d1
+ init_conntrack.isra.0 (net/netfilter/nf_conntrack_core.c:1862)
+ nf_conntrack_in (net/netfilter/nf_conntrack_core.c:2049)
+ ipv4_conntrack_local (net/netfilter/nf_conntrack_proto.c:223)
+ nf_hook_slow (net/netfilter/core.c:619)
+ __ip_local_out (net/ipv4/ip_output.c:120)
+ __tcp_transmit_skb (net/ipv4/tcp_output.c:1715)
+ tcp_connect (net/ipv4/tcp_output.c:4374)
+ tcp_v4_connect (net/ipv4/tcp_ipv4.c:345)
+ __sys_connect (net/socket.c:2167)
+ Modules linked in: nf_conntrack_h323 [last unloaded: nf_nat_h323]
+
+Reaching the dangling state requires CAP_SYS_MODULE in the initial user
+namespace to remove a NAT helper that still has live expectations, so this
+is a robustness fix; leaving an expectation pointing at freed text is wrong
+regardless.
+
+Add nf_ct_helper_expectfn_destroy(), which walks the expectation table and
+drops every expectation whose ->expectfn matches the descriptor being torn
+down. Call it from each NAT helper's exit path after the existing RCU grace
+period, so no expectation outlives the code it points at and no extra
+synchronize_rcu() is introduced. With the fix, the same reproducer runs to
+completion without the Oops.
+
+Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netfilter/nf_conntrack_helper.h | 1 +
+ net/ipv4/netfilter/nf_nat_h323.c | 2 ++
+ net/netfilter/nf_conntrack_helper.c | 19 +++++++++++++++++++
+ net/netfilter/nf_nat_core.c | 2 ++
+ net/netfilter/nf_nat_sip.c | 1 +
+ 5 files changed, 25 insertions(+)
+
+diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
+index 9939c366f720d4..2435039434ea9d 100644
+--- a/include/net/netfilter/nf_conntrack_helper.h
++++ b/include/net/netfilter/nf_conntrack_helper.h
+@@ -152,6 +152,7 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
+
+ void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n);
+ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n);
++void nf_ct_helper_expectfn_destroy(const struct nf_ct_helper_expectfn *n);
+ struct nf_ct_helper_expectfn *
+ nf_ct_helper_expectfn_find_by_name(const char *name);
+ struct nf_ct_helper_expectfn *
+diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
+index faee20af485613..10e1b0837731b7 100644
+--- a/net/ipv4/netfilter/nf_nat_h323.c
++++ b/net/ipv4/netfilter/nf_nat_h323.c
+@@ -555,6 +555,8 @@ static void __exit nf_nat_h323_fini(void)
+ nf_ct_helper_expectfn_unregister(&q931_nat);
+ nf_ct_helper_expectfn_unregister(&callforwarding_nat);
+ synchronize_rcu();
++ nf_ct_helper_expectfn_destroy(&q931_nat);
++ nf_ct_helper_expectfn_destroy(&callforwarding_nat);
+ }
+
+ /****************************************************************************/
+diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
+index 6a2ad31ac62f12..8e72c3d4db4ad1 100644
+--- a/net/netfilter/nf_conntrack_helper.c
++++ b/net/netfilter/nf_conntrack_helper.c
+@@ -286,6 +286,25 @@ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n)
+ }
+ EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_unregister);
+
++static bool expect_iter_expectfn(struct nf_conntrack_expect *exp, void *data)
++{
++ const struct nf_ct_helper_expectfn *n = data;
++
++ /* Relies on registered expectfn descriptors having unique ->expectfn
++ * pointers, which holds for the in-tree NAT helpers.
++ */
++ return exp->expectfn == n->expectfn;
++}
++
++/* Destroy expectations still pointing at @n->expectfn; call after the
++ * caller's RCU grace period so none outlives the (often modular) callback.
++ */
++void nf_ct_helper_expectfn_destroy(const struct nf_ct_helper_expectfn *n)
++{
++ nf_ct_expect_iterate_destroy(expect_iter_expectfn, (void *)n);
++}
++EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_destroy);
++
+ /* Caller should hold the rcu lock */
+ struct nf_ct_helper_expectfn *
+ nf_ct_helper_expectfn_find_by_name(const char *name)
+diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
+index 6b683ff015b9cc..cf7c06b79d5614 100644
+--- a/net/netfilter/nf_nat_core.c
++++ b/net/netfilter/nf_nat_core.c
+@@ -1157,6 +1157,7 @@ static int __init nf_nat_init(void)
+ RCU_INIT_POINTER(nf_nat_hook, NULL);
+ nf_ct_helper_expectfn_unregister(&follow_master_nat);
+ synchronize_net();
++ nf_ct_helper_expectfn_destroy(&follow_master_nat);
+ unregister_pernet_subsys(&nat_net_ops);
+ kvfree(nf_nat_bysource);
+ }
+@@ -1174,6 +1175,7 @@ static void __exit nf_nat_cleanup(void)
+ RCU_INIT_POINTER(nf_nat_hook, NULL);
+
+ synchronize_net();
++ nf_ct_helper_expectfn_destroy(&follow_master_nat);
+ kvfree(nf_nat_bysource);
+ unregister_pernet_subsys(&nat_net_ops);
+ }
+diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c
+index 9fbfc6bff0c221..00838c0cc5bb28 100644
+--- a/net/netfilter/nf_nat_sip.c
++++ b/net/netfilter/nf_nat_sip.c
+@@ -655,6 +655,7 @@ static void __exit nf_nat_sip_fini(void)
+ RCU_INIT_POINTER(nf_nat_sip_hooks, NULL);
+ nf_ct_helper_expectfn_unregister(&sip_nat);
+ synchronize_rcu();
++ nf_ct_helper_expectfn_destroy(&sip_nat);
+ }
+
+ static const struct nf_nat_sip_hooks sip_hooks = {
+--
+2.53.0
+
--- /dev/null
+From 2c17ceb139ad598981338457a15c157f782271bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 15:55:02 -0700
+Subject: netfilter: nf_log: validate MAC header was set before dumping it
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit a84b6fedbc97078788be78dbdd7517d143ad1a77 ]
+
+The fallback path of dump_mac_header() guards the MAC header access
+only with "skb->mac_header != skb->network_header", without checking
+skb_mac_header_was_set(). When the MAC header is unset, mac_header is
+0xffff, so the test passes and skb_mac_header(skb) returns
+skb->head + 0xffff, ~64 KiB past the buffer; the loop then reads
+dev->hard_header_len bytes out of bounds into the kernel log.
+
+This is reachable via the netdev logger: nf_log_unknown_packet() calls
+dump_mac_header() unconditionally, and an skb sent through AF_PACKET
+with PACKET_QDISC_BYPASS reaches the egress hook with mac_header still
+unset (__dev_queue_xmit(), which would reset it, is bypassed).
+
+Add the skb_mac_header_was_set() check the ARPHRD_ETHER path already
+uses, and replace the open-coded MAC header length test with
+skb_mac_header_len(). Only skbs with an unset MAC header are affected;
+valid ones are dumped as before.
+
+ BUG: KASAN: slab-out-of-bounds in dump_mac_header (net/netfilter/nf_log_syslog.c:831)
+ Read of size 1 at addr ffff88800ea49d3f by task exploit/148
+ Call Trace:
+ kasan_report (mm/kasan/report.c:595)
+ dump_mac_header (net/netfilter/nf_log_syslog.c:831)
+ nf_log_netdev_packet (net/netfilter/nf_log_syslog.c:938 net/netfilter/nf_log_syslog.c:963)
+ nf_log_packet (net/netfilter/nf_log.c:260)
+ nft_log_eval (net/netfilter/nft_log.c:60)
+ nft_do_chain (net/netfilter/nf_tables_core.c:285)
+ nft_do_chain_netdev (net/netfilter/nft_chain_filter.c:307)
+ nf_hook_slow (net/netfilter/core.c:619)
+ nf_hook_direct_egress (net/packet/af_packet.c:257)
+ packet_xmit (net/packet/af_packet.c:280)
+ packet_sendmsg (net/packet/af_packet.c:3114)
+ __sys_sendto (net/socket.c:2265)
+
+Fixes: 7eb9282cd0ef ("netfilter: ipt_LOG/ip6t_LOG: add option to print decoded MAC header")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_log_syslog.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
+index 58402226045e84..09b9152e9e5492 100644
+--- a/net/netfilter/nf_log_syslog.c
++++ b/net/netfilter/nf_log_syslog.c
+@@ -799,8 +799,8 @@ static void dump_mac_header(struct nf_log_buf *m,
+
+ fallback:
+ nf_log_buf_add(m, "MAC=");
+- if (dev->hard_header_len &&
+- skb->mac_header != skb->network_header) {
++ if (dev->hard_header_len && skb_mac_header_was_set(skb) &&
++ skb_mac_header_len(skb) != 0) {
+ const unsigned char *p = skb_mac_header(skb);
+ unsigned int i;
+
+--
+2.53.0
+
--- /dev/null
+From 5f0b506efff4cd41ff330f4c98e0c39a749e0dc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 21:28:09 +0200
+Subject: netfilter: nft_exthdr: fix register tracking for F_PRESENT flag
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 772cecf198da732faebb5dcfc46d66a505be8495 ]
+
+nft_exthdr_init() passes user-controlled priv->len to
+nft_parse_register_store(), which marks that many bytes in the
+register bitmap as initialized. However, when NFT_EXTHDR_F_PRESENT
+is set, the eval paths write only 1 byte (nft_reg_store8) or
+4 bytes (*dest = 0 on TCP/DCCP error path). When len > 4,
+registers beyond the first are never written, retaining
+uninitialized stack data from nft_regs.
+
+Bail out if userspace requests too much data when F_PRESENT is set.
+
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Fixes: c078ca3b0c5b ("netfilter: nft_exthdr: Add support for existence check")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_exthdr.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
+index 60d18bd60d821e..a7cb4dd6205e9f 100644
+--- a/net/netfilter/nft_exthdr.c
++++ b/net/netfilter/nft_exthdr.c
+@@ -531,6 +531,9 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
+ return err;
+ }
+
++ if ((flags & NFT_EXTHDR_F_PRESENT) && len != 1)
++ return -EINVAL;
++
+ priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
+ priv->offset = offset;
+ priv->len = len;
+--
+2.53.0
+
--- /dev/null
+From 70a35aee774cd42cd42e5bd1a2a0b4b7bf843b69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 01:10:31 -0700
+Subject: netfilter: x_tables: avoid leaking percpu counter pointers
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f7f2fbb0e893a0238dc464f8d8c0f5609bec584f ]
+
+The native and compat get-entries paths copy the fixed rule entry header
+from the kernelized rule blob to userspace before overwriting the entry's
+counter fields with a sanitized counter snapshot.
+
+On SMP kernels, entry->counters.pcnt contains the percpu allocation
+address used by x_tables rule counters. A caller can provide a userspace
+buffer that faults during the initial fixed-header copy after pcnt has
+been copied but before the later sanitized counter copy runs. The syscall
+then returns -EFAULT while leaving the raw percpu pointer in userspace.
+
+Copy only the fixed entry prefix before counters from the kernelized rule
+blob, then copy the sanitized counter snapshot into the counter field.
+Apply this ordering to the IPv4, IPv6, and ARP native and compat
+get-entries implementations so a fault cannot expose the internal percpu
+counter pointer.
+
+Fixes: 71ae0dff02d7 ("netfilter: xtables: use percpu rule counters")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/netfilter/arp_tables.c | 15 ++++++---------
+ net/ipv4/netfilter/ip_tables.c | 15 ++++++---------
+ net/ipv6/netfilter/ip6_tables.c | 15 ++++++---------
+ 3 files changed, 18 insertions(+), 27 deletions(-)
+
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+index 564054123772a1..eeb48265208a2b 100644
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -702,14 +702,12 @@ static int copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct arpt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct arpt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1327,9 +1325,8 @@ static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct arpt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_arpt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_arpt_entry);
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
+index a6208efcfccfce..055d5e28a44f46 100644
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -834,14 +834,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ipt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ipt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1230,9 +1228,8 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ipt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ipt_entry);
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+index b844e519da1b4e..333115dff69ae7 100644
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -850,14 +850,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ip6t_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ip6t_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1246,9 +1244,8 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ip6t_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ip6t_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ip6t_entry);
+--
+2.53.0
+
--- /dev/null
+From e033f44bab1132c07c4d8231ce095cb23111c585 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 09:13:53 +0800
+Subject: netlabel: validate unlabeled address and mask attribute lengths
+
+From: Chenguang Zhao <zhaochenguang@kylinos.cn>
+
+[ Upstream commit 9772589b57e44aedc240211c5c3f7a684a034d3a ]
+
+netlbl_unlabel_addrinfo_get() used the address attribute length to
+determine whether the attribute data could be read as an IPv4 or IPv6
+address, but did not independently validate the corresponding mask
+attribute length. A crafted Generic Netlink request could therefore
+provide a valid IPv4/IPv6 address attribute with a shorter mask
+attribute, which would later be read as a full struct in_addr or
+struct in6_addr.
+
+NLA_BINARY policy lengths are maximum lengths by default, so use
+NLA_POLICY_EXACT_LEN() for the unlabeled IPv4/IPv6 address and mask
+attributes. This rejects short attributes during policy validation and
+also exposes the exact length requirements through policy introspection.
+
+Fixes: 8cc44579d1bd ("NetLabel: Introduce static network labels for unlabeled connections")
+Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlabel/netlabel_unlabeled.c | 30 ++++++++++--------------------
+ 1 file changed, 10 insertions(+), 20 deletions(-)
+
+diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
+index 9996883bf2b78d..6007cb000da678 100644
+--- a/net/netlabel/netlabel_unlabeled.c
++++ b/net/netlabel/netlabel_unlabeled.c
+@@ -114,14 +114,14 @@ static struct genl_family netlbl_unlabel_gnl_family;
+ /* NetLabel Netlink attribute policy */
+ static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
+ [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
+- [NLBL_UNLABEL_A_IPV6ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV6MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV4ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
+- [NLBL_UNLABEL_A_IPV4MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
++ [NLBL_UNLABEL_A_IPV6ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV6MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV4ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
++ [NLBL_UNLABEL_A_IPV4MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
+ [NLBL_UNLABEL_A_IFACE] = { .type = NLA_NUL_STRING,
+ .len = IFNAMSIZ - 1 },
+ [NLBL_UNLABEL_A_SECCTX] = { .type = NLA_BINARY }
+@@ -764,24 +764,14 @@ static int netlbl_unlabel_addrinfo_get(struct genl_info *info,
+ void **mask,
+ u32 *len)
+ {
+- u32 addr_len;
+-
+ if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR] &&
+ info->attrs[NLBL_UNLABEL_A_IPV4MASK]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+- if (addr_len != sizeof(struct in_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV4MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4MASK]);
+ return 0;
+ } else if (info->attrs[NLBL_UNLABEL_A_IPV6ADDR]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+- if (addr_len != sizeof(struct in6_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV6MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in6_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6MASK]);
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From 18083fee3edce7c1e3d1601dd1e64c8a39e3782b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Oct 2023 14:06:59 -0700
+Subject: r8152: Block future register access if register access fails
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit d9962b0d42029bcb40fe3c38bce06d1870fa4df4 ]
+
+Even though the functions to read/write registers can fail, most of
+the places in the r8152 driver that read/write register values don't
+check error codes. The lack of error code checking is problematic in
+at least two ways.
+
+The first problem is that the r8152 driver often uses code patterns
+similar to this:
+ x = read_register()
+ x = x | SOME_BIT;
+ write_register(x);
+
+...with the above pattern, if the read_register() fails and returns
+garbage then we'll end up trying to write modified garbage back to the
+Realtek adapter. If the write_register() succeeds that's bad. Note
+that as of commit f53a7ad18959 ("r8152: Set memory to all 0xFFs on
+failed reg reads") the "garbage" returned by read_register() will at
+least be consistent garbage, but it is still garbage.
+
+It turns out that this problem is very serious. Writing garbage to
+some of the hardware registers on the Ethernet adapter can put the
+adapter in such a bad state that it needs to be power cycled (fully
+unplugged and plugged in again) before it can enumerate again.
+
+The second problem is that the r8152 driver generally has functions
+that are long sequences of register writes. Assuming everything will
+be OK if a random register write fails in the middle isn't a great
+assumption.
+
+One might wonder if the above two problems are real. You could ask if
+we would really have a successful write after a failed read. It turns
+out that the answer appears to be "yes, this can happen". In fact,
+we've seen at least two distinct failure modes where this happens.
+
+On a sc7180-trogdor Chromebook if you drop into kdb for a while and
+then resume, you can see:
+1. We get a "Tx timeout"
+2. The "Tx timeout" queues up a USB reset.
+3. In rtl8152_pre_reset() we try to reinit the hardware.
+4. The first several (2-9) register accesses fail with a timeout, then
+ things recover.
+
+The above test case was actually fixed by the patch ("r8152: Increase
+USB control msg timeout to 5000ms as per spec") but at least shows
+that we really can see successful calls after failed ones.
+
+On a different (AMD) based Chromebook with a particular adapter, we
+found that during reboot tests we'd also sometimes get a transitory
+failure. In this case we saw -EPIPE being returned sometimes. Retrying
+worked, but retrying is not always safe for all register accesses
+since reading/writing some registers might have side effects (like
+registers that clear on read).
+
+Let's fully lock out all register access if a register access fails.
+When we do this, we'll try to queue up a USB reset and try to unlock
+register access after the reset. This is slightly tricker than it
+sounds since the r8152 driver has an optimized reset sequence that
+only works reliably after probe happens. In order to handle this, we
+avoid the optimized reset if probe didn't finish. Instead, we simply
+retry the probe routine in this case.
+
+When locking out access, we'll use the existing infrastructure that
+the driver was using when it detected we were unplugged. This keeps us
+from getting stuck in delay loops in some parts of the driver.
+
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Grant Grundler <grundler@chromium.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 19440600e729 ("r8152: handle the return value of usb_reset_device()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/r8152.c | 207 ++++++++++++++++++++++++++++++++++------
+ 1 file changed, 176 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index f730f6a797e767..e8a69d3d418379 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -772,6 +772,9 @@ enum rtl8152_flags {
+ SCHEDULE_TASKLET,
+ GREEN_ETHERNET,
+ RX_EPROTO,
++ IN_PRE_RESET,
++ PROBED_WITH_NO_ERRORS,
++ PROBE_SHOULD_RETRY,
+ };
+
+ #define DEVICE_ID_LENOVO_USB_C_TRAVEL_HUB 0x721e
+@@ -952,6 +955,8 @@ struct r8152 {
+ u8 version;
+ u8 duplex;
+ u8 autoneg;
++
++ unsigned int reg_access_reset_count;
+ };
+
+ /**
+@@ -1199,6 +1204,96 @@ static unsigned int agg_buf_sz = 16384;
+
+ #define RTL_LIMITED_TSO_SIZE (size_to_mtu(agg_buf_sz) - sizeof(struct tx_desc))
+
++/* If register access fails then we block access and issue a reset. If this
++ * happens too many times in a row without a successful access then we stop
++ * trying to reset and just leave access blocked.
++ */
++#define REGISTER_ACCESS_MAX_RESETS 3
++
++static void rtl_set_inaccessible(struct r8152 *tp)
++{
++ set_bit(RTL8152_INACCESSIBLE, &tp->flags);
++ smp_mb__after_atomic();
++}
++
++static void rtl_set_accessible(struct r8152 *tp)
++{
++ clear_bit(RTL8152_INACCESSIBLE, &tp->flags);
++ smp_mb__after_atomic();
++}
++
++static
++int r8152_control_msg(struct r8152 *tp, unsigned int pipe, __u8 request,
++ __u8 requesttype, __u16 value, __u16 index, void *data,
++ __u16 size, const char *msg_tag)
++{
++ struct usb_device *udev = tp->udev;
++ int ret;
++
++ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
++ return -ENODEV;
++
++ ret = usb_control_msg(udev, pipe, request, requesttype,
++ value, index, data, size,
++ USB_CTRL_GET_TIMEOUT);
++
++ /* No need to issue a reset to report an error if the USB device got
++ * unplugged; just return immediately.
++ */
++ if (ret == -ENODEV)
++ return ret;
++
++ /* If the write was successful then we're done */
++ if (ret >= 0) {
++ tp->reg_access_reset_count = 0;
++ return ret;
++ }
++
++ dev_err(&udev->dev,
++ "Failed to %s %d bytes at %#06x/%#06x (%d)\n",
++ msg_tag, size, value, index, ret);
++
++ /* Block all future register access until we reset. Much of the code
++ * in the driver doesn't check for errors. Notably, many parts of the
++ * driver do a read/modify/write of a register value without
++ * confirming that the read succeeded. Writing back modified garbage
++ * like this can fully wedge the adapter, requiring a power cycle.
++ */
++ rtl_set_inaccessible(tp);
++
++ /* If probe hasn't yet finished, then we'll request a retry of the
++ * whole probe routine if we get any control transfer errors. We
++ * never have to clear this bit since we free/reallocate the whole "tp"
++ * structure if we retry probe.
++ */
++ if (!test_bit(PROBED_WITH_NO_ERRORS, &tp->flags)) {
++ set_bit(PROBE_SHOULD_RETRY, &tp->flags);
++ return ret;
++ }
++
++ /* Failing to access registers in pre-reset is not surprising since we
++ * wouldn't be resetting if things were behaving normally. The register
++ * access we do in pre-reset isn't truly mandatory--we're just reusing
++ * the disable() function and trying to be nice by powering the
++ * adapter down before resetting it. Thus, if we're in pre-reset,
++ * we'll return right away and not try to queue up yet another reset.
++ * We know the post-reset is already coming.
++ */
++ if (test_bit(IN_PRE_RESET, &tp->flags))
++ return ret;
++
++ if (tp->reg_access_reset_count < REGISTER_ACCESS_MAX_RESETS) {
++ usb_queue_reset_device(tp->intf);
++ tp->reg_access_reset_count++;
++ } else if (tp->reg_access_reset_count == REGISTER_ACCESS_MAX_RESETS) {
++ dev_err(&udev->dev,
++ "Tried to reset %d times; giving up.\n",
++ REGISTER_ACCESS_MAX_RESETS);
++ }
++
++ return ret;
++}
++
+ static
+ int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
+ {
+@@ -1209,9 +1304,10 @@ int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
+ if (!tmp)
+ return -ENOMEM;
+
+- ret = usb_control_msg(tp->udev, tp->pipe_ctrl_in,
+- RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
+- value, index, tmp, size, USB_CTRL_GET_TIMEOUT);
++ ret = r8152_control_msg(tp, tp->pipe_ctrl_in,
++ RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
++ value, index, tmp, size, "read");
++
+ if (ret < 0)
+ memset(data, 0xff, size);
+ else
+@@ -1232,9 +1328,9 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
+ if (!tmp)
+ return -ENOMEM;
+
+- ret = usb_control_msg(tp->udev, tp->pipe_ctrl_out,
+- RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE,
+- value, index, tmp, size, USB_CTRL_SET_TIMEOUT);
++ ret = r8152_control_msg(tp, tp->pipe_ctrl_out,
++ RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE,
++ value, index, tmp, size, "write");
+
+ kfree(tmp);
+
+@@ -1243,10 +1339,8 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
+
+ static void rtl_set_unplug(struct r8152 *tp)
+ {
+- if (tp->udev->state == USB_STATE_NOTATTACHED) {
+- set_bit(RTL8152_INACCESSIBLE, &tp->flags);
+- smp_mb__after_atomic();
+- }
++ if (tp->udev->state == USB_STATE_NOTATTACHED)
++ rtl_set_inaccessible(tp);
+ }
+
+ static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size,
+@@ -8295,7 +8389,7 @@ static int rtl8152_pre_reset(struct usb_interface *intf)
+ struct r8152 *tp = usb_get_intfdata(intf);
+ struct net_device *netdev;
+
+- if (!tp)
++ if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags))
+ return 0;
+
+ netdev = tp->netdev;
+@@ -8310,7 +8404,9 @@ static int rtl8152_pre_reset(struct usb_interface *intf)
+ napi_disable(&tp->napi);
+ if (netif_carrier_ok(netdev)) {
+ mutex_lock(&tp->control);
++ set_bit(IN_PRE_RESET, &tp->flags);
+ tp->rtl_ops.disable(tp);
++ clear_bit(IN_PRE_RESET, &tp->flags);
+ mutex_unlock(&tp->control);
+ }
+
+@@ -8323,9 +8419,11 @@ static int rtl8152_post_reset(struct usb_interface *intf)
+ struct net_device *netdev;
+ struct sockaddr sa;
+
+- if (!tp)
++ if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags))
+ return 0;
+
++ rtl_set_accessible(tp);
++
+ /* reset the MAC address in case of policy change */
+ if (determine_ethernet_addr(tp, &sa) >= 0) {
+ rtnl_lock();
+@@ -9527,17 +9625,29 @@ static u8 __rtl_get_hw_ver(struct usb_device *udev)
+ __le32 *tmp;
+ u8 version;
+ int ret;
++ int i;
+
+ tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+ if (!tmp)
+ return 0;
+
+- ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+- RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
+- PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp),
+- USB_CTRL_GET_TIMEOUT);
+- if (ret > 0)
+- ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK;
++ /* Retry up to 3 times in case there is a transitory error. We do this
++ * since retrying a read of the version is always safe and this
++ * function doesn't take advantage of r8152_control_msg().
++ */
++ for (i = 0; i < 3; i++) {
++ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
++ RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
++ PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp),
++ USB_CTRL_GET_TIMEOUT);
++ if (ret > 0) {
++ ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK;
++ break;
++ }
++ }
++
++ if (i != 0 && ret > 0)
++ dev_warn(&udev->dev, "Needed %d retries to read version\n", i);
+
+ kfree(tmp);
+
+@@ -9636,25 +9746,14 @@ static bool rtl8152_supports_lenovo_macpassthru(struct usb_device *udev)
+ return 0;
+ }
+
+-static int rtl8152_probe(struct usb_interface *intf,
+- const struct usb_device_id *id)
++static int rtl8152_probe_once(struct usb_interface *intf,
++ const struct usb_device_id *id, u8 version)
+ {
+ struct usb_device *udev = interface_to_usbdev(intf);
+ struct r8152 *tp;
+ struct net_device *netdev;
+- u8 version;
+ int ret;
+
+- if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
+- return -ENODEV;
+-
+- if (!rtl_check_vendor_ok(intf))
+- return -ENODEV;
+-
+- version = rtl8152_get_version(intf);
+- if (version == RTL_VER_UNKNOWN)
+- return -ENODEV;
+-
+ usb_reset_device(udev);
+ netdev = alloc_etherdev(sizeof(struct r8152));
+ if (!netdev) {
+@@ -9818,10 +9917,20 @@ static int rtl8152_probe(struct usb_interface *intf,
+ else
+ device_set_wakeup_enable(&udev->dev, false);
+
++ /* If we saw a control transfer error while probing then we may
++ * want to try probe() again. Consider this an error.
++ */
++ if (test_bit(PROBE_SHOULD_RETRY, &tp->flags))
++ goto out2;
++
++ set_bit(PROBED_WITH_NO_ERRORS, &tp->flags);
+ netif_info(tp, probe, netdev, "%s\n", DRIVER_VERSION);
+
+ return 0;
+
++out2:
++ unregister_netdev(netdev);
++
+ out1:
+ tasklet_kill(&tp->tx_tl);
+ cancel_delayed_work_sync(&tp->hw_phy_work);
+@@ -9830,10 +9939,46 @@ static int rtl8152_probe(struct usb_interface *intf,
+ rtl8152_release_firmware(tp);
+ usb_set_intfdata(intf, NULL);
+ out:
++ if (test_bit(PROBE_SHOULD_RETRY, &tp->flags))
++ ret = -EAGAIN;
++
+ free_netdev(netdev);
+ return ret;
+ }
+
++#define RTL8152_PROBE_TRIES 3
++
++static int rtl8152_probe(struct usb_interface *intf,
++ const struct usb_device_id *id)
++{
++ u8 version;
++ int ret;
++ int i;
++
++ if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
++ return -ENODEV;
++
++ if (!rtl_check_vendor_ok(intf))
++ return -ENODEV;
++
++ version = rtl8152_get_version(intf);
++ if (version == RTL_VER_UNKNOWN)
++ return -ENODEV;
++
++ for (i = 0; i < RTL8152_PROBE_TRIES; i++) {
++ ret = rtl8152_probe_once(intf, id, version);
++ if (ret != -EAGAIN)
++ break;
++ }
++ if (ret == -EAGAIN) {
++ dev_err(&intf->dev,
++ "r8152 failed probe after %d tries; giving up\n", i);
++ return -ENODEV;
++ }
++
++ return ret;
++}
++
+ static void rtl8152_disconnect(struct usb_interface *intf)
+ {
+ struct r8152 *tp = usb_get_intfdata(intf);
+--
+2.53.0
+
--- /dev/null
+From 50f11c2e6edffc77ecadd2914f58b1f652dc6559 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 17:22:47 +0800
+Subject: r8152: handle the return value of usb_reset_device()
+
+From: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+
+[ Upstream commit 19440600e729d4f74a42591a872099cf25c7d28a ]
+
+If usb_reset_device() returns a negative error code, stop the
+process of probing.
+
+Fixes: 10c3271712f5 ("r8152: disable the ECM mode")
+Signed-off-by: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+Reviewed-by: Hayes Wang <hayeswang@realtek.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20260604092247.27158-450-nic_swsd@realtek.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/r8152.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index e8a69d3d418379..c0f7a15e406fee 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -9754,7 +9754,12 @@ static int rtl8152_probe_once(struct usb_interface *intf,
+ struct net_device *netdev;
+ int ret;
+
+- usb_reset_device(udev);
++ ret = usb_reset_device(udev);
++ if (ret < 0) {
++ dev_err(&intf->dev, "USB reset failed, errno=%d\n", ret);
++ return ret;
++ }
++
+ netdev = alloc_etherdev(sizeof(struct r8152));
+ if (!netdev) {
+ dev_err(&intf->dev, "Out of memory\n");
+--
+2.53.0
+
--- /dev/null
+From 6f1fc466faaa20bcd9c1c90a3952eaadf4f56568 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Jan 2023 15:40:43 +0800
+Subject: r8152: reduce the control transfer of rtl8152_get_version()
+
+From: Hayes Wang <hayeswang@realtek.com>
+
+[ Upstream commit 02767440e1dda9861a11ca1dbe0f19a760b1d5c2 ]
+
+Reduce the control transfer by moving calling rtl8152_get_version() in
+rtl8152_probe(). This could prevent from calling rtl8152_get_version()
+for unnecessary situations. For example, after setting config #2 for the
+device, there are two interfaces and rtl8152_probe() may be called
+twice. However, we don't need to call rtl8152_get_version() for this
+situation.
+
+Signed-off-by: Hayes Wang <hayeswang@realtek.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 19440600e729 ("r8152: handle the return value of usb_reset_device()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/r8152.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index 98e30291b0500b..f730f6a797e767 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -9640,20 +9640,21 @@ static int rtl8152_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+ {
+ struct usb_device *udev = interface_to_usbdev(intf);
+- u8 version = rtl8152_get_version(intf);
+ struct r8152 *tp;
+ struct net_device *netdev;
++ u8 version;
+ int ret;
+
+- if (version == RTL_VER_UNKNOWN)
+- return -ENODEV;
+-
+ if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
+ return -ENODEV;
+
+ if (!rtl_check_vendor_ok(intf))
+ return -ENODEV;
+
++ version = rtl8152_get_version(intf);
++ if (version == RTL_VER_UNKNOWN)
++ return -ENODEV;
++
+ usb_reset_device(udev);
+ netdev = alloc_etherdev(sizeof(struct r8152));
+ if (!netdev) {
+--
+2.53.0
+
--- /dev/null
+From a8876c0734d785a00a9259a169ba42275c836105 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 02:32:05 -0700
+Subject: rds: mark snapshot pages dirty in rds_info_getsockopt()
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 512db8267b73a220a64180d95ab5eebe7c4964a8 ]
+
+rds_info_getsockopt() pins the destination user pages with FOLL_WRITE and
+the RDS_INFO_* producers memcpy the snapshot into them through
+kmap_atomic(). Because that copy goes through the kernel direct map, the
+dirty bit on the user PTE is never set, so unpin_user_pages() releases the
+pages without marking them dirty. A file-backed destination page can then
+be reclaimed without writeback, silently discarding the copied data.
+
+Use unpin_user_pages_dirty_lock() with make_dirty=true so the modified
+pages are marked dirty before they are unpinned.
+
+Fixes: a8c879a7ee98 ("RDS: Info and stats")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260608-rds_fix-v1-1-006c88543408@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/info.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/rds/info.c b/net/rds/info.c
+index b6b46a8214a0a5..b3ee5f8238c44d 100644
+--- a/net/rds/info.c
++++ b/net/rds/info.c
+@@ -235,7 +235,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
+
+ out:
+ if (pages)
+- unpin_user_pages(pages, nr_pages);
++ unpin_user_pages_dirty_lock(pages, nr_pages, true);
+ kfree(pages);
+
+ return ret;
+--
+2.53.0
+
--- /dev/null
+From 2dc72968d8d246492fb1ef6bcb469fd15222ebee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 08:22:34 -0400
+Subject: sctp: fix uninit-value in __sctp_rcv_asconf_lookup()
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit f8373d7090b745728de66308deeecc67e8d319ce ]
+
+__sctp_rcv_asconf_lookup() in net/sctp/input.c only checks that the ASCONF
+chunk can hold the ADDIP header and a parameter header, then calls
+af->from_addr_param(), which reads the full address (16 bytes for IPv6)
+trusting the parameter's declared length.
+
+An unauthenticated peer can send a truncated trailing ASCONF chunk that
+declares an IPv6 address parameter but stops after the 4-byte parameter
+header; reached from the no-association lookup path, from_addr_param() then
+reads uninitialized bytes past the parameter.
+
+Impact: an unauthenticated SCTP peer makes the receive path read up to 16
+bytes of uninitialized memory past a truncated ASCONF address parameter.
+
+The sibling __sctp_rcv_init_lookup() bounds parameters with
+sctp_walk_params(); this path open-codes the fetch and omits the bound.
+Verify the whole address parameter lies within the chunk before
+from_addr_param() reads it, the same class of fix as commit 51e5ad549c43
+("net: sctp: fix KMSAN uninit-value in sctp_inq_pop").
+
+Fixes: df2185771439 ("[SCTP]: Update association lookup to look at ASCONF chunks as well")
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260608122234.459098-1-michael.bommarito@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/input.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/sctp/input.c b/net/sctp/input.c
+index 182898cb754a52..70530cbe57d0a7 100644
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -1197,6 +1197,14 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
+ /* Skip over the ADDIP header and find the Address parameter */
+ param = (union sctp_addr_param *)(asconf + 1);
+
++ /* The whole address parameter must lie within the chunk before
++ * af->from_addr_param() reads the variable-length address; otherwise a
++ * truncated trailing ASCONF chunk lets it read uninitialized bytes past
++ * the parameter.
++ */
++ if (sizeof(*asconf) + ntohs(param->p.length) > ntohs(ch->length))
++ return NULL;
++
+ af = sctp_get_af_specific(param_type2af(param->p.type));
+ if (unlikely(!af))
+ return NULL;
+--
+2.53.0
+
kvm-arm64-remove-vpipt-i-cache-handling.patch
arm64-tlb-allow-xzr-argument-to-tlbi-ops.patch
arm64-tlb-optimize-arm64_workaround_repeat_tlbi.patch
+iomap-don-t-revert-iov_iter-on-partially-completed-b.patch
+xfrm-policy-fix-use-after-free-on-inexact-bin-in-xfr.patch
+netlabel-validate-unlabeled-address-and-mask-attribu.patch
+asoc-wm_adsp-fix-null-dereference-when-removing-firm.patch
+tcp-restrict-so_attach_filter-to-priv-users.patch
+net-mlx4-avoid-gcc-10-__bad_copy_from-false-positive.patch
+net-qrtr-fix-refcount-saturation-and-potential-uaf-i.patch
+ipv6-sit-reload-inner-ipv6-header-after-gso-offloads.patch
+net-openvswitch-fix-possible-kfree_skb-of-err_ptr.patch
+r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch
+r8152-block-future-register-access-if-register-acces.patch
+r8152-handle-the-return-value-of-usb_reset_device.patch
+sctp-fix-uninit-value-in-__sctp_rcv_asconf_lookup.patch
+net-guard-timestamp-cmsgs-to-real-error-queue-skbs.patch
+net-rds-fix-null-deref-in-rds_ib_send_cqe_handler-on.patch
+ip6_vti-fix-incorrect-tunnel-matching-in-vti6_tnl_lo.patch
+rds-mark-snapshot-pages-dirty-in-rds_info_getsockopt.patch
+netfilter-nf_conntrack-destroy-stale-expectfn-expect.patch
+netfilter-x_tables-avoid-leaking-percpu-counter-poin.patch
+netfilter-nf_log-validate-mac-header-was-set-before-.patch
+netfilter-nft_exthdr-fix-register-tracking-for-f_pre.patch
+net-mvpp2-sync-rx-data-at-the-hardware-packet-offset.patch
+net-mvpp2-limit-xdp-frame-size-to-the-rx-buffer.patch
+net-mvpp2-add-metadata-support-for-xdp-mode.patch
+net-mvpp2-refill-rx-buffers-before-xdp-or-skb-use.patch
+net-mvpp2-build-skb-from-xdp-adjusted-data-on-xdp_pa.patch
--- /dev/null
+From 6e6cbe7fb7e97b3567fa3c2cc312f85d125ed771 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 11:21:34 +0000
+Subject: tcp: restrict SO_ATTACH_FILTER to priv users
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 5d39580f68e6ddeedd15e587282207489dfb3da2 ]
+
+This patch restricts the use of SO_ATTACH_FILTER (cBPF) on TCP sockets
+to users with CAP_NET_ADMIN capability.
+
+This blocks potential side-channel attack where an unprivileged application
+attaches a filter to leak TCP sequence/acknowledgment numbers.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Tamir Shahar <tamirthesis@gmail.com>
+Reported-by: Amit Klein <aksecurity@gmail.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Andrii Nakryiko <andrii@kernel.org>
+Cc: Martin KaFai Lau <martin.lau@linux.dev>
+Cc: Eduard Zingerman <eddyz87@gmail.com>
+Cc: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Cc: Song Liu <song@kernel.org>
+Cc: Yonghong Song <yonghong.song@linux.dev>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: Stanislav Fomichev <sdf@fomichev.me>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 62411c8870e855..5f79f0b78321c8 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1294,6 +1294,11 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
+ case SO_ATTACH_FILTER: {
+ struct sock_fprog fprog;
+
++ if (sk_is_tcp(sk) &&
++ !sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
++ ret = -EPERM;
++ break;
++ }
+ ret = copy_bpf_fprog_from_user(&fprog, optval, optlen);
+ if (!ret)
+ ret = sk_attach_filter(&fprog, sk);
+--
+2.53.0
+
--- /dev/null
+From 59dea7d990068f4d89c2828c6a2d971547058813 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 18:49:05 +0900
+Subject: xfrm: policy: fix use-after-free on inexact bin in
+ xfrm_policy_bysel_ctx()
+
+From: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+
+[ Upstream commit 7f2d76c9c03257c0782afef9d95321fa04096f60 ]
+
+Fix the race by pruning the bin while still holding xfrm_policy_lock,
+before dropping it. Use __xfrm_policy_inexact_prune_bin() directly since
+the lock is already held. The wrapper xfrm_policy_inexact_prune_bin()
+becomes unused and is removed.
+
+Race:
+
+ CPU0 (XFRM_MSG_DELPOLICY) CPU1 (XFRM_MSG_NEWSPDINFO)
+ ========================== ==========================
+ xfrm_policy_bysel_ctx():
+ spin_lock_bh(xfrm_policy_lock)
+ bin = xfrm_policy_inexact_lookup()
+ __xfrm_policy_unlink(pol)
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_kill(ret)
+ // wide window, lock not held
+ xfrm_hash_rebuild():
+ spin_lock_bh(xfrm_policy_lock)
+ __xfrm_policy_inexact_flush():
+ kfree_rcu(bin) // bin freed
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_inexact_prune_bin(bin)
+ // UAF: bin is freed
+
+Fixes: 6be3b0db6db8 ("xfrm: policy: add inexact policy search tree infrastructure")
+Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index cebbb47f701f47..aeb994f96192cd 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1124,15 +1124,6 @@ static void __xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b, bool
+ }
+ }
+
+-static void xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b)
+-{
+- struct net *net = read_pnet(&b->k.net);
+-
+- spin_lock_bh(&net->xfrm.xfrm_policy_lock);
+- __xfrm_policy_inexact_prune_bin(b, false);
+- spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+-}
+-
+ static void __xfrm_policy_inexact_flush(struct net *net)
+ {
+ struct xfrm_pol_inexact_bin *bin, *t;
+@@ -1723,12 +1714,12 @@ xfrm_policy_bysel_ctx(struct net *net, const struct xfrm_mark *mark, u32 if_id,
+ }
+ ret = pol;
+ }
++ if (bin && delete)
++ __xfrm_policy_inexact_prune_bin(bin, false);
+ spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+
+ if (ret && delete)
+ xfrm_policy_kill(ret);
+- if (bin && delete)
+- xfrm_policy_inexact_prune_bin(bin);
+ return ret;
+ }
+ EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
+--
+2.53.0
+
--- /dev/null
+From 660cca34c8f2c47f6619bcc86880694b4c25b7c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 11:12:44 +0100
+Subject: ASoC: wm_adsp: Fix NULL dereference when removing firmware controls
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 7d3fb78b550301e43fdc60312aed733069694426 ]
+
+In wm_adsp_control_remove() check that the priv pointer is not NULL
+before attempting to cleanup what it points to.
+
+When cs_dsp creates a control it calls wm_adsp_control_add_cb() so that
+wm_adsp can create its own private control data. There are two cases
+where private data is not created:
+
+1. The control is a SYSTEM control, so an ALSA control is not created.
+
+2. The codec driver has registered a control_add() callback that
+ hides the control, so wm_adsp_control_add() is not called.
+
+When cs_dsp_remove destroys its control list it calls
+wm_adsp_control_remove() for each control. But wm_adsp_control_remove()
+was attempting to cleanup the private data pointed to by cs_ctl->priv
+without checking the pointer for NULL.
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Fixes: 0700bc2fb94c ("ASoC: wm_adsp: Separate generic cs_dsp_coeff_ctl handling")
+Link: https://patch.msgid.link/20260604101244.1402862-1-rf@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/wm_adsp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
+index e69283195f362f..5d5d1c0c9b936b 100644
+--- a/sound/soc/codecs/wm_adsp.c
++++ b/sound/soc/codecs/wm_adsp.c
+@@ -674,6 +674,9 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl)
+ {
+ struct wm_coeff_ctl *ctl = cs_ctl->priv;
+
++ if (!ctl)
++ return;
++
+ cancel_work_sync(&ctl->work);
+
+ kfree(ctl->name);
+--
+2.53.0
+
--- /dev/null
+From 5fa724b94c77a6647f71a7bb053717938b04d6ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 20:37:08 +0800
+Subject: dma-debug: fix physical address retrieval in
+ debug_dma_sync_sg_for_device
+
+From: Li RongQing <lirongqing@baidu.com>
+
+[ Upstream commit 9bfaa86b405381326c971984fd6da184c289713f ]
+
+In debug_dma_sync_sg_for_device(), when iterating over a scatterlist,
+the debug entry population mistakenly uses the head of the scatterlist
+'sg' to fetch the physical address via sg_phys(), instead of using the
+current iterator variable 's'.
+
+This causes dma-debug to track the physical address of the very first
+scatterlist entry for all subsequent entries in the list.
+
+Fix this by passing the correct loop iterator 's' to sg_phys()
+
+Fixes: 9d4f645a1fd49ee ("dma-debug: store a phys_addr_t in struct dma_debug_entry")
+Signed-off-by: Li RongQing <lirongqing@baidu.com>
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20260603123708.1665-1-lirongqing@baidu.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/dma/debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c
+index 035dda07ab0d08..b1192cff035924 100644
+--- a/kernel/dma/debug.c
++++ b/kernel/dma/debug.c
+@@ -1573,7 +1573,7 @@ void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+ struct dma_debug_entry ref = {
+ .type = dma_debug_sg,
+ .dev = dev,
+- .paddr = sg_phys(sg),
++ .paddr = sg_phys(s),
+ .dev_addr = sg_dma_address(s),
+ .size = sg_dma_len(s),
+ .direction = direction,
+--
+2.53.0
+
--- /dev/null
+From 2b7ce7615d2f7b88c34eb5bb8b1b7fe1b4a725f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 16:43:34 +0800
+Subject: gpio: mvebu: fix NULL pointer dereference in suspend/resume
+
+From: Yun Zhou <yun.zhou@windriver.com>
+
+[ Upstream commit b9ad50d7505ebd48282ec3630258dc820fc85c81 ]
+
+mvebu_pwm_suspend() and mvebu_pwm_resume() are called for all GPIO
+banks during suspend/resume, but not all banks have PWM functionality.
+GPIO banks without PWM have mvchip->mvpwm set to NULL.
+
+Calling mvebu_pwm_suspend() with mvpwm == NULL causes a NULL pointer
+dereference when it tries to access mvpwm->blink_select.
+
+ Unable to handle kernel NULL pointer dereference at virtual address 00000020 when write
+ [00000020] *pgd=00000000
+ Internal error: Oops: 815 [#1] PREEMPT ARM
+ Modules linked in:
+ CPU: 0 UID: 0 PID: 406 Comm: sh Not tainted 6.12.74-rt12-yocto-standard-g4e96f98fb7db-dirty #353
+ Hardware name: Marvell Armada 370/XP (Device Tree)
+ PC is at regmap_mmio_read+0x38/0x54
+ LR is at regmap_mmio_read+0x38/0x54
+ pc : [<c05fd2ac>] lr : [<c05fd2ac>] psr: 200f0013
+ sp : f0c11d10 ip : 00000000 fp : c100d2f0
+ r10: c14fb854 r9 : 00000000 r8 : 00000000
+ r7 : c1799c00 r6 : 00000020 r5 : 00000020 r4 : c179c7c0
+ r3 : f0a231a0 r2 : 00000020 r1 : 00000020 r0 : 00000000
+ Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
+ Control: 10c5387d Table: 135ec059 DAC: 00000051
+ Call trace:
+ regmap_mmio_read from _regmap_bus_reg_read+0x78/0xac
+ _regmap_bus_reg_read from _regmap_read+0x60/0x154
+ _regmap_read from regmap_read+0x3c/0x60
+ regmap_read from mvebu_gpio_suspend+0xa4/0x14c
+ mvebu_gpio_suspend from dpm_run_callback+0x54/0x180
+ dpm_run_callback from device_suspend+0x124/0x630
+ device_suspend from dpm_suspend+0x124/0x270
+ dpm_suspend from dpm_suspend_start+0x64/0x6c
+ dpm_suspend_start from suspend_devices_and_enter+0x140/0x8e8
+ suspend_devices_and_enter from pm_suspend+0x2fc/0x308
+ pm_suspend from state_store+0x6c/0xc8
+ state_store from kernfs_fop_write_iter+0x10c/0x1f8
+ kernfs_fop_write_iter from vfs_write+0x270/0x468
+ vfs_write from ksys_write+0x70/0xf0
+ ksys_write from ret_fast_syscall+0x0/0x54
+
+Add a NULL check for mvchip->mvpwm before calling the PWM
+suspend/resume functions.
+
+Fixes: 757642f9a584 ("gpio: mvebu: Add limited PWM support")
+Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
+Link: https://patch.msgid.link/20260608084334.2960803-1-yun.zhou@windriver.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-mvebu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
+index 8cfd3a89c0184d..c85ab356bc72a9 100644
+--- a/drivers/gpio/gpio-mvebu.c
++++ b/drivers/gpio/gpio-mvebu.c
+@@ -1002,7 +1002,7 @@ static int mvebu_gpio_suspend(struct platform_device *pdev, pm_message_t state)
+ BUG();
+ }
+
+- if (IS_REACHABLE(CONFIG_PWM))
++ if (IS_REACHABLE(CONFIG_PWM) && mvchip->mvpwm)
+ mvebu_pwm_suspend(mvchip);
+
+ return 0;
+@@ -1054,7 +1054,7 @@ static int mvebu_gpio_resume(struct platform_device *pdev)
+ BUG();
+ }
+
+- if (IS_REACHABLE(CONFIG_PWM))
++ if (IS_REACHABLE(CONFIG_PWM) && mvchip->mvpwm)
+ mvebu_pwm_resume(mvchip);
+
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From a37f9cf60ced2d195b1c96cbc77dd73581a66650 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 15:33:13 +0800
+Subject: gpio: zynq: fix runtime PM leak on remove
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit 6edb934de9bda3b7abcec856eaee6fc8b4278dd1 ]
+
+pm_runtime_get_sync() increments the runtime PM usage counter even when it
+returns an error. zynq_gpio_remove() uses it to keep the controller active
+while removing the GPIO chip, but never drops the usage counter again.
+
+Balance the get with pm_runtime_put_noidle() after disabling runtime PM.
+
+Fixes: 3242ba117e9b ("gpio: Add driver for Zynq GPIO controller")
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Link: https://patch.msgid.link/20260609073313.5-1-ruoyuw560@gmail.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-zynq.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c
+index cc53e6940ad7e6..50fa4938161dde 100644
+--- a/drivers/gpio/gpio-zynq.c
++++ b/drivers/gpio/gpio-zynq.c
+@@ -1015,6 +1015,7 @@ static void zynq_gpio_remove(struct platform_device *pdev)
+ gpiochip_remove(&gpio->chip);
+ device_set_wakeup_capable(&pdev->dev, 0);
+ pm_runtime_disable(&pdev->dev);
++ pm_runtime_put_noidle(&pdev->dev);
+ }
+
+ static struct platform_driver zynq_gpio_driver = {
+--
+2.53.0
+
--- /dev/null
+From 69f85fcb83ec012b74fcc5b43100e7a4f2f4b26d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 08:10:47 -0400
+Subject: iomap: don't revert iov_iter on partially completed buffered writes
+
+From: Brian Foster <bfoster@redhat.com>
+
+Gregg reports that the iomap retry behavior for nonblocking (nowait)
+append writes is broken. The problem occurs when an append write is
+first submitted in non-blocking mode (i.e. via io_uring), partially
+completes before hitting -EAGAIN, and then is resubmitted from
+blocking context.
+
+The specific problem is that at least one iteration of the loop in
+iomap_write_iter() completes in non-blocking context and thus has
+bumped i_size. The next iteration hits -EAGAIN, reverts the iov_iter
+and returns. io_uring retries the entire append write from blocking
+context, but since i_size has already been increased, the data that
+was partially written on the first attempt is rewritten at the new
+i_size. This is essentially an intra-write data corruption since the
+data written to the file does not reflect the write from userspace.
+
+This problem is already fixed on master as of commit 1a1a3b574b97
+("iomap: advance the iter directly on buffered writes"). That commit
+was primarily intended to clean up iomap iter state tracking, but it
+also happened to remove the iov_iter revert and thus accidentally
+fix this problem as well. Without the revert, iomap will commit
+partial progress internally and loop once more before it more than
+likely hits -EAGAIN and returns partial progress consistent with the
+inode updates. This means the blocking retry from io_uring will pick
+up where the first attempt left off at the current i_size and
+perform the remainder of the write correctly.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 18e419f6e80a ("iomap: Return -EAGAIN from iomap_write_iter()")
+Reported-by: Gregg Leventhal <gleventhal@janestreet.com>
+Reported-by: Eric Hagberg <ehagberg@janestreet.com>
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/iomap/buffered-io.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
+index 0178292c186485..5f885286b2f4a0 100644
+--- a/fs/iomap/buffered-io.c
++++ b/fs/iomap/buffered-io.c
+@@ -1037,10 +1037,6 @@ static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
+ }
+ } while (iov_iter_count(i) && length);
+
+- if (status == -EAGAIN) {
+- iov_iter_revert(i, total_written);
+- return -EAGAIN;
+- }
+ return total_written ? total_written : status;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 1f0ee433668038cf7e20d1efd74496a942ea72b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 16:46:13 +0000
+Subject: ip6_vti: fix incorrect tunnel matching in vti6_tnl_lookup()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit a5c0359f5cbc51a2e2b114d6041e0f3c73f903e9 ]
+
+In vti6_tnl_lookup(), when an exact match for a tunnel fails,
+the code falls back to searching for wildcard tunnels:
+
+- Tunnels matching the packet's local address, with any remote address
+ wildcard remote).
+
+- Tunnels matching the packet's remote address, with any local address
+ (wildcard local).
+
+However, vti6 stores all these different types of tunnels in the same
+hash table (ip6n->tnls_r_l) prone to hash collisions.
+
+The bug is that the fallback search loops in vti6_tnl_lookup() were
+missing checks to ensure that the candidate tunnel actually has
+a wildcard address.
+
+Fixes: fbe68ee87522 ("vti6: Add a lookup method for tunnels with wildcard endpoints.")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260608164613.933023-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_vti.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
+index 2ac88593a95427..6fe696939d041e 100644
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -105,6 +105,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(&any, local);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(local, &t->parms.laddr) &&
++ ipv6_addr_any(&t->parms.raddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+@@ -112,6 +113,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(remote, &any);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(remote, &t->parms.raddr) &&
++ ipv6_addr_any(&t->parms.laddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+--
+2.53.0
+
--- /dev/null
+From af07db0cc2273db4b62267b4e031dd6ea537c949 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 17:54:48 +0300
+Subject: ipv6: Fix a potential NPD in cleanup_prefix_route()
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit b70c687b7cf267fb08586667a3946c8851cad672 ]
+
+addrconf_get_prefix_route() can return the fib6_null_entry sentinel
+entry which has a NULL fib6_table pointer. Therefore, before setting the
+route's expiration time, check that we are not working with this entry,
+as otherwise a NPD will be triggered [1].
+
+Note that the other callers of addrconf_get_prefix_route() are not
+susceptible to this bug:
+
+1. addrconf_prefix_rcv(): Requests a route with the 'RTF_ADDRCONF |
+ RTF_PREFIX_RT' flags which are not set on fib6_null_entry.
+
+2. modify_prefix_route(): Fixed by commit a747e02430df ("ipv6: avoid
+ possible NULL deref in modify_prefix_route()").
+
+3. __ipv6_ifa_notify(): Calls ip6_del_rt() which specifically checks for
+ fib6_null_entry and returns an error.
+
+[1]
+Oops: general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] SMP KASAN
+KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037]
+[...]
+Call Trace:
+<TASK>
+__kasan_check_byte (mm/kasan/common.c:573)
+lock_acquire.part.0 (kernel/locking/lockdep.c:5842 (discriminator 1))
+_raw_spin_lock_bh (kernel/locking/spinlock.c:182 (discriminator 1))
+cleanup_prefix_route (net/ipv6/addrconf.c:1280)
+ipv6_del_addr (net/ipv6/addrconf.c:1342)
+inet6_addr_del.isra.0 (net/ipv6/addrconf.c:3119)
+inet6_rtm_deladdr (net/ipv6/addrconf.c:4812)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6997)
+netlink_rcv_skb (net/netlink/af_netlink.c:2555)
+netlink_unicast (net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1899)
+__sock_sendmsg (net/socket.c:802 (discriminator 4))
+____sys_sendmsg (net/socket.c:2698)
+___sys_sendmsg (net/socket.c:2752)
+__sys_sendmsg (net/socket.c:2784)
+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)
+
+Fixes: 5eb902b8e719 ("net/ipv6: Remove expired routes with a separated list of routes.")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Reviewed-by: David Ahern <dahern@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260609145448.768318-1-idosch@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/addrconf.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index e104ec8efe1c0c..c6fcdb60dfee14 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1259,6 +1259,7 @@ static void
+ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires,
+ bool del_rt, bool del_peer)
+ {
++ struct net *net = dev_net(ifp->idev->dev);
+ struct fib6_table *table;
+ struct fib6_info *f6i;
+
+@@ -1267,9 +1268,10 @@ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires,
+ ifp->idev->dev, 0, RTF_DEFAULT, true);
+ if (f6i) {
+ if (del_rt)
+- ip6_del_rt(dev_net(ifp->idev->dev), f6i, false);
++ ip6_del_rt(net, f6i, false);
+ else {
+- if (!(f6i->fib6_flags & RTF_EXPIRES)) {
++ if (f6i != net->ipv6.fib6_null_entry &&
++ !(f6i->fib6_flags & RTF_EXPIRES)) {
+ table = f6i->fib6_table;
+ spin_lock_bh(&table->tb6_lock);
+
+--
+2.53.0
+
--- /dev/null
+From fa97f62f7395c19518cca3dd7ab4a41b62c4398c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 00:34:48 -0700
+Subject: ipv6: sit: reload inner IPv6 header after GSO offloads
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f0e42f0c4337b1f220de1ddd63f47197c7dee4de ]
+
+ipip6_tunnel_xmit() caches the inner IPv6 header pointer at function
+entry and continues using it after iptunnel_handle_offloads().
+
+For GSO skbs, iptunnel_handle_offloads() calls skb_header_unclone().
+When the skb header is cloned, skb_header_unclone() can call
+pskb_expand_head(), which may move the skb head. The pskb_expand_head()
+contract requires pointers into the skb header to be reloaded after the
+call.
+
+If the later skb_realloc_headroom() branch is not taken, SIT uses the
+stale iph6 pointer to read the inner hop limit and DS field. That can
+read from a freed skb head after the old head's remaining clone is
+released.
+
+Reload iph6 after the offload helper succeeds and before subsequent
+reads from the inner IPv6 header. Keep the existing reload after
+skb_realloc_headroom(), since that branch can also replace the skb.
+
+Fixes: 14909664e4e1 ("sit: Setup and TX path for sit/UDP foo-over-udp encapsulation")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot+6eb9ca986d80f6f88cf9@syzkaller.appspotmail.com
+Link: https://patch.msgid.link/20260605073448.6524-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/sit.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index 3c15a0ae228e21..5c1982358aca5e 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -968,6 +968,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ ip_rt_put(rt);
+ goto tx_error;
+ }
++ iph6 = ipv6_hdr(skb);
+
+ if (df) {
+ mtu = dst_mtu(&rt->dst) - t_hlen;
+--
+2.53.0
+
--- /dev/null
+From 14ded45002a80124470c8f7dfe7db0d3e020c4c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:46:25 +0000
+Subject: net: add pskb_may_pull() to skb_gro_receive_list()
+
+From: HanQuan <eilaimemedsnaimel@gmail.com>
+
+[ Upstream commit f2bb3434544454099a5b6dec213567267b05d79d ]
+
+skb_gro_receive_list() calls skb_pull(skb, skb_gro_offset(skb)) without
+first ensuring the data is in the linear area via pskb_may_pull(). When
+the skb arrives via napi_gro_frags(), skb_headlen can be 0 (all data in
+page fragments) while skb_gro_offset is non-zero (after IP+TCP header
+parsing). The skb_pull() then decrements skb->len by skb_gro_offset
+but skb->data_len stays unchanged, hitting BUG_ON(skb->len < skb->data_len)
+in __skb_pull().
+
+The UDP fraglist GRO path already contains this guard at
+udp_offload.c:749. Adding it to skb_gro_receive_list() itself provides
+centralized protection for all callers (TCP, UDP, and any future
+protocols), and ensures the precondition of skb_pull() is satisfied
+before it is called.
+
+On pskb_may_pull() failure, set NAPI_GRO_CB(skb)->flush = 1 so the
+skb is not held as a new GRO head and is instead delivered through the
+normal receive path, matching the UDP handling.
+
+Fixes: 8d95dc474f85 ("net: add code for TCP fraglist GRO")
+Reported-by: HanQuan <eilaimemedsnaimel@gmail.com>
+Reported-by: MingXuan <bwnie0730@outlook.com>
+Signed-off-by: HanQuan <eilaimemedsnaimel@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/gro.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/core/gro.c b/net/core/gro.c
+index e4cebf162efb70..4e7b9848771edc 100644
+--- a/net/core/gro.c
++++ b/net/core/gro.c
+@@ -233,6 +233,11 @@ int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
+ if (unlikely(p->len + skb->len >= 65536))
+ return -E2BIG;
+
++ if (!pskb_may_pull(skb, skb_gro_offset(skb))) {
++ NAPI_GRO_CB(skb)->flush = 1;
++ return -ENOMEM;
++ }
++
+ if (NAPI_GRO_CB(p)->last == p)
+ skb_shinfo(p)->frag_list = skb;
+ else
+--
+2.53.0
+
--- /dev/null
+From 3e6310ef102ee1238c3fa73a3ccfc8d77c41e166 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 19:18:19 -0700
+Subject: net: guard timestamp cmsgs to real error queue skbs
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit 1ee90b77b727df903033db873c75caac5c27ec98 ]
+
+skb_is_err_queue() treats PACKET_OUTGOING as the sole marker for an skb
+from sk_error_queue. That assumption is not true for AF_PACKET sockets:
+outgoing packet taps are also delivered to packet sockets with
+skb->pkt_type == PACKET_OUTGOING, but their skb->cb is owned by AF_PACKET
+instead of struct sock_exterr_skb.
+
+If such an skb is received with timestamping enabled, the generic
+timestamp cmsg path can read AF_PACKET control-buffer state as
+sock_exterr_skb::opt_stats. With SO_RXQ_OVFL enabled, the packet drop
+counter overlaps opt_stats. An odd drop count makes the path emit
+SCM_TIMESTAMPING_OPT_STATS with skb->len and skb->data. For non-linear
+skbs this copies past the linear head and can trigger hardened usercopy or
+disclose adjacent heap contents.
+
+Keep skb_is_err_queue() local to net/socket.c, but make it verify that
+the PACKET_OUTGOING marker is paired with the sock_rmem_free destructor
+installed by sock_queue_err_skb(). AF_PACKET receive skbs use normal
+receive ownership and no longer pass as error-queue skbs, while legitimate
+sk_error_queue entries keep the PACKET_OUTGOING marker and sock_rmem_free
+ownership.
+
+Fixes: 8605330aac5a ("tcp: fix SCM_TIMESTAMPING_OPT_STATS for normal skbs")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260607021819.49698-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 1 +
+ net/core/skbuff.c | 6 +++---
+ net/socket.c | 11 ++++++-----
+ 3 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 6edd9cac500675..0d77a87929f938 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1806,6 +1806,7 @@ struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size,
+ gfp_t priority);
+ void skb_orphan_partial(struct sk_buff *skb);
+ void sock_rfree(struct sk_buff *skb);
++void sock_rmem_free(struct sk_buff *skb);
+ void sock_efree(struct sk_buff *skb);
+ #ifdef CONFIG_INET
+ void sock_edemux(struct sk_buff *skb);
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index fba5f06b94d9d6..4be699bd3a17f7 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -5384,7 +5384,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
+ }
+ EXPORT_SYMBOL_GPL(skb_cow_data);
+
+-static void sock_rmem_free(struct sk_buff *skb)
++void sock_rmem_free(struct sk_buff *skb)
+ {
+ struct sock *sk = skb->sk;
+
+@@ -5393,8 +5393,8 @@ static void sock_rmem_free(struct sk_buff *skb)
+
+ static void skb_set_err_queue(struct sk_buff *skb)
+ {
+- /* pkt_type of skbs received on local sockets is never PACKET_OUTGOING.
+- * So, it is safe to (mis)use it to mark skbs on the error queue.
++ /* The error-queue test in skb_is_err_queue() matches this marker
++ * with the sock_rmem_free destructor installed by sock_queue_err_skb().
+ */
+ skb->pkt_type = PACKET_OUTGOING;
+ BUILD_BUG_ON(PACKET_OUTGOING == 0);
+diff --git a/net/socket.c b/net/socket.c
+index 878155076bc0f8..5c5dd9f6605a94 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -804,12 +804,13 @@ EXPORT_SYMBOL(kernel_sendmsg_locked);
+
+ static bool skb_is_err_queue(const struct sk_buff *skb)
+ {
+- /* pkt_type of skbs enqueued on the error queue are set to
+- * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
+- * in recvmsg, since skbs received on a local socket will never
+- * have a pkt_type of PACKET_OUTGOING.
++ /* Error-queue skbs are marked as PACKET_OUTGOING in
++ * skb_set_err_queue() and use the destructor installed by
++ * sock_queue_err_skb(). PACKET_OUTGOING alone is not unique:
++ * AF_PACKET outgoing taps use the same pkt_type.
+ */
+- return skb->pkt_type == PACKET_OUTGOING;
++ return skb->pkt_type == PACKET_OUTGOING &&
++ skb->destructor == sock_rmem_free;
+ }
+
+ /* On transmit, software and hardware timestamps are returned independently.
+--
+2.53.0
+
--- /dev/null
+From 7cdf59dd61e0b808753cd6da2b584610d62f2e13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 15:12:17 -0700
+Subject: net: ibm: emac: Fix use-after-free during device removal
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit a0130d682222ae21afc395aead7cd2d87e1a8358 ]
+
+The driver was using devm_register_netdev() which causes unregister_netdev()
+to be deferred until the devres cleanup phase, which runs after emac_remove()
+returns. This creates a use-after-free window where:
+
+1. emac_remove() is called, which tears down hardware (cancels work, detaches
+ modules, unregisters from MAL)
+2. emac_remove() returns
+3. devres cleanup runs and finally calls unregister_netdev()
+
+During step 3, the network stack might still process packets, triggering
+emac_irq(), emac_poll(), or other handlers that access now-freed hardware
+resources (dev->emacp, dev->mal, etc.).
+
+Fix this by replacing devm_register_netdev() with manual register_netdev()
+and calling unregister_netdev() at the beginning of emac_remove(), before
+any hardware teardown. This ensures the network device is fully stopped and
+unregistered before hardware resources are released.
+
+The change is safe because:
+- dev->ndev is assigned very early in probe (before any error paths that
+ could bypass emac_remove)
+- platform_set_drvdata() is only called after successful registration, so
+ emac_remove() only runs for fully registered devices
+- unregister_netdev() is idempotent and safe to call on any registered device
+
+Fixes: a4dd8535a527 ("net: ibm: emac: use devm for register_netdev")
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/emac/core.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
+index dac570f3c11036..0db3f558c95bb1 100644
+--- a/drivers/net/ethernet/ibm/emac/core.c
++++ b/drivers/net/ethernet/ibm/emac/core.c
+@@ -3147,7 +3147,7 @@ static int emac_probe(struct platform_device *ofdev)
+
+ netif_carrier_off(ndev);
+
+- err = devm_register_netdev(&ofdev->dev, ndev);
++ err = register_netdev(ndev);
+ if (err) {
+ printk(KERN_ERR "%pOF: failed to register net device (%d)!\n",
+ np, err);
+@@ -3200,6 +3200,13 @@ static void emac_remove(struct platform_device *ofdev)
+
+ DBG(dev, "remove" NL);
+
++ /* Unregister network device before tearing down hardware
++ * to prevent use-after-free during deferred cleanup. This ensures
++ * the network stack stops all operations before hardware resources
++ * are released.
++ */
++ unregister_netdev(dev->ndev);
++
+ cancel_work_sync(&dev->reset_work);
+
+ if (emac_has_feature(dev, EMAC_FTR_HAS_TAH))
+--
+2.53.0
+
--- /dev/null
+From 66959d551777d4bac9fa630a65b0055a0e2f2606 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 14:10:44 +0800
+Subject: net/mlx4: avoid GCC 10 __bad_copy_from() false positive
+
+From: Yao Sang <sangyao@kylinos.cn>
+
+[ Upstream commit 2365343f4aad3e1b1e7a2e87e98cf66d5e590589 ]
+
+mlx4_init_user_cqes() fills a scratch buffer with the CQE
+initialization pattern and then copies from that buffer to userspace.
+
+In the single-copy path, the copy length is array_size(entries,
+cqe_size), but the scratch buffer is allocated with PAGE_SIZE. GCC 10
+does not carry the branch invariant strongly enough through the object
+size checks and falsely triggers __bad_copy_from().
+
+Size the scratch buffer to the actual copy length for the active path,
+keep array_size() for the single-copy case, and retain a WARN_ON_ONCE()
+guard for the PAGE_SIZE invariant before allocating the buffer.
+
+Fixes: f69bf5dee7ef ("net/mlx4: Use array_size() helper in copy_to_user()")
+Signed-off-by: Yao Sang <sangyao@kylinos.cn>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx4/cq.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c
+index e130e7259275a3..5c55971abbf072 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
++++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
+@@ -290,6 +290,7 @@ static void mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
+ static int mlx4_init_user_cqes(void *buf, int entries, int cqe_size)
+ {
+ int entries_per_copy = PAGE_SIZE / cqe_size;
++ size_t copy_bytes;
+ void *init_ents;
+ int err = 0;
+ int i;
+@@ -314,8 +315,14 @@ static int mlx4_init_user_cqes(void *buf, int entries, int cqe_size)
+ buf += PAGE_SIZE;
+ }
+ } else {
++ copy_bytes = array_size(entries, cqe_size);
++ if (WARN_ON_ONCE(copy_bytes > PAGE_SIZE)) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ err = copy_to_user((void __user *)buf, init_ents,
+- array_size(entries, cqe_size)) ?
++ copy_bytes) ?
+ -EFAULT : 0;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 28c6cc5c3e9a08a2456405a90f9871e5f90372e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 16:58:49 +0300
+Subject: net/mlx5: Fix slab-out-of-bounds in mlx5_query_nic_vport_mac_list
+
+From: Dragos Tatulea <dtatulea@nvidia.com>
+
+[ Upstream commit 894e036a24a26a6dd7b17d8d3fb5c53ab48a6074 ]
+
+mlx5_query_nic_vport_mac_list() sizes its firmware command buffer using
+the PF's log_max_current_uc/mc_list capabilities. When querying a VF
+vport with a larger configured max (via devlink), the firmware response
+can overflow this buffer:
+
+ BUG: KASAN: slab-out-of-bounds in mlx5_query_nic_vport_mac_list+0x453/0x4c0 [mlx5_core]
+ Read of size 4 at addr ff1100013ffc8a12 by task kworker/u96:2/385
+
+ CPU: 12 UID: 0 PID: 385 Comm: kworker/u96:2 Not tainted 7.0.0-rc6+ #1 PREEMPT
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009)
+ Workqueue: mlx5_esw_wq esw_vport_change_handler [mlx5_core]
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x69/0xa0
+ print_report+0x176/0x4e4
+ kasan_report+0xc8/0x100
+ mlx5_query_nic_vport_mac_list+0x453/0x4c0 [mlx5_core]
+ esw_update_vport_addr_list+0x2e3/0xda0 [mlx5_core]
+ esw_vport_change_handle_locked+0xa1f/0x1060 [mlx5_core]
+ esw_vport_change_handler+0x6a/0x90 [mlx5_core]
+ process_one_work+0x87f/0x15e0
+ worker_thread+0x62b/0x1020
+ kthread+0x375/0x490
+ ret_from_fork+0x4dc/0x810
+ ret_from_fork_asm+0x11/0x20
+ </TASK>
+
+Fix by querying the vport's own HCA caps to size the buffer correctly.
+Refactor the function to allocate and return the MAC list internally,
+removing the caller's dependency on knowing the correct max.
+
+Fixes: e16aea2744ab ("net/mlx5: Introduce access functions to modify/query vport mac lists")
+Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
+Reviewed-by: Carolina Jubran <cjubran@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20260604135849.458060-1-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/eswitch.c | 13 +---
+ .../net/ethernet/mellanox/mlx5/core/vport.c | 72 ++++++++++++++-----
+ include/linux/mlx5/vport.h | 4 +-
+ 3 files changed, 59 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+index 864e88f0577145..383ca082e8419d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+@@ -533,23 +533,16 @@ static void esw_update_vport_addr_list(struct mlx5_eswitch *esw,
+ struct mlx5_vport *vport, int list_type)
+ {
+ bool is_uc = list_type == MLX5_NVPRT_LIST_TYPE_UC;
+- u8 (*mac_list)[ETH_ALEN];
++ u8 (*mac_list)[ETH_ALEN] = NULL;
+ struct l2addr_node *node;
+ struct vport_addr *addr;
+ struct hlist_head *hash;
+ struct hlist_node *tmp;
+- int size;
++ int size = 0;
+ int err;
+ int hi;
+ int i;
+
+- size = is_uc ? MLX5_MAX_UC_PER_VPORT(esw->dev) :
+- MLX5_MAX_MC_PER_VPORT(esw->dev);
+-
+- mac_list = kcalloc(size, ETH_ALEN, GFP_KERNEL);
+- if (!mac_list)
+- return;
+-
+ hash = is_uc ? vport->uc_list : vport->mc_list;
+
+ for_each_l2hash_node(node, tmp, hash, hi) {
+@@ -561,7 +554,7 @@ static void esw_update_vport_addr_list(struct mlx5_eswitch *esw,
+ goto out;
+
+ err = mlx5_query_nic_vport_mac_list(esw->dev, vport->vport, list_type,
+- mac_list, &size);
++ &mac_list, &size);
+ if (err)
+ goto out;
+ esw_debug(esw->dev, "vport[%d] context update %s list size (%d)\n",
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+index b04024d0ae676c..fdee284835e001 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+@@ -250,35 +250,63 @@ int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu)
+ }
+ EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mtu);
+
++static int mlx5_vport_max_mac_list_size(struct mlx5_core_dev *dev, u16 vport,
++ enum mlx5_list_type list_type)
++{
++ void *query_ctx, *hca_caps;
++ int ret = 0;
++
++ if (!vport && !mlx5_core_is_ecpf(dev))
++ return list_type == MLX5_NVPRT_LIST_TYPE_UC ?
++ 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
++ 1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
++
++ query_ctx = kzalloc(MLX5_ST_SZ_BYTES(query_hca_cap_out), GFP_KERNEL);
++ if (!query_ctx)
++ return -ENOMEM;
++
++ ret = mlx5_vport_get_other_func_general_cap(dev, vport, query_ctx);
++ if (ret)
++ goto out;
++
++ hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
++ ret = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
++ 1 << MLX5_GET(cmd_hca_cap, hca_caps, log_max_current_uc_list) :
++ 1 << MLX5_GET(cmd_hca_cap, hca_caps, log_max_current_mc_list);
++
++out:
++ kfree(query_ctx);
++
++ return ret;
++}
++
+ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+ u16 vport,
+ enum mlx5_list_type list_type,
+- u8 addr_list[][ETH_ALEN],
+- int *list_size)
++ u8 (**addr_list)[ETH_ALEN],
++ int *addr_list_size)
+ {
+ u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
++ int allowed_list_size;
+ void *nic_vport_ctx;
+ int max_list_size;
+- int req_list_size;
+ int out_sz;
+ void *out;
+ int err;
+ int i;
+
+- req_list_size = *list_size;
++ if (!addr_list || !addr_list_size)
++ return -EINVAL;
+
+- max_list_size = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
+- 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
+- 1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
++ *addr_list = NULL;
++ *addr_list_size = 0;
+
+- if (req_list_size > max_list_size) {
+- mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
+- req_list_size, max_list_size);
+- req_list_size = max_list_size;
+- }
++ max_list_size = mlx5_vport_max_mac_list_size(dev, vport, list_type);
++ if (max_list_size < 0)
++ return max_list_size;
+
+ out_sz = MLX5_ST_SZ_BYTES(query_nic_vport_context_out) +
+- req_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
++ max_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
+
+ out = kvzalloc(out_sz, GFP_KERNEL);
+ if (!out)
+@@ -297,16 +325,24 @@ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+
+ nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
+ nic_vport_context);
+- req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
+- allowed_list_size);
++ allowed_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
++ allowed_list_size);
++ if (!allowed_list_size)
++ goto out;
++
++ *addr_list = kcalloc(allowed_list_size, ETH_ALEN, GFP_KERNEL);
++ if (!*addr_list) {
++ err = -ENOMEM;
++ goto out;
++ }
+
+- *list_size = req_list_size;
+- for (i = 0; i < req_list_size; i++) {
++ for (i = 0; i < allowed_list_size; i++) {
+ u8 *mac_addr = MLX5_ADDR_OF(nic_vport_context,
+ nic_vport_ctx,
+ current_uc_mac_address[i]) + 2;
+- ether_addr_copy(addr_list[i], mac_addr);
++ ether_addr_copy((*addr_list)[i], mac_addr);
+ }
++ *addr_list_size = allowed_list_size;
+ out:
+ kvfree(out);
+ return err;
+diff --git a/include/linux/mlx5/vport.h b/include/linux/mlx5/vport.h
+index c36cc6d829267e..80992c370fb074 100644
+--- a/include/linux/mlx5/vport.h
++++ b/include/linux/mlx5/vport.h
+@@ -95,8 +95,8 @@ int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *dev,
+ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+ u16 vport,
+ enum mlx5_list_type list_type,
+- u8 addr_list[][ETH_ALEN],
+- int *list_size);
++ u8 (**mac_list)[ETH_ALEN],
++ int *mac_list_size);
+ int mlx5_modify_nic_vport_mac_list(struct mlx5_core_dev *dev,
+ enum mlx5_list_type list_type,
+ u8 addr_list[][ETH_ALEN],
+--
+2.53.0
+
--- /dev/null
+From 81a013c079f8f91d1d12898ad7332a7b05b683bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 18:21:12 +0800
+Subject: net/mlx5: Use effective affinity mask for IRQ selection
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fushuai Wang <wangfushuai@baidu.com>
+
+[ Upstream commit a7767290e77ca2e926b49f8bfa29daa12262c612 ]
+
+When a sf is created after a CPU has been taken offline, the IRQ pool may
+contain IRQs with affinity masks that include the offline CPU. Since only
+online CPUs should be considered for IRQ placement, cpumask_subset() check
+would fail because the iter_mask contains offline CPUs that are not present
+in req_mask, causing sf creation to fail.
+
+This is an example:
+ 1. When mlx5 driver loads, it initializes the IRQ pools.
+ For sf_ctrl_pool with ≤64 sf:
+ - xa_num_irqs = {N, N} (There is only one slot)
+ 2. When the first SF is created:
+ - The ctrl IRQ is allocated with mask=cpu_online_mask={0-191}
+ 2. We take CPU 20 offline
+ 3. Existing ctl irq still have mask={0-191}
+ 4. Create a new SF:
+ - req_mask={0-19,21-191}
+ - iter_mask={0-191}
+ - {0-191} is NOT a subset of {0-19,21-191}
+ - least_loaded_irq=NULL
+ 5. Try to allocate a new irq via irq_pool_request_irq()
+ 6. xa_alloc() fails because the pool is full(There is only one slot)
+ 7. sf creation fails with error
+
+Use irq_get_effective_affinity_mask() instead, which returns the IRQ's
+actual effective affinity that already excludes offline CPUs.
+
+Fixes: 061f5b23588a ("net/mlx5: SF, Use all available cpu for setting cpu affinity")
+Suggested-by: Shay Drory <shayd@nvidia.com>
+Signed-off-by: Fushuai Wang <wangfushuai@baidu.com>
+Reviewed-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20260605102112.91772-1-fushuai.wang@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c b/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
+index 2691d88cdee1f7..589051ffb49d3a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
+@@ -94,9 +94,12 @@ irq_pool_find_least_loaded(struct mlx5_irq_pool *pool, const struct cpumask *req
+
+ lockdep_assert_held(&pool->lock);
+ xa_for_each_range(&pool->irqs, index, iter, start, end) {
+- struct cpumask *iter_mask = mlx5_irq_get_affinity_mask(iter);
+ int iter_refcount = mlx5_irq_read_locked(iter);
++ const struct cpumask *iter_mask;
+
++ iter_mask = irq_get_effective_affinity_mask(mlx5_irq_get_irq(iter));
++ if (!iter_mask)
++ continue;
+ if (!cpumask_subset(iter_mask, req_mask))
+ /* skip IRQs with a mask which is not subset of req_mask */
+ continue;
+--
+2.53.0
+
--- /dev/null
+From f1bcc44a23790f55a7690d9bb23e6a96fa03247e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 16:54:46 +0300
+Subject: net/mlx5e: xsk: Fix DMA and xdp_frame leak on XDP_TX xmit failure
+
+From: Dragos Tatulea <dtatulea@nvidia.com>
+
+[ Upstream commit b69004f5a6ad32da84d8aa5b23b9c0caafe6252e ]
+
+In the XSK branch of mlx5e_xmit_xdp_buff(), when sq->xmit_xdp_frame()
+returns false (e.g. XDPSQ is full), the function returns without
+unmapping the DMA address or freeing the xdp_frame allocated by
+xdp_convert_zc_to_xdp_frame(). The xdpi_fifo push only happens on
+success, so the completion path cannot recover these entries.
+
+With CONFIG_DMA_API_DEBUG=y, the leak surfaces on driver unbind:
+
+ DMA-API: pci 0000:08:00.0: device driver has pending DMA
+ allocations while released from device [count=1116]
+ One of leaked entries details: [device address=0x000000010ffd7028]
+ [size=1534 bytes] [mapped with DMA_TO_DEVICE] [mapped as phy]
+ WARNING: kernel/dma/debug.c:881 at dma_debug_device_change+0x127/0x180
+ ...
+ DMA-API: Mapped at:
+ debug_dma_map_phys+0x4b/0xd0
+ dma_map_phys+0xfd/0x2d0
+ mlx5e_xdp_handle+0x5ae/0xac0 [mlx5_core]
+ mlx5e_xsk_skb_from_cqe_mpwrq_linear+0xc4/0x170 [mlx5_core]
+ mlx5e_handle_rx_cqe_mpwrq+0xc1/0x290 [mlx5_core]
+
+Add the missing unmap + xdp_return_frame, matching the cleanup already
+done in mlx5e_xdp_xmit(). has_frags is rejected earlier in this branch,
+so no per-frag unmap is needed.
+
+Fixes: 84a0a2310d6d ("net/mlx5e: XDP_TX from UMEM support")
+Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20260604135446.456119-1-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
+index 14192da4b8ed0d..d4d2de017a504d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
+@@ -102,9 +102,15 @@ mlx5e_xmit_xdp_buff(struct mlx5e_xdpsq *sq, struct mlx5e_rq *rq,
+
+ xdptxd->dma_addr = dma_addr;
+
+- if (unlikely(!INDIRECT_CALL_2(sq->xmit_xdp_frame, mlx5e_xmit_xdp_frame_mpwqe,
+- mlx5e_xmit_xdp_frame, sq, xdptxd, 0, NULL)))
++ if (unlikely(!INDIRECT_CALL_2(sq->xmit_xdp_frame,
++ mlx5e_xmit_xdp_frame_mpwqe,
++ mlx5e_xmit_xdp_frame,
++ sq, xdptxd, 0, NULL))) {
++ dma_unmap_single(sq->pdev, dma_addr, xdptxd->len,
++ DMA_TO_DEVICE);
++ xdp_return_frame(xdpf);
+ return false;
++ }
+
+ /* xmit_mode == MLX5E_XDP_XMIT_MODE_FRAME */
+ mlx5e_xdpi_fifo_push(&sq->db.xdpi_fifo,
+--
+2.53.0
+
--- /dev/null
+From cd8e9a14d051e7122a4d2472b737ae64e99ff55b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 12:46:06 +0100
+Subject: net: mvpp2: Add metadata support for xdp mode
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 9a45e193c88a55a536d7fd0ebfa29823d588c2cf ]
+
+Set metadata size building the skb from xdp_buff in mvpp2 driver
+mvpp2 driver sets xdp headroom to:
+
+MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM
+
+where
+
+MVPP2_MH_SIZE 2
+MVPP2_SKB_HEADROOM min(max(XDP_PACKET_HEADROOM, NET_SKB_PAD), 224)
+
+so the headroom is large enough to contain xdp_frame and xdp metadata.
+Please note this patch is just compiled tested.
+
+Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20250318-mvneta-xdp-meta-v2-2-b6075778f61f@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 77a6b90ce56b ("net: mvpp2: build skb from XDP-adjusted data on XDP_PASS")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index d5d2cbe127b0e7..e43d844b14aaef 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3928,13 +3928,13 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ while (rx_done < rx_todo) {
+ struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq);
++ u32 rx_status, timestamp, metasize = 0;
+ struct mvpp2_bm_pool *bm_pool;
+ struct page_pool *pp = NULL;
+ struct sk_buff *skb;
+ unsigned int frag_size;
+ dma_addr_t dma_addr;
+ phys_addr_t phys_addr;
+- u32 rx_status, timestamp;
+ int pool, rx_bytes, err, ret;
+ struct page *page;
+ void *data;
+@@ -3997,7 +3997,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ xdp_init_buff(&xdp, bm_pool->frag_size, xdp_rxq);
+ xdp_prepare_buff(&xdp, data,
+ MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM,
+- rx_bytes, false);
++ rx_bytes, true);
+
+ ret = mvpp2_run_xdp(port, xdp_prog, &xdp, pp, &ps);
+
+@@ -4013,6 +4013,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ ps.rx_bytes += rx_bytes;
+ continue;
+ }
++
++ metasize = xdp.data - xdp.data_meta;
+ }
+
+ if (frag_size)
+@@ -4052,6 +4054,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);
+ skb_put(skb, rx_bytes);
++ if (metasize)
++ skb_metadata_set(skb, metasize);
+ skb->ip_summed = mvpp2_rx_csum(port, rx_status);
+ skb->protocol = eth_type_trans(skb, dev);
+
+--
+2.53.0
+
--- /dev/null
+From 045d23f9bcea62d8579181c0e45ec4ecb45b26ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:43 +0200
+Subject: net: mvpp2: build skb from XDP-adjusted data on XDP_PASS
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 77a6b90ce56bc982dcfa94229b8e28e6abb16e95 ]
+
+When an XDP program uses bpf_xdp_adjust_head() or bpf_xdp_adjust_tail()
+and then returns XDP_PASS, mvpp2 still builds the skb from fixed offsets
+derived from the original RX descriptor. Packet geometry changes made by
+the XDP program are therefore discarded before the skb reaches the stack.
+
+Update rx_offset and rx_bytes from xdp.data and xdp.data_end for
+XDP_PASS. This makes skb_reserve() and skb_put() reflect the packet seen
+by XDP, and makes RX byte accounting for XDP_PASS follow the length of the
+skb passed to the network stack.
+
+Keep a separate rx_sync_size for page-pool recycling on skb allocation
+failure, which must stay tied to the received buffer range.
+
+Non-PASS verdicts continue to account the descriptor length because no skb
+is passed up in those cases.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-5-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 21 +++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 2c517f6ca39c40..325a3a657249df 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3932,10 +3932,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ struct mvpp2_bm_pool *bm_pool;
+ struct page_pool *pp = NULL;
+ struct sk_buff *skb;
+- unsigned int frag_size;
++ unsigned int frag_size, rx_sync_size;
+ dma_addr_t dma_addr;
+ phys_addr_t phys_addr;
+- int pool, rx_bytes, err, ret;
++ int pool, rx_bytes, rx_offset, err, ret;
+ struct page *page;
+ void *data;
+
+@@ -3948,6 +3948,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ rx_status = mvpp2_rxdesc_status_get(port, rx_desc);
+ rx_bytes = mvpp2_rxdesc_size_get(port, rx_desc);
+ rx_bytes -= MVPP2_MH_SIZE;
++ rx_sync_size = rx_bytes + MVPP2_MH_SIZE;
++ rx_offset = MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM;
+ dma_addr = mvpp2_rxdesc_dma_addr_get(port, rx_desc);
+
+ pool = (rx_status & MVPP2_RXD_BM_POOL_ID_MASK) >>
+@@ -3963,7 +3965,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
+ MVPP2_SKB_HEADROOM,
+- rx_bytes + MVPP2_MH_SIZE,
++ rx_sync_size,
+ dma_dir);
+
+ /* Buffer header not supported */
+@@ -4014,6 +4016,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ continue;
+ }
+
++ rx_sync_size = max_t(unsigned int, rx_sync_size,
++ xdp.data_end - xdp.data_hard_start -
++ MVPP2_SKB_HEADROOM);
++
++ /* Update offset and length to reflect any XDP adjustments. */
++ rx_offset = xdp.data - data;
++ rx_bytes = xdp.data_end - xdp.data;
++
+ metasize = xdp.data - xdp.data_meta;
+ }
+
+@@ -4025,8 +4035,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ netdev_warn(port->dev, "skb build failed\n");
+ if (pp) {
+ page_pool_put_page(pp, virt_to_head_page(data),
+- rx_bytes + MVPP2_MH_SIZE,
+- true);
++ rx_sync_size, true);
+ } else {
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size,
+@@ -4056,7 +4065,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
+
+- skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);
++ skb_reserve(skb, rx_offset);
+ skb_put(skb, rx_bytes);
+ if (metasize)
+ skb_metadata_set(skb, metasize);
+--
+2.53.0
+
--- /dev/null
+From 197cbb46650742088a2b368f470a26308b779d9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:41 +0200
+Subject: net: mvpp2: limit XDP frame size to the RX buffer
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit f3c6aa078927e6fe8121c9c591ddee8716c5305a ]
+
+mvpp2 has short and long BM pools, and short pool buffers can be smaller
+than PAGE_SIZE. The XDP path nevertheless initializes every xdp_buff with
+PAGE_SIZE as frame size.
+
+XDP helpers use frame_sz to validate tail growth and to derive the hard
+end of the data area. Advertising PAGE_SIZE for short buffers can let
+bpf_xdp_adjust_tail() grow a packet past the real allocation, corrupting
+memory or later tripping skb tailroom checks.
+
+Initialize the XDP buffer with bm_pool->frag_size so XDP tailroom matches
+the actual buffer backing the packet.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-3-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 4aaa661f78f288..d5d2cbe127b0e7 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3994,7 +3994,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ else
+ xdp_rxq = &rxq->xdp_rxq_long;
+
+- xdp_init_buff(&xdp, PAGE_SIZE, xdp_rxq);
++ xdp_init_buff(&xdp, bm_pool->frag_size, xdp_rxq);
+ xdp_prepare_buff(&xdp, data,
+ MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM,
+ rx_bytes, false);
+--
+2.53.0
+
--- /dev/null
+From 05741e4ed5abacde3d97c7b9e2661a318a1824b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:42 +0200
+Subject: net: mvpp2: refill RX buffers before XDP or skb use
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 5e8e2a9624df72fca7c736b2966b2cbf6c9c3ff6 ]
+
+The RX error path returns the current descriptor buffer to the hardware
+BM pool. That is only valid while the driver still owns the buffer.
+
+mvpp2_rx_refill() can fail after the current buffer has been handed to
+XDP or attached to an skb. In those cases mvpp2_run_xdp() may have
+recycled, redirected, or queued the page for XDP_TX, and an skb free also
+retires the data buffer. Returning such a buffer to BM lets hardware DMA
+into memory that is no longer owned by the RX ring.
+
+Refill the BM pool before handing the current buffer to XDP or to the
+skb. If the allocation fails there, drop the packet and return the
+still-owned current buffer to BM, preserving the pool depth. Once the
+refill succeeds, later local drops retire/free the current buffer instead
+of returning it to BM.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Fixes: d6526926de73 ("net: mvpp2: fix memory leak in mvpp2_rx")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-4-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 77a6b90ce56b ("net: mvpp2: build skb from XDP-adjusted data on XDP_PASS")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 43 +++++++++++--------
+ 1 file changed, 24 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index e43d844b14aaef..2c517f6ca39c40 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3986,6 +3986,12 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ else
+ frag_size = bm_pool->frag_size;
+
++ err = mvpp2_rx_refill(port, bm_pool, pp, pool);
++ if (err) {
++ netdev_err(port->dev, "failed to refill BM pools\n");
++ goto err_drop_frame;
++ }
++
+ if (xdp_prog) {
+ struct xdp_rxq_info *xdp_rxq;
+
+@@ -4003,12 +4009,6 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ if (ret) {
+ xdp_ret |= ret;
+- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+- if (err) {
+- netdev_err(port->dev, "failed to refill BM pools\n");
+- goto err_drop_frame;
+- }
+-
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
+ continue;
+@@ -4023,8 +4023,21 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ skb = slab_build_skb(data);
+ if (!skb) {
+ netdev_warn(port->dev, "skb build failed\n");
+- goto err_drop_frame;
++ if (pp) {
++ page_pool_put_page(pp, virt_to_head_page(data),
++ rx_bytes + MVPP2_MH_SIZE,
++ true);
++ } else {
++ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
++ bm_pool->buf_size,
++ DMA_FROM_DEVICE,
++ DMA_ATTR_SKIP_CPU_SYNC);
++ mvpp2_frag_free(bm_pool, pp, data);
++ }
++ goto err_drop_frame_retired;
+ }
++ if (pp)
++ skb_mark_for_recycle(skb);
+
+ /* If we have RX hardware timestamping enabled, grab the
+ * timestamp from the queue and convert.
+@@ -4035,16 +4048,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ skb_hwtstamps(skb));
+ }
+
+- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+- if (err) {
+- netdev_err(port->dev, "failed to refill BM pools\n");
+- dev_kfree_skb_any(skb);
+- goto err_drop_frame;
+- }
+-
+- if (pp)
+- skb_mark_for_recycle(skb);
+- else
++ if (!pp)
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size, DMA_FROM_DEVICE,
+ DMA_ATTR_SKIP_CPU_SYNC);
+@@ -4063,13 +4067,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ continue;
+
+ err_drop_frame:
+- dev->stats.rx_errors++;
+- mvpp2_rx_error(port, rx_desc);
+ /* Return the buffer to the pool */
+ if (rx_status & MVPP2_RXD_BUF_HDR)
+ mvpp2_buff_hdr_pool_put(port, rx_desc, pool, rx_status);
+ else
+ mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);
++err_drop_frame_retired:
++ dev->stats.rx_errors++;
++ mvpp2_rx_error(port, rx_desc);
+ }
+
+ if (xdp_ret & MVPP2_XDP_REDIR)
+--
+2.53.0
+
--- /dev/null
+From 4c6459f690a8466c0b22eee3f9f3af9fff6cc332 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:40 +0200
+Subject: net: mvpp2: sync RX data at the hardware packet offset
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 180235600934bef6add3be637c296d6cf3272e67 ]
+
+mvpp2 programs the RX queue packet offset, so hardware writes received
+data at dma_addr + MVPP2_SKB_HEADROOM. The current CPU sync starts at
+dma_addr and only covers rx_bytes + MVPP2_MH_SIZE bytes, which syncs the
+unused headroom and misses the same number of bytes at the packet tail.
+
+On non-coherent DMA systems this can leave the CPU reading stale cache
+contents for the end of the received frame.
+
+Use dma_sync_single_range_for_cpu() with MVPP2_SKB_HEADROOM as the range
+offset so the sync covers the Marvell header and packet data actually
+written by hardware.
+
+Fixes: e1921168bbd4 ("mvpp2: sync only the received frame")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-2-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 51e35c4d9ea972..4aaa661f78f288 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3961,9 +3961,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ dma_dir = DMA_FROM_DEVICE;
+ }
+
+- dma_sync_single_for_cpu(dev->dev.parent, dma_addr,
+- rx_bytes + MVPP2_MH_SIZE,
+- dma_dir);
++ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
++ MVPP2_SKB_HEADROOM,
++ rx_bytes + MVPP2_MH_SIZE,
++ dma_dir);
+
+ /* Buffer header not supported */
+ if (rx_status & MVPP2_RXD_BUF_HDR)
+--
+2.53.0
+
--- /dev/null
+From 9d6be8de6d6e1a625cbfd2188aaf782403920d82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:19:46 +0200
+Subject: net: openvswitch: fix possible kfree_skb of ERR_PTR
+
+From: Adrian Moreno <amorenoz@redhat.com>
+
+[ Upstream commit ee30dd2909d8b98619f4341c70ec8dc8e155ab02 ]
+
+After the patch in the "Fixes" tag, the allocation of the "reply" skb
+can happen either before or after locking the ovs_mutex.
+
+However, error cleanups still follow the classical reversed order,
+assuming "reply" is allocated before locking: it is freed after unlocking.
+
+If "reply" allocation happens after locking the mutex and it fails,
+"reply" is left with an ERR_PTR, and execution jumps to the correspondent
+cleanup stage which will try to free an invalid pointer.
+
+Fix this by setting the pointer to NULL after having saved its error
+value.
+
+Fixes: 893f139b9a6c ("openvswitch: Minimize ovs_flow_cmd_new|set critical sections.")
+Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Acked-by: Eelco Chaudron <echaudro@redhat.com>
+Link: https://patch.msgid.link/20260604121946.942164-1-amorenoz@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/datapath.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 607b5ca70ea547..260d1af64afc90 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -1286,6 +1286,7 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
+
+ if (IS_ERR(reply)) {
+ error = PTR_ERR(reply);
++ reply = NULL;
+ goto err_unlock_ovs;
+ }
+ }
+--
+2.53.0
+
--- /dev/null
+From 93f506689ddb4114ce02fa538d5fe07c1e710e36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 11:28:15 +0200
+Subject: net: phy: clean the sfp upstream if phy probing fails
+
+From: Maxime Chevallier <maxime.chevallier@bootlin.com>
+
+[ Upstream commit 48774e87bbaa0056819d4b52301e4692e50e3252 ]
+
+Sashiko reported that we don't call sfp_bus_del_upstream() in the probe
+failure path, so let's add it, otherwise the sfp-bus is left with a
+dangling 'upstream' field, that may be used later on during SFP events.
+
+This issue existed before the generic phylib sfp support, back when
+drivers were calling phy_sfp_probe themselves.
+
+Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
+Fixes: 298e54fa810e ("net: phy: add core phylib sfp support")
+Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260604092819.723505-2-maxime.chevallier@bootlin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/phy_device.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index eb478e4961cb9b..f2d067b907bf99 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -1508,6 +1508,9 @@ int phy_sfp_probe(struct phy_device *phydev,
+
+ ret = sfp_bus_add_upstream(bus, phydev, ops);
+ sfp_bus_put(bus);
++
++ if (ret)
++ phydev->sfp_bus = NULL;
+ }
+ return ret;
+ }
+@@ -3672,6 +3675,9 @@ static int phy_probe(struct device *dev)
+ return 0;
+
+ out:
++ sfp_bus_del_upstream(phydev->sfp_bus);
++ phydev->sfp_bus = NULL;
++
+ if (!phydev->is_on_sfp_module)
+ phy_led_triggers_unregister(phydev);
+
+--
+2.53.0
+
--- /dev/null
+From aa8d99f840e6bf92d7d9e27474036cce12c3464d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:48:01 +0800
+Subject: net: qrtr: fix refcount saturation and potential UAF in
+ qrtr_port_remove
+
+From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+
+[ Upstream commit a2171131ecda1ed61a594a1eb715e75fdad0fef5 ]
+
+In qrtr_port_remove(), the socket reference count is decremented via
+__sock_put() before the port is removed from the qrtr_ports XArray and
+before the RCU grace period elapses.
+
+This breaks the fundamental RCU update paradigm. It exposes a race
+window where a concurrent RCU reader (such as qrtr_reset_ports() or
+qrtr_port_lookup()) can obtain a pointer to the socket from the XArray,
+and attempt to call sock_hold() on a socket whose reference count has
+already dropped to zero.
+
+This exact race condition was hit during syzkaller fuzzing, leading to
+the following refcount saturation warning and a potential Use-After-Free:
+
+ refcount_t: saturated; leaking memory.
+ WARNING: CPU: 3 PID: 1273 at lib/refcount.c:22 refcount_warn_saturate+0xae/0x1d0
+ Modules linked in: qrtr(+) bochs drm_shmem_helper ...
+ Call Trace:
+ <TASK>
+ qrtr_reset_ports net/qrtr/af_qrtr.c:768 [inline] [qrtr]
+ __qrtr_bind.isra.0+0x48b/0x570 net/qrtr/af_qrtr.c:805 [qrtr]
+ qrtr_bind+0x17d/0x210 net/qrtr/af_qrtr.c:901 [qrtr]
+ kernel_bind+0xe4/0x120 net/socket.c:3592
+ qrtr_ns_init+0x1a6/0x380 net/qrtr/ns.c:715 [qrtr]
+ qrtr_proto_init+0x3b/0xff0 net/qrtr/af_qrtr.c:169 [qrtr]
+ do_one_initcall+0xf5/0x5e0 init/main.c:1283
+ ...
+ </TASK>
+
+Fix this by deferring the reference count decrement until after the
+xa_erase() and the synchronize_rcu() complete.
+
+(Note: The v1 of this patch incorrectly replaced __sock_put() with
+sock_put(). As Simon Horman pointed out, the callers of qrtr_port_remove()
+still hold a reference to the socket, so freeing the socket memory here
+would lead to a subsequent UAF in the caller. Thus, the __sock_put() is
+kept, but only repositioned to close the RCU race.)
+
+Fixes: bdabad3e363d ("net: Add Qualcomm IPC router")
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260604064801.1180388-1-w15303746062@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/af_qrtr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c
+index b703e4c6458532..2c009793f1931d 100644
+--- a/net/qrtr/af_qrtr.c
++++ b/net/qrtr/af_qrtr.c
+@@ -707,13 +707,13 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
+ if (port == QRTR_PORT_CTRL)
+ port = 0;
+
+- __sock_put(&ipc->sk);
+-
+ xa_erase(&qrtr_ports, port);
+
+ /* Ensure that if qrtr_port_lookup() did enter the RCU read section we
+ * wait for it to up increment the refcount */
+ synchronize_rcu();
++
++ __sock_put(&ipc->sk);
+ }
+
+ /* Assign port number to socket.
+--
+2.53.0
+
--- /dev/null
+From 9ac8441f6c16d695a96dca64a845efa247b4a0cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 12:24:48 -0700
+Subject: net/rds: fix NULL deref in rds_ib_send_cqe_handler() on masked atomic
+ completion
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 34080db3e70ddf94c38512ad2331e3c3afca6cc1 ]
+
+rds_ib_xmit_atomic() always programs a masked atomic opcode
+(IB_WR_MASKED_ATOMIC_CMP_AND_SWP or IB_WR_MASKED_ATOMIC_FETCH_AND_ADD)
+for every RDS atomic cmsg. But the completion-side switch in
+rds_ib_send_unmap_op() only handles the non-masked opcodes, so a masked
+atomic completion falls through to default and returns rm == NULL while
+send->s_op is left set. rds_ib_send_cqe_handler() then dereferences the
+NULL rm via rm->m_final_op, oopsing in softirq context. An unprivileged
+AF_RDS sendmsg() of an atomic cmsg over an active RDS/IB connection
+triggers it; on hardware that natively accepts masked atomics (mlx4,
+mlx5) no extra setup is needed.
+
+ RDS/IB: rds_ib_send_unmap_op: unexpected opcode 0xd in WR!
+ Oops: general protection fault [#1] SMP KASAN
+ KASAN: null-ptr-deref in range [0x0000000000000190-0x0000000000000197]
+ RIP: rds_ib_send_cqe_handler+0x25c/0xb10 (net/rds/ib_send.c:282)
+ Call Trace:
+ <IRQ>
+ rds_ib_send_cqe_handler (net/rds/ib_send.c:282)
+ poll_scq (net/rds/ib_cm.c:274)
+ rds_ib_tasklet_fn_send (net/rds/ib_cm.c:294)
+ tasklet_action_common (kernel/softirq.c:943)
+ handle_softirqs (kernel/softirq.c:573)
+ run_ksoftirqd (kernel/softirq.c:479)
+ </IRQ>
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Handle the masked atomic opcodes in the same case as the non-masked
+ones: they map to the same struct rds_message.atomic union member, so
+the existing container_of()/rds_ib_send_unmap_atomic() body is correct
+for them.
+
+Fixes: 20c72bd5f5f9 ("RDS: Implement masked atomic operations")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260606192447.1179255-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/ib_send.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
+index 4190b90ff3b18a..1909cd440a4b66 100644
+--- a/net/rds/ib_send.c
++++ b/net/rds/ib_send.c
+@@ -170,6 +170,8 @@ static struct rds_message *rds_ib_send_unmap_op(struct rds_ib_connection *ic,
+ break;
+ case IB_WR_ATOMIC_FETCH_AND_ADD:
+ case IB_WR_ATOMIC_CMP_AND_SWP:
++ case IB_WR_MASKED_ATOMIC_FETCH_AND_ADD:
++ case IB_WR_MASKED_ATOMIC_CMP_AND_SWP:
+ if (send->s_op) {
+ rm = container_of(send->s_op, struct rds_message, atomic);
+ rds_ib_send_unmap_atomic(ic, send->s_op, wc_status);
+--
+2.53.0
+
--- /dev/null
+From c60cd7d1aa7fa85b7c9dd4b5577212f646f92da8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 18:21:24 -0700
+Subject: netdev: fix double-free in netdev_nl_bind_rx_doit()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit c849de7d8757a7af801fc4a4058f71d481d367f2 ]
+
+Sashiko flags that genlmsg_reply() always consumes the skb.
+The error path calls nlmsg_free(rsp) so we can't jump directly
+to it. Let's not unbind, just propagate the error to the user.
+This is the typical way of handling genlmsg_reply() failures.
+They shouldn't happen unless user does something silly like
+calling the kernel with an already-full rcvbuf.
+
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Fixes: 170aafe35cb9 ("netdev: support binding dma-buf to netdevice")
+Reviewed-by: Bobby Eshleman <bobbyeshleman@meta.com>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/netdev-genl.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
+index 0fe537781bc4d9..6d4db55e90ed5a 100644
+--- a/net/core/netdev-genl.c
++++ b/net/core/netdev-genl.c
+@@ -854,12 +854,10 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
+ genlmsg_end(rsp, hdr);
+
+ err = genlmsg_reply(rsp, info);
+- if (err)
+- goto err_unbind;
+
+ rtnl_unlock();
+
+- return 0;
++ return err < 0 ? err : 0;
+
+ err_unbind:
+ net_devmem_unbind_dmabuf(binding);
+--
+2.53.0
+
--- /dev/null
+From 3826e8d50dc503a48baef6af94517d64cfdd8c40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 00:38:17 -0700
+Subject: netfilter: nf_conntrack: destroy stale expectfn expectations on
+ unregister
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit c3009418f9fa1dcb3eb86f4d8c92583537b5faa3 ]
+
+NAT helpers such as nf_nat_h323 store a raw pointer to module text in
+exp->expectfn (e.g. ip_nat_q931_expect). nf_ct_helper_expectfn_unregister()
+only unlinks the callback descriptor and never walks the expectation table,
+so an expectation pending at module removal survives with a dangling
+exp->expectfn into freed module text.
+
+When the expected connection arrives, init_conntrack() invokes
+exp->expectfn(), now a stale pointer into the unloaded module. Reproduced
+on a KASAN build by loading the H.323 helpers, creating a Q.931
+expectation, unloading nf_nat_h323, then connecting to the expected port:
+
+ Oops: int3: 0000 [#1] SMP KASAN NOPTI
+ RIP: 0010:0xffffffffa06102d1
+ init_conntrack.isra.0 (net/netfilter/nf_conntrack_core.c:1862)
+ nf_conntrack_in (net/netfilter/nf_conntrack_core.c:2049)
+ ipv4_conntrack_local (net/netfilter/nf_conntrack_proto.c:223)
+ nf_hook_slow (net/netfilter/core.c:619)
+ __ip_local_out (net/ipv4/ip_output.c:120)
+ __tcp_transmit_skb (net/ipv4/tcp_output.c:1715)
+ tcp_connect (net/ipv4/tcp_output.c:4374)
+ tcp_v4_connect (net/ipv4/tcp_ipv4.c:345)
+ __sys_connect (net/socket.c:2167)
+ Modules linked in: nf_conntrack_h323 [last unloaded: nf_nat_h323]
+
+Reaching the dangling state requires CAP_SYS_MODULE in the initial user
+namespace to remove a NAT helper that still has live expectations, so this
+is a robustness fix; leaving an expectation pointing at freed text is wrong
+regardless.
+
+Add nf_ct_helper_expectfn_destroy(), which walks the expectation table and
+drops every expectation whose ->expectfn matches the descriptor being torn
+down. Call it from each NAT helper's exit path after the existing RCU grace
+period, so no expectation outlives the code it points at and no extra
+synchronize_rcu() is introduced. With the fix, the same reproducer runs to
+completion without the Oops.
+
+Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netfilter/nf_conntrack_helper.h | 1 +
+ net/ipv4/netfilter/nf_nat_h323.c | 2 ++
+ net/netfilter/nf_conntrack_helper.c | 19 +++++++++++++++++++
+ net/netfilter/nf_nat_core.c | 2 ++
+ net/netfilter/nf_nat_sip.c | 1 +
+ 5 files changed, 25 insertions(+)
+
+diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
+index de2f956abf3480..24cf3d2d97450f 100644
+--- a/include/net/netfilter/nf_conntrack_helper.h
++++ b/include/net/netfilter/nf_conntrack_helper.h
+@@ -155,6 +155,7 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
+
+ void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n);
+ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n);
++void nf_ct_helper_expectfn_destroy(const struct nf_ct_helper_expectfn *n);
+ struct nf_ct_helper_expectfn *
+ nf_ct_helper_expectfn_find_by_name(const char *name);
+ struct nf_ct_helper_expectfn *
+diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
+index faee20af485613..10e1b0837731b7 100644
+--- a/net/ipv4/netfilter/nf_nat_h323.c
++++ b/net/ipv4/netfilter/nf_nat_h323.c
+@@ -555,6 +555,8 @@ static void __exit nf_nat_h323_fini(void)
+ nf_ct_helper_expectfn_unregister(&q931_nat);
+ nf_ct_helper_expectfn_unregister(&callforwarding_nat);
+ synchronize_rcu();
++ nf_ct_helper_expectfn_destroy(&q931_nat);
++ nf_ct_helper_expectfn_destroy(&callforwarding_nat);
+ }
+
+ /****************************************************************************/
+diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
+index a715304a53d8c2..9150bcfd7ca83b 100644
+--- a/net/netfilter/nf_conntrack_helper.c
++++ b/net/netfilter/nf_conntrack_helper.c
+@@ -283,6 +283,25 @@ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n)
+ }
+ EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_unregister);
+
++static bool expect_iter_expectfn(struct nf_conntrack_expect *exp, void *data)
++{
++ const struct nf_ct_helper_expectfn *n = data;
++
++ /* Relies on registered expectfn descriptors having unique ->expectfn
++ * pointers, which holds for the in-tree NAT helpers.
++ */
++ return exp->expectfn == n->expectfn;
++}
++
++/* Destroy expectations still pointing at @n->expectfn; call after the
++ * caller's RCU grace period so none outlives the (often modular) callback.
++ */
++void nf_ct_helper_expectfn_destroy(const struct nf_ct_helper_expectfn *n)
++{
++ nf_ct_expect_iterate_destroy(expect_iter_expectfn, (void *)n);
++}
++EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_destroy);
++
+ /* Caller should hold the rcu lock */
+ struct nf_ct_helper_expectfn *
+ nf_ct_helper_expectfn_find_by_name(const char *name)
+diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
+index 746acd124ea285..6ba7733355df39 100644
+--- a/net/netfilter/nf_nat_core.c
++++ b/net/netfilter/nf_nat_core.c
+@@ -1353,6 +1353,7 @@ static int __init nf_nat_init(void)
+ RCU_INIT_POINTER(nf_nat_hook, NULL);
+ nf_ct_helper_expectfn_unregister(&follow_master_nat);
+ synchronize_net();
++ nf_ct_helper_expectfn_destroy(&follow_master_nat);
+ unregister_pernet_subsys(&nat_net_ops);
+ kvfree(nf_nat_bysource);
+ }
+@@ -1370,6 +1371,7 @@ static void __exit nf_nat_cleanup(void)
+ RCU_INIT_POINTER(nf_nat_hook, NULL);
+
+ synchronize_net();
++ nf_ct_helper_expectfn_destroy(&follow_master_nat);
+ kvfree(nf_nat_bysource);
+ unregister_pernet_subsys(&nat_net_ops);
+ }
+diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c
+index 9fbfc6bff0c221..00838c0cc5bb28 100644
+--- a/net/netfilter/nf_nat_sip.c
++++ b/net/netfilter/nf_nat_sip.c
+@@ -655,6 +655,7 @@ static void __exit nf_nat_sip_fini(void)
+ RCU_INIT_POINTER(nf_nat_sip_hooks, NULL);
+ nf_ct_helper_expectfn_unregister(&sip_nat);
+ synchronize_rcu();
++ nf_ct_helper_expectfn_destroy(&sip_nat);
+ }
+
+ static const struct nf_nat_sip_hooks sip_hooks = {
+--
+2.53.0
+
--- /dev/null
+From e6acecfdb03a55bf856d0e9c6a48b3f791f00b24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 15:55:02 -0700
+Subject: netfilter: nf_log: validate MAC header was set before dumping it
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit a84b6fedbc97078788be78dbdd7517d143ad1a77 ]
+
+The fallback path of dump_mac_header() guards the MAC header access
+only with "skb->mac_header != skb->network_header", without checking
+skb_mac_header_was_set(). When the MAC header is unset, mac_header is
+0xffff, so the test passes and skb_mac_header(skb) returns
+skb->head + 0xffff, ~64 KiB past the buffer; the loop then reads
+dev->hard_header_len bytes out of bounds into the kernel log.
+
+This is reachable via the netdev logger: nf_log_unknown_packet() calls
+dump_mac_header() unconditionally, and an skb sent through AF_PACKET
+with PACKET_QDISC_BYPASS reaches the egress hook with mac_header still
+unset (__dev_queue_xmit(), which would reset it, is bypassed).
+
+Add the skb_mac_header_was_set() check the ARPHRD_ETHER path already
+uses, and replace the open-coded MAC header length test with
+skb_mac_header_len(). Only skbs with an unset MAC header are affected;
+valid ones are dumped as before.
+
+ BUG: KASAN: slab-out-of-bounds in dump_mac_header (net/netfilter/nf_log_syslog.c:831)
+ Read of size 1 at addr ffff88800ea49d3f by task exploit/148
+ Call Trace:
+ kasan_report (mm/kasan/report.c:595)
+ dump_mac_header (net/netfilter/nf_log_syslog.c:831)
+ nf_log_netdev_packet (net/netfilter/nf_log_syslog.c:938 net/netfilter/nf_log_syslog.c:963)
+ nf_log_packet (net/netfilter/nf_log.c:260)
+ nft_log_eval (net/netfilter/nft_log.c:60)
+ nft_do_chain (net/netfilter/nf_tables_core.c:285)
+ nft_do_chain_netdev (net/netfilter/nft_chain_filter.c:307)
+ nf_hook_slow (net/netfilter/core.c:619)
+ nf_hook_direct_egress (net/packet/af_packet.c:257)
+ packet_xmit (net/packet/af_packet.c:280)
+ packet_sendmsg (net/packet/af_packet.c:3114)
+ __sys_sendto (net/socket.c:2265)
+
+Fixes: 7eb9282cd0ef ("netfilter: ipt_LOG/ip6t_LOG: add option to print decoded MAC header")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_log_syslog.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
+index 58402226045e84..09b9152e9e5492 100644
+--- a/net/netfilter/nf_log_syslog.c
++++ b/net/netfilter/nf_log_syslog.c
+@@ -799,8 +799,8 @@ static void dump_mac_header(struct nf_log_buf *m,
+
+ fallback:
+ nf_log_buf_add(m, "MAC=");
+- if (dev->hard_header_len &&
+- skb->mac_header != skb->network_header) {
++ if (dev->hard_header_len && skb_mac_header_was_set(skb) &&
++ skb_mac_header_len(skb) != 0) {
+ const unsigned char *p = skb_mac_header(skb);
+ unsigned int i;
+
+--
+2.53.0
+
--- /dev/null
+From c506d612b1d984e3fba9f3f7a88aa349a6b8479a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 21:28:09 +0200
+Subject: netfilter: nft_exthdr: fix register tracking for F_PRESENT flag
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 772cecf198da732faebb5dcfc46d66a505be8495 ]
+
+nft_exthdr_init() passes user-controlled priv->len to
+nft_parse_register_store(), which marks that many bytes in the
+register bitmap as initialized. However, when NFT_EXTHDR_F_PRESENT
+is set, the eval paths write only 1 byte (nft_reg_store8) or
+4 bytes (*dest = 0 on TCP/DCCP error path). When len > 4,
+registers beyond the first are never written, retaining
+uninitialized stack data from nft_regs.
+
+Bail out if userspace requests too much data when F_PRESENT is set.
+
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Fixes: c078ca3b0c5b ("netfilter: nft_exthdr: Add support for existence check")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_exthdr.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
+index c74012c9912554..1fc2a948d00afc 100644
+--- a/net/netfilter/nft_exthdr.c
++++ b/net/netfilter/nft_exthdr.c
+@@ -530,6 +530,9 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
+ return err;
+ }
+
++ if ((flags & NFT_EXTHDR_F_PRESENT) && len != 1)
++ return -EINVAL;
++
+ priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
+ priv->offset = offset;
+ priv->len = len;
+--
+2.53.0
+
--- /dev/null
+From 1e362948a49353f7fa76102482f9145746e2cb87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 17:04:25 +0200
+Subject: netfilter: revalidate bridge ports
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit ccb9fd4b87538ccf19ccff78ee26700526d94867 ]
+
+ebt_redirect_tg() dereferences br_port_get_rcu() return without a
+NULL check, causing a kernel panic when the bridge port has been
+removed between the original hook invocation and an NFQUEUE
+reinject.
+
+A mere NULL check isn't sufficient, however. As sashiko review
+points out userspace can not only remove the port from the bridge,
+it could also place the device in a different virtual device, e.g.
+macvlan.
+
+If this happens, we must drop the packet, there is no way for us to
+reinject it into the bridge path.
+
+Switch to _upper API, we don't need the bridge port structure.
+Also, this fix keeps another bug intact:
+
+Both nfnetlink_log and nfnetlink_queue use CONFIG_BRIDGE_NETFILTER
+too aggressive, which prevents certain logging features when queueing
+in bridge family: NETFILTER_FAMILY_BRIDGE can be enabled while the old
+CONFIG_BRIDGE_NETFILTER cruft is off.
+
+Fixes tag is a common ancestor, this was always broken.
+
+Fixes: f350a0a87374 ("bridge: use rx_handler_data pointer to store net_bridge_port pointer")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Assisted-by: Claude:claude-sonnet-4-6
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/netfilter/ebt_dnat.c | 4 +-
+ net/bridge/netfilter/ebt_redirect.c | 16 +++++---
+ net/netfilter/nfnetlink_log.c | 23 +++++++++--
+ net/netfilter/nfnetlink_queue.c | 64 +++++++++++++++++++++++++----
+ 4 files changed, 89 insertions(+), 18 deletions(-)
+
+diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c
+index 3fda71a8579d13..73f185cccd63df 100644
+--- a/net/bridge/netfilter/ebt_dnat.c
++++ b/net/bridge/netfilter/ebt_dnat.c
+@@ -39,7 +39,9 @@ ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ dev = xt_in(par);
+ break;
+ case NF_BR_PRE_ROUTING:
+- dev = br_port_get_rcu(xt_in(par))->br->dev;
++ dev = netdev_master_upper_dev_get_rcu(xt_in(par));
++ if (!dev) /* bridge port removed? */
++ return EBT_DROP;
+ break;
+ default:
+ dev = NULL;
+diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c
+index 307790562b4929..83486cd4d564b1 100644
+--- a/net/bridge/netfilter/ebt_redirect.c
++++ b/net/bridge/netfilter/ebt_redirect.c
+@@ -24,12 +24,18 @@ ebt_redirect_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ if (skb_ensure_writable(skb, 0))
+ return EBT_DROP;
+
+- if (xt_hooknum(par) != NF_BR_BROUTING)
+- /* rcu_read_lock()ed by nf_hook_thresh */
+- ether_addr_copy(eth_hdr(skb)->h_dest,
+- br_port_get_rcu(xt_in(par))->br->dev->dev_addr);
+- else
++ if (xt_hooknum(par) != NF_BR_BROUTING) {
++ const struct net_device *dev;
++
++ dev = netdev_master_upper_dev_get_rcu(xt_in(par));
++ if (!dev)
++ return EBT_DROP;
++
++ ether_addr_copy(eth_hdr(skb)->h_dest, dev->dev_addr);
++ } else {
+ ether_addr_copy(eth_hdr(skb)->h_dest, xt_in(par)->dev_addr);
++ }
++
+ skb->pkt_type = PACKET_HOST;
+ return info->target;
+ }
+diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
+index 3da32d2f68e092..cfd68bc005d26b 100644
+--- a/net/netfilter/nfnetlink_log.c
++++ b/net/netfilter/nfnetlink_log.c
+@@ -450,6 +450,23 @@ static int nfulnl_put_bridge(struct nfulnl_instance *inst, const struct sk_buff
+ return -1;
+ }
+
++#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
++static int nflog_put_master_ifindex(struct sk_buff *nlskb, int attr,
++ const struct net_device *dev)
++{
++ const struct net_device *upper;
++
++ if (dev && !netif_is_bridge_port(dev))
++ return 0;
++
++ upper = netdev_master_upper_dev_get_rcu((struct net_device *)dev);
++ if (upper && nla_put_be32(nlskb, attr, htonl(upper->ifindex)))
++ return -EMSGSIZE;
++
++ return 0;
++}
++#endif
++
+ /* This is an inline function, we don't really care about a long
+ * list of arguments */
+ static inline int
+@@ -504,8 +521,7 @@ __build_packet_message(struct nfnl_log_net *log,
+ /* rcu_read_lock()ed by nf_hook_thresh or
+ * nf_log_packet.
+ */
+- nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
+- htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
++ nflog_put_master_ifindex(inst->skb, NFULA_IFINDEX_INDEV, indev))
+ goto nla_put_failure;
+ } else {
+ int physinif;
+@@ -541,8 +557,7 @@ __build_packet_message(struct nfnl_log_net *log,
+ /* rcu_read_lock()ed by nf_hook_thresh or
+ * nf_log_packet.
+ */
+- nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
+- htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
++ nflog_put_master_ifindex(inst->skb, NFULA_IFINDEX_OUTDEV, outdev))
+ goto nla_put_failure;
+ } else {
+ struct net_device *physoutdev;
+diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
+index 8518b620ae50ed..1b517cd2bb58cc 100644
+--- a/net/netfilter/nfnetlink_queue.c
++++ b/net/netfilter/nfnetlink_queue.c
+@@ -426,10 +426,47 @@ static bool nf_ct_drop_unconfirmed(const struct nf_queue_entry *entry, bool *is_
+ return false;
+ }
+
++static bool nf_bridge_port_valid(const struct net_device *dev)
++{
++ if (!dev)
++ return true;
++
++ return netif_is_bridge_port(dev);
++}
++
++/* queued skbs leave rcu protection. We bump device refcount so that
++ * the device cannot go away. However, while packet was out the port
++ * could have been removed from the bridge.
++ *
++ * Ensure in+outdev are still part of a bridge at reinject time.
++ *
++ * The device rx_handler_data could even be pointing at data that is
++ * not a net_bridge_port structure.
++ */
++static bool nf_bridge_ports_valid(const struct nf_queue_entry *entry)
++{
++#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
++ if (!nf_bridge_port_valid(entry->physin) ||
++ !nf_bridge_port_valid(entry->physout))
++ return false;
++#endif
++ if (entry->state.pf != PF_BRIDGE)
++ return true;
++
++ if (!nf_bridge_port_valid(entry->state.in) ||
++ !nf_bridge_port_valid(entry->state.out))
++ return false;
++
++ return true;
++}
++
+ static void nfqnl_reinject(struct nf_queue_entry *entry, unsigned int verdict)
+ {
+ const struct nf_ct_hook *ct_hook;
+
++ if (!nf_bridge_ports_valid(entry))
++ verdict = NF_DROP;
++
+ if (verdict == NF_ACCEPT ||
+ verdict == NF_REPEAT ||
+ verdict == NF_STOP) {
+@@ -622,6 +659,23 @@ static int nf_queue_checksum_help(struct sk_buff *entskb)
+ return skb_checksum_help(entskb);
+ }
+
++#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
++static int nfqnl_put_master_ifindex(struct sk_buff *nlskb, int attr,
++ const struct net_device *dev)
++{
++ const struct net_device *upper;
++
++ if (dev && !netif_is_bridge_port(dev))
++ return 0;
++
++ upper = netdev_master_upper_dev_get_rcu((struct net_device *)dev);
++ if (upper && nla_put_be32(nlskb, attr, htonl(upper->ifindex)))
++ return -EMSGSIZE;
++
++ return 0;
++}
++#endif
++
+ static struct sk_buff *
+ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
+ struct nf_queue_entry *entry,
+@@ -755,10 +809,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
+ * netfilter_bridge) */
+ if (nla_put_be32(skb, NFQA_IFINDEX_PHYSINDEV,
+ htonl(indev->ifindex)) ||
+- /* this is the bridge group "brX" */
+- /* rcu_read_lock()ed by __nf_queue */
+- nla_put_be32(skb, NFQA_IFINDEX_INDEV,
+- htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
++ nfqnl_put_master_ifindex(skb, NFQA_IFINDEX_INDEV, indev))
+ goto nla_put_failure;
+ } else {
+ int physinif;
+@@ -789,10 +840,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
+ * netfilter_bridge) */
+ if (nla_put_be32(skb, NFQA_IFINDEX_PHYSOUTDEV,
+ htonl(outdev->ifindex)) ||
+- /* this is the bridge group "brX" */
+- /* rcu_read_lock()ed by __nf_queue */
+- nla_put_be32(skb, NFQA_IFINDEX_OUTDEV,
+- htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
++ nfqnl_put_master_ifindex(skb, NFQA_IFINDEX_OUTDEV, outdev))
+ goto nla_put_failure;
+ } else {
+ int physoutif;
+--
+2.53.0
+
--- /dev/null
+From 1a90c8ebd96e729c8e3cd49690ed5480017eb673 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 01:10:31 -0700
+Subject: netfilter: x_tables: avoid leaking percpu counter pointers
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f7f2fbb0e893a0238dc464f8d8c0f5609bec584f ]
+
+The native and compat get-entries paths copy the fixed rule entry header
+from the kernelized rule blob to userspace before overwriting the entry's
+counter fields with a sanitized counter snapshot.
+
+On SMP kernels, entry->counters.pcnt contains the percpu allocation
+address used by x_tables rule counters. A caller can provide a userspace
+buffer that faults during the initial fixed-header copy after pcnt has
+been copied but before the later sanitized counter copy runs. The syscall
+then returns -EFAULT while leaving the raw percpu pointer in userspace.
+
+Copy only the fixed entry prefix before counters from the kernelized rule
+blob, then copy the sanitized counter snapshot into the counter field.
+Apply this ordering to the IPv4, IPv6, and ARP native and compat
+get-entries implementations so a fault cannot expose the internal percpu
+counter pointer.
+
+Fixes: 71ae0dff02d7 ("netfilter: xtables: use percpu rule counters")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/netfilter/arp_tables.c | 15 ++++++---------
+ net/ipv4/netfilter/ip_tables.c | 15 ++++++---------
+ net/ipv6/netfilter/ip6_tables.c | 15 ++++++---------
+ 3 files changed, 18 insertions(+), 27 deletions(-)
+
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+index 97ead883e4a13b..b752c9eac998e4 100644
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -702,14 +702,12 @@ static int copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct arpt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct arpt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1327,9 +1325,8 @@ static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct arpt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_arpt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_arpt_entry);
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
+index 3d101613f27fa5..0ba456c4c63416 100644
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -832,14 +832,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ipt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ipt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1228,9 +1226,8 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ipt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ipt_entry);
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+index 7d5602950ae72a..6c5022242cf0b0 100644
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -848,14 +848,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ip6t_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ip6t_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1244,9 +1242,8 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ip6t_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ip6t_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ip6t_entry);
+--
+2.53.0
+
--- /dev/null
+From b522c72995b51f192c71b7ec6d1b8fd1ebc8a2e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 09:13:53 +0800
+Subject: netlabel: validate unlabeled address and mask attribute lengths
+
+From: Chenguang Zhao <zhaochenguang@kylinos.cn>
+
+[ Upstream commit 9772589b57e44aedc240211c5c3f7a684a034d3a ]
+
+netlbl_unlabel_addrinfo_get() used the address attribute length to
+determine whether the attribute data could be read as an IPv4 or IPv6
+address, but did not independently validate the corresponding mask
+attribute length. A crafted Generic Netlink request could therefore
+provide a valid IPv4/IPv6 address attribute with a shorter mask
+attribute, which would later be read as a full struct in_addr or
+struct in6_addr.
+
+NLA_BINARY policy lengths are maximum lengths by default, so use
+NLA_POLICY_EXACT_LEN() for the unlabeled IPv4/IPv6 address and mask
+attributes. This rejects short attributes during policy validation and
+also exposes the exact length requirements through policy introspection.
+
+Fixes: 8cc44579d1bd ("NetLabel: Introduce static network labels for unlabeled connections")
+Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlabel/netlabel_unlabeled.c | 30 ++++++++++--------------------
+ 1 file changed, 10 insertions(+), 20 deletions(-)
+
+diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
+index 9996883bf2b78d..6007cb000da678 100644
+--- a/net/netlabel/netlabel_unlabeled.c
++++ b/net/netlabel/netlabel_unlabeled.c
+@@ -114,14 +114,14 @@ static struct genl_family netlbl_unlabel_gnl_family;
+ /* NetLabel Netlink attribute policy */
+ static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
+ [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
+- [NLBL_UNLABEL_A_IPV6ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV6MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV4ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
+- [NLBL_UNLABEL_A_IPV4MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
++ [NLBL_UNLABEL_A_IPV6ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV6MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV4ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
++ [NLBL_UNLABEL_A_IPV4MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
+ [NLBL_UNLABEL_A_IFACE] = { .type = NLA_NUL_STRING,
+ .len = IFNAMSIZ - 1 },
+ [NLBL_UNLABEL_A_SECCTX] = { .type = NLA_BINARY }
+@@ -764,24 +764,14 @@ static int netlbl_unlabel_addrinfo_get(struct genl_info *info,
+ void **mask,
+ u32 *len)
+ {
+- u32 addr_len;
+-
+ if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR] &&
+ info->attrs[NLBL_UNLABEL_A_IPV4MASK]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+- if (addr_len != sizeof(struct in_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV4MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4MASK]);
+ return 0;
+ } else if (info->attrs[NLBL_UNLABEL_A_IPV6ADDR]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+- if (addr_len != sizeof(struct in6_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV6MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in6_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6MASK]);
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From bf80a69c4781a569a0005e092471d3e970d5b0f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 17:22:47 +0800
+Subject: r8152: handle the return value of usb_reset_device()
+
+From: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+
+[ Upstream commit 19440600e729d4f74a42591a872099cf25c7d28a ]
+
+If usb_reset_device() returns a negative error code, stop the
+process of probing.
+
+Fixes: 10c3271712f5 ("r8152: disable the ECM mode")
+Signed-off-by: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+Reviewed-by: Hayes Wang <hayeswang@realtek.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20260604092247.27158-450-nic_swsd@realtek.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/r8152.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index 1c36816405f13b..f3a4a40d534631 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -9811,7 +9811,12 @@ static int rtl8152_probe_once(struct usb_interface *intf,
+ struct net_device *netdev;
+ int ret;
+
+- usb_reset_device(udev);
++ ret = usb_reset_device(udev);
++ if (ret < 0) {
++ dev_err(&intf->dev, "USB reset failed, errno=%d\n", ret);
++ return ret;
++ }
++
+ netdev = alloc_etherdev(sizeof(struct r8152));
+ if (!netdev) {
+ dev_err(&intf->dev, "Out of memory\n");
+--
+2.53.0
+
--- /dev/null
+From 96b7ae42b632136e4b7a494b8c911cac2fd9995c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 02:32:05 -0700
+Subject: rds: mark snapshot pages dirty in rds_info_getsockopt()
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 512db8267b73a220a64180d95ab5eebe7c4964a8 ]
+
+rds_info_getsockopt() pins the destination user pages with FOLL_WRITE and
+the RDS_INFO_* producers memcpy the snapshot into them through
+kmap_atomic(). Because that copy goes through the kernel direct map, the
+dirty bit on the user PTE is never set, so unpin_user_pages() releases the
+pages without marking them dirty. A file-backed destination page can then
+be reclaimed without writeback, silently discarding the copied data.
+
+Use unpin_user_pages_dirty_lock() with make_dirty=true so the modified
+pages are marked dirty before they are unpinned.
+
+Fixes: a8c879a7ee98 ("RDS: Info and stats")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260608-rds_fix-v1-1-006c88543408@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/info.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/rds/info.c b/net/rds/info.c
+index b6b46a8214a0a5..b3ee5f8238c44d 100644
+--- a/net/rds/info.c
++++ b/net/rds/info.c
+@@ -235,7 +235,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
+
+ out:
+ if (pages)
+- unpin_user_pages(pages, nr_pages);
++ unpin_user_pages_dirty_lock(pages, nr_pages, true);
+ kfree(pages);
+
+ return ret;
+--
+2.53.0
+
--- /dev/null
+From 524009126b15617308336481b694358d752748eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 08:22:34 -0400
+Subject: sctp: fix uninit-value in __sctp_rcv_asconf_lookup()
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit f8373d7090b745728de66308deeecc67e8d319ce ]
+
+__sctp_rcv_asconf_lookup() in net/sctp/input.c only checks that the ASCONF
+chunk can hold the ADDIP header and a parameter header, then calls
+af->from_addr_param(), which reads the full address (16 bytes for IPv6)
+trusting the parameter's declared length.
+
+An unauthenticated peer can send a truncated trailing ASCONF chunk that
+declares an IPv6 address parameter but stops after the 4-byte parameter
+header; reached from the no-association lookup path, from_addr_param() then
+reads uninitialized bytes past the parameter.
+
+Impact: an unauthenticated SCTP peer makes the receive path read up to 16
+bytes of uninitialized memory past a truncated ASCONF address parameter.
+
+The sibling __sctp_rcv_init_lookup() bounds parameters with
+sctp_walk_params(); this path open-codes the fetch and omits the bound.
+Verify the whole address parameter lies within the chunk before
+from_addr_param() reads it, the same class of fix as commit 51e5ad549c43
+("net: sctp: fix KMSAN uninit-value in sctp_inq_pop").
+
+Fixes: df2185771439 ("[SCTP]: Update association lookup to look at ASCONF chunks as well")
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260608122234.459098-1-michael.bommarito@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/input.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/sctp/input.c b/net/sctp/input.c
+index 032a10d82302c3..df5b2187b8fada 100644
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -1204,6 +1204,14 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
+ /* Skip over the ADDIP header and find the Address parameter */
+ param = (union sctp_addr_param *)(asconf + 1);
+
++ /* The whole address parameter must lie within the chunk before
++ * af->from_addr_param() reads the variable-length address; otherwise a
++ * truncated trailing ASCONF chunk lets it read uninitialized bytes past
++ * the parameter.
++ */
++ if (sizeof(*asconf) + ntohs(param->p.length) > ntohs(ch->length))
++ return NULL;
++
+ af = sctp_get_af_specific(param_type2af(param->p.type));
+ if (unlikely(!af))
+ return NULL;
+--
+2.53.0
+
tap-free-page-on-error-paths-in-tap_get_user_xdp.patch
arm64-tlb-allow-xzr-argument-to-tlbi-ops.patch
arm64-tlb-optimize-arm64_workaround_repeat_tlbi.patch
+iomap-don-t-revert-iov_iter-on-partially-completed-b.patch
+dma-debug-fix-physical-address-retrieval-in-debug_dm.patch
+xfrm-policy-fix-use-after-free-on-inexact-bin-in-xfr.patch
+netlabel-validate-unlabeled-address-and-mask-attribu.patch
+gpio-mvebu-fix-null-pointer-dereference-in-suspend-r.patch
+asoc-wm_adsp-fix-null-dereference-when-removing-firm.patch
+tcp-restrict-so_attach_filter-to-priv-users.patch
+net-add-pskb_may_pull-to-skb_gro_receive_list.patch
+net-mlx4-avoid-gcc-10-__bad_copy_from-false-positive.patch
+net-ibm-emac-fix-use-after-free-during-device-remova.patch
+netdev-fix-double-free-in-netdev_nl_bind_rx_doit.patch
+net-phy-clean-the-sfp-upstream-if-phy-probing-fails.patch
+net-qrtr-fix-refcount-saturation-and-potential-uaf-i.patch
+net-mlx5-fix-slab-out-of-bounds-in-mlx5_query_nic_vp.patch
+net-mlx5e-xsk-fix-dma-and-xdp_frame-leak-on-xdp_tx-x.patch
+net-mlx5-use-effective-affinity-mask-for-irq-selecti.patch
+ipv6-sit-reload-inner-ipv6-header-after-gso-offloads.patch
+net-openvswitch-fix-possible-kfree_skb-of-err_ptr.patch
+r8152-handle-the-return-value-of-usb_reset_device.patch
+gpio-zynq-fix-runtime-pm-leak-on-remove.patch
+sctp-fix-uninit-value-in-__sctp_rcv_asconf_lookup.patch
+net-guard-timestamp-cmsgs-to-real-error-queue-skbs.patch
+net-rds-fix-null-deref-in-rds_ib_send_cqe_handler-on.patch
+ip6_vti-fix-incorrect-tunnel-matching-in-vti6_tnl_lo.patch
+rds-mark-snapshot-pages-dirty-in-rds_info_getsockopt.patch
+netfilter-revalidate-bridge-ports.patch
+netfilter-nf_conntrack-destroy-stale-expectfn-expect.patch
+netfilter-x_tables-avoid-leaking-percpu-counter-poin.patch
+netfilter-nf_log-validate-mac-header-was-set-before-.patch
+netfilter-nft_exthdr-fix-register-tracking-for-f_pre.patch
+net-mvpp2-sync-rx-data-at-the-hardware-packet-offset.patch
+net-mvpp2-limit-xdp-frame-size-to-the-rx-buffer.patch
+net-mvpp2-add-metadata-support-for-xdp-mode.patch
+net-mvpp2-refill-rx-buffers-before-xdp-or-skb-use.patch
+net-mvpp2-build-skb-from-xdp-adjusted-data-on-xdp_pa.patch
+ipv6-fix-a-potential-npd-in-cleanup_prefix_route.patch
--- /dev/null
+From 05d65973cac229286fc634130caa58eab1c8aed0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 11:21:34 +0000
+Subject: tcp: restrict SO_ATTACH_FILTER to priv users
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 5d39580f68e6ddeedd15e587282207489dfb3da2 ]
+
+This patch restricts the use of SO_ATTACH_FILTER (cBPF) on TCP sockets
+to users with CAP_NET_ADMIN capability.
+
+This blocks potential side-channel attack where an unprivileged application
+attaches a filter to leak TCP sequence/acknowledgment numbers.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Tamir Shahar <tamirthesis@gmail.com>
+Reported-by: Amit Klein <aksecurity@gmail.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Andrii Nakryiko <andrii@kernel.org>
+Cc: Martin KaFai Lau <martin.lau@linux.dev>
+Cc: Eduard Zingerman <eddyz87@gmail.com>
+Cc: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Cc: Song Liu <song@kernel.org>
+Cc: Yonghong Song <yonghong.song@linux.dev>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: Stanislav Fomichev <sdf@fomichev.me>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 7b6ed7c85a58cc..4a09e780406fe8 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1455,6 +1455,11 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
+ case SO_ATTACH_FILTER: {
+ struct sock_fprog fprog;
+
++ if (sk_is_tcp(sk) &&
++ !sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
++ ret = -EPERM;
++ break;
++ }
+ ret = copy_bpf_fprog_from_user(&fprog, optval, optlen);
+ if (!ret)
+ ret = sk_attach_filter(&fprog, sk);
+--
+2.53.0
+
--- /dev/null
+From a8242415ac4f31c3bea5956433dfa52741c16fa0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 18:49:05 +0900
+Subject: xfrm: policy: fix use-after-free on inexact bin in
+ xfrm_policy_bysel_ctx()
+
+From: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+
+[ Upstream commit 7f2d76c9c03257c0782afef9d95321fa04096f60 ]
+
+Fix the race by pruning the bin while still holding xfrm_policy_lock,
+before dropping it. Use __xfrm_policy_inexact_prune_bin() directly since
+the lock is already held. The wrapper xfrm_policy_inexact_prune_bin()
+becomes unused and is removed.
+
+Race:
+
+ CPU0 (XFRM_MSG_DELPOLICY) CPU1 (XFRM_MSG_NEWSPDINFO)
+ ========================== ==========================
+ xfrm_policy_bysel_ctx():
+ spin_lock_bh(xfrm_policy_lock)
+ bin = xfrm_policy_inexact_lookup()
+ __xfrm_policy_unlink(pol)
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_kill(ret)
+ // wide window, lock not held
+ xfrm_hash_rebuild():
+ spin_lock_bh(xfrm_policy_lock)
+ __xfrm_policy_inexact_flush():
+ kfree_rcu(bin) // bin freed
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_inexact_prune_bin(bin)
+ // UAF: bin is freed
+
+Fixes: 6be3b0db6db8 ("xfrm: policy: add inexact policy search tree infrastructure")
+Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index dab782dcc829de..5a7ec72e17b0e5 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1156,15 +1156,6 @@ static void __xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b, bool
+ }
+ }
+
+-static void xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b)
+-{
+- struct net *net = read_pnet(&b->k.net);
+-
+- spin_lock_bh(&net->xfrm.xfrm_policy_lock);
+- __xfrm_policy_inexact_prune_bin(b, false);
+- spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+-}
+-
+ static void __xfrm_policy_inexact_flush(struct net *net)
+ {
+ struct xfrm_pol_inexact_bin *bin, *t;
+@@ -1707,12 +1698,12 @@ xfrm_policy_bysel_ctx(struct net *net, const struct xfrm_mark *mark, u32 if_id,
+ }
+ ret = pol;
+ }
++ if (bin && delete)
++ __xfrm_policy_inexact_prune_bin(bin, false);
+ spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+
+ if (ret && delete)
+ xfrm_policy_kill(ret);
+- if (bin && delete)
+- xfrm_policy_inexact_prune_bin(bin);
+ return ret;
+ }
+ EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
+--
+2.53.0
+
--- /dev/null
+From 8c4a3db8b59af6f5503e397109dbeee8589354dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 21:38:44 +0530
+Subject: ASoC: SOF: amd: fix for ipc flags check
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit 6042c91df60e825625bc7d5c5c3b5a87b91d5805 ]
+
+Firmware will set dsp_ack to 1 when firmware sends response for the IPC
+command issued by host. Similarly dsp_msg flag will be updated to 1.
+
+During ACP D0 entry, the value read from the sof_dsp_ack_write scratch
+flag can be uninitialized. A non-zero garbage value is treated as a
+pending DSP IPC ack before SOF_FW_BOOT_COMPLETE, causing a spurious
+"IPC reply before FW_BOOT_COMPLETE" log.
+
+Fix the condition checks for ipc flags.
+
+Fixes: 738a2b5e2cc9 ("ASoC: SOF: amd: Add IPC support for ACP IP block")
+Link: https://github.com/thesofproject/linux/pull/5642
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Tested-by: Umang Jain <uajain@igalia.com>
+Link: https://patch.msgid.link/20260609160938.3717513-1-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/amd/acp-ipc.c | 4 ++--
+ sound/soc/sof/amd/acp.h | 2 ++
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/sof/amd/acp-ipc.c b/sound/soc/sof/amd/acp-ipc.c
+index 22d4b807e1bb75..1c3f7601a8c4ce 100644
+--- a/sound/soc/sof/amd/acp-ipc.c
++++ b/sound/soc/sof/amd/acp-ipc.c
+@@ -181,14 +181,14 @@ irqreturn_t acp_sof_ipc_irq_thread(int irq, void *context)
+ }
+
+ dsp_msg = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_msg_write);
+- if (dsp_msg) {
++ if (dsp_msg == ACP_DSP_MSG_SET) {
+ snd_sof_ipc_msgs_rx(sdev);
+ acp_dsp_ipc_host_done(sdev);
+ ipc_irq = true;
+ }
+
+ dsp_ack = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write);
+- if (dsp_ack) {
++ if (dsp_ack == ACP_DSP_ACK_SET) {
+ if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) {
+ spin_lock_irq(&sdev->ipc_lock);
+
+diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
+index 2b7ea8c6410602..7bcb76676a984a 100644
+--- a/sound/soc/sof/amd/acp.h
++++ b/sound/soc/sof/amd/acp.h
+@@ -116,6 +116,8 @@
+ #define ACP_SRAM_PAGE_COUNT 128
+ #define ACP6X_SDW_MAX_MANAGER_COUNT 2
+ #define ACP70_SDW_MAX_MANAGER_COUNT ACP6X_SDW_MAX_MANAGER_COUNT
++#define ACP_DSP_MSG_SET 1
++#define ACP_DSP_ACK_SET 1
+
+ enum clock_source {
+ ACP_CLOCK_96M = 0,
+--
+2.53.0
+
--- /dev/null
+From 0e78363d86abed255e370db5edfdaf4a0f157674 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 11:12:44 +0100
+Subject: ASoC: wm_adsp: Fix NULL dereference when removing firmware controls
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 7d3fb78b550301e43fdc60312aed733069694426 ]
+
+In wm_adsp_control_remove() check that the priv pointer is not NULL
+before attempting to cleanup what it points to.
+
+When cs_dsp creates a control it calls wm_adsp_control_add_cb() so that
+wm_adsp can create its own private control data. There are two cases
+where private data is not created:
+
+1. The control is a SYSTEM control, so an ALSA control is not created.
+
+2. The codec driver has registered a control_add() callback that
+ hides the control, so wm_adsp_control_add() is not called.
+
+When cs_dsp_remove destroys its control list it calls
+wm_adsp_control_remove() for each control. But wm_adsp_control_remove()
+was attempting to cleanup the private data pointed to by cs_ctl->priv
+without checking the pointer for NULL.
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Fixes: 0700bc2fb94c ("ASoC: wm_adsp: Separate generic cs_dsp_coeff_ctl handling")
+Link: https://patch.msgid.link/20260604101244.1402862-1-rf@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/wm_adsp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
+index 8782c331e92529..751a3c25e4f0b1 100644
+--- a/sound/soc/codecs/wm_adsp.c
++++ b/sound/soc/codecs/wm_adsp.c
+@@ -666,6 +666,9 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl)
+ {
+ struct wm_coeff_ctl *ctl = cs_ctl->priv;
+
++ if (!ctl)
++ return;
++
+ cancel_work_sync(&ctl->work);
+
+ kfree(ctl->name);
+--
+2.53.0
+
--- /dev/null
+From 2e0c7b62d85f19964a0c424617588a59c0218e0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 22:07:09 +0530
+Subject: bnge: fix context mem iteration
+
+From: Vikas Gupta <vikas.gupta@broadcom.com>
+
+[ Upstream commit 3847d94783c0b893c27ff0b26a3325796d9444c6 ]
+
+The firmware advertises context memory (backing store) types
+through a linked list, with BNGE_CTX_INV serving as the
+end-of-list sentinel.
+However, the driver incorrectly assumes that the list is strictly
+ordered and prematurely terminates traversal when it encounters
+an unrecognized type (>=BNGE_CTX_V2_MAX). As a result, any valid
+context types that appear later in the chain are silently skipped,
+leading to incomplete memory configuration and eventual driver load
+failure.
+
+Fix this by traversing the entire list until the BNGE_CTX_INV sentinel
+is reached, while safely ignoring only those context types that fall
+outside the supported range.
+
+Fixes: 29c5b358f385 ("bng_en: Add backing store support")
+Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
+Reviewed-by: Dharmender Garg <dharmender.garg@broadcom.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
+index 2994f10446a63c..0042d7d6ff9bc2 100644
+--- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
++++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
+@@ -259,7 +259,7 @@ int bnge_hwrm_func_backing_store_qcaps(struct bnge_dev *bd)
+ struct hwrm_func_backing_store_qcaps_v2_output *resp;
+ struct hwrm_func_backing_store_qcaps_v2_input *req;
+ struct bnge_ctx_mem_info *ctx;
+- u16 type;
++ u16 type, next_type;
+ int rc;
+
+ if (bd->ctx)
+@@ -276,8 +276,8 @@ int bnge_hwrm_func_backing_store_qcaps(struct bnge_dev *bd)
+
+ resp = bnge_hwrm_req_hold(bd, req);
+
+- for (type = 0; type < BNGE_CTX_V2_MAX; ) {
+- struct bnge_ctx_mem_type *ctxm = &ctx->ctx_arr[type];
++ for (type = 0; type < BNGE_CTX_INV; type = next_type) {
++ struct bnge_ctx_mem_type *ctxm;
+ u8 init_val, init_off, i;
+ __le32 *p;
+ u32 flags;
+@@ -286,8 +286,14 @@ int bnge_hwrm_func_backing_store_qcaps(struct bnge_dev *bd)
+ rc = bnge_hwrm_req_send(bd, req);
+ if (rc)
+ goto ctx_done;
++
++ next_type = le16_to_cpu(resp->next_valid_type);
++ if (type >= BNGE_CTX_V2_MAX)
++ continue;
++
++ ctxm = &ctx->ctx_arr[type];
+ flags = le32_to_cpu(resp->flags);
+- type = le16_to_cpu(resp->next_valid_type);
++
+ if (!(flags &
+ FUNC_BACKING_STORE_QCAPS_V2_RESP_FLAGS_TYPE_VALID))
+ continue;
+--
+2.53.0
+
--- /dev/null
+From d327d997176ac629827569af7dc105849d6135fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 20:37:08 +0800
+Subject: dma-debug: fix physical address retrieval in
+ debug_dma_sync_sg_for_device
+
+From: Li RongQing <lirongqing@baidu.com>
+
+[ Upstream commit 9bfaa86b405381326c971984fd6da184c289713f ]
+
+In debug_dma_sync_sg_for_device(), when iterating over a scatterlist,
+the debug entry population mistakenly uses the head of the scatterlist
+'sg' to fetch the physical address via sg_phys(), instead of using the
+current iterator variable 's'.
+
+This causes dma-debug to track the physical address of the very first
+scatterlist entry for all subsequent entries in the list.
+
+Fix this by passing the correct loop iterator 's' to sg_phys()
+
+Fixes: 9d4f645a1fd49ee ("dma-debug: store a phys_addr_t in struct dma_debug_entry")
+Signed-off-by: Li RongQing <lirongqing@baidu.com>
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20260603123708.1665-1-lirongqing@baidu.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/dma/debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c
+index fa4aac33391723..03780f39613cca 100644
+--- a/kernel/dma/debug.c
++++ b/kernel/dma/debug.c
+@@ -1555,7 +1555,7 @@ void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+ struct dma_debug_entry ref = {
+ .type = dma_debug_sg,
+ .dev = dev,
+- .paddr = sg_phys(sg),
++ .paddr = sg_phys(s),
+ .dev_addr = sg_dma_address(s),
+ .size = sg_dma_len(s),
+ .direction = direction,
+--
+2.53.0
+
--- /dev/null
+From bc5a32e3fa194e68226719ed2b9339b19c44cb60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 09:37:23 +0800
+Subject: dma-mapping: direct: fix missing mapping for THRU_HOST_BRIDGE
+ segments
+
+From: Li RongQing <lirongqing@baidu.com>
+
+[ Upstream commit 560000d619ef162568746ce287f0c725e24ea967 ]
+
+In dma_direct_map_sg(), the case PCI_P2PDMA_MAP_THRU_HOST_BRIDGE
+incorrectly used 'break' instead of falling through to MAP_NONE.
+As a result, segments traversing the host bridge skipped the required
+dma_direct_map_phys() call entirely, leaving sg->dma_address
+uninitialized and leading to DMA failures. Fix this by using
+'fallthrough;'.
+
+Fixes: a25e7962db0d79 ("PCI/P2PDMA: Refactor the p2pdma mapping helpers")
+Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
+Signed-off-by: Li RongQing <lirongqing@baidu.com>
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20260603013723.2439-1-lirongqing@baidu.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/dma/direct.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
+index f973e7e73c90bb..fd483b558b504c 100644
+--- a/kernel/dma/direct.c
++++ b/kernel/dma/direct.c
+@@ -469,7 +469,7 @@ int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
+ * must be mapped with CPU physical address and not PCI
+ * bus addresses.
+ */
+- break;
++ fallthrough;
+ case PCI_P2PDMA_MAP_NONE:
+ sg->dma_address = dma_direct_map_phys(dev, sg_phys(sg),
+ sg->length, dir, attrs);
+--
+2.53.0
+
--- /dev/null
+From e187f982337d7823c46dc75a63c650f35d298b2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 16:43:34 +0800
+Subject: gpio: mvebu: fix NULL pointer dereference in suspend/resume
+
+From: Yun Zhou <yun.zhou@windriver.com>
+
+[ Upstream commit b9ad50d7505ebd48282ec3630258dc820fc85c81 ]
+
+mvebu_pwm_suspend() and mvebu_pwm_resume() are called for all GPIO
+banks during suspend/resume, but not all banks have PWM functionality.
+GPIO banks without PWM have mvchip->mvpwm set to NULL.
+
+Calling mvebu_pwm_suspend() with mvpwm == NULL causes a NULL pointer
+dereference when it tries to access mvpwm->blink_select.
+
+ Unable to handle kernel NULL pointer dereference at virtual address 00000020 when write
+ [00000020] *pgd=00000000
+ Internal error: Oops: 815 [#1] PREEMPT ARM
+ Modules linked in:
+ CPU: 0 UID: 0 PID: 406 Comm: sh Not tainted 6.12.74-rt12-yocto-standard-g4e96f98fb7db-dirty #353
+ Hardware name: Marvell Armada 370/XP (Device Tree)
+ PC is at regmap_mmio_read+0x38/0x54
+ LR is at regmap_mmio_read+0x38/0x54
+ pc : [<c05fd2ac>] lr : [<c05fd2ac>] psr: 200f0013
+ sp : f0c11d10 ip : 00000000 fp : c100d2f0
+ r10: c14fb854 r9 : 00000000 r8 : 00000000
+ r7 : c1799c00 r6 : 00000020 r5 : 00000020 r4 : c179c7c0
+ r3 : f0a231a0 r2 : 00000020 r1 : 00000020 r0 : 00000000
+ Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
+ Control: 10c5387d Table: 135ec059 DAC: 00000051
+ Call trace:
+ regmap_mmio_read from _regmap_bus_reg_read+0x78/0xac
+ _regmap_bus_reg_read from _regmap_read+0x60/0x154
+ _regmap_read from regmap_read+0x3c/0x60
+ regmap_read from mvebu_gpio_suspend+0xa4/0x14c
+ mvebu_gpio_suspend from dpm_run_callback+0x54/0x180
+ dpm_run_callback from device_suspend+0x124/0x630
+ device_suspend from dpm_suspend+0x124/0x270
+ dpm_suspend from dpm_suspend_start+0x64/0x6c
+ dpm_suspend_start from suspend_devices_and_enter+0x140/0x8e8
+ suspend_devices_and_enter from pm_suspend+0x2fc/0x308
+ pm_suspend from state_store+0x6c/0xc8
+ state_store from kernfs_fop_write_iter+0x10c/0x1f8
+ kernfs_fop_write_iter from vfs_write+0x270/0x468
+ vfs_write from ksys_write+0x70/0xf0
+ ksys_write from ret_fast_syscall+0x0/0x54
+
+Add a NULL check for mvchip->mvpwm before calling the PWM
+suspend/resume functions.
+
+Fixes: 757642f9a584 ("gpio: mvebu: Add limited PWM support")
+Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
+Link: https://patch.msgid.link/20260608084334.2960803-1-yun.zhou@windriver.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-mvebu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
+index ac799fced950e3..a7018e8ed88b10 100644
+--- a/drivers/gpio/gpio-mvebu.c
++++ b/drivers/gpio/gpio-mvebu.c
+@@ -997,7 +997,7 @@ static int mvebu_gpio_suspend(struct platform_device *pdev, pm_message_t state)
+ BUG();
+ }
+
+- if (IS_REACHABLE(CONFIG_PWM))
++ if (IS_REACHABLE(CONFIG_PWM) && mvchip->mvpwm)
+ mvebu_pwm_suspend(mvchip);
+
+ return 0;
+@@ -1049,7 +1049,7 @@ static int mvebu_gpio_resume(struct platform_device *pdev)
+ BUG();
+ }
+
+- if (IS_REACHABLE(CONFIG_PWM))
++ if (IS_REACHABLE(CONFIG_PWM) && mvchip->mvpwm)
+ mvebu_pwm_resume(mvchip);
+
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From 99fab45149831505bf0250fa54f418f8aaebc5c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 01:05:02 +0200
+Subject: gpio: rockchip: fix generic IRQ chip leak on remove
+
+From: Marco Scardovi <scardracs@disroot.org>
+
+[ Upstream commit 1c1e0fc88d6ef65bf15d517853251f75ab9d18c3 ]
+
+The driver allocates domain generic chips using
+irq_alloc_domain_generic_chips() during probe. However, on driver
+remove/teardown, the generic chips are not automatically freed when the
+IRQ domain is removed because the domain flags do not include
+IRQ_DOMAIN_FLAG_DESTROY_GC.
+
+This causes both the domain generic chips structure and the associated
+generic chips to be leaked. Additionally, the generic chips remain on
+the global gc_list and may later be visited by generic IRQ chip suspend,
+resume, or shutdown callbacks after the GPIO bank has been removed,
+potentially resulting in a use-after-free and kernel crash.
+
+Fix the resource leak by explicitly calling
+irq_domain_remove_generic_chips() before removing the IRQ domain in
+rockchip_gpio_remove().
+
+Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
+Assisted-by: Antigravity:gemini-3.5-flash
+Signed-off-by: Marco Scardovi <scardracs@disroot.org>
+Link: https://patch.msgid.link/20260607230504.35392-2-scardracs@disroot.org
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-rockchip.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index 1ef0ba956cfd8c..46dd9085d9c8cd 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -802,8 +802,10 @@ static void rockchip_gpio_remove(struct platform_device *pdev)
+ struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);
+
+ irq_set_chained_handler_and_data(bank->irq, NULL, NULL);
+- if (bank->domain)
++ if (bank->domain) {
++ irq_domain_remove_generic_chips(bank->domain);
+ irq_domain_remove(bank->domain);
++ }
+ gpiochip_remove(&bank->gpio_chip);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From f6716c72fe40889a127e42b82f9e2a383fb50a86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 15:33:13 +0800
+Subject: gpio: zynq: fix runtime PM leak on remove
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit 6edb934de9bda3b7abcec856eaee6fc8b4278dd1 ]
+
+pm_runtime_get_sync() increments the runtime PM usage counter even when it
+returns an error. zynq_gpio_remove() uses it to keep the controller active
+while removing the GPIO chip, but never drops the usage counter again.
+
+Balance the get with pm_runtime_put_noidle() after disabling runtime PM.
+
+Fixes: 3242ba117e9b ("gpio: Add driver for Zynq GPIO controller")
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Link: https://patch.msgid.link/20260609073313.5-1-ruoyuw560@gmail.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-zynq.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c
+index 0ffd76e8951fc0..c2e4a79cd6d8ce 100644
+--- a/drivers/gpio/gpio-zynq.c
++++ b/drivers/gpio/gpio-zynq.c
+@@ -1017,6 +1017,7 @@ static void zynq_gpio_remove(struct platform_device *pdev)
+ gpiochip_remove(&gpio->chip);
+ device_set_wakeup_capable(&pdev->dev, 0);
+ pm_runtime_disable(&pdev->dev);
++ pm_runtime_put_noidle(&pdev->dev);
+ }
+
+ static struct platform_driver zynq_gpio_driver = {
+--
+2.53.0
+
--- /dev/null
+From d31f2e63f9f8e9438a10054eab36bea40b4eaef5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 15:55:10 -0700
+Subject: ice: fix missing priority callbacks for U.FL DPLL pins
+
+From: Petr Oros <poros@redhat.com>
+
+[ Upstream commit f1fa677e428e8873486938086bd934dc18169b47 ]
+
+The U.FL2 input pin advertises DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE
+in its capability mask, but ice_dpll_pin_ufl_ops does not provide
+.prio_get and .prio_set callbacks. As a result the DPLL subsystem
+cannot report or accept priority for U.FL pins: pin-get omits the prio
+field on U.FL2 and pin-set with prio is rejected as invalid, even
+though the capability is present. This prevents user space from using
+priority to select or disable U.FL2 as a DPLL input source.
+
+Reproducer with iproute2 (dpll command):
+
+ # dpll pin show board-label U.FL2
+ pin id 16:
+ module-name ice
+ board-label U.FL2
+ type ext
+ capabilities priority-can-change|state-can-change
+ parent-device:
+ id 0 direction input state selectable phase-offset 0
+ /* note: no "prio" between "direction" and "state",
+ even though priority-can-change is advertised */
+
+ # dpll pin set id 16 parent-device 0 prio 5
+ RTNETLINK answers: Operation not supported
+
+After the fix the prio field is reported by pin show and pin set with
+prio is accepted on U.FL2.
+
+Add the missing .prio_get and .prio_set callbacks to
+ice_dpll_pin_ufl_ops, reusing ice_dpll_sw_input_prio_{get,set}. The
+same ops struct is shared by U.FL1 and U.FL2: U.FL2 (input) delegates
+to the backing hardware input pin, while U.FL1 (output) does not
+advertise DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE so the dpll core
+capability gate never invokes prio_set for it, and prio_get reports
+the OUTPUT sentinel (ICE_DPLL_PIN_PRIO_OUTPUT) on the output side
+exactly like the SMA path does today.
+
+Fixes: 2dd5d03c77e2 ("ice: redesign dpll sma/u.fl pins control")
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Petr Oros <poros@redhat.com>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Link: https://patch.msgid.link/20260602225513.393338-3-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_dpll.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
+index 14048ac5eff56f..81267bae0e5cb5 100644
+--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
++++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
+@@ -2481,6 +2481,8 @@ static const struct dpll_pin_ops ice_dpll_pin_ufl_ops = {
+ .state_on_dpll_set = ice_dpll_ufl_pin_state_set,
+ .state_on_dpll_get = ice_dpll_sw_pin_state_get,
+ .direction_get = ice_dpll_pin_sw_direction_get,
++ .prio_get = ice_dpll_sw_input_prio_get,
++ .prio_set = ice_dpll_sw_input_prio_set,
+ .frequency_get = ice_dpll_sw_pin_frequency_get,
+ .frequency_set = ice_dpll_sw_pin_frequency_set,
+ .esync_set = ice_dpll_sw_esync_set,
+--
+2.53.0
+
--- /dev/null
+From 7a8feaeb35f0a82bfb6c0f8dba3885751e8abfeb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 15:55:11 -0700
+Subject: idpf: fix mailbox capability for set device clock time
+
+From: Alok Tiwari <alok.a.tiwari@oracle.com>
+
+[ Upstream commit 85b0cbc1f38bc1e38956a9e6d7b04d309b435697 ]
+
+The current code incorrectly uses VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME
+for both direct and mailbox capabilities, causing mailbox-only support
+to be ignored and potentially reporting IDPF_PTP_NONE.
+
+Fixes: d5dba8f7206da ("idpf: add PTP clock configuration")
+Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Link: https://patch.msgid.link/20260602225513.393338-4-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/idpf/idpf_ptp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_ptp.c b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
+index 31c5593550e1af..1063c1a96ee5c1 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_ptp.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
+@@ -51,7 +51,7 @@ void idpf_ptp_get_features_access(const struct idpf_adapter *adapter)
+
+ /* Set the device clock time */
+ direct = VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME;
+- mailbox = VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME;
++ mailbox = VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME_MB;
+ ptp->set_dev_clk_time_access = idpf_ptp_get_access(adapter,
+ direct,
+ mailbox);
+--
+2.53.0
+
--- /dev/null
+From c66bd9717ef227118bdb317afc8fcd2b9531cc57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 16:46:13 +0000
+Subject: ip6_vti: fix incorrect tunnel matching in vti6_tnl_lookup()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit a5c0359f5cbc51a2e2b114d6041e0f3c73f903e9 ]
+
+In vti6_tnl_lookup(), when an exact match for a tunnel fails,
+the code falls back to searching for wildcard tunnels:
+
+- Tunnels matching the packet's local address, with any remote address
+ wildcard remote).
+
+- Tunnels matching the packet's remote address, with any local address
+ (wildcard local).
+
+However, vti6 stores all these different types of tunnels in the same
+hash table (ip6n->tnls_r_l) prone to hash collisions.
+
+The bug is that the fallback search loops in vti6_tnl_lookup() were
+missing checks to ensure that the candidate tunnel actually has
+a wildcard address.
+
+Fixes: fbe68ee87522 ("vti6: Add a lookup method for tunnels with wildcard endpoints.")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260608164613.933023-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_vti.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
+index d2b74a6f2cf62d..d871cab6938d36 100644
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -106,6 +106,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(&any, local);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(local, &t->parms.laddr) &&
++ ipv6_addr_any(&t->parms.raddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+@@ -113,6 +114,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(remote, &any);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(remote, &t->parms.raddr) &&
++ ipv6_addr_any(&t->parms.laddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+--
+2.53.0
+
--- /dev/null
+From ef76e998461a9a89687e3354715ddf3f81809656 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 15:59:18 +0000
+Subject: ip6_vti: set netns_immutable on the fallback device.
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit d289d5307762d1838aaece22c6b6fcad9e8865f9 ]
+
+john1988 and Noam Rathaus reported that vti6_init_net() does not set the
+netns_immutable flag on the per-netns fallback tunnel device (ip6_vti0).
+
+Other similar tunnel drivers (like ip6_tunnel, sit, ip6_gre, and ip_tunnel)
+correctly set this flag during their fallback device initialization to
+prevent them from being moved to another network namespace.
+
+Fixes: 61220ab34948 ("vti6: Enable namespace changing")
+Reported-by: Noam Rathaus <noamr@ssd-disclosure.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260608155918.787644-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_vti.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
+index df793c8bfffb0a..d2b74a6f2cf62d 100644
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -1159,6 +1159,7 @@ static int __net_init vti6_init_net(struct net *net)
+ goto err_alloc_dev;
+ dev_net_set(ip6n->fb_tnl_dev, net);
+ ip6n->fb_tnl_dev->rtnl_link_ops = &vti6_link_ops;
++ ip6n->fb_tnl_dev->netns_immutable = true;
+
+ err = vti6_fb_tnl_dev_init(ip6n->fb_tnl_dev);
+ if (err < 0)
+--
+2.53.0
+
--- /dev/null
+From 04d48bd2630d218d63b61f8eaba76313257e9ce2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 17:54:48 +0300
+Subject: ipv6: Fix a potential NPD in cleanup_prefix_route()
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit b70c687b7cf267fb08586667a3946c8851cad672 ]
+
+addrconf_get_prefix_route() can return the fib6_null_entry sentinel
+entry which has a NULL fib6_table pointer. Therefore, before setting the
+route's expiration time, check that we are not working with this entry,
+as otherwise a NPD will be triggered [1].
+
+Note that the other callers of addrconf_get_prefix_route() are not
+susceptible to this bug:
+
+1. addrconf_prefix_rcv(): Requests a route with the 'RTF_ADDRCONF |
+ RTF_PREFIX_RT' flags which are not set on fib6_null_entry.
+
+2. modify_prefix_route(): Fixed by commit a747e02430df ("ipv6: avoid
+ possible NULL deref in modify_prefix_route()").
+
+3. __ipv6_ifa_notify(): Calls ip6_del_rt() which specifically checks for
+ fib6_null_entry and returns an error.
+
+[1]
+Oops: general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] SMP KASAN
+KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037]
+[...]
+Call Trace:
+<TASK>
+__kasan_check_byte (mm/kasan/common.c:573)
+lock_acquire.part.0 (kernel/locking/lockdep.c:5842 (discriminator 1))
+_raw_spin_lock_bh (kernel/locking/spinlock.c:182 (discriminator 1))
+cleanup_prefix_route (net/ipv6/addrconf.c:1280)
+ipv6_del_addr (net/ipv6/addrconf.c:1342)
+inet6_addr_del.isra.0 (net/ipv6/addrconf.c:3119)
+inet6_rtm_deladdr (net/ipv6/addrconf.c:4812)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6997)
+netlink_rcv_skb (net/netlink/af_netlink.c:2555)
+netlink_unicast (net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1899)
+__sock_sendmsg (net/socket.c:802 (discriminator 4))
+____sys_sendmsg (net/socket.c:2698)
+___sys_sendmsg (net/socket.c:2752)
+__sys_sendmsg (net/socket.c:2784)
+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)
+
+Fixes: 5eb902b8e719 ("net/ipv6: Remove expired routes with a separated list of routes.")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Reviewed-by: David Ahern <dahern@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260609145448.768318-1-idosch@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/addrconf.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 2d4c3d9c1a2a51..b2e1328371d3f6 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1265,6 +1265,7 @@ static void
+ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires,
+ bool del_rt, bool del_peer)
+ {
++ struct net *net = dev_net(ifp->idev->dev);
+ struct fib6_table *table;
+ struct fib6_info *f6i;
+
+@@ -1273,9 +1274,10 @@ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires,
+ ifp->idev->dev, 0, RTF_DEFAULT, true);
+ if (f6i) {
+ if (del_rt)
+- ip6_del_rt(dev_net(ifp->idev->dev), f6i, false);
++ ip6_del_rt(net, f6i, false);
+ else {
+- if (!(f6i->fib6_flags & RTF_EXPIRES)) {
++ if (f6i != net->ipv6.fib6_null_entry &&
++ !(f6i->fib6_flags & RTF_EXPIRES)) {
+ table = f6i->fib6_table;
+ spin_lock_bh(&table->tb6_lock);
+
+--
+2.53.0
+
--- /dev/null
+From 34475980a8afb2f7e3884e55348d935c02534c61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 00:34:48 -0700
+Subject: ipv6: sit: reload inner IPv6 header after GSO offloads
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f0e42f0c4337b1f220de1ddd63f47197c7dee4de ]
+
+ipip6_tunnel_xmit() caches the inner IPv6 header pointer at function
+entry and continues using it after iptunnel_handle_offloads().
+
+For GSO skbs, iptunnel_handle_offloads() calls skb_header_unclone().
+When the skb header is cloned, skb_header_unclone() can call
+pskb_expand_head(), which may move the skb head. The pskb_expand_head()
+contract requires pointers into the skb header to be reloaded after the
+call.
+
+If the later skb_realloc_headroom() branch is not taken, SIT uses the
+stale iph6 pointer to read the inner hop limit and DS field. That can
+read from a freed skb head after the old head's remaining clone is
+released.
+
+Reload iph6 after the offload helper succeeds and before subsequent
+reads from the inner IPv6 header. Keep the existing reload after
+skb_realloc_headroom(), since that branch can also replace the skb.
+
+Fixes: 14909664e4e1 ("sit: Setup and TX path for sit/UDP foo-over-udp encapsulation")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot+6eb9ca986d80f6f88cf9@syzkaller.appspotmail.com
+Link: https://patch.msgid.link/20260605073448.6524-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/sit.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index cf37ad9686e698..6a833ee665e9b4 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -960,6 +960,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ ip_rt_put(rt);
+ goto tx_error;
+ }
++ iph6 = ipv6_hdr(skb);
+
+ if (df) {
+ mtu = dst_mtu(&rt->dst) - t_hlen;
+--
+2.53.0
+
--- /dev/null
+From 1b1d95d28702273c9f70650511ab2a98a9702e7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:46:25 +0000
+Subject: net: add pskb_may_pull() to skb_gro_receive_list()
+
+From: HanQuan <eilaimemedsnaimel@gmail.com>
+
+[ Upstream commit f2bb3434544454099a5b6dec213567267b05d79d ]
+
+skb_gro_receive_list() calls skb_pull(skb, skb_gro_offset(skb)) without
+first ensuring the data is in the linear area via pskb_may_pull(). When
+the skb arrives via napi_gro_frags(), skb_headlen can be 0 (all data in
+page fragments) while skb_gro_offset is non-zero (after IP+TCP header
+parsing). The skb_pull() then decrements skb->len by skb_gro_offset
+but skb->data_len stays unchanged, hitting BUG_ON(skb->len < skb->data_len)
+in __skb_pull().
+
+The UDP fraglist GRO path already contains this guard at
+udp_offload.c:749. Adding it to skb_gro_receive_list() itself provides
+centralized protection for all callers (TCP, UDP, and any future
+protocols), and ensures the precondition of skb_pull() is satisfied
+before it is called.
+
+On pskb_may_pull() failure, set NAPI_GRO_CB(skb)->flush = 1 so the
+skb is not held as a new GRO head and is instead delivered through the
+normal receive path, matching the UDP handling.
+
+Fixes: 8d95dc474f85 ("net: add code for TCP fraglist GRO")
+Reported-by: HanQuan <eilaimemedsnaimel@gmail.com>
+Reported-by: MingXuan <bwnie0730@outlook.com>
+Signed-off-by: HanQuan <eilaimemedsnaimel@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/gro.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/core/gro.c b/net/core/gro.c
+index b5f790a643d497..9ec8a46b30bb97 100644
+--- a/net/core/gro.c
++++ b/net/core/gro.c
+@@ -234,6 +234,11 @@ int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
+ if (unlikely(p->len + skb->len >= 65536))
+ return -E2BIG;
+
++ if (!pskb_may_pull(skb, skb_gro_offset(skb))) {
++ NAPI_GRO_CB(skb)->flush = 1;
++ return -ENOMEM;
++ }
++
+ if (NAPI_GRO_CB(p)->last == p)
+ skb_shinfo(p)->frag_list = skb;
+ else
+--
+2.53.0
+
--- /dev/null
+From a4eeb31d7ade52e6e3bbe92b25762fca67ab0afe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 08:07:04 +0000
+Subject: net: ena: PHC: Add missing barrier
+
+From: Arthur Kiyanovski <akiyano@amazon.com>
+
+[ Upstream commit 954981dbbfbd78f21d2fbac1ac0742dbf38b4e69 ]
+
+Add dma_rmb() barrier after req_id completion check in
+ena_com_phc_get_timestamp(). On weakly-ordered architectures,
+payload fields may be read before req_id is observed as updated.
+
+Fixes: e0ea34158ee8 ("net: ena: Add PHC support in the ENA driver")
+Closes: https://sashiko.dev/#/patchset/20260430032507.11586-1-akiyano%40amazon.com
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c
+index 8c86789d867a5f..297fb36ab8c16f 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_com.c
++++ b/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -1880,6 +1880,11 @@ int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp)
+ continue;
+ }
+
++ /* Ensure PHC payload (timestamp, error_flags) is read
++ * after req_id update is observed
++ */
++ dma_rmb();
++
+ /* req_id was updated by the device which indicates that
+ * PHC timestamp and error_flags are updated too,
+ * checking errors before retrieving timestamp
+--
+2.53.0
+
--- /dev/null
+From 7293fb4a339175d1df5f4189357d30a544e1b765 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 19:18:19 -0700
+Subject: net: guard timestamp cmsgs to real error queue skbs
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit 1ee90b77b727df903033db873c75caac5c27ec98 ]
+
+skb_is_err_queue() treats PACKET_OUTGOING as the sole marker for an skb
+from sk_error_queue. That assumption is not true for AF_PACKET sockets:
+outgoing packet taps are also delivered to packet sockets with
+skb->pkt_type == PACKET_OUTGOING, but their skb->cb is owned by AF_PACKET
+instead of struct sock_exterr_skb.
+
+If such an skb is received with timestamping enabled, the generic
+timestamp cmsg path can read AF_PACKET control-buffer state as
+sock_exterr_skb::opt_stats. With SO_RXQ_OVFL enabled, the packet drop
+counter overlaps opt_stats. An odd drop count makes the path emit
+SCM_TIMESTAMPING_OPT_STATS with skb->len and skb->data. For non-linear
+skbs this copies past the linear head and can trigger hardened usercopy or
+disclose adjacent heap contents.
+
+Keep skb_is_err_queue() local to net/socket.c, but make it verify that
+the PACKET_OUTGOING marker is paired with the sock_rmem_free destructor
+installed by sock_queue_err_skb(). AF_PACKET receive skbs use normal
+receive ownership and no longer pass as error-queue skbs, while legitimate
+sk_error_queue entries keep the PACKET_OUTGOING marker and sock_rmem_free
+ownership.
+
+Fixes: 8605330aac5a ("tcp: fix SCM_TIMESTAMPING_OPT_STATS for normal skbs")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260607021819.49698-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 1 +
+ net/core/skbuff.c | 6 +++---
+ net/socket.c | 11 ++++++-----
+ 3 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 9540dcc5a0c012..5a26a3834ac68f 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1818,6 +1818,7 @@ struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size,
+ gfp_t priority);
+ void skb_orphan_partial(struct sk_buff *skb);
+ void sock_rfree(struct sk_buff *skb);
++void sock_rmem_free(struct sk_buff *skb);
+ void sock_efree(struct sk_buff *skb);
+ #ifdef CONFIG_INET
+ void sock_edemux(struct sk_buff *skb);
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 745bb0a67c6a4c..43dca2c045766f 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -5399,7 +5399,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
+ }
+ EXPORT_SYMBOL_GPL(skb_cow_data);
+
+-static void sock_rmem_free(struct sk_buff *skb)
++void sock_rmem_free(struct sk_buff *skb)
+ {
+ struct sock *sk = skb->sk;
+
+@@ -5408,8 +5408,8 @@ static void sock_rmem_free(struct sk_buff *skb)
+
+ static void skb_set_err_queue(struct sk_buff *skb)
+ {
+- /* pkt_type of skbs received on local sockets is never PACKET_OUTGOING.
+- * So, it is safe to (mis)use it to mark skbs on the error queue.
++ /* The error-queue test in skb_is_err_queue() matches this marker
++ * with the sock_rmem_free destructor installed by sock_queue_err_skb().
+ */
+ skb->pkt_type = PACKET_OUTGOING;
+ BUILD_BUG_ON(PACKET_OUTGOING == 0);
+diff --git a/net/socket.c b/net/socket.c
+index 2b6e11b085ebd7..4ce6ddd768fb46 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -792,12 +792,13 @@ EXPORT_SYMBOL(kernel_sendmsg);
+
+ static bool skb_is_err_queue(const struct sk_buff *skb)
+ {
+- /* pkt_type of skbs enqueued on the error queue are set to
+- * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
+- * in recvmsg, since skbs received on a local socket will never
+- * have a pkt_type of PACKET_OUTGOING.
++ /* Error-queue skbs are marked as PACKET_OUTGOING in
++ * skb_set_err_queue() and use the destructor installed by
++ * sock_queue_err_skb(). PACKET_OUTGOING alone is not unique:
++ * AF_PACKET outgoing taps use the same pkt_type.
+ */
+- return skb->pkt_type == PACKET_OUTGOING;
++ return skb->pkt_type == PACKET_OUTGOING &&
++ skb->destructor == sock_rmem_free;
+ }
+
+ /* On transmit, software and hardware timestamps are returned independently.
+--
+2.53.0
+
--- /dev/null
+From cb3a84a3ba0a470dad778a7e12ebd7413c6a6fb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 15:12:17 -0700
+Subject: net: ibm: emac: Fix use-after-free during device removal
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit a0130d682222ae21afc395aead7cd2d87e1a8358 ]
+
+The driver was using devm_register_netdev() which causes unregister_netdev()
+to be deferred until the devres cleanup phase, which runs after emac_remove()
+returns. This creates a use-after-free window where:
+
+1. emac_remove() is called, which tears down hardware (cancels work, detaches
+ modules, unregisters from MAL)
+2. emac_remove() returns
+3. devres cleanup runs and finally calls unregister_netdev()
+
+During step 3, the network stack might still process packets, triggering
+emac_irq(), emac_poll(), or other handlers that access now-freed hardware
+resources (dev->emacp, dev->mal, etc.).
+
+Fix this by replacing devm_register_netdev() with manual register_netdev()
+and calling unregister_netdev() at the beginning of emac_remove(), before
+any hardware teardown. This ensures the network device is fully stopped and
+unregistered before hardware resources are released.
+
+The change is safe because:
+- dev->ndev is assigned very early in probe (before any error paths that
+ could bypass emac_remove)
+- platform_set_drvdata() is only called after successful registration, so
+ emac_remove() only runs for fully registered devices
+- unregister_netdev() is idempotent and safe to call on any registered device
+
+Fixes: a4dd8535a527 ("net: ibm: emac: use devm for register_netdev")
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/emac/core.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
+index 417dfa18daae3a..4e503b3d0d2d34 100644
+--- a/drivers/net/ethernet/ibm/emac/core.c
++++ b/drivers/net/ethernet/ibm/emac/core.c
+@@ -3144,7 +3144,7 @@ static int emac_probe(struct platform_device *ofdev)
+
+ netif_carrier_off(ndev);
+
+- err = devm_register_netdev(&ofdev->dev, ndev);
++ err = register_netdev(ndev);
+ if (err) {
+ printk(KERN_ERR "%pOF: failed to register net device (%d)!\n",
+ np, err);
+@@ -3197,6 +3197,13 @@ static void emac_remove(struct platform_device *ofdev)
+
+ DBG(dev, "remove" NL);
+
++ /* Unregister network device before tearing down hardware
++ * to prevent use-after-free during deferred cleanup. This ensures
++ * the network stack stops all operations before hardware resources
++ * are released.
++ */
++ unregister_netdev(dev->ndev);
++
+ cancel_work_sync(&dev->reset_work);
+
+ if (emac_has_feature(dev, EMAC_FTR_HAS_TAH))
+--
+2.53.0
+
--- /dev/null
+From 317ec0104495a390f4c771f6a2e81ee5b822ac8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 09:25:41 +0800
+Subject: net: mctp: usb: don't fail mctp_usb_rx_queue on a deferred submission
+
+From: Jeremy Kerr <jk@codeconstruct.com.au>
+
+[ Upstream commit 881a3113b74964918cdd72747e3bc119c02b0c0c ]
+
+In the ndo_open path, a deferred queue open will report a failure, and
+so the netdev will not be ndo_stop()ed, leaving us with the rx_retry
+work potentially pending.
+
+Don't report a deferred queue as an error, as we are still operational.
+This means we use the ndo_stop() path for future cleanup, which handles
+rx_retry_work cancellation.
+
+Fixes: 0791c0327a6e ("net: mctp: Add MCTP USB transport driver")
+Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
+Link: https://patch.msgid.link/20260608-dev-mctp-usb-rx-requeue-v2-2-29a3aa507609@codeconstruct.com.au
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/mctp/mctp-usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/mctp/mctp-usb.c b/drivers/net/mctp/mctp-usb.c
+index cf6f6a93a45112..fade65f2f26995 100644
+--- a/drivers/net/mctp/mctp-usb.c
++++ b/drivers/net/mctp/mctp-usb.c
+@@ -154,7 +154,7 @@ static int mctp_usb_rx_queue(struct mctp_usb *mctp_usb, gfp_t gfp)
+ if (!mctp_usb->rx_stopped)
+ schedule_delayed_work(&mctp_usb->rx_retry_work, RX_RETRY_DELAY);
+ spin_unlock_irqrestore(&mctp_usb->rx_lock, flags);
+- return rc;
++ return 0;
+ }
+
+ static void mctp_usb_in_complete(struct urb *urb)
+--
+2.53.0
+
--- /dev/null
+From 4cd9f5cb070786a9bab65a7933b92eae2e16b8a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 09:25:40 +0800
+Subject: net: mctp: usb: fix race between urb completion and rx_retry
+ cancellation
+
+From: Jeremy Kerr <jk@codeconstruct.com.au>
+
+[ Upstream commit 54665dce982689e2fd99b32e9a0dcc204fda8a51 ]
+
+It's possible that sequencing between setting ->stopped and cancelling
+the rx_retry work (in ndo_stop) could leave us with an urb queued:
+
+ T1: ndo_stop T2: rx_retry_work
+ ------------ ----------------
+ LD: ->stopped => false
+ ST: ->stopped <= true
+ usb_kill_urb()
+ mctp_usb_rx_queue()
+ usb_submit_urb()
+ cancel_delayed_work_sync()
+
+That urb completion can then re-schedule rx_retry_work.
+
+Strenghen the sequencing between the stop (preventing another requeue)
+and the cancel by updating both atomically under a new rx lock. After
+setting ->rx_stopped, and cancelling pending work, we know that the
+requeue cannot occur, so all that's left is killing any pending urb.
+
+Fixes: 0791c0327a6e ("net: mctp: Add MCTP USB transport driver")
+Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
+Link: https://patch.msgid.link/20260608-dev-mctp-usb-rx-requeue-v2-1-29a3aa507609@codeconstruct.com.au
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/mctp/mctp-usb.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/mctp/mctp-usb.c b/drivers/net/mctp/mctp-usb.c
+index 3b5dff14417747..cf6f6a93a45112 100644
+--- a/drivers/net/mctp/mctp-usb.c
++++ b/drivers/net/mctp/mctp-usb.c
+@@ -22,7 +22,6 @@
+ struct mctp_usb {
+ struct usb_device *usbdev;
+ struct usb_interface *intf;
+- bool stopped;
+
+ struct net_device *netdev;
+
+@@ -32,6 +31,9 @@ struct mctp_usb {
+ struct urb *tx_urb;
+ struct urb *rx_urb;
+
++ /* enforces atomic access to rx_stopped and requeuing the retry work */
++ spinlock_t rx_lock;
++ bool rx_stopped;
+ struct delayed_work rx_retry_work;
+ };
+
+@@ -122,6 +124,7 @@ static const unsigned long RX_RETRY_DELAY = HZ / 4;
+
+ static int mctp_usb_rx_queue(struct mctp_usb *mctp_usb, gfp_t gfp)
+ {
++ unsigned long flags;
+ struct sk_buff *skb;
+ int rc;
+
+@@ -147,7 +150,10 @@ static int mctp_usb_rx_queue(struct mctp_usb *mctp_usb, gfp_t gfp)
+ return rc;
+
+ err_retry:
+- schedule_delayed_work(&mctp_usb->rx_retry_work, RX_RETRY_DELAY);
++ spin_lock_irqsave(&mctp_usb->rx_lock, flags);
++ if (!mctp_usb->rx_stopped)
++ schedule_delayed_work(&mctp_usb->rx_retry_work, RX_RETRY_DELAY);
++ spin_unlock_irqrestore(&mctp_usb->rx_lock, flags);
+ return rc;
+ }
+
+@@ -248,9 +254,6 @@ static void mctp_usb_rx_retry_work(struct work_struct *work)
+ struct mctp_usb *mctp_usb = container_of(work, struct mctp_usb,
+ rx_retry_work.work);
+
+- if (READ_ONCE(mctp_usb->stopped))
+- return;
+-
+ mctp_usb_rx_queue(mctp_usb, GFP_KERNEL);
+ }
+
+@@ -258,7 +261,7 @@ static int mctp_usb_open(struct net_device *dev)
+ {
+ struct mctp_usb *mctp_usb = netdev_priv(dev);
+
+- WRITE_ONCE(mctp_usb->stopped, false);
++ WRITE_ONCE(mctp_usb->rx_stopped, false);
+
+ netif_start_queue(dev);
+
+@@ -268,17 +271,21 @@ static int mctp_usb_open(struct net_device *dev)
+ static int mctp_usb_stop(struct net_device *dev)
+ {
+ struct mctp_usb *mctp_usb = netdev_priv(dev);
++ unsigned long flags;
+
+ netif_stop_queue(dev);
+
+ /* prevent RX submission retry */
+- WRITE_ONCE(mctp_usb->stopped, true);
++ spin_lock_irqsave(&mctp_usb->rx_lock, flags);
++ mctp_usb->rx_stopped = true;
++ cancel_delayed_work(&mctp_usb->rx_retry_work);
++ spin_unlock_irqrestore(&mctp_usb->rx_lock, flags);
++
++ flush_delayed_work(&mctp_usb->rx_retry_work);
+
+ usb_kill_urb(mctp_usb->rx_urb);
+ usb_kill_urb(mctp_usb->tx_urb);
+
+- cancel_delayed_work_sync(&mctp_usb->rx_retry_work);
+-
+ return 0;
+ }
+
+@@ -331,6 +338,7 @@ static int mctp_usb_probe(struct usb_interface *intf,
+ dev->netdev = netdev;
+ dev->usbdev = interface_to_usbdev(intf);
+ dev->intf = intf;
++ spin_lock_init(&dev->rx_lock);
+ usb_set_intfdata(intf, dev);
+
+ dev->ep_in = ep_in->bEndpointAddress;
+--
+2.53.0
+
--- /dev/null
+From 51ab2faf201f12f72a6dd6bc13ab73d9f7f3704f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 14:10:44 +0800
+Subject: net/mlx4: avoid GCC 10 __bad_copy_from() false positive
+
+From: Yao Sang <sangyao@kylinos.cn>
+
+[ Upstream commit 2365343f4aad3e1b1e7a2e87e98cf66d5e590589 ]
+
+mlx4_init_user_cqes() fills a scratch buffer with the CQE
+initialization pattern and then copies from that buffer to userspace.
+
+In the single-copy path, the copy length is array_size(entries,
+cqe_size), but the scratch buffer is allocated with PAGE_SIZE. GCC 10
+does not carry the branch invariant strongly enough through the object
+size checks and falsely triggers __bad_copy_from().
+
+Size the scratch buffer to the actual copy length for the active path,
+keep array_size() for the single-copy case, and retain a WARN_ON_ONCE()
+guard for the PAGE_SIZE invariant before allocating the buffer.
+
+Fixes: f69bf5dee7ef ("net/mlx4: Use array_size() helper in copy_to_user()")
+Signed-off-by: Yao Sang <sangyao@kylinos.cn>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx4/cq.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c
+index e130e7259275a3..5c55971abbf072 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
++++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
+@@ -290,6 +290,7 @@ static void mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
+ static int mlx4_init_user_cqes(void *buf, int entries, int cqe_size)
+ {
+ int entries_per_copy = PAGE_SIZE / cqe_size;
++ size_t copy_bytes;
+ void *init_ents;
+ int err = 0;
+ int i;
+@@ -314,8 +315,14 @@ static int mlx4_init_user_cqes(void *buf, int entries, int cqe_size)
+ buf += PAGE_SIZE;
+ }
+ } else {
++ copy_bytes = array_size(entries, cqe_size);
++ if (WARN_ON_ONCE(copy_bytes > PAGE_SIZE)) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ err = copy_to_user((void __user *)buf, init_ents,
+- array_size(entries, cqe_size)) ?
++ copy_bytes) ?
+ -EFAULT : 0;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 88debfe2a40232cb29e180e32dbb2a56a2b8489b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 16:58:49 +0300
+Subject: net/mlx5: Fix slab-out-of-bounds in mlx5_query_nic_vport_mac_list
+
+From: Dragos Tatulea <dtatulea@nvidia.com>
+
+[ Upstream commit 894e036a24a26a6dd7b17d8d3fb5c53ab48a6074 ]
+
+mlx5_query_nic_vport_mac_list() sizes its firmware command buffer using
+the PF's log_max_current_uc/mc_list capabilities. When querying a VF
+vport with a larger configured max (via devlink), the firmware response
+can overflow this buffer:
+
+ BUG: KASAN: slab-out-of-bounds in mlx5_query_nic_vport_mac_list+0x453/0x4c0 [mlx5_core]
+ Read of size 4 at addr ff1100013ffc8a12 by task kworker/u96:2/385
+
+ CPU: 12 UID: 0 PID: 385 Comm: kworker/u96:2 Not tainted 7.0.0-rc6+ #1 PREEMPT
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009)
+ Workqueue: mlx5_esw_wq esw_vport_change_handler [mlx5_core]
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x69/0xa0
+ print_report+0x176/0x4e4
+ kasan_report+0xc8/0x100
+ mlx5_query_nic_vport_mac_list+0x453/0x4c0 [mlx5_core]
+ esw_update_vport_addr_list+0x2e3/0xda0 [mlx5_core]
+ esw_vport_change_handle_locked+0xa1f/0x1060 [mlx5_core]
+ esw_vport_change_handler+0x6a/0x90 [mlx5_core]
+ process_one_work+0x87f/0x15e0
+ worker_thread+0x62b/0x1020
+ kthread+0x375/0x490
+ ret_from_fork+0x4dc/0x810
+ ret_from_fork_asm+0x11/0x20
+ </TASK>
+
+Fix by querying the vport's own HCA caps to size the buffer correctly.
+Refactor the function to allocate and return the MAC list internally,
+removing the caller's dependency on knowing the correct max.
+
+Fixes: e16aea2744ab ("net/mlx5: Introduce access functions to modify/query vport mac lists")
+Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
+Reviewed-by: Carolina Jubran <cjubran@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20260604135849.458060-1-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/eswitch.c | 13 +---
+ .../net/ethernet/mellanox/mlx5/core/vport.c | 72 ++++++++++++++-----
+ include/linux/mlx5/vport.h | 4 +-
+ 3 files changed, 59 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+index 49bc409d7dbb00..c38deabcb7b966 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+@@ -533,23 +533,16 @@ static void esw_update_vport_addr_list(struct mlx5_eswitch *esw,
+ struct mlx5_vport *vport, int list_type)
+ {
+ bool is_uc = list_type == MLX5_NVPRT_LIST_TYPE_UC;
+- u8 (*mac_list)[ETH_ALEN];
++ u8 (*mac_list)[ETH_ALEN] = NULL;
+ struct l2addr_node *node;
+ struct vport_addr *addr;
+ struct hlist_head *hash;
+ struct hlist_node *tmp;
+- int size;
++ int size = 0;
+ int err;
+ int hi;
+ int i;
+
+- size = is_uc ? MLX5_MAX_UC_PER_VPORT(esw->dev) :
+- MLX5_MAX_MC_PER_VPORT(esw->dev);
+-
+- mac_list = kcalloc(size, ETH_ALEN, GFP_KERNEL);
+- if (!mac_list)
+- return;
+-
+ hash = is_uc ? vport->uc_list : vport->mc_list;
+
+ for_each_l2hash_node(node, tmp, hash, hi) {
+@@ -561,7 +554,7 @@ static void esw_update_vport_addr_list(struct mlx5_eswitch *esw,
+ goto out;
+
+ err = mlx5_query_nic_vport_mac_list(esw->dev, vport->vport, list_type,
+- mac_list, &size);
++ &mac_list, &size);
+ if (err)
+ goto out;
+ esw_debug(esw->dev, "vport[%d] context update %s list size (%d)\n",
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+index 2ed2e530b07d0f..a44214c660b03b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+@@ -251,35 +251,63 @@ int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu)
+ }
+ EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mtu);
+
++static int mlx5_vport_max_mac_list_size(struct mlx5_core_dev *dev, u16 vport,
++ enum mlx5_list_type list_type)
++{
++ void *query_ctx, *hca_caps;
++ int ret = 0;
++
++ if (!vport && !mlx5_core_is_ecpf(dev))
++ return list_type == MLX5_NVPRT_LIST_TYPE_UC ?
++ 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
++ 1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
++
++ query_ctx = kzalloc(MLX5_ST_SZ_BYTES(query_hca_cap_out), GFP_KERNEL);
++ if (!query_ctx)
++ return -ENOMEM;
++
++ ret = mlx5_vport_get_other_func_general_cap(dev, vport, query_ctx);
++ if (ret)
++ goto out;
++
++ hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
++ ret = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
++ 1 << MLX5_GET(cmd_hca_cap, hca_caps, log_max_current_uc_list) :
++ 1 << MLX5_GET(cmd_hca_cap, hca_caps, log_max_current_mc_list);
++
++out:
++ kfree(query_ctx);
++
++ return ret;
++}
++
+ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+ u16 vport,
+ enum mlx5_list_type list_type,
+- u8 addr_list[][ETH_ALEN],
+- int *list_size)
++ u8 (**addr_list)[ETH_ALEN],
++ int *addr_list_size)
+ {
+ u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
++ int allowed_list_size;
+ void *nic_vport_ctx;
+ int max_list_size;
+- int req_list_size;
+ int out_sz;
+ void *out;
+ int err;
+ int i;
+
+- req_list_size = *list_size;
++ if (!addr_list || !addr_list_size)
++ return -EINVAL;
+
+- max_list_size = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
+- 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
+- 1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
++ *addr_list = NULL;
++ *addr_list_size = 0;
+
+- if (req_list_size > max_list_size) {
+- mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
+- req_list_size, max_list_size);
+- req_list_size = max_list_size;
+- }
++ max_list_size = mlx5_vport_max_mac_list_size(dev, vport, list_type);
++ if (max_list_size < 0)
++ return max_list_size;
+
+ out_sz = MLX5_ST_SZ_BYTES(query_nic_vport_context_out) +
+- req_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
++ max_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
+
+ out = kvzalloc(out_sz, GFP_KERNEL);
+ if (!out)
+@@ -298,16 +326,24 @@ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+
+ nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
+ nic_vport_context);
+- req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
+- allowed_list_size);
++ allowed_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
++ allowed_list_size);
++ if (!allowed_list_size)
++ goto out;
++
++ *addr_list = kcalloc(allowed_list_size, ETH_ALEN, GFP_KERNEL);
++ if (!*addr_list) {
++ err = -ENOMEM;
++ goto out;
++ }
+
+- *list_size = req_list_size;
+- for (i = 0; i < req_list_size; i++) {
++ for (i = 0; i < allowed_list_size; i++) {
+ u8 *mac_addr = MLX5_ADDR_OF(nic_vport_context,
+ nic_vport_ctx,
+ current_uc_mac_address[i]) + 2;
+- ether_addr_copy(addr_list[i], mac_addr);
++ ether_addr_copy((*addr_list)[i], mac_addr);
+ }
++ *addr_list_size = allowed_list_size;
+ out:
+ kvfree(out);
+ return err;
+diff --git a/include/linux/mlx5/vport.h b/include/linux/mlx5/vport.h
+index c87b9507cfa180..b98aaa471ac228 100644
+--- a/include/linux/mlx5/vport.h
++++ b/include/linux/mlx5/vport.h
+@@ -95,8 +95,8 @@ int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *dev,
+ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+ u16 vport,
+ enum mlx5_list_type list_type,
+- u8 addr_list[][ETH_ALEN],
+- int *list_size);
++ u8 (**mac_list)[ETH_ALEN],
++ int *mac_list_size);
+ int mlx5_modify_nic_vport_mac_list(struct mlx5_core_dev *dev,
+ enum mlx5_list_type list_type,
+ u8 addr_list[][ETH_ALEN],
+--
+2.53.0
+
--- /dev/null
+From 964a9a69770f26c410422ed2373a330a7550241b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 18:21:12 +0800
+Subject: net/mlx5: Use effective affinity mask for IRQ selection
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fushuai Wang <wangfushuai@baidu.com>
+
+[ Upstream commit a7767290e77ca2e926b49f8bfa29daa12262c612 ]
+
+When a sf is created after a CPU has been taken offline, the IRQ pool may
+contain IRQs with affinity masks that include the offline CPU. Since only
+online CPUs should be considered for IRQ placement, cpumask_subset() check
+would fail because the iter_mask contains offline CPUs that are not present
+in req_mask, causing sf creation to fail.
+
+This is an example:
+ 1. When mlx5 driver loads, it initializes the IRQ pools.
+ For sf_ctrl_pool with ≤64 sf:
+ - xa_num_irqs = {N, N} (There is only one slot)
+ 2. When the first SF is created:
+ - The ctrl IRQ is allocated with mask=cpu_online_mask={0-191}
+ 2. We take CPU 20 offline
+ 3. Existing ctl irq still have mask={0-191}
+ 4. Create a new SF:
+ - req_mask={0-19,21-191}
+ - iter_mask={0-191}
+ - {0-191} is NOT a subset of {0-19,21-191}
+ - least_loaded_irq=NULL
+ 5. Try to allocate a new irq via irq_pool_request_irq()
+ 6. xa_alloc() fails because the pool is full(There is only one slot)
+ 7. sf creation fails with error
+
+Use irq_get_effective_affinity_mask() instead, which returns the IRQ's
+actual effective affinity that already excludes offline CPUs.
+
+Fixes: 061f5b23588a ("net/mlx5: SF, Use all available cpu for setting cpu affinity")
+Suggested-by: Shay Drory <shayd@nvidia.com>
+Signed-off-by: Fushuai Wang <wangfushuai@baidu.com>
+Reviewed-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20260605102112.91772-1-fushuai.wang@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c b/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
+index 14d339eceb92d5..cc63b091b70e8a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
+@@ -105,9 +105,12 @@ irq_pool_find_least_loaded(struct mlx5_irq_pool *pool, const struct cpumask *req
+
+ lockdep_assert_held(&pool->lock);
+ xa_for_each_range(&pool->irqs, index, iter, start, end) {
+- struct cpumask *iter_mask = mlx5_irq_get_affinity_mask(iter);
+ int iter_refcount = mlx5_irq_read_locked(iter);
++ const struct cpumask *iter_mask;
+
++ iter_mask = irq_get_effective_affinity_mask(mlx5_irq_get_irq(iter));
++ if (!iter_mask)
++ continue;
+ if (!cpumask_subset(iter_mask, req_mask))
+ /* skip IRQs with a mask which is not subset of req_mask */
+ continue;
+--
+2.53.0
+
--- /dev/null
+From 5f1f371c5804d5f9057d3e3587a0b868c7f35896 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 16:54:46 +0300
+Subject: net/mlx5e: xsk: Fix DMA and xdp_frame leak on XDP_TX xmit failure
+
+From: Dragos Tatulea <dtatulea@nvidia.com>
+
+[ Upstream commit b69004f5a6ad32da84d8aa5b23b9c0caafe6252e ]
+
+In the XSK branch of mlx5e_xmit_xdp_buff(), when sq->xmit_xdp_frame()
+returns false (e.g. XDPSQ is full), the function returns without
+unmapping the DMA address or freeing the xdp_frame allocated by
+xdp_convert_zc_to_xdp_frame(). The xdpi_fifo push only happens on
+success, so the completion path cannot recover these entries.
+
+With CONFIG_DMA_API_DEBUG=y, the leak surfaces on driver unbind:
+
+ DMA-API: pci 0000:08:00.0: device driver has pending DMA
+ allocations while released from device [count=1116]
+ One of leaked entries details: [device address=0x000000010ffd7028]
+ [size=1534 bytes] [mapped with DMA_TO_DEVICE] [mapped as phy]
+ WARNING: kernel/dma/debug.c:881 at dma_debug_device_change+0x127/0x180
+ ...
+ DMA-API: Mapped at:
+ debug_dma_map_phys+0x4b/0xd0
+ dma_map_phys+0xfd/0x2d0
+ mlx5e_xdp_handle+0x5ae/0xac0 [mlx5_core]
+ mlx5e_xsk_skb_from_cqe_mpwrq_linear+0xc4/0x170 [mlx5_core]
+ mlx5e_handle_rx_cqe_mpwrq+0xc1/0x290 [mlx5_core]
+
+Add the missing unmap + xdp_return_frame, matching the cleanup already
+done in mlx5e_xdp_xmit(). has_frags is rejected earlier in this branch,
+so no per-frag unmap is needed.
+
+Fixes: 84a0a2310d6d ("net/mlx5e: XDP_TX from UMEM support")
+Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20260604135446.456119-1-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
+index 5d51600935a6f8..5322964214b22e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
+@@ -102,9 +102,15 @@ mlx5e_xmit_xdp_buff(struct mlx5e_xdpsq *sq, struct mlx5e_rq *rq,
+
+ xdptxd->dma_addr = dma_addr;
+
+- if (unlikely(!INDIRECT_CALL_2(sq->xmit_xdp_frame, mlx5e_xmit_xdp_frame_mpwqe,
+- mlx5e_xmit_xdp_frame, sq, xdptxd, 0, NULL)))
++ if (unlikely(!INDIRECT_CALL_2(sq->xmit_xdp_frame,
++ mlx5e_xmit_xdp_frame_mpwqe,
++ mlx5e_xmit_xdp_frame,
++ sq, xdptxd, 0, NULL))) {
++ dma_unmap_single(sq->pdev, dma_addr, xdptxd->len,
++ DMA_TO_DEVICE);
++ xdp_return_frame(xdpf);
+ return false;
++ }
+
+ /* xmit_mode == MLX5E_XDP_XMIT_MODE_FRAME */
+ mlx5e_xdpi_fifo_push(&sq->db.xdpi_fifo,
+--
+2.53.0
+
--- /dev/null
+From 9282e7de4f6b6d34b35498e8f95c05aba5056893 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:43 +0200
+Subject: net: mvpp2: build skb from XDP-adjusted data on XDP_PASS
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 77a6b90ce56bc982dcfa94229b8e28e6abb16e95 ]
+
+When an XDP program uses bpf_xdp_adjust_head() or bpf_xdp_adjust_tail()
+and then returns XDP_PASS, mvpp2 still builds the skb from fixed offsets
+derived from the original RX descriptor. Packet geometry changes made by
+the XDP program are therefore discarded before the skb reaches the stack.
+
+Update rx_offset and rx_bytes from xdp.data and xdp.data_end for
+XDP_PASS. This makes skb_reserve() and skb_put() reflect the packet seen
+by XDP, and makes RX byte accounting for XDP_PASS follow the length of the
+skb passed to the network stack.
+
+Keep a separate rx_sync_size for page-pool recycling on skb allocation
+failure, which must stay tied to the received buffer range.
+
+Non-PASS verdicts continue to account the descriptor length because no skb
+is passed up in those cases.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-5-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 21 +++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 7f748cd6605ae4..79f8e0abfdbfd1 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3919,10 +3919,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ struct mvpp2_bm_pool *bm_pool;
+ struct page_pool *pp = NULL;
+ struct sk_buff *skb;
+- unsigned int frag_size;
++ unsigned int frag_size, rx_sync_size;
+ dma_addr_t dma_addr;
+ phys_addr_t phys_addr;
+- int pool, rx_bytes, err, ret;
++ int pool, rx_bytes, rx_offset, err, ret;
+ struct page *page;
+ void *data;
+
+@@ -3935,6 +3935,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ rx_status = mvpp2_rxdesc_status_get(port, rx_desc);
+ rx_bytes = mvpp2_rxdesc_size_get(port, rx_desc);
+ rx_bytes -= MVPP2_MH_SIZE;
++ rx_sync_size = rx_bytes + MVPP2_MH_SIZE;
++ rx_offset = MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM;
+ dma_addr = mvpp2_rxdesc_dma_addr_get(port, rx_desc);
+
+ pool = (rx_status & MVPP2_RXD_BM_POOL_ID_MASK) >>
+@@ -3950,7 +3952,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
+ MVPP2_SKB_HEADROOM,
+- rx_bytes + MVPP2_MH_SIZE,
++ rx_sync_size,
+ dma_dir);
+
+ /* Buffer header not supported */
+@@ -4001,6 +4003,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ continue;
+ }
+
++ rx_sync_size = max_t(unsigned int, rx_sync_size,
++ xdp.data_end - xdp.data_hard_start -
++ MVPP2_SKB_HEADROOM);
++
++ /* Update offset and length to reflect any XDP adjustments. */
++ rx_offset = xdp.data - data;
++ rx_bytes = xdp.data_end - xdp.data;
++
+ metasize = xdp.data - xdp.data_meta;
+ }
+
+@@ -4012,8 +4022,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ netdev_warn(port->dev, "skb build failed\n");
+ if (pp) {
+ page_pool_put_page(pp, virt_to_head_page(data),
+- rx_bytes + MVPP2_MH_SIZE,
+- true);
++ rx_sync_size, true);
+ } else {
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size,
+@@ -4043,7 +4052,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
+
+- skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);
++ skb_reserve(skb, rx_offset);
+ skb_put(skb, rx_bytes);
+ if (metasize)
+ skb_metadata_set(skb, metasize);
+--
+2.53.0
+
--- /dev/null
+From 0ed4da342532ab78937e6fadd236ebc46c8b5e1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:41 +0200
+Subject: net: mvpp2: limit XDP frame size to the RX buffer
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit f3c6aa078927e6fe8121c9c591ddee8716c5305a ]
+
+mvpp2 has short and long BM pools, and short pool buffers can be smaller
+than PAGE_SIZE. The XDP path nevertheless initializes every xdp_buff with
+PAGE_SIZE as frame size.
+
+XDP helpers use frame_sz to validate tail growth and to derive the hard
+end of the data area. Advertising PAGE_SIZE for short buffers can let
+bpf_xdp_adjust_tail() grow a packet past the real allocation, corrupting
+memory or later tripping skb tailroom checks.
+
+Initialize the XDP buffer with bm_pool->frag_size so XDP tailroom matches
+the actual buffer backing the packet.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-3-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 5ef8637d408015..814b60b16a23dc 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3981,7 +3981,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ else
+ xdp_rxq = &rxq->xdp_rxq_long;
+
+- xdp_init_buff(&xdp, PAGE_SIZE, xdp_rxq);
++ xdp_init_buff(&xdp, bm_pool->frag_size, xdp_rxq);
+ xdp_prepare_buff(&xdp, data,
+ MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM,
+ rx_bytes, true);
+--
+2.53.0
+
--- /dev/null
+From 2003aa4535fe1add359de82cfdd2c47abdfb6e8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:42 +0200
+Subject: net: mvpp2: refill RX buffers before XDP or skb use
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 5e8e2a9624df72fca7c736b2966b2cbf6c9c3ff6 ]
+
+The RX error path returns the current descriptor buffer to the hardware
+BM pool. That is only valid while the driver still owns the buffer.
+
+mvpp2_rx_refill() can fail after the current buffer has been handed to
+XDP or attached to an skb. In those cases mvpp2_run_xdp() may have
+recycled, redirected, or queued the page for XDP_TX, and an skb free also
+retires the data buffer. Returning such a buffer to BM lets hardware DMA
+into memory that is no longer owned by the RX ring.
+
+Refill the BM pool before handing the current buffer to XDP or to the
+skb. If the allocation fails there, drop the packet and return the
+still-owned current buffer to BM, preserving the pool depth. Once the
+refill succeeds, later local drops retire/free the current buffer instead
+of returning it to BM.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Fixes: d6526926de73 ("net: mvpp2: fix memory leak in mvpp2_rx")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-4-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 77a6b90ce56b ("net: mvpp2: build skb from XDP-adjusted data on XDP_PASS")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 43 +++++++++++--------
+ 1 file changed, 24 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 814b60b16a23dc..7f748cd6605ae4 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3973,6 +3973,12 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ else
+ frag_size = bm_pool->frag_size;
+
++ err = mvpp2_rx_refill(port, bm_pool, pp, pool);
++ if (err) {
++ netdev_err(port->dev, "failed to refill BM pools\n");
++ goto err_drop_frame;
++ }
++
+ if (xdp_prog) {
+ struct xdp_rxq_info *xdp_rxq;
+
+@@ -3990,12 +3996,6 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ if (ret) {
+ xdp_ret |= ret;
+- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+- if (err) {
+- netdev_err(port->dev, "failed to refill BM pools\n");
+- goto err_drop_frame;
+- }
+-
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
+ continue;
+@@ -4010,8 +4010,21 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ skb = slab_build_skb(data);
+ if (!skb) {
+ netdev_warn(port->dev, "skb build failed\n");
+- goto err_drop_frame;
++ if (pp) {
++ page_pool_put_page(pp, virt_to_head_page(data),
++ rx_bytes + MVPP2_MH_SIZE,
++ true);
++ } else {
++ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
++ bm_pool->buf_size,
++ DMA_FROM_DEVICE,
++ DMA_ATTR_SKIP_CPU_SYNC);
++ mvpp2_frag_free(bm_pool, pp, data);
++ }
++ goto err_drop_frame_retired;
+ }
++ if (pp)
++ skb_mark_for_recycle(skb);
+
+ /* If we have RX hardware timestamping enabled, grab the
+ * timestamp from the queue and convert.
+@@ -4022,16 +4035,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ skb_hwtstamps(skb));
+ }
+
+- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+- if (err) {
+- netdev_err(port->dev, "failed to refill BM pools\n");
+- dev_kfree_skb_any(skb);
+- goto err_drop_frame;
+- }
+-
+- if (pp)
+- skb_mark_for_recycle(skb);
+- else
++ if (!pp)
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size, DMA_FROM_DEVICE,
+ DMA_ATTR_SKIP_CPU_SYNC);
+@@ -4050,13 +4054,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ continue;
+
+ err_drop_frame:
+- dev->stats.rx_errors++;
+- mvpp2_rx_error(port, rx_desc);
+ /* Return the buffer to the pool */
+ if (rx_status & MVPP2_RXD_BUF_HDR)
+ mvpp2_buff_hdr_pool_put(port, rx_desc, pool, rx_status);
+ else
+ mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);
++err_drop_frame_retired:
++ dev->stats.rx_errors++;
++ mvpp2_rx_error(port, rx_desc);
+ }
+
+ if (xdp_ret & MVPP2_XDP_REDIR)
+--
+2.53.0
+
--- /dev/null
+From 35fa984fa499b321fff83e89bc54ce5845b913bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:40 +0200
+Subject: net: mvpp2: sync RX data at the hardware packet offset
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 180235600934bef6add3be637c296d6cf3272e67 ]
+
+mvpp2 programs the RX queue packet offset, so hardware writes received
+data at dma_addr + MVPP2_SKB_HEADROOM. The current CPU sync starts at
+dma_addr and only covers rx_bytes + MVPP2_MH_SIZE bytes, which syncs the
+unused headroom and misses the same number of bytes at the packet tail.
+
+On non-coherent DMA systems this can leave the CPU reading stale cache
+contents for the end of the received frame.
+
+Use dma_sync_single_range_for_cpu() with MVPP2_SKB_HEADROOM as the range
+offset so the sync covers the Marvell header and packet data actually
+written by hardware.
+
+Fixes: e1921168bbd4 ("mvpp2: sync only the received frame")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-2-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 74d44510684bfb..5ef8637d408015 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3948,9 +3948,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ dma_dir = DMA_FROM_DEVICE;
+ }
+
+- dma_sync_single_for_cpu(dev->dev.parent, dma_addr,
+- rx_bytes + MVPP2_MH_SIZE,
+- dma_dir);
++ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
++ MVPP2_SKB_HEADROOM,
++ rx_bytes + MVPP2_MH_SIZE,
++ dma_dir);
+
+ /* Buffer header not supported */
+ if (rx_status & MVPP2_RXD_BUF_HDR)
+--
+2.53.0
+
--- /dev/null
+From 858ce1b2d60b04decca950e4a2dee0938228eebc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:19:46 +0200
+Subject: net: openvswitch: fix possible kfree_skb of ERR_PTR
+
+From: Adrian Moreno <amorenoz@redhat.com>
+
+[ Upstream commit ee30dd2909d8b98619f4341c70ec8dc8e155ab02 ]
+
+After the patch in the "Fixes" tag, the allocation of the "reply" skb
+can happen either before or after locking the ovs_mutex.
+
+However, error cleanups still follow the classical reversed order,
+assuming "reply" is allocated before locking: it is freed after unlocking.
+
+If "reply" allocation happens after locking the mutex and it fails,
+"reply" is left with an ERR_PTR, and execution jumps to the correspondent
+cleanup stage which will try to free an invalid pointer.
+
+Fix this by setting the pointer to NULL after having saved its error
+value.
+
+Fixes: 893f139b9a6c ("openvswitch: Minimize ovs_flow_cmd_new|set critical sections.")
+Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Acked-by: Eelco Chaudron <echaudro@redhat.com>
+Link: https://patch.msgid.link/20260604121946.942164-1-amorenoz@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/datapath.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 2304c8e3be4f70..56c744e1e14c5f 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -1316,6 +1316,7 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
+
+ if (IS_ERR(reply)) {
+ error = PTR_ERR(reply);
++ reply = NULL;
+ goto err_unlock_ovs;
+ }
+ }
+--
+2.53.0
+
--- /dev/null
+From 45599696180a9061c503c086cc2468b31f10ce73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 11:28:15 +0200
+Subject: net: phy: clean the sfp upstream if phy probing fails
+
+From: Maxime Chevallier <maxime.chevallier@bootlin.com>
+
+[ Upstream commit 48774e87bbaa0056819d4b52301e4692e50e3252 ]
+
+Sashiko reported that we don't call sfp_bus_del_upstream() in the probe
+failure path, so let's add it, otherwise the sfp-bus is left with a
+dangling 'upstream' field, that may be used later on during SFP events.
+
+This issue existed before the generic phylib sfp support, back when
+drivers were calling phy_sfp_probe themselves.
+
+Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
+Fixes: 298e54fa810e ("net: phy: add core phylib sfp support")
+Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260604092819.723505-2-maxime.chevallier@bootlin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/phy_device.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 78cf05a17f8ff2..26b08e3dbd1dee 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -1598,6 +1598,9 @@ int phy_sfp_probe(struct phy_device *phydev,
+
+ ret = sfp_bus_add_upstream(bus, phydev, ops);
+ sfp_bus_put(bus);
++
++ if (ret)
++ phydev->sfp_bus = NULL;
+ }
+ return ret;
+ }
+@@ -3513,6 +3516,9 @@ static int phy_probe(struct device *dev)
+ return 0;
+
+ out:
++ sfp_bus_del_upstream(phydev->sfp_bus);
++ phydev->sfp_bus = NULL;
++
+ if (!phydev->is_on_sfp_module)
+ phy_led_triggers_unregister(phydev);
+
+--
+2.53.0
+
--- /dev/null
+From 8f476d5c6de5b839c1cce9f33128477b67bdfdc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:48:01 +0800
+Subject: net: qrtr: fix refcount saturation and potential UAF in
+ qrtr_port_remove
+
+From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+
+[ Upstream commit a2171131ecda1ed61a594a1eb715e75fdad0fef5 ]
+
+In qrtr_port_remove(), the socket reference count is decremented via
+__sock_put() before the port is removed from the qrtr_ports XArray and
+before the RCU grace period elapses.
+
+This breaks the fundamental RCU update paradigm. It exposes a race
+window where a concurrent RCU reader (such as qrtr_reset_ports() or
+qrtr_port_lookup()) can obtain a pointer to the socket from the XArray,
+and attempt to call sock_hold() on a socket whose reference count has
+already dropped to zero.
+
+This exact race condition was hit during syzkaller fuzzing, leading to
+the following refcount saturation warning and a potential Use-After-Free:
+
+ refcount_t: saturated; leaking memory.
+ WARNING: CPU: 3 PID: 1273 at lib/refcount.c:22 refcount_warn_saturate+0xae/0x1d0
+ Modules linked in: qrtr(+) bochs drm_shmem_helper ...
+ Call Trace:
+ <TASK>
+ qrtr_reset_ports net/qrtr/af_qrtr.c:768 [inline] [qrtr]
+ __qrtr_bind.isra.0+0x48b/0x570 net/qrtr/af_qrtr.c:805 [qrtr]
+ qrtr_bind+0x17d/0x210 net/qrtr/af_qrtr.c:901 [qrtr]
+ kernel_bind+0xe4/0x120 net/socket.c:3592
+ qrtr_ns_init+0x1a6/0x380 net/qrtr/ns.c:715 [qrtr]
+ qrtr_proto_init+0x3b/0xff0 net/qrtr/af_qrtr.c:169 [qrtr]
+ do_one_initcall+0xf5/0x5e0 init/main.c:1283
+ ...
+ </TASK>
+
+Fix this by deferring the reference count decrement until after the
+xa_erase() and the synchronize_rcu() complete.
+
+(Note: The v1 of this patch incorrectly replaced __sock_put() with
+sock_put(). As Simon Horman pointed out, the callers of qrtr_port_remove()
+still hold a reference to the socket, so freeing the socket memory here
+would lead to a subsequent UAF in the caller. Thus, the __sock_put() is
+kept, but only repositioned to close the RCU race.)
+
+Fixes: bdabad3e363d ("net: Add Qualcomm IPC router")
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260604064801.1180388-1-w15303746062@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/af_qrtr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c
+index b703e4c6458532..2c009793f1931d 100644
+--- a/net/qrtr/af_qrtr.c
++++ b/net/qrtr/af_qrtr.c
+@@ -707,13 +707,13 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
+ if (port == QRTR_PORT_CTRL)
+ port = 0;
+
+- __sock_put(&ipc->sk);
+-
+ xa_erase(&qrtr_ports, port);
+
+ /* Ensure that if qrtr_port_lookup() did enter the RCU read section we
+ * wait for it to up increment the refcount */
+ synchronize_rcu();
++
++ __sock_put(&ipc->sk);
+ }
+
+ /* Assign port number to socket.
+--
+2.53.0
+
--- /dev/null
+From d45c180590855c67796de510e5eed0e8d3c07961 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 12:24:48 -0700
+Subject: net/rds: fix NULL deref in rds_ib_send_cqe_handler() on masked atomic
+ completion
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 34080db3e70ddf94c38512ad2331e3c3afca6cc1 ]
+
+rds_ib_xmit_atomic() always programs a masked atomic opcode
+(IB_WR_MASKED_ATOMIC_CMP_AND_SWP or IB_WR_MASKED_ATOMIC_FETCH_AND_ADD)
+for every RDS atomic cmsg. But the completion-side switch in
+rds_ib_send_unmap_op() only handles the non-masked opcodes, so a masked
+atomic completion falls through to default and returns rm == NULL while
+send->s_op is left set. rds_ib_send_cqe_handler() then dereferences the
+NULL rm via rm->m_final_op, oopsing in softirq context. An unprivileged
+AF_RDS sendmsg() of an atomic cmsg over an active RDS/IB connection
+triggers it; on hardware that natively accepts masked atomics (mlx4,
+mlx5) no extra setup is needed.
+
+ RDS/IB: rds_ib_send_unmap_op: unexpected opcode 0xd in WR!
+ Oops: general protection fault [#1] SMP KASAN
+ KASAN: null-ptr-deref in range [0x0000000000000190-0x0000000000000197]
+ RIP: rds_ib_send_cqe_handler+0x25c/0xb10 (net/rds/ib_send.c:282)
+ Call Trace:
+ <IRQ>
+ rds_ib_send_cqe_handler (net/rds/ib_send.c:282)
+ poll_scq (net/rds/ib_cm.c:274)
+ rds_ib_tasklet_fn_send (net/rds/ib_cm.c:294)
+ tasklet_action_common (kernel/softirq.c:943)
+ handle_softirqs (kernel/softirq.c:573)
+ run_ksoftirqd (kernel/softirq.c:479)
+ </IRQ>
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Handle the masked atomic opcodes in the same case as the non-masked
+ones: they map to the same struct rds_message.atomic union member, so
+the existing container_of()/rds_ib_send_unmap_atomic() body is correct
+for them.
+
+Fixes: 20c72bd5f5f9 ("RDS: Implement masked atomic operations")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260606192447.1179255-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/ib_send.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
+index 4190b90ff3b18a..1909cd440a4b66 100644
+--- a/net/rds/ib_send.c
++++ b/net/rds/ib_send.c
+@@ -170,6 +170,8 @@ static struct rds_message *rds_ib_send_unmap_op(struct rds_ib_connection *ic,
+ break;
+ case IB_WR_ATOMIC_FETCH_AND_ADD:
+ case IB_WR_ATOMIC_CMP_AND_SWP:
++ case IB_WR_MASKED_ATOMIC_FETCH_AND_ADD:
++ case IB_WR_MASKED_ATOMIC_CMP_AND_SWP:
+ if (send->s_op) {
+ rm = container_of(send->s_op, struct rds_message, atomic);
+ rds_ib_send_unmap_atomic(ic, send->s_op, wc_status);
+--
+2.53.0
+
--- /dev/null
+From 528a48a00f75a06e9b5b849d6982fa028002a7da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 15:08:40 +0800
+Subject: net: txgbe: initialize module info buffer
+
+From: Jiawen Wu <jiawenwu@trustnetic.com>
+
+[ Upstream commit 0487cfca46517ff6699c72dc1a8872b0af3c31a9 ]
+
+The module info buffer should be initialized to 0 before the firmware
+returns information. Otherwise, there is a risk that the buffer field
+not filled by the firmware is random value.
+
+Fixes: 343929799ace ("net: txgbe: Support to handle GPIO IRQs for AML devices")
+Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
+Link: https://patch.msgid.link/20260608070842.36504-2-jiawenwu@trustnetic.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+index 0bc59431d43343..07ae491e3bc9b9 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+@@ -220,7 +220,7 @@ static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id)
+
+ int txgbe_identify_module(struct wx *wx)
+ {
+- struct txgbe_hic_get_module_info buffer;
++ struct txgbe_hic_get_module_info buffer = { 0 };
+ struct txgbe_sff_id *id;
+ int err = 0;
+ u32 gpio;
+--
+2.53.0
+
--- /dev/null
+From 485a7e42021adae2ac1434eab27c550e9baa7f45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Oct 2025 14:17:25 +0800
+Subject: net: txgbe: optimize the flow to setup PHY for AML devices
+
+From: Jiawen Wu <jiawenwu@trustnetic.com>
+
+[ Upstream commit 1f863ce5c71276710a7689c88bf4003fa5173998 ]
+
+To adapt to new firmware for AML devices, the driver should send the
+"SET_LINK_CMD" to the firmware only once when switching PHY interface
+mode, and no longer needs to re-trigger PHY configuration based on the
+RX signal interrupt (TXGBE_GPIOBIT_3).
+
+In previous firmware versions, the PHY was configured only after receiving
+"SET_LINK_CMD", and might remain incomplete if the RX signal was lost.
+To handle this case, the driver used TXGBE_GPIOBIT_3 interrupt to resend
+the command. This workaround is no longer necessary with the new firmware.
+
+And the unknown link speed is permitted in the mailbox buffer.
+
+Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
+Link: https://patch.msgid.link/20251014061726.36660-3-jiawenwu@trustnetic.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 0487cfca4651 ("net: txgbe: initialize module info buffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/wangxun/libwx/wx_type.h | 2 -
+ .../net/ethernet/wangxun/txgbe/txgbe_aml.c | 50 ++++++-------------
+ .../net/ethernet/wangxun/txgbe/txgbe_type.h | 1 +
+ 3 files changed, 15 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h
+index 2f8319e031820c..d367644debef36 100644
+--- a/drivers/net/ethernet/wangxun/libwx/wx_type.h
++++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h
+@@ -1271,8 +1271,6 @@ struct wx {
+
+ /* PHY stuff */
+ bool notify_down;
+- int adv_speed;
+- int adv_duplex;
+ unsigned int link;
+ int speed;
+ int duplex;
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+index 08b9b426f64846..80413504e4bc86 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+@@ -19,8 +19,8 @@ void txgbe_gpio_init_aml(struct wx *wx)
+ {
+ u32 status;
+
+- wr32(wx, WX_GPIO_INTTYPE_LEVEL, TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3);
+- wr32(wx, WX_GPIO_INTEN, TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3);
++ wr32(wx, WX_GPIO_INTTYPE_LEVEL, TXGBE_GPIOBIT_2);
++ wr32(wx, WX_GPIO_INTEN, TXGBE_GPIOBIT_2);
+
+ status = rd32(wx, WX_GPIO_INTSTATUS);
+ for (int i = 0; i < 6; i++) {
+@@ -42,11 +42,6 @@ irqreturn_t txgbe_gpio_irq_handler_aml(int irq, void *data)
+ wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_2);
+ wx_service_event_schedule(wx);
+ }
+- if (status & TXGBE_GPIOBIT_3) {
+- set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
+- wx_service_event_schedule(wx);
+- wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_3);
+- }
+
+ wr32(wx, WX_GPIO_INTMASK, 0);
+ return IRQ_HANDLED;
+@@ -96,6 +91,9 @@ static int txgbe_set_phy_link_hostif(struct wx *wx, int speed, int autoneg, int
+ case SPEED_10000:
+ buffer.speed = TXGBE_LINK_SPEED_10GB_FULL;
+ break;
++ default:
++ buffer.speed = TXGBE_LINK_SPEED_UNKNOWN;
++ break;
+ }
+
+ buffer.fec_mode = TXGBE_PHY_FEC_AUTO;
+@@ -106,19 +104,18 @@ static int txgbe_set_phy_link_hostif(struct wx *wx, int speed, int autoneg, int
+ WX_HI_COMMAND_TIMEOUT, false);
+ }
+
+-static void txgbe_get_link_capabilities(struct wx *wx)
++static void txgbe_get_link_capabilities(struct wx *wx, int *speed, int *duplex)
+ {
+ struct txgbe *txgbe = wx->priv;
+
+ if (test_bit(PHY_INTERFACE_MODE_25GBASER, txgbe->sfp_interfaces))
+- wx->adv_speed = SPEED_25000;
++ *speed = SPEED_25000;
+ else if (test_bit(PHY_INTERFACE_MODE_10GBASER, txgbe->sfp_interfaces))
+- wx->adv_speed = SPEED_10000;
++ *speed = SPEED_10000;
+ else
+- wx->adv_speed = SPEED_UNKNOWN;
++ *speed = SPEED_UNKNOWN;
+
+- wx->adv_duplex = wx->adv_speed == SPEED_UNKNOWN ?
+- DUPLEX_HALF : DUPLEX_FULL;
++ *duplex = *speed == SPEED_UNKNOWN ? DUPLEX_HALF : DUPLEX_FULL;
+ }
+
+ static void txgbe_get_phy_link(struct wx *wx, int *speed)
+@@ -138,23 +135,11 @@ static void txgbe_get_phy_link(struct wx *wx, int *speed)
+
+ int txgbe_set_phy_link(struct wx *wx)
+ {
+- int speed, err;
+- u32 gpio;
++ int speed, duplex, err;
+
+- /* Check RX signal */
+- gpio = rd32(wx, WX_GPIO_EXT);
+- if (gpio & TXGBE_GPIOBIT_3)
+- return -ENODEV;
++ txgbe_get_link_capabilities(wx, &speed, &duplex);
+
+- txgbe_get_link_capabilities(wx);
+- if (wx->adv_speed == SPEED_UNKNOWN)
+- return -ENODEV;
+-
+- txgbe_get_phy_link(wx, &speed);
+- if (speed == wx->adv_speed)
+- return 0;
+-
+- err = txgbe_set_phy_link_hostif(wx, wx->adv_speed, 0, wx->adv_duplex);
++ err = txgbe_set_phy_link_hostif(wx, speed, 0, duplex);
+ if (err) {
+ wx_err(wx, "Failed to setup link\n");
+ return err;
+@@ -230,14 +215,7 @@ int txgbe_identify_sfp(struct wx *wx)
+ return -ENODEV;
+ }
+
+- err = txgbe_sfp_to_linkmodes(wx, id);
+- if (err)
+- return err;
+-
+- if (gpio & TXGBE_GPIOBIT_3)
+- set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
+-
+- return 0;
++ return txgbe_sfp_to_linkmodes(wx, id);
+ }
+
+ void txgbe_setup_link(struct wx *wx)
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
+index be78f8f61a7950..34920b49d0c09b 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
+@@ -314,6 +314,7 @@ void txgbe_up(struct wx *wx);
+ int txgbe_setup_tc(struct net_device *dev, u8 tc);
+ void txgbe_do_reset(struct net_device *netdev);
+
++#define TXGBE_LINK_SPEED_UNKNOWN 0
+ #define TXGBE_LINK_SPEED_10GB_FULL 4
+ #define TXGBE_LINK_SPEED_25GB_FULL 0x10
+
+--
+2.53.0
+
--- /dev/null
+From 030e2da3139e7d29c870bffe2bdd11b6200cec71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Nov 2025 16:02:56 +0800
+Subject: net: txgbe: rename the SFP related
+
+From: Jiawen Wu <jiawenwu@trustnetic.com>
+
+[ Upstream commit dbba6b7a47cba914d48890da7233a64c7b9f3ccc ]
+
+QSFP supported will be introduced for AML 40G devices, the code related
+to identify various modules should be renamed to more appropriate names.
+
+And struct txgbe_hic_i2c_read used to get module information is renamed
+as struct txgbe_hic_get_module_info, because another SW-FW command to
+read I2C will be added later.
+
+Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
+Link: https://patch.msgid.link/20251118080259.24676-3-jiawenwu@trustnetic.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 0487cfca4651 ("net: txgbe: initialize module info buffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/wangxun/libwx/wx_type.h | 2 +-
+ .../net/ethernet/wangxun/txgbe/txgbe_aml.c | 39 ++++++++++---------
+ .../net/ethernet/wangxun/txgbe/txgbe_aml.h | 2 +-
+ .../ethernet/wangxun/txgbe/txgbe_ethtool.c | 2 +-
+ .../net/ethernet/wangxun/txgbe/txgbe_main.c | 12 +++---
+ .../net/ethernet/wangxun/txgbe/txgbe_type.h | 12 +++---
+ 6 files changed, 35 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h
+index d367644debef36..f040b014f2dd74 100644
+--- a/drivers/net/ethernet/wangxun/libwx/wx_type.h
++++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h
+@@ -1229,7 +1229,7 @@ enum wx_pf_flags {
+ WX_FLAG_RX_HWTSTAMP_IN_REGISTER,
+ WX_FLAG_PTP_PPS_ENABLED,
+ WX_FLAG_NEED_LINK_CONFIG,
+- WX_FLAG_NEED_SFP_RESET,
++ WX_FLAG_NEED_MODULE_RESET,
+ WX_FLAG_NEED_UPDATE_LINK,
+ WX_FLAG_NEED_DO_RESET,
+ WX_PF_FLAGS_NBITS /* must be last */
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+index 05f852e31e6e52..0bc59431d43343 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+@@ -38,7 +38,7 @@ irqreturn_t txgbe_gpio_irq_handler_aml(int irq, void *data)
+ wr32(wx, WX_GPIO_INTMASK, 0xFF);
+ status = rd32(wx, WX_GPIO_INTSTATUS);
+ if (status & TXGBE_GPIOBIT_2) {
+- set_bit(WX_FLAG_NEED_SFP_RESET, wx->flags);
++ set_bit(WX_FLAG_NEED_MODULE_RESET, wx->flags);
+ wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_2);
+ wx_service_event_schedule(wx);
+ }
+@@ -63,15 +63,16 @@ int txgbe_test_hostif(struct wx *wx)
+ WX_HI_COMMAND_TIMEOUT, false);
+ }
+
+-static int txgbe_identify_sfp_hostif(struct wx *wx, struct txgbe_hic_i2c_read *buffer)
++static int txgbe_identify_module_hostif(struct wx *wx,
++ struct txgbe_hic_get_module_info *buffer)
+ {
+- buffer->hdr.cmd = FW_READ_SFP_INFO_CMD;
+- buffer->hdr.buf_len = sizeof(struct txgbe_hic_i2c_read) -
++ buffer->hdr.cmd = FW_GET_MODULE_INFO_CMD;
++ buffer->hdr.buf_len = sizeof(struct txgbe_hic_get_module_info) -
+ sizeof(struct wx_hic_hdr);
+ buffer->hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
+
+ return wx_host_interface_command(wx, (u32 *)buffer,
+- sizeof(struct txgbe_hic_i2c_read),
++ sizeof(struct txgbe_hic_get_module_info),
+ WX_HI_COMMAND_TIMEOUT, true);
+ }
+
+@@ -109,9 +110,9 @@ static void txgbe_get_link_capabilities(struct wx *wx, int *speed,
+ {
+ struct txgbe *txgbe = wx->priv;
+
+- if (test_bit(PHY_INTERFACE_MODE_25GBASER, txgbe->sfp_interfaces))
++ if (test_bit(PHY_INTERFACE_MODE_25GBASER, txgbe->link_interfaces))
+ *speed = SPEED_25000;
+- else if (test_bit(PHY_INTERFACE_MODE_10GBASER, txgbe->sfp_interfaces))
++ else if (test_bit(PHY_INTERFACE_MODE_10GBASER, txgbe->link_interfaces))
+ *speed = SPEED_10000;
+ else
+ *speed = SPEED_UNKNOWN;
+@@ -150,7 +151,7 @@ int txgbe_set_phy_link(struct wx *wx)
+ return 0;
+ }
+
+-static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sfp_id *id)
++static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id)
+ {
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
+ DECLARE_PHY_INTERFACE_MASK(interfaces);
+@@ -204,9 +205,9 @@ static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sfp_id *id)
+ phylink_set(modes, Asym_Pause);
+ phylink_set(modes, FIBRE);
+
+- if (!linkmode_equal(txgbe->sfp_support, modes)) {
+- linkmode_copy(txgbe->sfp_support, modes);
+- phy_interface_and(txgbe->sfp_interfaces,
++ if (!linkmode_equal(txgbe->link_support, modes)) {
++ linkmode_copy(txgbe->link_support, modes);
++ phy_interface_and(txgbe->link_interfaces,
+ wx->phylink_config.supported_interfaces,
+ interfaces);
+ linkmode_copy(txgbe->advertising, modes);
+@@ -217,10 +218,10 @@ static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sfp_id *id)
+ return 0;
+ }
+
+-int txgbe_identify_sfp(struct wx *wx)
++int txgbe_identify_module(struct wx *wx)
+ {
+- struct txgbe_hic_i2c_read buffer;
+- struct txgbe_sfp_id *id;
++ struct txgbe_hic_get_module_info buffer;
++ struct txgbe_sff_id *id;
+ int err = 0;
+ u32 gpio;
+
+@@ -228,9 +229,9 @@ int txgbe_identify_sfp(struct wx *wx)
+ if (gpio & TXGBE_GPIOBIT_2)
+ return -ENODEV;
+
+- err = txgbe_identify_sfp_hostif(wx, &buffer);
++ err = txgbe_identify_module_hostif(wx, &buffer);
+ if (err) {
+- wx_err(wx, "Failed to identify SFP module\n");
++ wx_err(wx, "Failed to identify module\n");
+ return err;
+ }
+
+@@ -247,10 +248,10 @@ void txgbe_setup_link(struct wx *wx)
+ {
+ struct txgbe *txgbe = wx->priv;
+
+- phy_interface_zero(txgbe->sfp_interfaces);
+- linkmode_zero(txgbe->sfp_support);
++ phy_interface_zero(txgbe->link_interfaces);
++ linkmode_zero(txgbe->link_support);
+
+- txgbe_identify_sfp(wx);
++ txgbe_identify_module(wx);
+ }
+
+ static void txgbe_get_link_state(struct phylink_config *config,
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.h
+index 25d4971ca0d911..7c8fa48e68d378 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.h
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.h
+@@ -8,7 +8,7 @@ void txgbe_gpio_init_aml(struct wx *wx);
+ irqreturn_t txgbe_gpio_irq_handler_aml(int irq, void *data);
+ int txgbe_test_hostif(struct wx *wx);
+ int txgbe_set_phy_link(struct wx *wx);
+-int txgbe_identify_sfp(struct wx *wx);
++int txgbe_identify_module(struct wx *wx);
+ void txgbe_setup_link(struct wx *wx);
+ int txgbe_phylink_init_aml(struct txgbe *txgbe);
+
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
+index e8dd277a35c7a4..d7f9053594588d 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
+@@ -32,7 +32,7 @@ int txgbe_get_link_ksettings(struct net_device *netdev,
+ cmd->base.port = txgbe->link_port;
+ cmd->base.autoneg = phylink_test(txgbe->advertising, Autoneg) ?
+ AUTONEG_ENABLE : AUTONEG_DISABLE;
+- linkmode_copy(cmd->link_modes.supported, txgbe->sfp_support);
++ linkmode_copy(cmd->link_modes.supported, txgbe->link_support);
+ linkmode_copy(cmd->link_modes.advertising, txgbe->advertising);
+
+ return 0;
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
+index 1377ea90a8c284..4d20b178af236b 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
+@@ -89,21 +89,21 @@ static int txgbe_enumerate_functions(struct wx *wx)
+ return physfns;
+ }
+
+-static void txgbe_sfp_detection_subtask(struct wx *wx)
++static void txgbe_module_detection_subtask(struct wx *wx)
+ {
+ int err;
+
+- if (!test_bit(WX_FLAG_NEED_SFP_RESET, wx->flags))
++ if (!test_bit(WX_FLAG_NEED_MODULE_RESET, wx->flags))
+ return;
+
+- /* wait for SFP module ready */
++ /* wait for SFF module ready */
+ msleep(200);
+
+- err = txgbe_identify_sfp(wx);
++ err = txgbe_identify_module(wx);
+ if (err)
+ return;
+
+- clear_bit(WX_FLAG_NEED_SFP_RESET, wx->flags);
++ clear_bit(WX_FLAG_NEED_MODULE_RESET, wx->flags);
+ }
+
+ static void txgbe_link_config_subtask(struct wx *wx)
+@@ -128,7 +128,7 @@ static void txgbe_service_task(struct work_struct *work)
+ {
+ struct wx *wx = container_of(work, struct wx, service_task);
+
+- txgbe_sfp_detection_subtask(wx);
++ txgbe_module_detection_subtask(wx);
+ txgbe_link_config_subtask(wx);
+
+ wx_service_event_complete(wx);
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
+index 34920b49d0c09b..4d77da720eba16 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
+@@ -341,9 +341,9 @@ void txgbe_do_reset(struct net_device *netdev);
+
+ #define FW_PHY_GET_LINK_CMD 0xC0
+ #define FW_PHY_SET_LINK_CMD 0xC1
+-#define FW_READ_SFP_INFO_CMD 0xC5
++#define FW_GET_MODULE_INFO_CMD 0xC5
+
+-struct txgbe_sfp_id {
++struct txgbe_sff_id {
+ u8 identifier; /* A0H 0x00 */
+ u8 com_1g_code; /* A0H 0x06 */
+ u8 com_10g_code; /* A0H 0x03 */
+@@ -356,9 +356,9 @@ struct txgbe_sfp_id {
+ u8 reserved[3];
+ };
+
+-struct txgbe_hic_i2c_read {
++struct txgbe_hic_get_module_info {
+ struct wx_hic_hdr hdr;
+- struct txgbe_sfp_id id;
++ struct txgbe_sff_id id;
+ };
+
+ struct txgbe_hic_ephy_setlink {
+@@ -449,8 +449,8 @@ struct txgbe {
+ int fdir_filter_count;
+ spinlock_t fdir_perfect_lock; /* spinlock for FDIR */
+
+- DECLARE_PHY_INTERFACE_MASK(sfp_interfaces);
+- __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
++ DECLARE_PHY_INTERFACE_MASK(link_interfaces);
++ __ETHTOOL_DECLARE_LINK_MODE_MASK(link_support);
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
+ u8 link_port;
+ };
+--
+2.53.0
+
--- /dev/null
+From 77d691a059518c90f60bb5e5b8b52d548ed49591 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Nov 2025 16:02:55 +0800
+Subject: net: txgbe: support CR modules for AML devices
+
+From: Jiawen Wu <jiawenwu@trustnetic.com>
+
+[ Upstream commit 354d128aa7212c53ffc7127877953264a445f5af ]
+
+Support to identify 25G/10G CR modules for AML devices. Autoneg is
+enbaled by default in CR mode.
+
+Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
+Link: https://patch.msgid.link/20251118080259.24676-2-jiawenwu@trustnetic.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 0487cfca4651 ("net: txgbe: initialize module info buffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/wangxun/txgbe/txgbe_aml.c | 59 +++++++++++++------
+ .../ethernet/wangxun/txgbe/txgbe_ethtool.c | 3 +-
+ 2 files changed, 44 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+index 80413504e4bc86..05f852e31e6e52 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+@@ -104,7 +104,8 @@ static int txgbe_set_phy_link_hostif(struct wx *wx, int speed, int autoneg, int
+ WX_HI_COMMAND_TIMEOUT, false);
+ }
+
+-static void txgbe_get_link_capabilities(struct wx *wx, int *speed, int *duplex)
++static void txgbe_get_link_capabilities(struct wx *wx, int *speed,
++ int *autoneg, int *duplex)
+ {
+ struct txgbe *txgbe = wx->priv;
+
+@@ -115,6 +116,7 @@ static void txgbe_get_link_capabilities(struct wx *wx, int *speed, int *duplex)
+ else
+ *speed = SPEED_UNKNOWN;
+
++ *autoneg = phylink_test(txgbe->advertising, Autoneg);
+ *duplex = *speed == SPEED_UNKNOWN ? DUPLEX_HALF : DUPLEX_FULL;
+ }
+
+@@ -135,11 +137,11 @@ static void txgbe_get_phy_link(struct wx *wx, int *speed)
+
+ int txgbe_set_phy_link(struct wx *wx)
+ {
+- int speed, duplex, err;
++ int speed, autoneg, duplex, err;
+
+- txgbe_get_link_capabilities(wx, &speed, &duplex);
++ txgbe_get_link_capabilities(wx, &speed, &autoneg, &duplex);
+
+- err = txgbe_set_phy_link_hostif(wx, speed, 0, duplex);
++ err = txgbe_set_phy_link_hostif(wx, speed, autoneg, duplex);
+ if (err) {
+ wx_err(wx, "Failed to setup link\n");
+ return err;
+@@ -154,19 +156,43 @@ static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sfp_id *id)
+ DECLARE_PHY_INTERFACE_MASK(interfaces);
+ struct txgbe *txgbe = wx->priv;
+
+- if (id->com_25g_code & (TXGBE_SFF_25GBASESR_CAPABLE |
+- TXGBE_SFF_25GBASEER_CAPABLE |
+- TXGBE_SFF_25GBASELR_CAPABLE)) {
+- phylink_set(modes, 25000baseSR_Full);
++ if (id->cable_tech & TXGBE_SFF_DA_PASSIVE_CABLE) {
++ txgbe->link_port = PORT_DA;
++ phylink_set(modes, Autoneg);
++ if (id->com_25g_code == TXGBE_SFF_25GBASECR_91FEC ||
++ id->com_25g_code == TXGBE_SFF_25GBASECR_74FEC ||
++ id->com_25g_code == TXGBE_SFF_25GBASECR_NOFEC) {
++ phylink_set(modes, 25000baseCR_Full);
++ phylink_set(modes, 10000baseCR_Full);
++ __set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces);
++ __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
++ } else {
++ phylink_set(modes, 10000baseCR_Full);
++ __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
++ }
++ } else if (id->cable_tech & TXGBE_SFF_DA_ACTIVE_CABLE) {
++ txgbe->link_port = PORT_DA;
++ phylink_set(modes, Autoneg);
++ phylink_set(modes, 25000baseCR_Full);
+ __set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces);
+- }
+- if (id->com_10g_code & TXGBE_SFF_10GBASESR_CAPABLE) {
+- phylink_set(modes, 10000baseSR_Full);
+- __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
+- }
+- if (id->com_10g_code & TXGBE_SFF_10GBASELR_CAPABLE) {
+- phylink_set(modes, 10000baseLR_Full);
+- __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
++ } else {
++ if (id->com_25g_code == TXGBE_SFF_25GBASESR_CAPABLE ||
++ id->com_25g_code == TXGBE_SFF_25GBASEER_CAPABLE ||
++ id->com_25g_code == TXGBE_SFF_25GBASELR_CAPABLE) {
++ txgbe->link_port = PORT_FIBRE;
++ phylink_set(modes, 25000baseSR_Full);
++ __set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces);
++ }
++ if (id->com_10g_code & TXGBE_SFF_10GBASESR_CAPABLE) {
++ txgbe->link_port = PORT_FIBRE;
++ phylink_set(modes, 10000baseSR_Full);
++ __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
++ }
++ if (id->com_10g_code & TXGBE_SFF_10GBASELR_CAPABLE) {
++ txgbe->link_port = PORT_FIBRE;
++ phylink_set(modes, 10000baseLR_Full);
++ __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
++ }
+ }
+
+ if (phy_interface_empty(interfaces)) {
+@@ -177,7 +203,6 @@ static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sfp_id *id)
+ phylink_set(modes, Pause);
+ phylink_set(modes, Asym_Pause);
+ phylink_set(modes, FIBRE);
+- txgbe->link_port = PORT_FIBRE;
+
+ if (!linkmode_equal(txgbe->sfp_support, modes)) {
+ linkmode_copy(txgbe->sfp_support, modes);
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
+index e285b088c7b267..e8dd277a35c7a4 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
+@@ -30,7 +30,8 @@ int txgbe_get_link_ksettings(struct net_device *netdev,
+ return 0;
+
+ cmd->base.port = txgbe->link_port;
+- cmd->base.autoneg = AUTONEG_DISABLE;
++ cmd->base.autoneg = phylink_test(txgbe->advertising, Autoneg) ?
++ AUTONEG_ENABLE : AUTONEG_DISABLE;
+ linkmode_copy(cmd->link_modes.supported, txgbe->sfp_support);
+ linkmode_copy(cmd->link_modes.advertising, txgbe->advertising);
+
+--
+2.53.0
+
--- /dev/null
+From ca35b33b0756d4cb21bb0e40869fed1070933691 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 18:21:24 -0700
+Subject: netdev: fix double-free in netdev_nl_bind_rx_doit()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit c849de7d8757a7af801fc4a4058f71d481d367f2 ]
+
+Sashiko flags that genlmsg_reply() always consumes the skb.
+The error path calls nlmsg_free(rsp) so we can't jump directly
+to it. Let's not unbind, just propagate the error to the user.
+This is the typical way of handling genlmsg_reply() failures.
+They shouldn't happen unless user does something silly like
+calling the kernel with an already-full rcvbuf.
+
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Fixes: 170aafe35cb9 ("netdev: support binding dma-buf to netdevice")
+Reviewed-by: Bobby Eshleman <bobbyeshleman@meta.com>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/netdev-genl.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
+index 470fabbeacd9bd..93ea09bd1e7bab 100644
+--- a/net/core/netdev-genl.c
++++ b/net/core/netdev-genl.c
+@@ -1019,8 +1019,6 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
+ genlmsg_end(rsp, hdr);
+
+ err = genlmsg_reply(rsp, info);
+- if (err)
+- goto err_unbind;
+
+ bitmap_free(rxq_bitmap);
+
+@@ -1028,7 +1026,7 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
+
+ mutex_unlock(&priv->lock);
+
+- return 0;
++ return err < 0 ? err : 0;
+
+ err_unbind:
+ net_devmem_unbind_dmabuf(binding);
+--
+2.53.0
+
--- /dev/null
+From f8b099609c291c073deb42c5b96ce8b5325fef43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 00:38:17 -0700
+Subject: netfilter: nf_conntrack: destroy stale expectfn expectations on
+ unregister
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit c3009418f9fa1dcb3eb86f4d8c92583537b5faa3 ]
+
+NAT helpers such as nf_nat_h323 store a raw pointer to module text in
+exp->expectfn (e.g. ip_nat_q931_expect). nf_ct_helper_expectfn_unregister()
+only unlinks the callback descriptor and never walks the expectation table,
+so an expectation pending at module removal survives with a dangling
+exp->expectfn into freed module text.
+
+When the expected connection arrives, init_conntrack() invokes
+exp->expectfn(), now a stale pointer into the unloaded module. Reproduced
+on a KASAN build by loading the H.323 helpers, creating a Q.931
+expectation, unloading nf_nat_h323, then connecting to the expected port:
+
+ Oops: int3: 0000 [#1] SMP KASAN NOPTI
+ RIP: 0010:0xffffffffa06102d1
+ init_conntrack.isra.0 (net/netfilter/nf_conntrack_core.c:1862)
+ nf_conntrack_in (net/netfilter/nf_conntrack_core.c:2049)
+ ipv4_conntrack_local (net/netfilter/nf_conntrack_proto.c:223)
+ nf_hook_slow (net/netfilter/core.c:619)
+ __ip_local_out (net/ipv4/ip_output.c:120)
+ __tcp_transmit_skb (net/ipv4/tcp_output.c:1715)
+ tcp_connect (net/ipv4/tcp_output.c:4374)
+ tcp_v4_connect (net/ipv4/tcp_ipv4.c:345)
+ __sys_connect (net/socket.c:2167)
+ Modules linked in: nf_conntrack_h323 [last unloaded: nf_nat_h323]
+
+Reaching the dangling state requires CAP_SYS_MODULE in the initial user
+namespace to remove a NAT helper that still has live expectations, so this
+is a robustness fix; leaving an expectation pointing at freed text is wrong
+regardless.
+
+Add nf_ct_helper_expectfn_destroy(), which walks the expectation table and
+drops every expectation whose ->expectfn matches the descriptor being torn
+down. Call it from each NAT helper's exit path after the existing RCU grace
+period, so no expectation outlives the code it points at and no extra
+synchronize_rcu() is introduced. With the fix, the same reproducer runs to
+completion without the Oops.
+
+Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netfilter/nf_conntrack_helper.h | 1 +
+ net/ipv4/netfilter/nf_nat_h323.c | 2 ++
+ net/netfilter/nf_conntrack_helper.c | 19 +++++++++++++++++++
+ net/netfilter/nf_nat_core.c | 2 ++
+ net/netfilter/nf_nat_sip.c | 1 +
+ 5 files changed, 25 insertions(+)
+
+diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
+index de2f956abf3480..24cf3d2d97450f 100644
+--- a/include/net/netfilter/nf_conntrack_helper.h
++++ b/include/net/netfilter/nf_conntrack_helper.h
+@@ -155,6 +155,7 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
+
+ void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n);
+ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n);
++void nf_ct_helper_expectfn_destroy(const struct nf_ct_helper_expectfn *n);
+ struct nf_ct_helper_expectfn *
+ nf_ct_helper_expectfn_find_by_name(const char *name);
+ struct nf_ct_helper_expectfn *
+diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
+index faee20af485613..10e1b0837731b7 100644
+--- a/net/ipv4/netfilter/nf_nat_h323.c
++++ b/net/ipv4/netfilter/nf_nat_h323.c
+@@ -555,6 +555,8 @@ static void __exit nf_nat_h323_fini(void)
+ nf_ct_helper_expectfn_unregister(&q931_nat);
+ nf_ct_helper_expectfn_unregister(&callforwarding_nat);
+ synchronize_rcu();
++ nf_ct_helper_expectfn_destroy(&q931_nat);
++ nf_ct_helper_expectfn_destroy(&callforwarding_nat);
+ }
+
+ /****************************************************************************/
+diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
+index a715304a53d8c2..9150bcfd7ca83b 100644
+--- a/net/netfilter/nf_conntrack_helper.c
++++ b/net/netfilter/nf_conntrack_helper.c
+@@ -283,6 +283,25 @@ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n)
+ }
+ EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_unregister);
+
++static bool expect_iter_expectfn(struct nf_conntrack_expect *exp, void *data)
++{
++ const struct nf_ct_helper_expectfn *n = data;
++
++ /* Relies on registered expectfn descriptors having unique ->expectfn
++ * pointers, which holds for the in-tree NAT helpers.
++ */
++ return exp->expectfn == n->expectfn;
++}
++
++/* Destroy expectations still pointing at @n->expectfn; call after the
++ * caller's RCU grace period so none outlives the (often modular) callback.
++ */
++void nf_ct_helper_expectfn_destroy(const struct nf_ct_helper_expectfn *n)
++{
++ nf_ct_expect_iterate_destroy(expect_iter_expectfn, (void *)n);
++}
++EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_destroy);
++
+ /* Caller should hold the rcu lock */
+ struct nf_ct_helper_expectfn *
+ nf_ct_helper_expectfn_find_by_name(const char *name)
+diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
+index 8e36b4e3e5c478..d3e158ecf729a3 100644
+--- a/net/netfilter/nf_nat_core.c
++++ b/net/netfilter/nf_nat_core.c
+@@ -1347,6 +1347,7 @@ static int __init nf_nat_init(void)
+ RCU_INIT_POINTER(nf_nat_hook, NULL);
+ nf_ct_helper_expectfn_unregister(&follow_master_nat);
+ synchronize_net();
++ nf_ct_helper_expectfn_destroy(&follow_master_nat);
+ unregister_pernet_subsys(&nat_net_ops);
+ kvfree(nf_nat_bysource);
+ }
+@@ -1364,6 +1365,7 @@ static void __exit nf_nat_cleanup(void)
+ RCU_INIT_POINTER(nf_nat_hook, NULL);
+
+ synchronize_net();
++ nf_ct_helper_expectfn_destroy(&follow_master_nat);
+ kvfree(nf_nat_bysource);
+ unregister_pernet_subsys(&nat_net_ops);
+ }
+diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c
+index 9fbfc6bff0c221..00838c0cc5bb28 100644
+--- a/net/netfilter/nf_nat_sip.c
++++ b/net/netfilter/nf_nat_sip.c
+@@ -655,6 +655,7 @@ static void __exit nf_nat_sip_fini(void)
+ RCU_INIT_POINTER(nf_nat_sip_hooks, NULL);
+ nf_ct_helper_expectfn_unregister(&sip_nat);
+ synchronize_rcu();
++ nf_ct_helper_expectfn_destroy(&sip_nat);
+ }
+
+ static const struct nf_nat_sip_hooks sip_hooks = {
+--
+2.53.0
+
--- /dev/null
+From 9456bdb324265e01d8e883f84b36db8c16d39afd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 15:55:02 -0700
+Subject: netfilter: nf_log: validate MAC header was set before dumping it
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit a84b6fedbc97078788be78dbdd7517d143ad1a77 ]
+
+The fallback path of dump_mac_header() guards the MAC header access
+only with "skb->mac_header != skb->network_header", without checking
+skb_mac_header_was_set(). When the MAC header is unset, mac_header is
+0xffff, so the test passes and skb_mac_header(skb) returns
+skb->head + 0xffff, ~64 KiB past the buffer; the loop then reads
+dev->hard_header_len bytes out of bounds into the kernel log.
+
+This is reachable via the netdev logger: nf_log_unknown_packet() calls
+dump_mac_header() unconditionally, and an skb sent through AF_PACKET
+with PACKET_QDISC_BYPASS reaches the egress hook with mac_header still
+unset (__dev_queue_xmit(), which would reset it, is bypassed).
+
+Add the skb_mac_header_was_set() check the ARPHRD_ETHER path already
+uses, and replace the open-coded MAC header length test with
+skb_mac_header_len(). Only skbs with an unset MAC header are affected;
+valid ones are dumped as before.
+
+ BUG: KASAN: slab-out-of-bounds in dump_mac_header (net/netfilter/nf_log_syslog.c:831)
+ Read of size 1 at addr ffff88800ea49d3f by task exploit/148
+ Call Trace:
+ kasan_report (mm/kasan/report.c:595)
+ dump_mac_header (net/netfilter/nf_log_syslog.c:831)
+ nf_log_netdev_packet (net/netfilter/nf_log_syslog.c:938 net/netfilter/nf_log_syslog.c:963)
+ nf_log_packet (net/netfilter/nf_log.c:260)
+ nft_log_eval (net/netfilter/nft_log.c:60)
+ nft_do_chain (net/netfilter/nf_tables_core.c:285)
+ nft_do_chain_netdev (net/netfilter/nft_chain_filter.c:307)
+ nf_hook_slow (net/netfilter/core.c:619)
+ nf_hook_direct_egress (net/packet/af_packet.c:257)
+ packet_xmit (net/packet/af_packet.c:280)
+ packet_sendmsg (net/packet/af_packet.c:3114)
+ __sys_sendto (net/socket.c:2265)
+
+Fixes: 7eb9282cd0ef ("netfilter: ipt_LOG/ip6t_LOG: add option to print decoded MAC header")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_log_syslog.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
+index 86d5fc5d28e3b6..613f37b300a560 100644
+--- a/net/netfilter/nf_log_syslog.c
++++ b/net/netfilter/nf_log_syslog.c
+@@ -801,8 +801,8 @@ static void dump_mac_header(struct nf_log_buf *m,
+
+ fallback:
+ nf_log_buf_add(m, "MAC=");
+- if (dev->hard_header_len &&
+- skb->mac_header != skb->network_header) {
++ if (dev->hard_header_len && skb_mac_header_was_set(skb) &&
++ skb_mac_header_len(skb) != 0) {
+ const unsigned char *p = skb_mac_header(skb);
+ unsigned int i;
+
+--
+2.53.0
+
--- /dev/null
+From 47fc7cd464150296cfb5acacbf52cb1de1ade4d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 21:28:09 +0200
+Subject: netfilter: nft_exthdr: fix register tracking for F_PRESENT flag
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 772cecf198da732faebb5dcfc46d66a505be8495 ]
+
+nft_exthdr_init() passes user-controlled priv->len to
+nft_parse_register_store(), which marks that many bytes in the
+register bitmap as initialized. However, when NFT_EXTHDR_F_PRESENT
+is set, the eval paths write only 1 byte (nft_reg_store8) or
+4 bytes (*dest = 0 on TCP/DCCP error path). When len > 4,
+registers beyond the first are never written, retaining
+uninitialized stack data from nft_regs.
+
+Bail out if userspace requests too much data when F_PRESENT is set.
+
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Fixes: c078ca3b0c5b ("netfilter: nft_exthdr: Add support for existence check")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_exthdr.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
+index 7eedf4e3ae9c75..9471328802d3b7 100644
+--- a/net/netfilter/nft_exthdr.c
++++ b/net/netfilter/nft_exthdr.c
+@@ -532,6 +532,9 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
+ return err;
+ }
+
++ if ((flags & NFT_EXTHDR_F_PRESENT) && len != 1)
++ return -EINVAL;
++
+ priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
+ priv->offset = offset;
+ priv->len = len;
+--
+2.53.0
+
--- /dev/null
+From 41794cbb9ea9f8eab0682b430cb4ff49cb87a521 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 17:04:25 +0200
+Subject: netfilter: revalidate bridge ports
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit ccb9fd4b87538ccf19ccff78ee26700526d94867 ]
+
+ebt_redirect_tg() dereferences br_port_get_rcu() return without a
+NULL check, causing a kernel panic when the bridge port has been
+removed between the original hook invocation and an NFQUEUE
+reinject.
+
+A mere NULL check isn't sufficient, however. As sashiko review
+points out userspace can not only remove the port from the bridge,
+it could also place the device in a different virtual device, e.g.
+macvlan.
+
+If this happens, we must drop the packet, there is no way for us to
+reinject it into the bridge path.
+
+Switch to _upper API, we don't need the bridge port structure.
+Also, this fix keeps another bug intact:
+
+Both nfnetlink_log and nfnetlink_queue use CONFIG_BRIDGE_NETFILTER
+too aggressive, which prevents certain logging features when queueing
+in bridge family: NETFILTER_FAMILY_BRIDGE can be enabled while the old
+CONFIG_BRIDGE_NETFILTER cruft is off.
+
+Fixes tag is a common ancestor, this was always broken.
+
+Fixes: f350a0a87374 ("bridge: use rx_handler_data pointer to store net_bridge_port pointer")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Assisted-by: Claude:claude-sonnet-4-6
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/netfilter/ebt_dnat.c | 4 +-
+ net/bridge/netfilter/ebt_redirect.c | 16 +++++---
+ net/netfilter/nfnetlink_log.c | 23 +++++++++--
+ net/netfilter/nfnetlink_queue.c | 64 +++++++++++++++++++++++++----
+ 4 files changed, 89 insertions(+), 18 deletions(-)
+
+diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c
+index 3fda71a8579d13..73f185cccd63df 100644
+--- a/net/bridge/netfilter/ebt_dnat.c
++++ b/net/bridge/netfilter/ebt_dnat.c
+@@ -39,7 +39,9 @@ ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ dev = xt_in(par);
+ break;
+ case NF_BR_PRE_ROUTING:
+- dev = br_port_get_rcu(xt_in(par))->br->dev;
++ dev = netdev_master_upper_dev_get_rcu(xt_in(par));
++ if (!dev) /* bridge port removed? */
++ return EBT_DROP;
+ break;
+ default:
+ dev = NULL;
+diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c
+index 307790562b4929..83486cd4d564b1 100644
+--- a/net/bridge/netfilter/ebt_redirect.c
++++ b/net/bridge/netfilter/ebt_redirect.c
+@@ -24,12 +24,18 @@ ebt_redirect_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ if (skb_ensure_writable(skb, 0))
+ return EBT_DROP;
+
+- if (xt_hooknum(par) != NF_BR_BROUTING)
+- /* rcu_read_lock()ed by nf_hook_thresh */
+- ether_addr_copy(eth_hdr(skb)->h_dest,
+- br_port_get_rcu(xt_in(par))->br->dev->dev_addr);
+- else
++ if (xt_hooknum(par) != NF_BR_BROUTING) {
++ const struct net_device *dev;
++
++ dev = netdev_master_upper_dev_get_rcu(xt_in(par));
++ if (!dev)
++ return EBT_DROP;
++
++ ether_addr_copy(eth_hdr(skb)->h_dest, dev->dev_addr);
++ } else {
+ ether_addr_copy(eth_hdr(skb)->h_dest, xt_in(par)->dev_addr);
++ }
++
+ skb->pkt_type = PACKET_HOST;
+ return info->target;
+ }
+diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
+index b1f3eda85989cd..25a30bf722c69a 100644
+--- a/net/netfilter/nfnetlink_log.c
++++ b/net/netfilter/nfnetlink_log.c
+@@ -450,6 +450,23 @@ static int nfulnl_put_bridge(struct nfulnl_instance *inst, const struct sk_buff
+ return -1;
+ }
+
++#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
++static int nflog_put_master_ifindex(struct sk_buff *nlskb, int attr,
++ const struct net_device *dev)
++{
++ const struct net_device *upper;
++
++ if (dev && !netif_is_bridge_port(dev))
++ return 0;
++
++ upper = netdev_master_upper_dev_get_rcu((struct net_device *)dev);
++ if (upper && nla_put_be32(nlskb, attr, htonl(upper->ifindex)))
++ return -EMSGSIZE;
++
++ return 0;
++}
++#endif
++
+ /* This is an inline function, we don't really care about a long
+ * list of arguments */
+ static inline int
+@@ -504,8 +521,7 @@ __build_packet_message(struct nfnl_log_net *log,
+ /* rcu_read_lock()ed by nf_hook_thresh or
+ * nf_log_packet.
+ */
+- nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
+- htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
++ nflog_put_master_ifindex(inst->skb, NFULA_IFINDEX_INDEV, indev))
+ goto nla_put_failure;
+ } else {
+ int physinif;
+@@ -541,8 +557,7 @@ __build_packet_message(struct nfnl_log_net *log,
+ /* rcu_read_lock()ed by nf_hook_thresh or
+ * nf_log_packet.
+ */
+- nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
+- htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
++ nflog_put_master_ifindex(inst->skb, NFULA_IFINDEX_OUTDEV, outdev))
+ goto nla_put_failure;
+ } else {
+ struct net_device *physoutdev;
+diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
+index d42e8ac3062fb1..0a5aa6b90fc271 100644
+--- a/net/netfilter/nfnetlink_queue.c
++++ b/net/netfilter/nfnetlink_queue.c
+@@ -426,10 +426,47 @@ static bool nf_ct_drop_unconfirmed(const struct nf_queue_entry *entry, bool *is_
+ return false;
+ }
+
++static bool nf_bridge_port_valid(const struct net_device *dev)
++{
++ if (!dev)
++ return true;
++
++ return netif_is_bridge_port(dev);
++}
++
++/* queued skbs leave rcu protection. We bump device refcount so that
++ * the device cannot go away. However, while packet was out the port
++ * could have been removed from the bridge.
++ *
++ * Ensure in+outdev are still part of a bridge at reinject time.
++ *
++ * The device rx_handler_data could even be pointing at data that is
++ * not a net_bridge_port structure.
++ */
++static bool nf_bridge_ports_valid(const struct nf_queue_entry *entry)
++{
++#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
++ if (!nf_bridge_port_valid(entry->physin) ||
++ !nf_bridge_port_valid(entry->physout))
++ return false;
++#endif
++ if (entry->state.pf != PF_BRIDGE)
++ return true;
++
++ if (!nf_bridge_port_valid(entry->state.in) ||
++ !nf_bridge_port_valid(entry->state.out))
++ return false;
++
++ return true;
++}
++
+ static void nfqnl_reinject(struct nf_queue_entry *entry, unsigned int verdict)
+ {
+ const struct nf_ct_hook *ct_hook;
+
++ if (!nf_bridge_ports_valid(entry))
++ verdict = NF_DROP;
++
+ if (verdict == NF_ACCEPT ||
+ verdict == NF_REPEAT ||
+ verdict == NF_STOP) {
+@@ -622,6 +659,23 @@ static int nf_queue_checksum_help(struct sk_buff *entskb)
+ return skb_checksum_help(entskb);
+ }
+
++#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
++static int nfqnl_put_master_ifindex(struct sk_buff *nlskb, int attr,
++ const struct net_device *dev)
++{
++ const struct net_device *upper;
++
++ if (dev && !netif_is_bridge_port(dev))
++ return 0;
++
++ upper = netdev_master_upper_dev_get_rcu((struct net_device *)dev);
++ if (upper && nla_put_be32(nlskb, attr, htonl(upper->ifindex)))
++ return -EMSGSIZE;
++
++ return 0;
++}
++#endif
++
+ static struct sk_buff *
+ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
+ struct nf_queue_entry *entry,
+@@ -757,10 +811,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
+ * netfilter_bridge) */
+ if (nla_put_be32(skb, NFQA_IFINDEX_PHYSINDEV,
+ htonl(indev->ifindex)) ||
+- /* this is the bridge group "brX" */
+- /* rcu_read_lock()ed by __nf_queue */
+- nla_put_be32(skb, NFQA_IFINDEX_INDEV,
+- htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
++ nfqnl_put_master_ifindex(skb, NFQA_IFINDEX_INDEV, indev))
+ goto nla_put_failure;
+ } else {
+ int physinif;
+@@ -791,10 +842,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
+ * netfilter_bridge) */
+ if (nla_put_be32(skb, NFQA_IFINDEX_PHYSOUTDEV,
+ htonl(outdev->ifindex)) ||
+- /* this is the bridge group "brX" */
+- /* rcu_read_lock()ed by __nf_queue */
+- nla_put_be32(skb, NFQA_IFINDEX_OUTDEV,
+- htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
++ nfqnl_put_master_ifindex(skb, NFQA_IFINDEX_OUTDEV, outdev))
+ goto nla_put_failure;
+ } else {
+ int physoutif;
+--
+2.53.0
+
--- /dev/null
+From 98b6dba8ca22e5c490e203a707134c48d9edf6d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 01:10:31 -0700
+Subject: netfilter: x_tables: avoid leaking percpu counter pointers
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f7f2fbb0e893a0238dc464f8d8c0f5609bec584f ]
+
+The native and compat get-entries paths copy the fixed rule entry header
+from the kernelized rule blob to userspace before overwriting the entry's
+counter fields with a sanitized counter snapshot.
+
+On SMP kernels, entry->counters.pcnt contains the percpu allocation
+address used by x_tables rule counters. A caller can provide a userspace
+buffer that faults during the initial fixed-header copy after pcnt has
+been copied but before the later sanitized counter copy runs. The syscall
+then returns -EFAULT while leaving the raw percpu pointer in userspace.
+
+Copy only the fixed entry prefix before counters from the kernelized rule
+blob, then copy the sanitized counter snapshot into the counter field.
+Apply this ordering to the IPv4, IPv6, and ARP native and compat
+get-entries implementations so a fault cannot expose the internal percpu
+counter pointer.
+
+Fixes: 71ae0dff02d7 ("netfilter: xtables: use percpu rule counters")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/netfilter/arp_tables.c | 15 ++++++---------
+ net/ipv4/netfilter/ip_tables.c | 15 ++++++---------
+ net/ipv6/netfilter/ip6_tables.c | 15 ++++++---------
+ 3 files changed, 18 insertions(+), 27 deletions(-)
+
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+index f3dadbc416a3a5..1490466b146e4b 100644
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -702,14 +702,12 @@ static int copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct arpt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct arpt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1327,9 +1325,8 @@ static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct arpt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_arpt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_arpt_entry);
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
+index f4079f0718deae..0549fad53c0364 100644
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -832,14 +832,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ipt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ipt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1228,9 +1226,8 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ipt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ipt_entry);
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+index dfaea4f6727ed9..3586e636c66bdc 100644
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -848,14 +848,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ip6t_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ip6t_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1244,9 +1242,8 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ip6t_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ip6t_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ip6t_entry);
+--
+2.53.0
+
--- /dev/null
+From a7d66930e176b427507cb8709bb1c9086403b015 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 09:13:53 +0800
+Subject: netlabel: validate unlabeled address and mask attribute lengths
+
+From: Chenguang Zhao <zhaochenguang@kylinos.cn>
+
+[ Upstream commit 9772589b57e44aedc240211c5c3f7a684a034d3a ]
+
+netlbl_unlabel_addrinfo_get() used the address attribute length to
+determine whether the attribute data could be read as an IPv4 or IPv6
+address, but did not independently validate the corresponding mask
+attribute length. A crafted Generic Netlink request could therefore
+provide a valid IPv4/IPv6 address attribute with a shorter mask
+attribute, which would later be read as a full struct in_addr or
+struct in6_addr.
+
+NLA_BINARY policy lengths are maximum lengths by default, so use
+NLA_POLICY_EXACT_LEN() for the unlabeled IPv4/IPv6 address and mask
+attributes. This rejects short attributes during policy validation and
+also exposes the exact length requirements through policy introspection.
+
+Fixes: 8cc44579d1bd ("NetLabel: Introduce static network labels for unlabeled connections")
+Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlabel/netlabel_unlabeled.c | 30 ++++++++++--------------------
+ 1 file changed, 10 insertions(+), 20 deletions(-)
+
+diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
+index dfda9ea61971b3..2237a5261dd2a2 100644
+--- a/net/netlabel/netlabel_unlabeled.c
++++ b/net/netlabel/netlabel_unlabeled.c
+@@ -114,14 +114,14 @@ static struct genl_family netlbl_unlabel_gnl_family;
+ /* NetLabel Netlink attribute policy */
+ static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
+ [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
+- [NLBL_UNLABEL_A_IPV6ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV6MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV4ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
+- [NLBL_UNLABEL_A_IPV4MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
++ [NLBL_UNLABEL_A_IPV6ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV6MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV4ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
++ [NLBL_UNLABEL_A_IPV4MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
+ [NLBL_UNLABEL_A_IFACE] = { .type = NLA_NUL_STRING,
+ .len = IFNAMSIZ - 1 },
+ [NLBL_UNLABEL_A_SECCTX] = { .type = NLA_BINARY }
+@@ -757,24 +757,14 @@ static int netlbl_unlabel_addrinfo_get(struct genl_info *info,
+ void **mask,
+ u32 *len)
+ {
+- u32 addr_len;
+-
+ if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR] &&
+ info->attrs[NLBL_UNLABEL_A_IPV4MASK]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+- if (addr_len != sizeof(struct in_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV4MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4MASK]);
+ return 0;
+ } else if (info->attrs[NLBL_UNLABEL_A_IPV6ADDR]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+- if (addr_len != sizeof(struct in6_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV6MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in6_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6MASK]);
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From ec4836a306d5bab97a9d6d95ab58c38718b53853 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 17:22:47 +0800
+Subject: r8152: handle the return value of usb_reset_device()
+
+From: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+
+[ Upstream commit 19440600e729d4f74a42591a872099cf25c7d28a ]
+
+If usb_reset_device() returns a negative error code, stop the
+process of probing.
+
+Fixes: 10c3271712f5 ("r8152: disable the ECM mode")
+Signed-off-by: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+Reviewed-by: Hayes Wang <hayeswang@realtek.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20260604092247.27158-450-nic_swsd@realtek.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/r8152.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index d610741782794b..8cf4e81f8f882b 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -9781,7 +9781,12 @@ static int rtl8152_probe_once(struct usb_interface *intf,
+ struct net_device *netdev;
+ int ret;
+
+- usb_reset_device(udev);
++ ret = usb_reset_device(udev);
++ if (ret < 0) {
++ dev_err(&intf->dev, "USB reset failed, errno=%d\n", ret);
++ return ret;
++ }
++
+ netdev = alloc_etherdev(sizeof(struct r8152));
+ if (!netdev) {
+ dev_err(&intf->dev, "Out of memory\n");
+--
+2.53.0
+
--- /dev/null
+From e0241c1b061ec6b232de394a932f7782e5f4229c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 02:32:05 -0700
+Subject: rds: mark snapshot pages dirty in rds_info_getsockopt()
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 512db8267b73a220a64180d95ab5eebe7c4964a8 ]
+
+rds_info_getsockopt() pins the destination user pages with FOLL_WRITE and
+the RDS_INFO_* producers memcpy the snapshot into them through
+kmap_atomic(). Because that copy goes through the kernel direct map, the
+dirty bit on the user PTE is never set, so unpin_user_pages() releases the
+pages without marking them dirty. A file-backed destination page can then
+be reclaimed without writeback, silently discarding the copied data.
+
+Use unpin_user_pages_dirty_lock() with make_dirty=true so the modified
+pages are marked dirty before they are unpinned.
+
+Fixes: a8c879a7ee98 ("RDS: Info and stats")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260608-rds_fix-v1-1-006c88543408@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/info.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/rds/info.c b/net/rds/info.c
+index b6b46a8214a0a5..b3ee5f8238c44d 100644
+--- a/net/rds/info.c
++++ b/net/rds/info.c
+@@ -235,7 +235,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
+
+ out:
+ if (pages)
+- unpin_user_pages(pages, nr_pages);
++ unpin_user_pages_dirty_lock(pages, nr_pages, true);
+ kfree(pages);
+
+ return ret;
+--
+2.53.0
+
--- /dev/null
+From 5dfa75c2b1eb714ab5825984aa25091ca2d733e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 08:22:34 -0400
+Subject: sctp: fix uninit-value in __sctp_rcv_asconf_lookup()
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit f8373d7090b745728de66308deeecc67e8d319ce ]
+
+__sctp_rcv_asconf_lookup() in net/sctp/input.c only checks that the ASCONF
+chunk can hold the ADDIP header and a parameter header, then calls
+af->from_addr_param(), which reads the full address (16 bytes for IPv6)
+trusting the parameter's declared length.
+
+An unauthenticated peer can send a truncated trailing ASCONF chunk that
+declares an IPv6 address parameter but stops after the 4-byte parameter
+header; reached from the no-association lookup path, from_addr_param() then
+reads uninitialized bytes past the parameter.
+
+Impact: an unauthenticated SCTP peer makes the receive path read up to 16
+bytes of uninitialized memory past a truncated ASCONF address parameter.
+
+The sibling __sctp_rcv_init_lookup() bounds parameters with
+sctp_walk_params(); this path open-codes the fetch and omits the bound.
+Verify the whole address parameter lies within the chunk before
+from_addr_param() reads it, the same class of fix as commit 51e5ad549c43
+("net: sctp: fix KMSAN uninit-value in sctp_inq_pop").
+
+Fixes: df2185771439 ("[SCTP]: Update association lookup to look at ASCONF chunks as well")
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260608122234.459098-1-michael.bommarito@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/input.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/sctp/input.c b/net/sctp/input.c
+index e119e460ccde0b..864741fae4187e 100644
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -1204,6 +1204,14 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
+ /* Skip over the ADDIP header and find the Address parameter */
+ param = (union sctp_addr_param *)(asconf + 1);
+
++ /* The whole address parameter must lie within the chunk before
++ * af->from_addr_param() reads the variable-length address; otherwise a
++ * truncated trailing ASCONF chunk lets it read uninitialized bytes past
++ * the parameter.
++ */
++ if (sizeof(*asconf) + ntohs(param->p.length) > ntohs(ch->length))
++ return NULL;
++
+ af = sctp_get_af_specific(param_type2af(param->p.type));
+ if (unlikely(!af))
+ return NULL;
+--
+2.53.0
+
--- /dev/null
+From d1fbe9ae50d19619b7a766173267c4780198b479 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 19:03:47 -0400
+Subject: sctp: validate embedded INIT chunk and address list lengths in cookie
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 6f4c80a2a7e6d06753b89a578b710a2499a5e62b ]
+
+sctp_unpack_cookie() only checked that the embedded INIT chunk length
+did not exceed the remaining cookie payload, but did not ensure that the
+INIT chunk is large enough to contain a complete INIT header.
+
+A malformed COOKIE_ECHO can therefore carry a truncated INIT chunk whose
+length field is smaller than sizeof(struct sctp_init_chunk). Later,
+sctp_process_init() accesses INIT parameters unconditionally, which may
+lead to out-of-bounds reads.
+
+In addition, raw_addr_list_len is not fully validated against the
+remaining cookie payload. When cookie authentication is disabled, an
+attacker can supply an oversized raw_addr_list_len and cause
+sctp_raw_to_bind_addrs() to read beyond the end of the cookie. The
+address parser also lacks sufficient bounds checks for parameter headers
+and lengths, allowing malformed address parameters to trigger
+out-of-bounds reads.
+
+Fix this by:
+
+- requiring the embedded INIT chunk length to be at least sizeof(struct
+ sctp_init_chunk);
+- validating that the INIT chunk and raw address list together fit
+ within the cookie payload;
+- verifying sufficient data exists for each address parameter header and
+ payload before parsing it.
+
+Note that sctp_verify_init() must be called after sctp_unpack_cookie()
+and before sctp_process_init() when cookie authentication is disabled.
+This will be addressed in a separate patch.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/75af23a89adf881a0895d511775e4770da367cbf.1780873427.git.lucien.xin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/bind_addr.c | 11 ++++++++++-
+ net/sctp/sm_make_chunk.c | 9 +++++++--
+ 2 files changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
+index 6b95d3ba8fe1ce..0947b276d1e085 100644
+--- a/net/sctp/bind_addr.c
++++ b/net/sctp/bind_addr.c
+@@ -275,6 +275,16 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
+ param = (struct sctp_paramhdr *)raw_addr_list;
+ rawaddr = (union sctp_addr_param *)raw_addr_list;
+
++ if (addrs_len < sizeof(*param)) {
++ retval = -EINVAL;
++ goto out_err;
++ }
++ len = ntohs(param->length);
++ if (addrs_len < len) {
++ retval = -EINVAL;
++ goto out_err;
++ }
++
+ af = sctp_get_af_specific(param_type2af(param->type));
+ if (unlikely(!af) ||
+ !af->from_addr_param(&addr, rawaddr, htons(port), 0)) {
+@@ -291,7 +301,6 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
+ goto out_err;
+
+ next:
+- len = ntohs(param->length);
+ addrs_len -= len;
+ raw_addr_list += len;
+ }
+diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
+index 9014b095f52ddb..51affa4fd396b7 100644
+--- a/net/sctp/sm_make_chunk.c
++++ b/net/sctp/sm_make_chunk.c
+@@ -1731,8 +1731,8 @@ struct sctp_association *sctp_unpack_cookie(
+ struct sk_buff *skb = chunk->skb;
+ struct sctp_cookie *bear_cookie;
+ struct sctp_chunkhdr *ch;
++ unsigned int len, chlen;
+ enum sctp_scope scope;
+- unsigned int len;
+ ktime_t kt;
+
+ /* Header size is static data prior to the actual cookie, including
+@@ -1761,7 +1761,12 @@ struct sctp_association *sctp_unpack_cookie(
+ bear_cookie = &cookie->c;
+
+ ch = (struct sctp_chunkhdr *)(bear_cookie + 1);
+- if (ntohs(ch->length) > len - fixed_size)
++ chlen = ntohs(ch->length);
++ if (chlen < sizeof(struct sctp_init_chunk))
++ goto malformed;
++ if (chlen > len - fixed_size)
++ goto malformed;
++ if (bear_cookie->raw_addr_list_len > len - fixed_size - chlen)
+ goto malformed;
+
+ /* Verify the cookie's MAC, if cookie authentication is enabled. */
+--
+2.53.0
+
verification-rvgen-fix-options-shared-among-commands.patch
verification-rvgen-fix-ltl2k-writing-true-as-a-liter.patch
tap-free-page-on-error-paths-in-tap_get_user_xdp.patch
+xfrm-iptfs-fix-use-after-free-on-first_skb-in-__inpu.patch
+dma-mapping-direct-fix-missing-mapping-for-thru_host.patch
+dma-debug-fix-physical-address-retrieval-in-debug_dm.patch
+xfrm-policy-fix-use-after-free-on-inexact-bin-in-xfr.patch
+ice-fix-missing-priority-callbacks-for-u.fl-dpll-pin.patch
+idpf-fix-mailbox-capability-for-set-device-clock-tim.patch
+net-ena-phc-add-missing-barrier.patch
+bnge-fix-context-mem-iteration.patch
+netlabel-validate-unlabeled-address-and-mask-attribu.patch
+gpio-mvebu-fix-null-pointer-dereference-in-suspend-r.patch
+asoc-wm_adsp-fix-null-dereference-when-removing-firm.patch
+tcp-restrict-so_attach_filter-to-priv-users.patch
+net-add-pskb_may_pull-to-skb_gro_receive_list.patch
+net-mlx4-avoid-gcc-10-__bad_copy_from-false-positive.patch
+net-ibm-emac-fix-use-after-free-during-device-remova.patch
+netdev-fix-double-free-in-netdev_nl_bind_rx_doit.patch
+net-phy-clean-the-sfp-upstream-if-phy-probing-fails.patch
+net-qrtr-fix-refcount-saturation-and-potential-uaf-i.patch
+net-mlx5-fix-slab-out-of-bounds-in-mlx5_query_nic_vp.patch
+net-mlx5e-xsk-fix-dma-and-xdp_frame-leak-on-xdp_tx-x.patch
+net-mlx5-use-effective-affinity-mask-for-irq-selecti.patch
+ipv6-sit-reload-inner-ipv6-header-after-gso-offloads.patch
+net-openvswitch-fix-possible-kfree_skb-of-err_ptr.patch
+r8152-handle-the-return-value-of-usb_reset_device.patch
+gpio-zynq-fix-runtime-pm-leak-on-remove.patch
+gpio-rockchip-fix-generic-irq-chip-leak-on-remove.patch
+net-mctp-usb-fix-race-between-urb-completion-and-rx_.patch
+net-mctp-usb-don-t-fail-mctp_usb_rx_queue-on-a-defer.patch
+asoc-sof-amd-fix-for-ipc-flags-check.patch
+sctp-fix-uninit-value-in-__sctp_rcv_asconf_lookup.patch
+ip6_vti-set-netns_immutable-on-the-fallback-device.patch
+sctp-validate-embedded-init-chunk-and-address-list-l.patch
+net-guard-timestamp-cmsgs-to-real-error-queue-skbs.patch
+net-rds-fix-null-deref-in-rds_ib_send_cqe_handler-on.patch
+tun-zero-the-whole-vnet-header-in-tun_put_user.patch
+ip6_vti-fix-incorrect-tunnel-matching-in-vti6_tnl_lo.patch
+rds-mark-snapshot-pages-dirty-in-rds_info_getsockopt.patch
+spi-rzv2h-rspi-fix-spdr-read-access-width-for-16-bit.patch
+netfilter-revalidate-bridge-ports.patch
+netfilter-nf_conntrack-destroy-stale-expectfn-expect.patch
+netfilter-x_tables-avoid-leaking-percpu-counter-poin.patch
+netfilter-nf_log-validate-mac-header-was-set-before-.patch
+netfilter-nft_exthdr-fix-register-tracking-for-f_pre.patch
+net-mvpp2-sync-rx-data-at-the-hardware-packet-offset.patch
+net-mvpp2-limit-xdp-frame-size-to-the-rx-buffer.patch
+net-mvpp2-refill-rx-buffers-before-xdp-or-skb-use.patch
+net-mvpp2-build-skb-from-xdp-adjusted-data-on-xdp_pa.patch
+net-txgbe-optimize-the-flow-to-setup-phy-for-aml-dev.patch
+net-txgbe-support-cr-modules-for-aml-devices.patch
+net-txgbe-rename-the-sfp-related.patch
+net-txgbe-initialize-module-info-buffer.patch
+ipv6-fix-a-potential-npd-in-cleanup_prefix_route.patch
--- /dev/null
+From 8cb0c8a7caee99ff1d508318654d9f9ea306d86e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 20:08:17 +0800
+Subject: spi: rzv2h-rspi: Fix SPDR read access width for 16-bit RX
+
+From: Felix Gu <ustc.gu@gmail.com>
+
+[ Upstream commit 310628484ef06f95c5589374fade917a5689787b ]
+
+The RZ/V2H hardware manual (section 7.5.2.2.1) specifies that read access
+size for the SPI Data Register (SPDR) are fixed at 32 bits. The
+RZV2H_RSPI_RX macro for the 16-bit data path used readw(), violating
+this requirement.
+
+Switch to readl() for the 16-bit RX path to conform to the hardware
+specification.
+
+Fixes: 8b61c8919dff ("spi: Add driver for the RZ/V2H(P) RSPI IP")
+Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Felix Gu <ustc.gu@gmail.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+Link: https://patch.msgid.link/20260610-rzv2h-rspi-v2-1-40c80b4a2c90@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-rzv2h-rspi.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
+index dcc431ba60a9e5..c981dd3c0dbab6 100644
+--- a/drivers/spi/spi-rzv2h-rspi.c
++++ b/drivers/spi/spi-rzv2h-rspi.c
+@@ -105,8 +105,9 @@ static inline void rzv2h_rspi_rx_##type(struct rzv2h_rspi_priv *rspi, \
+ RZV2H_RSPI_TX(writel, u32)
+ RZV2H_RSPI_TX(writew, u16)
+ RZV2H_RSPI_TX(writeb, u8)
++/* The read access size for RSPI_SPDR is fixed at 32 bits */
+ RZV2H_RSPI_RX(readl, u32)
+-RZV2H_RSPI_RX(readw, u16)
++RZV2H_RSPI_RX(readl, u16)
+ RZV2H_RSPI_RX(readl, u8)
+
+ static void rzv2h_rspi_reg_rmw(const struct rzv2h_rspi_priv *rspi,
+--
+2.53.0
+
--- /dev/null
+From 3cc30c8e8de96e425da1ae0b120bda5c7d3a6ae7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 11:21:34 +0000
+Subject: tcp: restrict SO_ATTACH_FILTER to priv users
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 5d39580f68e6ddeedd15e587282207489dfb3da2 ]
+
+This patch restricts the use of SO_ATTACH_FILTER (cBPF) on TCP sockets
+to users with CAP_NET_ADMIN capability.
+
+This blocks potential side-channel attack where an unprivileged application
+attaches a filter to leak TCP sequence/acknowledgment numbers.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Tamir Shahar <tamirthesis@gmail.com>
+Reported-by: Amit Klein <aksecurity@gmail.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Andrii Nakryiko <andrii@kernel.org>
+Cc: Martin KaFai Lau <martin.lau@linux.dev>
+Cc: Eduard Zingerman <eddyz87@gmail.com>
+Cc: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Cc: Song Liu <song@kernel.org>
+Cc: Yonghong Song <yonghong.song@linux.dev>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: Stanislav Fomichev <sdf@fomichev.me>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 82470f59fa5c50..04fa0c18adc3e4 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1457,6 +1457,11 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
+ case SO_ATTACH_FILTER: {
+ struct sock_fprog fprog;
+
++ if (sk_is_tcp(sk) &&
++ !sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
++ ret = -EPERM;
++ break;
++ }
+ ret = copy_bpf_fprog_from_user(&fprog, optval, optlen);
+ if (!ret)
+ ret = sk_attach_filter(&fprog, sk);
+--
+2.53.0
+
--- /dev/null
+From d6c6067c234efba5f76be25f4d38187369b52581 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 22:44:28 -0700
+Subject: tun: zero the whole vnet header in tun_put_user()
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit 7f2fcff15e99bb852f6967396ed12b38376e2c8d ]
+
+tun_put_user() declares an on-stack struct virtio_net_hdr_v1_hash_tunnel
+without zeroing it. For a non-tunnel skb, virtio_net_hdr_tnl_from_skb()
+only initializes the first 10 bytes (sizeof(struct virtio_net_hdr)),
+leaving bytes 10..23 (num_buffers and the hash/tunnel fields) as stack
+garbage.
+
+An unprivileged user can set the vnet header size to 24 with
+TUNSETVNETHDRSZ, so __tun_vnet_hdr_put() copies all 24 bytes of the
+partially-initialized struct to userspace, leaking 14 bytes of kernel
+stack on every read of a non-tunnel packet.
+
+Fix it the same way tun_get_user() already does by zeroing the whole
+header right after declaration.
+
+Fixes: 288f30435132 ("tun: enable gso over UDP tunnel support.")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260607054428.3050243-1-xmei5@asu.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 9a767da38c71e7..d27c3229465ad9 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2068,6 +2068,7 @@ static ssize_t tun_put_user(struct tun_struct *tun,
+ struct virtio_net_hdr_v1_hash_tunnel hdr;
+ struct virtio_net_hdr *gso;
+
++ memset(&hdr, 0, sizeof(hdr));
+ ret = tun_vnet_hdr_tnl_from_skb(tun->flags, tun->dev, skb,
+ &hdr);
+ if (ret)
+--
+2.53.0
+
--- /dev/null
+From f6b78540048be4a550437216fdc5ceeb82b02b1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 18:53:28 +0800
+Subject: xfrm: iptfs: fix use-after-free on first_skb in
+ __input_process_payload
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit eb48730bb827d1550401a5d391903f9d90b493c8 ]
+
+__input_process_payload() stores first_skb into xtfs->ra_newskb under
+drop_lock when starting partial reassembly, then unlocks and breaks out
+of the processing loop. The post-loop check reads xtfs->ra_newskb
+without the lock to decide whether first_skb is still owned:
+
+ if (first_skb && first_iplen && !defer && first_skb != xtfs->ra_newskb)
+
+Between spin_unlock and this read, a concurrent CPU running
+iptfs_reassem_cont() (or the drop_timer hrtimer) can complete
+reassembly, NULL xtfs->ra_newskb, and free the skb. The check then
+evaluates first_skb != NULL as true, and pskb_trim/ip_summed/consume_skb
+operate on the freed skb — a use-after-free in skbuff_head_cache.
+
+Replace the unlocked read with a local bool that records whether
+first_skb was handed to the reassembly state in the current call. The
+flag is set after the existing spin_unlock, before the break, using the
+pointer equality that is stable at that point (first_skb == skb iff
+first_skb was stored in ra_newskb).
+
+Fixes: 3f3339885fb3 ("xfrm: iptfs: add reusing received skb for the tunnel egress packet")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_iptfs.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/xfrm/xfrm_iptfs.c b/net/xfrm/xfrm_iptfs.c
+index e11e4f7411fd25..3dbb9c2cf4d5f6 100644
+--- a/net/xfrm/xfrm_iptfs.c
++++ b/net/xfrm/xfrm_iptfs.c
+@@ -954,6 +954,7 @@ static bool __input_process_payload(struct xfrm_state *x, u32 data,
+ u32 first_iplen, iphlen, iplen, remaining, tail;
+ u32 capturelen;
+ u64 seq;
++ bool first_skb_partial = false;
+
+ xtfs = x->mode_data;
+ net = xs_net(x);
+@@ -1161,6 +1162,7 @@ static bool __input_process_payload(struct xfrm_state *x, u32 data,
+
+ spin_unlock(&xtfs->drop_lock);
+
++ first_skb_partial = (first_skb == skb);
+ break;
+ }
+
+@@ -1172,7 +1174,7 @@ static bool __input_process_payload(struct xfrm_state *x, u32 data,
+ /* this should not happen from the above code */
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINIPTFSERROR);
+
+- if (first_skb && first_iplen && !defer && first_skb != xtfs->ra_newskb) {
++ if (first_skb && first_iplen && !defer && !first_skb_partial) {
+ /* first_skb is queued b/c !defer and not partial */
+ if (pskb_trim(first_skb, first_iplen)) {
+ /* error trimming */
+--
+2.53.0
+
--- /dev/null
+From d45c07932e60a1e66b7a73f220549fc5e0d3f9b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 18:49:05 +0900
+Subject: xfrm: policy: fix use-after-free on inexact bin in
+ xfrm_policy_bysel_ctx()
+
+From: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+
+[ Upstream commit 7f2d76c9c03257c0782afef9d95321fa04096f60 ]
+
+Fix the race by pruning the bin while still holding xfrm_policy_lock,
+before dropping it. Use __xfrm_policy_inexact_prune_bin() directly since
+the lock is already held. The wrapper xfrm_policy_inexact_prune_bin()
+becomes unused and is removed.
+
+Race:
+
+ CPU0 (XFRM_MSG_DELPOLICY) CPU1 (XFRM_MSG_NEWSPDINFO)
+ ========================== ==========================
+ xfrm_policy_bysel_ctx():
+ spin_lock_bh(xfrm_policy_lock)
+ bin = xfrm_policy_inexact_lookup()
+ __xfrm_policy_unlink(pol)
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_kill(ret)
+ // wide window, lock not held
+ xfrm_hash_rebuild():
+ spin_lock_bh(xfrm_policy_lock)
+ __xfrm_policy_inexact_flush():
+ kfree_rcu(bin) // bin freed
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_inexact_prune_bin(bin)
+ // UAF: bin is freed
+
+Fixes: 6be3b0db6db8 ("xfrm: policy: add inexact policy search tree infrastructure")
+Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index ee1f6d5c391de8..c76625d511ec34 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1156,15 +1156,6 @@ static void __xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b, bool
+ }
+ }
+
+-static void xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b)
+-{
+- struct net *net = read_pnet(&b->k.net);
+-
+- spin_lock_bh(&net->xfrm.xfrm_policy_lock);
+- __xfrm_policy_inexact_prune_bin(b, false);
+- spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+-}
+-
+ static void __xfrm_policy_inexact_flush(struct net *net)
+ {
+ struct xfrm_pol_inexact_bin *bin, *t;
+@@ -1707,12 +1698,12 @@ xfrm_policy_bysel_ctx(struct net *net, const struct xfrm_mark *mark, u32 if_id,
+ }
+ ret = pol;
+ }
++ if (bin && delete)
++ __xfrm_policy_inexact_prune_bin(bin, false);
+ spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+
+ if (ret && delete)
+ xfrm_policy_kill(ret);
+- if (bin && delete)
+- xfrm_policy_inexact_prune_bin(bin);
+ return ret;
+ }
+ EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
+--
+2.53.0
+
--- /dev/null
+From 5f715649ced3b8552b79e96bfe684b4d18ecf551 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 11:12:44 +0100
+Subject: ASoC: wm_adsp: Fix NULL dereference when removing firmware controls
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 7d3fb78b550301e43fdc60312aed733069694426 ]
+
+In wm_adsp_control_remove() check that the priv pointer is not NULL
+before attempting to cleanup what it points to.
+
+When cs_dsp creates a control it calls wm_adsp_control_add_cb() so that
+wm_adsp can create its own private control data. There are two cases
+where private data is not created:
+
+1. The control is a SYSTEM control, so an ALSA control is not created.
+
+2. The codec driver has registered a control_add() callback that
+ hides the control, so wm_adsp_control_add() is not called.
+
+When cs_dsp_remove destroys its control list it calls
+wm_adsp_control_remove() for each control. But wm_adsp_control_remove()
+was attempting to cleanup the private data pointed to by cs_ctl->priv
+without checking the pointer for NULL.
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Fixes: 0700bc2fb94c ("ASoC: wm_adsp: Separate generic cs_dsp_coeff_ctl handling")
+Link: https://patch.msgid.link/20260604101244.1402862-1-rf@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/wm_adsp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
+index b9c20e29fe63ef..2da19de4800e2f 100644
+--- a/sound/soc/codecs/wm_adsp.c
++++ b/sound/soc/codecs/wm_adsp.c
+@@ -674,6 +674,9 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl)
+ {
+ struct wm_coeff_ctl *ctl = cs_ctl->priv;
+
++ if (!ctl)
++ return;
++
+ cancel_work_sync(&ctl->work);
+
+ kfree(ctl->name);
+--
+2.53.0
+
--- /dev/null
+From 3acb0100e369067d5c9fe2c63720d5763486b5f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 16:43:34 +0800
+Subject: gpio: mvebu: fix NULL pointer dereference in suspend/resume
+
+From: Yun Zhou <yun.zhou@windriver.com>
+
+[ Upstream commit b9ad50d7505ebd48282ec3630258dc820fc85c81 ]
+
+mvebu_pwm_suspend() and mvebu_pwm_resume() are called for all GPIO
+banks during suspend/resume, but not all banks have PWM functionality.
+GPIO banks without PWM have mvchip->mvpwm set to NULL.
+
+Calling mvebu_pwm_suspend() with mvpwm == NULL causes a NULL pointer
+dereference when it tries to access mvpwm->blink_select.
+
+ Unable to handle kernel NULL pointer dereference at virtual address 00000020 when write
+ [00000020] *pgd=00000000
+ Internal error: Oops: 815 [#1] PREEMPT ARM
+ Modules linked in:
+ CPU: 0 UID: 0 PID: 406 Comm: sh Not tainted 6.12.74-rt12-yocto-standard-g4e96f98fb7db-dirty #353
+ Hardware name: Marvell Armada 370/XP (Device Tree)
+ PC is at regmap_mmio_read+0x38/0x54
+ LR is at regmap_mmio_read+0x38/0x54
+ pc : [<c05fd2ac>] lr : [<c05fd2ac>] psr: 200f0013
+ sp : f0c11d10 ip : 00000000 fp : c100d2f0
+ r10: c14fb854 r9 : 00000000 r8 : 00000000
+ r7 : c1799c00 r6 : 00000020 r5 : 00000020 r4 : c179c7c0
+ r3 : f0a231a0 r2 : 00000020 r1 : 00000020 r0 : 00000000
+ Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
+ Control: 10c5387d Table: 135ec059 DAC: 00000051
+ Call trace:
+ regmap_mmio_read from _regmap_bus_reg_read+0x78/0xac
+ _regmap_bus_reg_read from _regmap_read+0x60/0x154
+ _regmap_read from regmap_read+0x3c/0x60
+ regmap_read from mvebu_gpio_suspend+0xa4/0x14c
+ mvebu_gpio_suspend from dpm_run_callback+0x54/0x180
+ dpm_run_callback from device_suspend+0x124/0x630
+ device_suspend from dpm_suspend+0x124/0x270
+ dpm_suspend from dpm_suspend_start+0x64/0x6c
+ dpm_suspend_start from suspend_devices_and_enter+0x140/0x8e8
+ suspend_devices_and_enter from pm_suspend+0x2fc/0x308
+ pm_suspend from state_store+0x6c/0xc8
+ state_store from kernfs_fop_write_iter+0x10c/0x1f8
+ kernfs_fop_write_iter from vfs_write+0x270/0x468
+ vfs_write from ksys_write+0x70/0xf0
+ ksys_write from ret_fast_syscall+0x0/0x54
+
+Add a NULL check for mvchip->mvpwm before calling the PWM
+suspend/resume functions.
+
+Fixes: 757642f9a584 ("gpio: mvebu: Add limited PWM support")
+Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
+Link: https://patch.msgid.link/20260608084334.2960803-1-yun.zhou@windriver.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-mvebu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
+index 67497116ce27d4..ee184720de57c2 100644
+--- a/drivers/gpio/gpio-mvebu.c
++++ b/drivers/gpio/gpio-mvebu.c
+@@ -1002,7 +1002,7 @@ static int mvebu_gpio_suspend(struct platform_device *pdev, pm_message_t state)
+ BUG();
+ }
+
+- if (IS_REACHABLE(CONFIG_PWM))
++ if (IS_REACHABLE(CONFIG_PWM) && mvchip->mvpwm)
+ mvebu_pwm_suspend(mvchip);
+
+ return 0;
+@@ -1054,7 +1054,7 @@ static int mvebu_gpio_resume(struct platform_device *pdev)
+ BUG();
+ }
+
+- if (IS_REACHABLE(CONFIG_PWM))
++ if (IS_REACHABLE(CONFIG_PWM) && mvchip->mvpwm)
+ mvebu_pwm_resume(mvchip);
+
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From 5453c1653edadf19761b340c5cd6bbc86905324d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jun 2026 08:10:47 -0400
+Subject: iomap: don't revert iov_iter on partially completed buffered writes
+
+From: Brian Foster <bfoster@redhat.com>
+
+Gregg reports that the iomap retry behavior for nonblocking (nowait)
+append writes is broken. The problem occurs when an append write is
+first submitted in non-blocking mode (i.e. via io_uring), partially
+completes before hitting -EAGAIN, and then is resubmitted from
+blocking context.
+
+The specific problem is that at least one iteration of the loop in
+iomap_write_iter() completes in non-blocking context and thus has
+bumped i_size. The next iteration hits -EAGAIN, reverts the iov_iter
+and returns. io_uring retries the entire append write from blocking
+context, but since i_size has already been increased, the data that
+was partially written on the first attempt is rewritten at the new
+i_size. This is essentially an intra-write data corruption since the
+data written to the file does not reflect the write from userspace.
+
+This problem is already fixed on master as of commit 1a1a3b574b97
+("iomap: advance the iter directly on buffered writes"). That commit
+was primarily intended to clean up iomap iter state tracking, but it
+also happened to remove the iov_iter revert and thus accidentally
+fix this problem as well. Without the revert, iomap will commit
+partial progress internally and loop once more before it more than
+likely hits -EAGAIN and returns partial progress consistent with the
+inode updates. This means the blocking retry from io_uring will pick
+up where the first attempt left off at the current i_size and
+perform the remainder of the write correctly.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 18e419f6e80a ("iomap: Return -EAGAIN from iomap_write_iter()")
+Reported-by: Gregg Leventhal <gleventhal@janestreet.com>
+Reported-by: Eric Hagberg <ehagberg@janestreet.com>
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/iomap/buffered-io.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
+index c5d439f8e2254e..4bc57934aa52df 100644
+--- a/fs/iomap/buffered-io.c
++++ b/fs/iomap/buffered-io.c
+@@ -974,10 +974,6 @@ static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
+ }
+ } while (iov_iter_count(i) && length);
+
+- if (status == -EAGAIN) {
+- iov_iter_revert(i, written);
+- return -EAGAIN;
+- }
+ return written ? written : status;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From b916f51035e075aae8458a807b51c8349873d814 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 16:46:13 +0000
+Subject: ip6_vti: fix incorrect tunnel matching in vti6_tnl_lookup()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit a5c0359f5cbc51a2e2b114d6041e0f3c73f903e9 ]
+
+In vti6_tnl_lookup(), when an exact match for a tunnel fails,
+the code falls back to searching for wildcard tunnels:
+
+- Tunnels matching the packet's local address, with any remote address
+ wildcard remote).
+
+- Tunnels matching the packet's remote address, with any local address
+ (wildcard local).
+
+However, vti6 stores all these different types of tunnels in the same
+hash table (ip6n->tnls_r_l) prone to hash collisions.
+
+The bug is that the fallback search loops in vti6_tnl_lookup() were
+missing checks to ensure that the candidate tunnel actually has
+a wildcard address.
+
+Fixes: fbe68ee87522 ("vti6: Add a lookup method for tunnels with wildcard endpoints.")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260608164613.933023-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_vti.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
+index 5e71dbd9401694..67cf616c1499a4 100644
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -105,6 +105,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(&any, local);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(local, &t->parms.laddr) &&
++ ipv6_addr_any(&t->parms.raddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+@@ -112,6 +113,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(remote, &any);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(remote, &t->parms.raddr) &&
++ ipv6_addr_any(&t->parms.laddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+--
+2.53.0
+
--- /dev/null
+From 093acb55d94e92e710ee6b10d37d195e8fb9e538 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 17:54:48 +0300
+Subject: ipv6: Fix a potential NPD in cleanup_prefix_route()
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit b70c687b7cf267fb08586667a3946c8851cad672 ]
+
+addrconf_get_prefix_route() can return the fib6_null_entry sentinel
+entry which has a NULL fib6_table pointer. Therefore, before setting the
+route's expiration time, check that we are not working with this entry,
+as otherwise a NPD will be triggered [1].
+
+Note that the other callers of addrconf_get_prefix_route() are not
+susceptible to this bug:
+
+1. addrconf_prefix_rcv(): Requests a route with the 'RTF_ADDRCONF |
+ RTF_PREFIX_RT' flags which are not set on fib6_null_entry.
+
+2. modify_prefix_route(): Fixed by commit a747e02430df ("ipv6: avoid
+ possible NULL deref in modify_prefix_route()").
+
+3. __ipv6_ifa_notify(): Calls ip6_del_rt() which specifically checks for
+ fib6_null_entry and returns an error.
+
+[1]
+Oops: general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] SMP KASAN
+KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037]
+[...]
+Call Trace:
+<TASK>
+__kasan_check_byte (mm/kasan/common.c:573)
+lock_acquire.part.0 (kernel/locking/lockdep.c:5842 (discriminator 1))
+_raw_spin_lock_bh (kernel/locking/spinlock.c:182 (discriminator 1))
+cleanup_prefix_route (net/ipv6/addrconf.c:1280)
+ipv6_del_addr (net/ipv6/addrconf.c:1342)
+inet6_addr_del.isra.0 (net/ipv6/addrconf.c:3119)
+inet6_rtm_deladdr (net/ipv6/addrconf.c:4812)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6997)
+netlink_rcv_skb (net/netlink/af_netlink.c:2555)
+netlink_unicast (net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1899)
+__sock_sendmsg (net/socket.c:802 (discriminator 4))
+____sys_sendmsg (net/socket.c:2698)
+___sys_sendmsg (net/socket.c:2752)
+__sys_sendmsg (net/socket.c:2784)
+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)
+
+Fixes: 5eb902b8e719 ("net/ipv6: Remove expired routes with a separated list of routes.")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Reviewed-by: David Ahern <dahern@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260609145448.768318-1-idosch@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/addrconf.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 32fa6236dacdd9..ba5de8b924b80c 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1268,6 +1268,7 @@ static void
+ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires,
+ bool del_rt, bool del_peer)
+ {
++ struct net *net = dev_net(ifp->idev->dev);
+ struct fib6_table *table;
+ struct fib6_info *f6i;
+
+@@ -1276,9 +1277,10 @@ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires,
+ ifp->idev->dev, 0, RTF_DEFAULT, true);
+ if (f6i) {
+ if (del_rt)
+- ip6_del_rt(dev_net(ifp->idev->dev), f6i, false);
++ ip6_del_rt(net, f6i, false);
+ else {
+- if (!(f6i->fib6_flags & RTF_EXPIRES)) {
++ if (f6i != net->ipv6.fib6_null_entry &&
++ !(f6i->fib6_flags & RTF_EXPIRES)) {
+ table = f6i->fib6_table;
+ spin_lock_bh(&table->tb6_lock);
+
+--
+2.53.0
+
--- /dev/null
+From b3e3ff5fab76731a09e1707bfb2821f901c23e7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 00:34:48 -0700
+Subject: ipv6: sit: reload inner IPv6 header after GSO offloads
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f0e42f0c4337b1f220de1ddd63f47197c7dee4de ]
+
+ipip6_tunnel_xmit() caches the inner IPv6 header pointer at function
+entry and continues using it after iptunnel_handle_offloads().
+
+For GSO skbs, iptunnel_handle_offloads() calls skb_header_unclone().
+When the skb header is cloned, skb_header_unclone() can call
+pskb_expand_head(), which may move the skb head. The pskb_expand_head()
+contract requires pointers into the skb header to be reloaded after the
+call.
+
+If the later skb_realloc_headroom() branch is not taken, SIT uses the
+stale iph6 pointer to read the inner hop limit and DS field. That can
+read from a freed skb head after the old head's remaining clone is
+released.
+
+Reload iph6 after the offload helper succeeds and before subsequent
+reads from the inner IPv6 header. Keep the existing reload after
+skb_realloc_headroom(), since that branch can also replace the skb.
+
+Fixes: 14909664e4e1 ("sit: Setup and TX path for sit/UDP foo-over-udp encapsulation")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot+6eb9ca986d80f6f88cf9@syzkaller.appspotmail.com
+Link: https://patch.msgid.link/20260605073448.6524-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/sit.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index eb4c8e2a2b12e0..aa88a41034d920 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -965,6 +965,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ ip_rt_put(rt);
+ goto tx_error;
+ }
++ iph6 = ipv6_hdr(skb);
+
+ if (df) {
+ mtu = dst_mtu(&rt->dst) - t_hlen;
+--
+2.53.0
+
--- /dev/null
+From 3db34b86ca87b3889a5fb1c7560d6d1c293b1740 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 19:18:19 -0700
+Subject: net: guard timestamp cmsgs to real error queue skbs
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit 1ee90b77b727df903033db873c75caac5c27ec98 ]
+
+skb_is_err_queue() treats PACKET_OUTGOING as the sole marker for an skb
+from sk_error_queue. That assumption is not true for AF_PACKET sockets:
+outgoing packet taps are also delivered to packet sockets with
+skb->pkt_type == PACKET_OUTGOING, but their skb->cb is owned by AF_PACKET
+instead of struct sock_exterr_skb.
+
+If such an skb is received with timestamping enabled, the generic
+timestamp cmsg path can read AF_PACKET control-buffer state as
+sock_exterr_skb::opt_stats. With SO_RXQ_OVFL enabled, the packet drop
+counter overlaps opt_stats. An odd drop count makes the path emit
+SCM_TIMESTAMPING_OPT_STATS with skb->len and skb->data. For non-linear
+skbs this copies past the linear head and can trigger hardened usercopy or
+disclose adjacent heap contents.
+
+Keep skb_is_err_queue() local to net/socket.c, but make it verify that
+the PACKET_OUTGOING marker is paired with the sock_rmem_free destructor
+installed by sock_queue_err_skb(). AF_PACKET receive skbs use normal
+receive ownership and no longer pass as error-queue skbs, while legitimate
+sk_error_queue entries keep the PACKET_OUTGOING marker and sock_rmem_free
+ownership.
+
+Fixes: 8605330aac5a ("tcp: fix SCM_TIMESTAMPING_OPT_STATS for normal skbs")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260607021819.49698-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 1 +
+ net/core/skbuff.c | 6 +++---
+ net/socket.c | 11 ++++++-----
+ 3 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index d516ed80500844..a6944844553afe 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1921,6 +1921,7 @@ struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size,
+ gfp_t priority);
+ void skb_orphan_partial(struct sk_buff *skb);
+ void sock_rfree(struct sk_buff *skb);
++void sock_rmem_free(struct sk_buff *skb);
+ void sock_efree(struct sk_buff *skb);
+ #ifdef CONFIG_INET
+ void sock_edemux(struct sk_buff *skb);
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 5f45a52cc8ca66..c5e2ae6d0406bd 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -5120,7 +5120,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
+ }
+ EXPORT_SYMBOL_GPL(skb_cow_data);
+
+-static void sock_rmem_free(struct sk_buff *skb)
++void sock_rmem_free(struct sk_buff *skb)
+ {
+ struct sock *sk = skb->sk;
+
+@@ -5129,8 +5129,8 @@ static void sock_rmem_free(struct sk_buff *skb)
+
+ static void skb_set_err_queue(struct sk_buff *skb)
+ {
+- /* pkt_type of skbs received on local sockets is never PACKET_OUTGOING.
+- * So, it is safe to (mis)use it to mark skbs on the error queue.
++ /* The error-queue test in skb_is_err_queue() matches this marker
++ * with the sock_rmem_free destructor installed by sock_queue_err_skb().
+ */
+ skb->pkt_type = PACKET_OUTGOING;
+ BUILD_BUG_ON(PACKET_OUTGOING == 0);
+diff --git a/net/socket.c b/net/socket.c
+index 94c38c73fc6982..fa242d7e51c791 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -823,12 +823,13 @@ EXPORT_SYMBOL(kernel_sendmsg_locked);
+
+ static bool skb_is_err_queue(const struct sk_buff *skb)
+ {
+- /* pkt_type of skbs enqueued on the error queue are set to
+- * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
+- * in recvmsg, since skbs received on a local socket will never
+- * have a pkt_type of PACKET_OUTGOING.
++ /* Error-queue skbs are marked as PACKET_OUTGOING in
++ * skb_set_err_queue() and use the destructor installed by
++ * sock_queue_err_skb(). PACKET_OUTGOING alone is not unique:
++ * AF_PACKET outgoing taps use the same pkt_type.
+ */
+- return skb->pkt_type == PACKET_OUTGOING;
++ return skb->pkt_type == PACKET_OUTGOING &&
++ skb->destructor == sock_rmem_free;
+ }
+
+ /* On transmit, software and hardware timestamps are returned independently.
+--
+2.53.0
+
--- /dev/null
+From 362b11f0bc6fc2178fc615d8b3efc6d9346a2912 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 14:10:44 +0800
+Subject: net/mlx4: avoid GCC 10 __bad_copy_from() false positive
+
+From: Yao Sang <sangyao@kylinos.cn>
+
+[ Upstream commit 2365343f4aad3e1b1e7a2e87e98cf66d5e590589 ]
+
+mlx4_init_user_cqes() fills a scratch buffer with the CQE
+initialization pattern and then copies from that buffer to userspace.
+
+In the single-copy path, the copy length is array_size(entries,
+cqe_size), but the scratch buffer is allocated with PAGE_SIZE. GCC 10
+does not carry the branch invariant strongly enough through the object
+size checks and falsely triggers __bad_copy_from().
+
+Size the scratch buffer to the actual copy length for the active path,
+keep array_size() for the single-copy case, and retain a WARN_ON_ONCE()
+guard for the PAGE_SIZE invariant before allocating the buffer.
+
+Fixes: f69bf5dee7ef ("net/mlx4: Use array_size() helper in copy_to_user()")
+Signed-off-by: Yao Sang <sangyao@kylinos.cn>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx4/cq.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c
+index 4d4f9cf9facb87..fb83d8af8dcb9c 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
++++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
+@@ -290,6 +290,7 @@ static void mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
+ static int mlx4_init_user_cqes(void *buf, int entries, int cqe_size)
+ {
+ int entries_per_copy = PAGE_SIZE / cqe_size;
++ size_t copy_bytes;
+ void *init_ents;
+ int err = 0;
+ int i;
+@@ -314,8 +315,14 @@ static int mlx4_init_user_cqes(void *buf, int entries, int cqe_size)
+ buf += PAGE_SIZE;
+ }
+ } else {
++ copy_bytes = array_size(entries, cqe_size);
++ if (WARN_ON_ONCE(copy_bytes > PAGE_SIZE)) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ err = copy_to_user((void __user *)buf, init_ents,
+- array_size(entries, cqe_size)) ?
++ copy_bytes) ?
+ -EFAULT : 0;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From a6bdf5057817a40c67566ddeab1c313586f05f9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 16:58:49 +0300
+Subject: net/mlx5: Fix slab-out-of-bounds in mlx5_query_nic_vport_mac_list
+
+From: Dragos Tatulea <dtatulea@nvidia.com>
+
+[ Upstream commit 894e036a24a26a6dd7b17d8d3fb5c53ab48a6074 ]
+
+mlx5_query_nic_vport_mac_list() sizes its firmware command buffer using
+the PF's log_max_current_uc/mc_list capabilities. When querying a VF
+vport with a larger configured max (via devlink), the firmware response
+can overflow this buffer:
+
+ BUG: KASAN: slab-out-of-bounds in mlx5_query_nic_vport_mac_list+0x453/0x4c0 [mlx5_core]
+ Read of size 4 at addr ff1100013ffc8a12 by task kworker/u96:2/385
+
+ CPU: 12 UID: 0 PID: 385 Comm: kworker/u96:2 Not tainted 7.0.0-rc6+ #1 PREEMPT
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009)
+ Workqueue: mlx5_esw_wq esw_vport_change_handler [mlx5_core]
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x69/0xa0
+ print_report+0x176/0x4e4
+ kasan_report+0xc8/0x100
+ mlx5_query_nic_vport_mac_list+0x453/0x4c0 [mlx5_core]
+ esw_update_vport_addr_list+0x2e3/0xda0 [mlx5_core]
+ esw_vport_change_handle_locked+0xa1f/0x1060 [mlx5_core]
+ esw_vport_change_handler+0x6a/0x90 [mlx5_core]
+ process_one_work+0x87f/0x15e0
+ worker_thread+0x62b/0x1020
+ kthread+0x375/0x490
+ ret_from_fork+0x4dc/0x810
+ ret_from_fork_asm+0x11/0x20
+ </TASK>
+
+Fix by querying the vport's own HCA caps to size the buffer correctly.
+Refactor the function to allocate and return the MAC list internally,
+removing the caller's dependency on knowing the correct max.
+
+Fixes: e16aea2744ab ("net/mlx5: Introduce access functions to modify/query vport mac lists")
+Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
+Reviewed-by: Carolina Jubran <cjubran@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20260604135849.458060-1-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/eswitch.c | 13 +---
+ .../net/ethernet/mellanox/mlx5/core/vport.c | 72 ++++++++++++++-----
+ include/linux/mlx5/vport.h | 4 +-
+ 3 files changed, 59 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+index 2559237da49c52..3593e2770baf7e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+@@ -533,23 +533,16 @@ static void esw_update_vport_addr_list(struct mlx5_eswitch *esw,
+ struct mlx5_vport *vport, int list_type)
+ {
+ bool is_uc = list_type == MLX5_NVPRT_LIST_TYPE_UC;
+- u8 (*mac_list)[ETH_ALEN];
++ u8 (*mac_list)[ETH_ALEN] = NULL;
+ struct l2addr_node *node;
+ struct vport_addr *addr;
+ struct hlist_head *hash;
+ struct hlist_node *tmp;
+- int size;
++ int size = 0;
+ int err;
+ int hi;
+ int i;
+
+- size = is_uc ? MLX5_MAX_UC_PER_VPORT(esw->dev) :
+- MLX5_MAX_MC_PER_VPORT(esw->dev);
+-
+- mac_list = kcalloc(size, ETH_ALEN, GFP_KERNEL);
+- if (!mac_list)
+- return;
+-
+ hash = is_uc ? vport->uc_list : vport->mc_list;
+
+ for_each_l2hash_node(node, tmp, hash, hi) {
+@@ -561,7 +554,7 @@ static void esw_update_vport_addr_list(struct mlx5_eswitch *esw,
+ goto out;
+
+ err = mlx5_query_nic_vport_mac_list(esw->dev, vport->vport, list_type,
+- mac_list, &size);
++ &mac_list, &size);
+ if (err)
+ goto out;
+ esw_debug(esw->dev, "vport[%d] context update %s list size (%d)\n",
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+index 06b5265b6e6db2..23a22caa955f31 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+@@ -250,35 +250,63 @@ int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu)
+ }
+ EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mtu);
+
++static int mlx5_vport_max_mac_list_size(struct mlx5_core_dev *dev, u16 vport,
++ enum mlx5_list_type list_type)
++{
++ void *query_ctx, *hca_caps;
++ int ret = 0;
++
++ if (!vport && !mlx5_core_is_ecpf(dev))
++ return list_type == MLX5_NVPRT_LIST_TYPE_UC ?
++ 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
++ 1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
++
++ query_ctx = kzalloc(MLX5_ST_SZ_BYTES(query_hca_cap_out), GFP_KERNEL);
++ if (!query_ctx)
++ return -ENOMEM;
++
++ ret = mlx5_vport_get_other_func_general_cap(dev, vport, query_ctx);
++ if (ret)
++ goto out;
++
++ hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
++ ret = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
++ 1 << MLX5_GET(cmd_hca_cap, hca_caps, log_max_current_uc_list) :
++ 1 << MLX5_GET(cmd_hca_cap, hca_caps, log_max_current_mc_list);
++
++out:
++ kfree(query_ctx);
++
++ return ret;
++}
++
+ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+ u16 vport,
+ enum mlx5_list_type list_type,
+- u8 addr_list[][ETH_ALEN],
+- int *list_size)
++ u8 (**addr_list)[ETH_ALEN],
++ int *addr_list_size)
+ {
+ u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
++ int allowed_list_size;
+ void *nic_vport_ctx;
+ int max_list_size;
+- int req_list_size;
+ int out_sz;
+ void *out;
+ int err;
+ int i;
+
+- req_list_size = *list_size;
++ if (!addr_list || !addr_list_size)
++ return -EINVAL;
+
+- max_list_size = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
+- 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
+- 1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
++ *addr_list = NULL;
++ *addr_list_size = 0;
+
+- if (req_list_size > max_list_size) {
+- mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
+- req_list_size, max_list_size);
+- req_list_size = max_list_size;
+- }
++ max_list_size = mlx5_vport_max_mac_list_size(dev, vport, list_type);
++ if (max_list_size < 0)
++ return max_list_size;
+
+ out_sz = MLX5_ST_SZ_BYTES(query_nic_vport_context_out) +
+- req_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
++ max_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
+
+ out = kvzalloc(out_sz, GFP_KERNEL);
+ if (!out)
+@@ -297,16 +325,24 @@ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+
+ nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
+ nic_vport_context);
+- req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
+- allowed_list_size);
++ allowed_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
++ allowed_list_size);
++ if (!allowed_list_size)
++ goto out;
++
++ *addr_list = kcalloc(allowed_list_size, ETH_ALEN, GFP_KERNEL);
++ if (!*addr_list) {
++ err = -ENOMEM;
++ goto out;
++ }
+
+- *list_size = req_list_size;
+- for (i = 0; i < req_list_size; i++) {
++ for (i = 0; i < allowed_list_size; i++) {
+ u8 *mac_addr = MLX5_ADDR_OF(nic_vport_context,
+ nic_vport_ctx,
+ current_uc_mac_address[i]) + 2;
+- ether_addr_copy(addr_list[i], mac_addr);
++ ether_addr_copy((*addr_list)[i], mac_addr);
+ }
++ *addr_list_size = allowed_list_size;
+ out:
+ kvfree(out);
+ return err;
+diff --git a/include/linux/mlx5/vport.h b/include/linux/mlx5/vport.h
+index fbb9bf4478894c..598e58cceeec50 100644
+--- a/include/linux/mlx5/vport.h
++++ b/include/linux/mlx5/vport.h
+@@ -94,8 +94,8 @@ int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *dev,
+ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+ u16 vport,
+ enum mlx5_list_type list_type,
+- u8 addr_list[][ETH_ALEN],
+- int *list_size);
++ u8 (**mac_list)[ETH_ALEN],
++ int *mac_list_size);
+ int mlx5_modify_nic_vport_mac_list(struct mlx5_core_dev *dev,
+ enum mlx5_list_type list_type,
+ u8 addr_list[][ETH_ALEN],
+--
+2.53.0
+
--- /dev/null
+From 43329ae1211443c1cbc9e396600f430e13915928 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 12:46:06 +0100
+Subject: net: mvpp2: Add metadata support for xdp mode
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 9a45e193c88a55a536d7fd0ebfa29823d588c2cf ]
+
+Set metadata size building the skb from xdp_buff in mvpp2 driver
+mvpp2 driver sets xdp headroom to:
+
+MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM
+
+where
+
+MVPP2_MH_SIZE 2
+MVPP2_SKB_HEADROOM min(max(XDP_PACKET_HEADROOM, NET_SKB_PAD), 224)
+
+so the headroom is large enough to contain xdp_frame and xdp metadata.
+Please note this patch is just compiled tested.
+
+Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://patch.msgid.link/20250318-mvneta-xdp-meta-v2-2-b6075778f61f@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 77a6b90ce56b ("net: mvpp2: build skb from XDP-adjusted data on XDP_PASS")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 9221ee209a309b..812c80d45859d5 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3915,13 +3915,13 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ while (rx_done < rx_todo) {
+ struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq);
++ u32 rx_status, timestamp, metasize = 0;
+ struct mvpp2_bm_pool *bm_pool;
+ struct page_pool *pp = NULL;
+ struct sk_buff *skb;
+ unsigned int frag_size;
+ dma_addr_t dma_addr;
+ phys_addr_t phys_addr;
+- u32 rx_status, timestamp;
+ int pool, rx_bytes, err, ret;
+ struct page *page;
+ void *data;
+@@ -3984,7 +3984,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ xdp_init_buff(&xdp, bm_pool->frag_size, xdp_rxq);
+ xdp_prepare_buff(&xdp, data,
+ MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM,
+- rx_bytes, false);
++ rx_bytes, true);
+
+ ret = mvpp2_run_xdp(port, xdp_prog, &xdp, pp, &ps);
+
+@@ -4000,6 +4000,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ ps.rx_bytes += rx_bytes;
+ continue;
+ }
++
++ metasize = xdp.data - xdp.data_meta;
+ }
+
+ if (frag_size)
+@@ -4039,6 +4041,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);
+ skb_put(skb, rx_bytes);
++ if (metasize)
++ skb_metadata_set(skb, metasize);
+ skb->ip_summed = mvpp2_rx_csum(port, rx_status);
+ skb->protocol = eth_type_trans(skb, dev);
+
+--
+2.53.0
+
--- /dev/null
+From 555ef7a681c8725bf16b0f333deb841c2a12c041 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:43 +0200
+Subject: net: mvpp2: build skb from XDP-adjusted data on XDP_PASS
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 77a6b90ce56bc982dcfa94229b8e28e6abb16e95 ]
+
+When an XDP program uses bpf_xdp_adjust_head() or bpf_xdp_adjust_tail()
+and then returns XDP_PASS, mvpp2 still builds the skb from fixed offsets
+derived from the original RX descriptor. Packet geometry changes made by
+the XDP program are therefore discarded before the skb reaches the stack.
+
+Update rx_offset and rx_bytes from xdp.data and xdp.data_end for
+XDP_PASS. This makes skb_reserve() and skb_put() reflect the packet seen
+by XDP, and makes RX byte accounting for XDP_PASS follow the length of the
+skb passed to the network stack.
+
+Keep a separate rx_sync_size for page-pool recycling on skb allocation
+failure, which must stay tied to the received buffer range.
+
+Non-PASS verdicts continue to account the descriptor length because no skb
+is passed up in those cases.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-5-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 21 +++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 5bdc26bebe4488..ab608cd497a936 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3919,10 +3919,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ struct mvpp2_bm_pool *bm_pool;
+ struct page_pool *pp = NULL;
+ struct sk_buff *skb;
+- unsigned int frag_size;
++ unsigned int frag_size, rx_sync_size;
+ dma_addr_t dma_addr;
+ phys_addr_t phys_addr;
+- int pool, rx_bytes, err, ret;
++ int pool, rx_bytes, rx_offset, err, ret;
+ struct page *page;
+ void *data;
+
+@@ -3935,6 +3935,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ rx_status = mvpp2_rxdesc_status_get(port, rx_desc);
+ rx_bytes = mvpp2_rxdesc_size_get(port, rx_desc);
+ rx_bytes -= MVPP2_MH_SIZE;
++ rx_sync_size = rx_bytes + MVPP2_MH_SIZE;
++ rx_offset = MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM;
+ dma_addr = mvpp2_rxdesc_dma_addr_get(port, rx_desc);
+
+ pool = (rx_status & MVPP2_RXD_BM_POOL_ID_MASK) >>
+@@ -3950,7 +3952,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
+ MVPP2_SKB_HEADROOM,
+- rx_bytes + MVPP2_MH_SIZE,
++ rx_sync_size,
+ dma_dir);
+
+ /* Buffer header not supported */
+@@ -4001,6 +4003,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ continue;
+ }
+
++ rx_sync_size = max_t(unsigned int, rx_sync_size,
++ xdp.data_end - xdp.data_hard_start -
++ MVPP2_SKB_HEADROOM);
++
++ /* Update offset and length to reflect any XDP adjustments. */
++ rx_offset = xdp.data - data;
++ rx_bytes = xdp.data_end - xdp.data;
++
+ metasize = xdp.data - xdp.data_meta;
+ }
+
+@@ -4012,8 +4022,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ netdev_warn(port->dev, "skb build failed\n");
+ if (pp) {
+ page_pool_put_page(pp, virt_to_head_page(data),
+- rx_bytes + MVPP2_MH_SIZE,
+- true);
++ rx_sync_size, true);
+ } else {
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size,
+@@ -4043,7 +4052,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
+
+- skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);
++ skb_reserve(skb, rx_offset);
+ skb_put(skb, rx_bytes);
+ if (metasize)
+ skb_metadata_set(skb, metasize);
+--
+2.53.0
+
--- /dev/null
+From 5322e56f0c0faa53504aa0d0b37b1c6a72459be3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:41 +0200
+Subject: net: mvpp2: limit XDP frame size to the RX buffer
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit f3c6aa078927e6fe8121c9c591ddee8716c5305a ]
+
+mvpp2 has short and long BM pools, and short pool buffers can be smaller
+than PAGE_SIZE. The XDP path nevertheless initializes every xdp_buff with
+PAGE_SIZE as frame size.
+
+XDP helpers use frame_sz to validate tail growth and to derive the hard
+end of the data area. Advertising PAGE_SIZE for short buffers can let
+bpf_xdp_adjust_tail() grow a packet past the real allocation, corrupting
+memory or later tripping skb tailroom checks.
+
+Initialize the XDP buffer with bm_pool->frag_size so XDP tailroom matches
+the actual buffer backing the packet.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-3-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index af10654f655674..9221ee209a309b 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3981,7 +3981,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ else
+ xdp_rxq = &rxq->xdp_rxq_long;
+
+- xdp_init_buff(&xdp, PAGE_SIZE, xdp_rxq);
++ xdp_init_buff(&xdp, bm_pool->frag_size, xdp_rxq);
+ xdp_prepare_buff(&xdp, data,
+ MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM,
+ rx_bytes, false);
+--
+2.53.0
+
--- /dev/null
+From fc4599dde5a49623e6d885950a04649a48947682 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:42 +0200
+Subject: net: mvpp2: refill RX buffers before XDP or skb use
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 5e8e2a9624df72fca7c736b2966b2cbf6c9c3ff6 ]
+
+The RX error path returns the current descriptor buffer to the hardware
+BM pool. That is only valid while the driver still owns the buffer.
+
+mvpp2_rx_refill() can fail after the current buffer has been handed to
+XDP or attached to an skb. In those cases mvpp2_run_xdp() may have
+recycled, redirected, or queued the page for XDP_TX, and an skb free also
+retires the data buffer. Returning such a buffer to BM lets hardware DMA
+into memory that is no longer owned by the RX ring.
+
+Refill the BM pool before handing the current buffer to XDP or to the
+skb. If the allocation fails there, drop the packet and return the
+still-owned current buffer to BM, preserving the pool depth. Once the
+refill succeeds, later local drops retire/free the current buffer instead
+of returning it to BM.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Fixes: d6526926de73 ("net: mvpp2: fix memory leak in mvpp2_rx")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-4-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 77a6b90ce56b ("net: mvpp2: build skb from XDP-adjusted data on XDP_PASS")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 43 +++++++++++--------
+ 1 file changed, 24 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 812c80d45859d5..5bdc26bebe4488 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3973,6 +3973,12 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ else
+ frag_size = bm_pool->frag_size;
+
++ err = mvpp2_rx_refill(port, bm_pool, pp, pool);
++ if (err) {
++ netdev_err(port->dev, "failed to refill BM pools\n");
++ goto err_drop_frame;
++ }
++
+ if (xdp_prog) {
+ struct xdp_rxq_info *xdp_rxq;
+
+@@ -3990,12 +3996,6 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ if (ret) {
+ xdp_ret |= ret;
+- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+- if (err) {
+- netdev_err(port->dev, "failed to refill BM pools\n");
+- goto err_drop_frame;
+- }
+-
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
+ continue;
+@@ -4010,8 +4010,21 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ skb = slab_build_skb(data);
+ if (!skb) {
+ netdev_warn(port->dev, "skb build failed\n");
+- goto err_drop_frame;
++ if (pp) {
++ page_pool_put_page(pp, virt_to_head_page(data),
++ rx_bytes + MVPP2_MH_SIZE,
++ true);
++ } else {
++ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
++ bm_pool->buf_size,
++ DMA_FROM_DEVICE,
++ DMA_ATTR_SKIP_CPU_SYNC);
++ mvpp2_frag_free(bm_pool, pp, data);
++ }
++ goto err_drop_frame_retired;
+ }
++ if (pp)
++ skb_mark_for_recycle(skb);
+
+ /* If we have RX hardware timestamping enabled, grab the
+ * timestamp from the queue and convert.
+@@ -4022,16 +4035,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ skb_hwtstamps(skb));
+ }
+
+- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+- if (err) {
+- netdev_err(port->dev, "failed to refill BM pools\n");
+- dev_kfree_skb_any(skb);
+- goto err_drop_frame;
+- }
+-
+- if (pp)
+- skb_mark_for_recycle(skb);
+- else
++ if (!pp)
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size, DMA_FROM_DEVICE,
+ DMA_ATTR_SKIP_CPU_SYNC);
+@@ -4050,13 +4054,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ continue;
+
+ err_drop_frame:
+- dev->stats.rx_errors++;
+- mvpp2_rx_error(port, rx_desc);
+ /* Return the buffer to the pool */
+ if (rx_status & MVPP2_RXD_BUF_HDR)
+ mvpp2_buff_hdr_pool_put(port, rx_desc, pool, rx_status);
+ else
+ mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);
++err_drop_frame_retired:
++ dev->stats.rx_errors++;
++ mvpp2_rx_error(port, rx_desc);
+ }
+
+ if (xdp_ret & MVPP2_XDP_REDIR)
+--
+2.53.0
+
--- /dev/null
+From cc59f1b01d6f164d5f317d31f0829316520171c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:40 +0200
+Subject: net: mvpp2: sync RX data at the hardware packet offset
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 180235600934bef6add3be637c296d6cf3272e67 ]
+
+mvpp2 programs the RX queue packet offset, so hardware writes received
+data at dma_addr + MVPP2_SKB_HEADROOM. The current CPU sync starts at
+dma_addr and only covers rx_bytes + MVPP2_MH_SIZE bytes, which syncs the
+unused headroom and misses the same number of bytes at the packet tail.
+
+On non-coherent DMA systems this can leave the CPU reading stale cache
+contents for the end of the received frame.
+
+Use dma_sync_single_range_for_cpu() with MVPP2_SKB_HEADROOM as the range
+offset so the sync covers the Marvell header and packet data actually
+written by hardware.
+
+Fixes: e1921168bbd4 ("mvpp2: sync only the received frame")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-2-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 410c9dea4fa2ef..af10654f655674 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3948,9 +3948,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ dma_dir = DMA_FROM_DEVICE;
+ }
+
+- dma_sync_single_for_cpu(dev->dev.parent, dma_addr,
+- rx_bytes + MVPP2_MH_SIZE,
+- dma_dir);
++ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
++ MVPP2_SKB_HEADROOM,
++ rx_bytes + MVPP2_MH_SIZE,
++ dma_dir);
+
+ /* Buffer header not supported */
+ if (rx_status & MVPP2_RXD_BUF_HDR)
+--
+2.53.0
+
--- /dev/null
+From 45691aaabdbc2b84541655b5fcd48dc3591ec765 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:19:46 +0200
+Subject: net: openvswitch: fix possible kfree_skb of ERR_PTR
+
+From: Adrian Moreno <amorenoz@redhat.com>
+
+[ Upstream commit ee30dd2909d8b98619f4341c70ec8dc8e155ab02 ]
+
+After the patch in the "Fixes" tag, the allocation of the "reply" skb
+can happen either before or after locking the ovs_mutex.
+
+However, error cleanups still follow the classical reversed order,
+assuming "reply" is allocated before locking: it is freed after unlocking.
+
+If "reply" allocation happens after locking the mutex and it fails,
+"reply" is left with an ERR_PTR, and execution jumps to the correspondent
+cleanup stage which will try to free an invalid pointer.
+
+Fix this by setting the pointer to NULL after having saved its error
+value.
+
+Fixes: 893f139b9a6c ("openvswitch: Minimize ovs_flow_cmd_new|set critical sections.")
+Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Acked-by: Eelco Chaudron <echaudro@redhat.com>
+Link: https://patch.msgid.link/20260604121946.942164-1-amorenoz@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/datapath.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 7803e7548d9203..857edc53739332 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -1287,6 +1287,7 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
+
+ if (IS_ERR(reply)) {
+ error = PTR_ERR(reply);
++ reply = NULL;
+ goto err_unlock_ovs;
+ }
+ }
+--
+2.53.0
+
--- /dev/null
+From 16dc2809eae6663bdd0fe7c026088e4108e239a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 11:28:15 +0200
+Subject: net: phy: clean the sfp upstream if phy probing fails
+
+From: Maxime Chevallier <maxime.chevallier@bootlin.com>
+
+[ Upstream commit 48774e87bbaa0056819d4b52301e4692e50e3252 ]
+
+Sashiko reported that we don't call sfp_bus_del_upstream() in the probe
+failure path, so let's add it, otherwise the sfp-bus is left with a
+dangling 'upstream' field, that may be used later on during SFP events.
+
+This issue existed before the generic phylib sfp support, back when
+drivers were calling phy_sfp_probe themselves.
+
+Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
+Fixes: 298e54fa810e ("net: phy: add core phylib sfp support")
+Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260604092819.723505-2-maxime.chevallier@bootlin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/phy_device.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 1d073947dd4c26..c8aa322f59918c 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -1432,6 +1432,9 @@ int phy_sfp_probe(struct phy_device *phydev,
+
+ ret = sfp_bus_add_upstream(bus, phydev, ops);
+ sfp_bus_put(bus);
++
++ if (ret)
++ phydev->sfp_bus = NULL;
+ }
+ return ret;
+ }
+@@ -3414,6 +3417,9 @@ static int phy_probe(struct device *dev)
+ return 0;
+
+ out:
++ sfp_bus_del_upstream(phydev->sfp_bus);
++ phydev->sfp_bus = NULL;
++
+ if (!phydev->is_on_sfp_module)
+ phy_led_triggers_unregister(phydev);
+
+--
+2.53.0
+
--- /dev/null
+From 40d14bd58923c11ecc30879ad706446598024c6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:48:01 +0800
+Subject: net: qrtr: fix refcount saturation and potential UAF in
+ qrtr_port_remove
+
+From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+
+[ Upstream commit a2171131ecda1ed61a594a1eb715e75fdad0fef5 ]
+
+In qrtr_port_remove(), the socket reference count is decremented via
+__sock_put() before the port is removed from the qrtr_ports XArray and
+before the RCU grace period elapses.
+
+This breaks the fundamental RCU update paradigm. It exposes a race
+window where a concurrent RCU reader (such as qrtr_reset_ports() or
+qrtr_port_lookup()) can obtain a pointer to the socket from the XArray,
+and attempt to call sock_hold() on a socket whose reference count has
+already dropped to zero.
+
+This exact race condition was hit during syzkaller fuzzing, leading to
+the following refcount saturation warning and a potential Use-After-Free:
+
+ refcount_t: saturated; leaking memory.
+ WARNING: CPU: 3 PID: 1273 at lib/refcount.c:22 refcount_warn_saturate+0xae/0x1d0
+ Modules linked in: qrtr(+) bochs drm_shmem_helper ...
+ Call Trace:
+ <TASK>
+ qrtr_reset_ports net/qrtr/af_qrtr.c:768 [inline] [qrtr]
+ __qrtr_bind.isra.0+0x48b/0x570 net/qrtr/af_qrtr.c:805 [qrtr]
+ qrtr_bind+0x17d/0x210 net/qrtr/af_qrtr.c:901 [qrtr]
+ kernel_bind+0xe4/0x120 net/socket.c:3592
+ qrtr_ns_init+0x1a6/0x380 net/qrtr/ns.c:715 [qrtr]
+ qrtr_proto_init+0x3b/0xff0 net/qrtr/af_qrtr.c:169 [qrtr]
+ do_one_initcall+0xf5/0x5e0 init/main.c:1283
+ ...
+ </TASK>
+
+Fix this by deferring the reference count decrement until after the
+xa_erase() and the synchronize_rcu() complete.
+
+(Note: The v1 of this patch incorrectly replaced __sock_put() with
+sock_put(). As Simon Horman pointed out, the callers of qrtr_port_remove()
+still hold a reference to the socket, so freeing the socket memory here
+would lead to a subsequent UAF in the caller. Thus, the __sock_put() is
+kept, but only repositioned to close the RCU race.)
+
+Fixes: bdabad3e363d ("net: Add Qualcomm IPC router")
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260604064801.1180388-1-w15303746062@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/af_qrtr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c
+index b703e4c6458532..2c009793f1931d 100644
+--- a/net/qrtr/af_qrtr.c
++++ b/net/qrtr/af_qrtr.c
+@@ -707,13 +707,13 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
+ if (port == QRTR_PORT_CTRL)
+ port = 0;
+
+- __sock_put(&ipc->sk);
+-
+ xa_erase(&qrtr_ports, port);
+
+ /* Ensure that if qrtr_port_lookup() did enter the RCU read section we
+ * wait for it to up increment the refcount */
+ synchronize_rcu();
++
++ __sock_put(&ipc->sk);
+ }
+
+ /* Assign port number to socket.
+--
+2.53.0
+
--- /dev/null
+From 16c2e1b90f0c17ca8b8c22d73343929d57f508e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 12:24:48 -0700
+Subject: net/rds: fix NULL deref in rds_ib_send_cqe_handler() on masked atomic
+ completion
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 34080db3e70ddf94c38512ad2331e3c3afca6cc1 ]
+
+rds_ib_xmit_atomic() always programs a masked atomic opcode
+(IB_WR_MASKED_ATOMIC_CMP_AND_SWP or IB_WR_MASKED_ATOMIC_FETCH_AND_ADD)
+for every RDS atomic cmsg. But the completion-side switch in
+rds_ib_send_unmap_op() only handles the non-masked opcodes, so a masked
+atomic completion falls through to default and returns rm == NULL while
+send->s_op is left set. rds_ib_send_cqe_handler() then dereferences the
+NULL rm via rm->m_final_op, oopsing in softirq context. An unprivileged
+AF_RDS sendmsg() of an atomic cmsg over an active RDS/IB connection
+triggers it; on hardware that natively accepts masked atomics (mlx4,
+mlx5) no extra setup is needed.
+
+ RDS/IB: rds_ib_send_unmap_op: unexpected opcode 0xd in WR!
+ Oops: general protection fault [#1] SMP KASAN
+ KASAN: null-ptr-deref in range [0x0000000000000190-0x0000000000000197]
+ RIP: rds_ib_send_cqe_handler+0x25c/0xb10 (net/rds/ib_send.c:282)
+ Call Trace:
+ <IRQ>
+ rds_ib_send_cqe_handler (net/rds/ib_send.c:282)
+ poll_scq (net/rds/ib_cm.c:274)
+ rds_ib_tasklet_fn_send (net/rds/ib_cm.c:294)
+ tasklet_action_common (kernel/softirq.c:943)
+ handle_softirqs (kernel/softirq.c:573)
+ run_ksoftirqd (kernel/softirq.c:479)
+ </IRQ>
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Handle the masked atomic opcodes in the same case as the non-masked
+ones: they map to the same struct rds_message.atomic union member, so
+the existing container_of()/rds_ib_send_unmap_atomic() body is correct
+for them.
+
+Fixes: 20c72bd5f5f9 ("RDS: Implement masked atomic operations")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260606192447.1179255-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/ib_send.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
+index 4190b90ff3b18a..1909cd440a4b66 100644
+--- a/net/rds/ib_send.c
++++ b/net/rds/ib_send.c
+@@ -170,6 +170,8 @@ static struct rds_message *rds_ib_send_unmap_op(struct rds_ib_connection *ic,
+ break;
+ case IB_WR_ATOMIC_FETCH_AND_ADD:
+ case IB_WR_ATOMIC_CMP_AND_SWP:
++ case IB_WR_MASKED_ATOMIC_FETCH_AND_ADD:
++ case IB_WR_MASKED_ATOMIC_CMP_AND_SWP:
+ if (send->s_op) {
+ rm = container_of(send->s_op, struct rds_message, atomic);
+ rds_ib_send_unmap_atomic(ic, send->s_op, wc_status);
+--
+2.53.0
+
--- /dev/null
+From 6cefa86add604fbcaea0114bc7ab7a37b4b24a06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 00:38:17 -0700
+Subject: netfilter: nf_conntrack: destroy stale expectfn expectations on
+ unregister
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit c3009418f9fa1dcb3eb86f4d8c92583537b5faa3 ]
+
+NAT helpers such as nf_nat_h323 store a raw pointer to module text in
+exp->expectfn (e.g. ip_nat_q931_expect). nf_ct_helper_expectfn_unregister()
+only unlinks the callback descriptor and never walks the expectation table,
+so an expectation pending at module removal survives with a dangling
+exp->expectfn into freed module text.
+
+When the expected connection arrives, init_conntrack() invokes
+exp->expectfn(), now a stale pointer into the unloaded module. Reproduced
+on a KASAN build by loading the H.323 helpers, creating a Q.931
+expectation, unloading nf_nat_h323, then connecting to the expected port:
+
+ Oops: int3: 0000 [#1] SMP KASAN NOPTI
+ RIP: 0010:0xffffffffa06102d1
+ init_conntrack.isra.0 (net/netfilter/nf_conntrack_core.c:1862)
+ nf_conntrack_in (net/netfilter/nf_conntrack_core.c:2049)
+ ipv4_conntrack_local (net/netfilter/nf_conntrack_proto.c:223)
+ nf_hook_slow (net/netfilter/core.c:619)
+ __ip_local_out (net/ipv4/ip_output.c:120)
+ __tcp_transmit_skb (net/ipv4/tcp_output.c:1715)
+ tcp_connect (net/ipv4/tcp_output.c:4374)
+ tcp_v4_connect (net/ipv4/tcp_ipv4.c:345)
+ __sys_connect (net/socket.c:2167)
+ Modules linked in: nf_conntrack_h323 [last unloaded: nf_nat_h323]
+
+Reaching the dangling state requires CAP_SYS_MODULE in the initial user
+namespace to remove a NAT helper that still has live expectations, so this
+is a robustness fix; leaving an expectation pointing at freed text is wrong
+regardless.
+
+Add nf_ct_helper_expectfn_destroy(), which walks the expectation table and
+drops every expectation whose ->expectfn matches the descriptor being torn
+down. Call it from each NAT helper's exit path after the existing RCU grace
+period, so no expectation outlives the code it points at and no extra
+synchronize_rcu() is introduced. With the fix, the same reproducer runs to
+completion without the Oops.
+
+Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netfilter/nf_conntrack_helper.h | 1 +
+ net/ipv4/netfilter/nf_nat_h323.c | 2 ++
+ net/netfilter/nf_conntrack_helper.c | 19 +++++++++++++++++++
+ net/netfilter/nf_nat_core.c | 2 ++
+ net/netfilter/nf_nat_sip.c | 1 +
+ 5 files changed, 25 insertions(+)
+
+diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
+index de2f956abf3480..24cf3d2d97450f 100644
+--- a/include/net/netfilter/nf_conntrack_helper.h
++++ b/include/net/netfilter/nf_conntrack_helper.h
+@@ -155,6 +155,7 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
+
+ void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n);
+ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n);
++void nf_ct_helper_expectfn_destroy(const struct nf_ct_helper_expectfn *n);
+ struct nf_ct_helper_expectfn *
+ nf_ct_helper_expectfn_find_by_name(const char *name);
+ struct nf_ct_helper_expectfn *
+diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
+index faee20af485613..10e1b0837731b7 100644
+--- a/net/ipv4/netfilter/nf_nat_h323.c
++++ b/net/ipv4/netfilter/nf_nat_h323.c
+@@ -555,6 +555,8 @@ static void __exit nf_nat_h323_fini(void)
+ nf_ct_helper_expectfn_unregister(&q931_nat);
+ nf_ct_helper_expectfn_unregister(&callforwarding_nat);
+ synchronize_rcu();
++ nf_ct_helper_expectfn_destroy(&q931_nat);
++ nf_ct_helper_expectfn_destroy(&callforwarding_nat);
+ }
+
+ /****************************************************************************/
+diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
+index 7d5e4f67f268c6..1d449e825dc63e 100644
+--- a/net/netfilter/nf_conntrack_helper.c
++++ b/net/netfilter/nf_conntrack_helper.c
+@@ -288,6 +288,25 @@ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n)
+ }
+ EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_unregister);
+
++static bool expect_iter_expectfn(struct nf_conntrack_expect *exp, void *data)
++{
++ const struct nf_ct_helper_expectfn *n = data;
++
++ /* Relies on registered expectfn descriptors having unique ->expectfn
++ * pointers, which holds for the in-tree NAT helpers.
++ */
++ return exp->expectfn == n->expectfn;
++}
++
++/* Destroy expectations still pointing at @n->expectfn; call after the
++ * caller's RCU grace period so none outlives the (often modular) callback.
++ */
++void nf_ct_helper_expectfn_destroy(const struct nf_ct_helper_expectfn *n)
++{
++ nf_ct_expect_iterate_destroy(expect_iter_expectfn, (void *)n);
++}
++EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_destroy);
++
+ /* Caller should hold the rcu lock */
+ struct nf_ct_helper_expectfn *
+ nf_ct_helper_expectfn_find_by_name(const char *name)
+diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
+index 9df883d79acc92..2500e409757d0d 100644
+--- a/net/netfilter/nf_nat_core.c
++++ b/net/netfilter/nf_nat_core.c
+@@ -1363,6 +1363,7 @@ static int __init nf_nat_init(void)
+ RCU_INIT_POINTER(nf_nat_hook, NULL);
+ nf_ct_helper_expectfn_unregister(&follow_master_nat);
+ synchronize_net();
++ nf_ct_helper_expectfn_destroy(&follow_master_nat);
+ unregister_pernet_subsys(&nat_net_ops);
+ kvfree(nf_nat_bysource);
+ }
+@@ -1380,6 +1381,7 @@ static void __exit nf_nat_cleanup(void)
+ RCU_INIT_POINTER(nf_nat_hook, NULL);
+
+ synchronize_net();
++ nf_ct_helper_expectfn_destroy(&follow_master_nat);
+ kvfree(nf_nat_bysource);
+ unregister_pernet_subsys(&nat_net_ops);
+ }
+diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c
+index 9fbfc6bff0c221..00838c0cc5bb28 100644
+--- a/net/netfilter/nf_nat_sip.c
++++ b/net/netfilter/nf_nat_sip.c
+@@ -655,6 +655,7 @@ static void __exit nf_nat_sip_fini(void)
+ RCU_INIT_POINTER(nf_nat_sip_hooks, NULL);
+ nf_ct_helper_expectfn_unregister(&sip_nat);
+ synchronize_rcu();
++ nf_ct_helper_expectfn_destroy(&sip_nat);
+ }
+
+ static const struct nf_nat_sip_hooks sip_hooks = {
+--
+2.53.0
+
--- /dev/null
+From a5e964995cd7e85d2317e53b2ec6ea002271e112 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 15:55:02 -0700
+Subject: netfilter: nf_log: validate MAC header was set before dumping it
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit a84b6fedbc97078788be78dbdd7517d143ad1a77 ]
+
+The fallback path of dump_mac_header() guards the MAC header access
+only with "skb->mac_header != skb->network_header", without checking
+skb_mac_header_was_set(). When the MAC header is unset, mac_header is
+0xffff, so the test passes and skb_mac_header(skb) returns
+skb->head + 0xffff, ~64 KiB past the buffer; the loop then reads
+dev->hard_header_len bytes out of bounds into the kernel log.
+
+This is reachable via the netdev logger: nf_log_unknown_packet() calls
+dump_mac_header() unconditionally, and an skb sent through AF_PACKET
+with PACKET_QDISC_BYPASS reaches the egress hook with mac_header still
+unset (__dev_queue_xmit(), which would reset it, is bypassed).
+
+Add the skb_mac_header_was_set() check the ARPHRD_ETHER path already
+uses, and replace the open-coded MAC header length test with
+skb_mac_header_len(). Only skbs with an unset MAC header are affected;
+valid ones are dumped as before.
+
+ BUG: KASAN: slab-out-of-bounds in dump_mac_header (net/netfilter/nf_log_syslog.c:831)
+ Read of size 1 at addr ffff88800ea49d3f by task exploit/148
+ Call Trace:
+ kasan_report (mm/kasan/report.c:595)
+ dump_mac_header (net/netfilter/nf_log_syslog.c:831)
+ nf_log_netdev_packet (net/netfilter/nf_log_syslog.c:938 net/netfilter/nf_log_syslog.c:963)
+ nf_log_packet (net/netfilter/nf_log.c:260)
+ nft_log_eval (net/netfilter/nft_log.c:60)
+ nft_do_chain (net/netfilter/nf_tables_core.c:285)
+ nft_do_chain_netdev (net/netfilter/nft_chain_filter.c:307)
+ nf_hook_slow (net/netfilter/core.c:619)
+ nf_hook_direct_egress (net/packet/af_packet.c:257)
+ packet_xmit (net/packet/af_packet.c:280)
+ packet_sendmsg (net/packet/af_packet.c:3114)
+ __sys_sendto (net/socket.c:2265)
+
+Fixes: 7eb9282cd0ef ("netfilter: ipt_LOG/ip6t_LOG: add option to print decoded MAC header")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_log_syslog.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
+index 58402226045e84..09b9152e9e5492 100644
+--- a/net/netfilter/nf_log_syslog.c
++++ b/net/netfilter/nf_log_syslog.c
+@@ -799,8 +799,8 @@ static void dump_mac_header(struct nf_log_buf *m,
+
+ fallback:
+ nf_log_buf_add(m, "MAC=");
+- if (dev->hard_header_len &&
+- skb->mac_header != skb->network_header) {
++ if (dev->hard_header_len && skb_mac_header_was_set(skb) &&
++ skb_mac_header_len(skb) != 0) {
+ const unsigned char *p = skb_mac_header(skb);
+ unsigned int i;
+
+--
+2.53.0
+
--- /dev/null
+From c9620b864707711b603a16d8d5d37af4dd4c0e77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 21:28:09 +0200
+Subject: netfilter: nft_exthdr: fix register tracking for F_PRESENT flag
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 772cecf198da732faebb5dcfc46d66a505be8495 ]
+
+nft_exthdr_init() passes user-controlled priv->len to
+nft_parse_register_store(), which marks that many bytes in the
+register bitmap as initialized. However, when NFT_EXTHDR_F_PRESENT
+is set, the eval paths write only 1 byte (nft_reg_store8) or
+4 bytes (*dest = 0 on TCP/DCCP error path). When len > 4,
+registers beyond the first are never written, retaining
+uninitialized stack data from nft_regs.
+
+Bail out if userspace requests too much data when F_PRESENT is set.
+
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Fixes: c078ca3b0c5b ("netfilter: nft_exthdr: Add support for existence check")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_exthdr.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
+index 1d4c9632072c8d..cac46accf566b5 100644
+--- a/net/netfilter/nft_exthdr.c
++++ b/net/netfilter/nft_exthdr.c
+@@ -530,6 +530,9 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
+ return err;
+ }
+
++ if ((flags & NFT_EXTHDR_F_PRESENT) && len != 1)
++ return -EINVAL;
++
+ priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
+ priv->offset = offset;
+ priv->len = len;
+--
+2.53.0
+
--- /dev/null
+From eca7f1f5d85bdbe0fd5a72b1f1502b9a5cf0b0b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 01:10:31 -0700
+Subject: netfilter: x_tables: avoid leaking percpu counter pointers
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f7f2fbb0e893a0238dc464f8d8c0f5609bec584f ]
+
+The native and compat get-entries paths copy the fixed rule entry header
+from the kernelized rule blob to userspace before overwriting the entry's
+counter fields with a sanitized counter snapshot.
+
+On SMP kernels, entry->counters.pcnt contains the percpu allocation
+address used by x_tables rule counters. A caller can provide a userspace
+buffer that faults during the initial fixed-header copy after pcnt has
+been copied but before the later sanitized counter copy runs. The syscall
+then returns -EFAULT while leaving the raw percpu pointer in userspace.
+
+Copy only the fixed entry prefix before counters from the kernelized rule
+blob, then copy the sanitized counter snapshot into the counter field.
+Apply this ordering to the IPv4, IPv6, and ARP native and compat
+get-entries implementations so a fault cannot expose the internal percpu
+counter pointer.
+
+Fixes: 71ae0dff02d7 ("netfilter: xtables: use percpu rule counters")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/netfilter/arp_tables.c | 15 ++++++---------
+ net/ipv4/netfilter/ip_tables.c | 15 ++++++---------
+ net/ipv6/netfilter/ip6_tables.c | 15 ++++++---------
+ 3 files changed, 18 insertions(+), 27 deletions(-)
+
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+index 564054123772a1..eeb48265208a2b 100644
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -702,14 +702,12 @@ static int copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct arpt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct arpt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1327,9 +1325,8 @@ static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct arpt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_arpt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_arpt_entry);
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
+index fe89a056eb06c4..74840604e8d963 100644
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -832,14 +832,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ipt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ipt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1228,9 +1226,8 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ipt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ipt_entry);
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+index 131f7bb2110d3a..858cea15e322f1 100644
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -848,14 +848,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ip6t_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ip6t_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1244,9 +1242,8 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ip6t_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ip6t_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ip6t_entry);
+--
+2.53.0
+
--- /dev/null
+From 17af861d96cca3dbcc899a57cc0d98252f4bf4f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 09:13:53 +0800
+Subject: netlabel: validate unlabeled address and mask attribute lengths
+
+From: Chenguang Zhao <zhaochenguang@kylinos.cn>
+
+[ Upstream commit 9772589b57e44aedc240211c5c3f7a684a034d3a ]
+
+netlbl_unlabel_addrinfo_get() used the address attribute length to
+determine whether the attribute data could be read as an IPv4 or IPv6
+address, but did not independently validate the corresponding mask
+attribute length. A crafted Generic Netlink request could therefore
+provide a valid IPv4/IPv6 address attribute with a shorter mask
+attribute, which would later be read as a full struct in_addr or
+struct in6_addr.
+
+NLA_BINARY policy lengths are maximum lengths by default, so use
+NLA_POLICY_EXACT_LEN() for the unlabeled IPv4/IPv6 address and mask
+attributes. This rejects short attributes during policy validation and
+also exposes the exact length requirements through policy introspection.
+
+Fixes: 8cc44579d1bd ("NetLabel: Introduce static network labels for unlabeled connections")
+Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlabel/netlabel_unlabeled.c | 30 ++++++++++--------------------
+ 1 file changed, 10 insertions(+), 20 deletions(-)
+
+diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
+index 9996883bf2b78d..6007cb000da678 100644
+--- a/net/netlabel/netlabel_unlabeled.c
++++ b/net/netlabel/netlabel_unlabeled.c
+@@ -114,14 +114,14 @@ static struct genl_family netlbl_unlabel_gnl_family;
+ /* NetLabel Netlink attribute policy */
+ static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
+ [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
+- [NLBL_UNLABEL_A_IPV6ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV6MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV4ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
+- [NLBL_UNLABEL_A_IPV4MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
++ [NLBL_UNLABEL_A_IPV6ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV6MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV4ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
++ [NLBL_UNLABEL_A_IPV4MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
+ [NLBL_UNLABEL_A_IFACE] = { .type = NLA_NUL_STRING,
+ .len = IFNAMSIZ - 1 },
+ [NLBL_UNLABEL_A_SECCTX] = { .type = NLA_BINARY }
+@@ -764,24 +764,14 @@ static int netlbl_unlabel_addrinfo_get(struct genl_info *info,
+ void **mask,
+ u32 *len)
+ {
+- u32 addr_len;
+-
+ if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR] &&
+ info->attrs[NLBL_UNLABEL_A_IPV4MASK]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+- if (addr_len != sizeof(struct in_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV4MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4MASK]);
+ return 0;
+ } else if (info->attrs[NLBL_UNLABEL_A_IPV6ADDR]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+- if (addr_len != sizeof(struct in6_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV6MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in6_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6MASK]);
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From 98b5ab47039461dc43fa9bfb5496e2cd4b02ea1f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 17:22:47 +0800
+Subject: r8152: handle the return value of usb_reset_device()
+
+From: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+
+[ Upstream commit 19440600e729d4f74a42591a872099cf25c7d28a ]
+
+If usb_reset_device() returns a negative error code, stop the
+process of probing.
+
+Fixes: 10c3271712f5 ("r8152: disable the ECM mode")
+Signed-off-by: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+Reviewed-by: Hayes Wang <hayeswang@realtek.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20260604092247.27158-450-nic_swsd@realtek.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/r8152.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index d39d66e25b01b9..cf8119924bb72e 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -9757,7 +9757,12 @@ static int rtl8152_probe_once(struct usb_interface *intf,
+ struct net_device *netdev;
+ int ret;
+
+- usb_reset_device(udev);
++ ret = usb_reset_device(udev);
++ if (ret < 0) {
++ dev_err(&intf->dev, "USB reset failed, errno=%d\n", ret);
++ return ret;
++ }
++
+ netdev = alloc_etherdev(sizeof(struct r8152));
+ if (!netdev) {
+ dev_err(&intf->dev, "Out of memory\n");
+--
+2.53.0
+
--- /dev/null
+From 159b9697255d0fb732b37e6fe60e1b5e165cd0af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 02:32:05 -0700
+Subject: rds: mark snapshot pages dirty in rds_info_getsockopt()
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 512db8267b73a220a64180d95ab5eebe7c4964a8 ]
+
+rds_info_getsockopt() pins the destination user pages with FOLL_WRITE and
+the RDS_INFO_* producers memcpy the snapshot into them through
+kmap_atomic(). Because that copy goes through the kernel direct map, the
+dirty bit on the user PTE is never set, so unpin_user_pages() releases the
+pages without marking them dirty. A file-backed destination page can then
+be reclaimed without writeback, silently discarding the copied data.
+
+Use unpin_user_pages_dirty_lock() with make_dirty=true so the modified
+pages are marked dirty before they are unpinned.
+
+Fixes: a8c879a7ee98 ("RDS: Info and stats")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260608-rds_fix-v1-1-006c88543408@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/info.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/rds/info.c b/net/rds/info.c
+index b6b46a8214a0a5..b3ee5f8238c44d 100644
+--- a/net/rds/info.c
++++ b/net/rds/info.c
+@@ -235,7 +235,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
+
+ out:
+ if (pages)
+- unpin_user_pages(pages, nr_pages);
++ unpin_user_pages_dirty_lock(pages, nr_pages, true);
+ kfree(pages);
+
+ return ret;
+--
+2.53.0
+
--- /dev/null
+From 3a7184814e8681fda92eee25d39cfcd8efca7472 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 08:22:34 -0400
+Subject: sctp: fix uninit-value in __sctp_rcv_asconf_lookup()
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit f8373d7090b745728de66308deeecc67e8d319ce ]
+
+__sctp_rcv_asconf_lookup() in net/sctp/input.c only checks that the ASCONF
+chunk can hold the ADDIP header and a parameter header, then calls
+af->from_addr_param(), which reads the full address (16 bytes for IPv6)
+trusting the parameter's declared length.
+
+An unauthenticated peer can send a truncated trailing ASCONF chunk that
+declares an IPv6 address parameter but stops after the 4-byte parameter
+header; reached from the no-association lookup path, from_addr_param() then
+reads uninitialized bytes past the parameter.
+
+Impact: an unauthenticated SCTP peer makes the receive path read up to 16
+bytes of uninitialized memory past a truncated ASCONF address parameter.
+
+The sibling __sctp_rcv_init_lookup() bounds parameters with
+sctp_walk_params(); this path open-codes the fetch and omits the bound.
+Verify the whole address parameter lies within the chunk before
+from_addr_param() reads it, the same class of fix as commit 51e5ad549c43
+("net: sctp: fix KMSAN uninit-value in sctp_inq_pop").
+
+Fixes: df2185771439 ("[SCTP]: Update association lookup to look at ASCONF chunks as well")
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260608122234.459098-1-michael.bommarito@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/input.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/sctp/input.c b/net/sctp/input.c
+index 032a10d82302c3..df5b2187b8fada 100644
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -1204,6 +1204,14 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
+ /* Skip over the ADDIP header and find the Address parameter */
+ param = (union sctp_addr_param *)(asconf + 1);
+
++ /* The whole address parameter must lie within the chunk before
++ * af->from_addr_param() reads the variable-length address; otherwise a
++ * truncated trailing ASCONF chunk lets it read uninitialized bytes past
++ * the parameter.
++ */
++ if (sizeof(*asconf) + ntohs(param->p.length) > ntohs(ch->length))
++ return NULL;
++
+ af = sctp_get_af_specific(param_type2af(param->p.type));
+ if (unlikely(!af))
+ return NULL;
+--
+2.53.0
+
kvm-arm64-remove-vpipt-i-cache-handling.patch
arm64-tlb-allow-xzr-argument-to-tlbi-ops.patch
arm64-tlb-optimize-arm64_workaround_repeat_tlbi.patch
+iomap-don-t-revert-iov_iter-on-partially-completed-b.patch
+xfrm-policy-fix-use-after-free-on-inexact-bin-in-xfr.patch
+netlabel-validate-unlabeled-address-and-mask-attribu.patch
+gpio-mvebu-fix-null-pointer-dereference-in-suspend-r.patch
+asoc-wm_adsp-fix-null-dereference-when-removing-firm.patch
+tcp-restrict-so_attach_filter-to-priv-users.patch
+net-mlx4-avoid-gcc-10-__bad_copy_from-false-positive.patch
+net-phy-clean-the-sfp-upstream-if-phy-probing-fails.patch
+net-qrtr-fix-refcount-saturation-and-potential-uaf-i.patch
+net-mlx5-fix-slab-out-of-bounds-in-mlx5_query_nic_vp.patch
+ipv6-sit-reload-inner-ipv6-header-after-gso-offloads.patch
+net-openvswitch-fix-possible-kfree_skb-of-err_ptr.patch
+r8152-handle-the-return-value-of-usb_reset_device.patch
+sctp-fix-uninit-value-in-__sctp_rcv_asconf_lookup.patch
+net-guard-timestamp-cmsgs-to-real-error-queue-skbs.patch
+net-rds-fix-null-deref-in-rds_ib_send_cqe_handler-on.patch
+ip6_vti-fix-incorrect-tunnel-matching-in-vti6_tnl_lo.patch
+rds-mark-snapshot-pages-dirty-in-rds_info_getsockopt.patch
+netfilter-nf_conntrack-destroy-stale-expectfn-expect.patch
+netfilter-x_tables-avoid-leaking-percpu-counter-poin.patch
+netfilter-nf_log-validate-mac-header-was-set-before-.patch
+netfilter-nft_exthdr-fix-register-tracking-for-f_pre.patch
+net-mvpp2-sync-rx-data-at-the-hardware-packet-offset.patch
+net-mvpp2-limit-xdp-frame-size-to-the-rx-buffer.patch
+net-mvpp2-add-metadata-support-for-xdp-mode.patch
+net-mvpp2-refill-rx-buffers-before-xdp-or-skb-use.patch
+net-mvpp2-build-skb-from-xdp-adjusted-data-on-xdp_pa.patch
+ipv6-fix-a-potential-npd-in-cleanup_prefix_route.patch
--- /dev/null
+From de3bd484deab85623a6d1d05aba82cbcb53cd876 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 11:21:34 +0000
+Subject: tcp: restrict SO_ATTACH_FILTER to priv users
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 5d39580f68e6ddeedd15e587282207489dfb3da2 ]
+
+This patch restricts the use of SO_ATTACH_FILTER (cBPF) on TCP sockets
+to users with CAP_NET_ADMIN capability.
+
+This blocks potential side-channel attack where an unprivileged application
+attaches a filter to leak TCP sequence/acknowledgment numbers.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Tamir Shahar <tamirthesis@gmail.com>
+Reported-by: Amit Klein <aksecurity@gmail.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Andrii Nakryiko <andrii@kernel.org>
+Cc: Martin KaFai Lau <martin.lau@linux.dev>
+Cc: Eduard Zingerman <eddyz87@gmail.com>
+Cc: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Cc: Song Liu <song@kernel.org>
+Cc: Yonghong Song <yonghong.song@linux.dev>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: Stanislav Fomichev <sdf@fomichev.me>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 267f771dda1cc2..87e6060c8bca7f 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1311,6 +1311,11 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
+ case SO_ATTACH_FILTER: {
+ struct sock_fprog fprog;
+
++ if (sk_is_tcp(sk) &&
++ !sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
++ ret = -EPERM;
++ break;
++ }
+ ret = copy_bpf_fprog_from_user(&fprog, optval, optlen);
+ if (!ret)
+ ret = sk_attach_filter(&fprog, sk);
+--
+2.53.0
+
--- /dev/null
+From 7bc0dcb90f1e2d268ceec6e8b5e435271ddbd9f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 18:49:05 +0900
+Subject: xfrm: policy: fix use-after-free on inexact bin in
+ xfrm_policy_bysel_ctx()
+
+From: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+
+[ Upstream commit 7f2d76c9c03257c0782afef9d95321fa04096f60 ]
+
+Fix the race by pruning the bin while still holding xfrm_policy_lock,
+before dropping it. Use __xfrm_policy_inexact_prune_bin() directly since
+the lock is already held. The wrapper xfrm_policy_inexact_prune_bin()
+becomes unused and is removed.
+
+Race:
+
+ CPU0 (XFRM_MSG_DELPOLICY) CPU1 (XFRM_MSG_NEWSPDINFO)
+ ========================== ==========================
+ xfrm_policy_bysel_ctx():
+ spin_lock_bh(xfrm_policy_lock)
+ bin = xfrm_policy_inexact_lookup()
+ __xfrm_policy_unlink(pol)
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_kill(ret)
+ // wide window, lock not held
+ xfrm_hash_rebuild():
+ spin_lock_bh(xfrm_policy_lock)
+ __xfrm_policy_inexact_flush():
+ kfree_rcu(bin) // bin freed
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_inexact_prune_bin(bin)
+ // UAF: bin is freed
+
+Fixes: 6be3b0db6db8 ("xfrm: policy: add inexact policy search tree infrastructure")
+Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 2dffccf370626d..2110941c8e9a75 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1127,15 +1127,6 @@ static void __xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b, bool
+ }
+ }
+
+-static void xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b)
+-{
+- struct net *net = read_pnet(&b->k.net);
+-
+- spin_lock_bh(&net->xfrm.xfrm_policy_lock);
+- __xfrm_policy_inexact_prune_bin(b, false);
+- spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+-}
+-
+ static void __xfrm_policy_inexact_flush(struct net *net)
+ {
+ struct xfrm_pol_inexact_bin *bin, *t;
+@@ -1729,12 +1720,12 @@ xfrm_policy_bysel_ctx(struct net *net, const struct xfrm_mark *mark, u32 if_id,
+ }
+ ret = pol;
+ }
++ if (bin && delete)
++ __xfrm_policy_inexact_prune_bin(bin, false);
+ spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+
+ if (ret && delete)
+ xfrm_policy_kill(ret);
+- if (bin && delete)
+- xfrm_policy_inexact_prune_bin(bin);
+ return ret;
+ }
+ EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
+--
+2.53.0
+
--- /dev/null
+From 25ca78c6c08ae78287c6bb0306e272b3ba667943 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jun 2026 10:37:57 +0800
+Subject: ASoC: SDCA: fix NULL pointer dereference in
+ sdca_dev_unregister_functions
+
+From: Kean Ren <rh_king@163.com>
+
+[ Upstream commit e4c60a1d4b6ccc66aefb3789cd908d4f9482eefd ]
+
+sdca_dev_unregister_functions() iterates over all SDCA function
+descriptors and calls sdca_dev_unregister() on each func_dev without
+checking for NULL. When a function registration has failed partway
+through, or the device cleanup races with probe deferral, func_dev
+entries may be NULL, leading to a kernel oops:
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000040
+ RIP: 0010:device_del+0x1e/0x3e0
+ Call Trace:
+ sdca_dev_unregister_functions+0x37/0x60 [snd_soc_sdca]
+ release_nodes+0x35/0xb0
+ devres_release_all+0x90/0x100
+ device_unbind_cleanup+0xe/0x80
+ device_release_driver_internal+0x1c1/0x200
+ bus_remove_device+0xc6/0x130
+ device_del+0x161/0x3e0
+ device_unregister+0x17/0x60
+ sdw_delete_slave+0xb6/0xd0 [soundwire_bus]
+ sdw_bus_master_delete+0x1e/0x50 [soundwire_bus]
+ ...
+ sof_probe_work+0x19/0x30 [snd_sof]
+
+This was observed on a Lenovo ThinkPad X1 Carbon G14 (Panther Lake)
+with the SOF audio driver probe failing due to missing Panther Lake
+firmware, causing the subsequent cleanup of SoundWire devices to
+trigger the crash.
+
+Fix this with three changes:
+
+1) Add a NULL guard in sdca_dev_unregister() so that callers do not
+ need to pre-validate the pointer (defense in depth).
+
+2) In sdca_dev_unregister_functions(), skip NULL func_dev entries
+ and clear func_dev to NULL after unregistration, making the
+ function idempotent and safe against double-invocation.
+
+3) In sdca_dev_register_functions(), roll back all previously
+ registered functions when a later one fails, so the function
+ array is never left in a partially-populated state.
+
+Fixes: 4496d1c65bad ("ASoC: SDCA: add function devices")
+Signed-off-by: Kean Ren <rh_king@163.com>
+Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://patch.msgid.link/20260611023757.1553960-1-rh_king@163.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sdca/sdca_function_device.c | 24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/sdca/sdca_function_device.c b/sound/soc/sdca/sdca_function_device.c
+index feacfbc6a51880..b5ca98283a8895 100644
+--- a/sound/soc/sdca/sdca_function_device.c
++++ b/sound/soc/sdca/sdca_function_device.c
+@@ -82,6 +82,9 @@ static struct sdca_dev *sdca_dev_register(struct device *parent,
+
+ static void sdca_dev_unregister(struct sdca_dev *sdev)
+ {
++ if (!sdev)
++ return;
++
+ auxiliary_device_delete(&sdev->auxdev);
+ auxiliary_device_uninit(&sdev->auxdev);
+ }
+@@ -90,14 +93,24 @@ int sdca_dev_register_functions(struct sdw_slave *slave)
+ {
+ struct sdca_device_data *sdca_data = &slave->sdca_data;
+ int i;
++ int ret;
+
+ for (i = 0; i < sdca_data->num_functions; i++) {
+ struct sdca_dev *func_dev;
+
+ func_dev = sdca_dev_register(&slave->dev,
+ &sdca_data->function[i]);
+- if (IS_ERR(func_dev))
+- return PTR_ERR(func_dev);
++ if (IS_ERR(func_dev)) {
++ ret = PTR_ERR(func_dev);
++ /*
++ * Unregister functions that were successfully
++ * registered before this failure. This also
++ * sets func_dev to NULL so the caller will not
++ * try to unregister them again.
++ */
++ sdca_dev_unregister_functions(slave);
++ return ret;
++ }
+
+ sdca_data->function[i].func_dev = func_dev;
+ }
+@@ -111,7 +124,12 @@ void sdca_dev_unregister_functions(struct sdw_slave *slave)
+ struct sdca_device_data *sdca_data = &slave->sdca_data;
+ int i;
+
+- for (i = 0; i < sdca_data->num_functions; i++)
++ for (i = 0; i < sdca_data->num_functions; i++) {
++ if (!sdca_data->function[i].func_dev)
++ continue;
++
+ sdca_dev_unregister(sdca_data->function[i].func_dev);
++ sdca_data->function[i].func_dev = NULL;
++ }
+ }
+ EXPORT_SYMBOL_NS(sdca_dev_unregister_functions, "SND_SOC_SDCA");
+--
+2.53.0
+
--- /dev/null
+From f566d8e5fbf506618a85422b7b73b45795dcc72d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 21:38:44 +0530
+Subject: ASoC: SOF: amd: fix for ipc flags check
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit 6042c91df60e825625bc7d5c5c3b5a87b91d5805 ]
+
+Firmware will set dsp_ack to 1 when firmware sends response for the IPC
+command issued by host. Similarly dsp_msg flag will be updated to 1.
+
+During ACP D0 entry, the value read from the sof_dsp_ack_write scratch
+flag can be uninitialized. A non-zero garbage value is treated as a
+pending DSP IPC ack before SOF_FW_BOOT_COMPLETE, causing a spurious
+"IPC reply before FW_BOOT_COMPLETE" log.
+
+Fix the condition checks for ipc flags.
+
+Fixes: 738a2b5e2cc9 ("ASoC: SOF: amd: Add IPC support for ACP IP block")
+Link: https://github.com/thesofproject/linux/pull/5642
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Tested-by: Umang Jain <uajain@igalia.com>
+Link: https://patch.msgid.link/20260609160938.3717513-1-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/amd/acp-ipc.c | 4 ++--
+ sound/soc/sof/amd/acp.h | 2 ++
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/sof/amd/acp-ipc.c b/sound/soc/sof/amd/acp-ipc.c
+index 3cd4674dd80075..94025bc799ea40 100644
+--- a/sound/soc/sof/amd/acp-ipc.c
++++ b/sound/soc/sof/amd/acp-ipc.c
+@@ -181,14 +181,14 @@ irqreturn_t acp_sof_ipc_irq_thread(int irq, void *context)
+ }
+
+ dsp_msg = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_msg_write);
+- if (dsp_msg) {
++ if (dsp_msg == ACP_DSP_MSG_SET) {
+ snd_sof_ipc_msgs_rx(sdev);
+ acp_dsp_ipc_host_done(sdev);
+ ipc_irq = true;
+ }
+
+ dsp_ack = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write);
+- if (dsp_ack) {
++ if (dsp_ack == ACP_DSP_ACK_SET) {
+ if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) {
+ guard(spinlock_irq)(&sdev->ipc_lock);
+
+diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
+index 2b7ea8c6410602..7bcb76676a984a 100644
+--- a/sound/soc/sof/amd/acp.h
++++ b/sound/soc/sof/amd/acp.h
+@@ -116,6 +116,8 @@
+ #define ACP_SRAM_PAGE_COUNT 128
+ #define ACP6X_SDW_MAX_MANAGER_COUNT 2
+ #define ACP70_SDW_MAX_MANAGER_COUNT ACP6X_SDW_MAX_MANAGER_COUNT
++#define ACP_DSP_MSG_SET 1
++#define ACP_DSP_ACK_SET 1
+
+ enum clock_source {
+ ACP_CLOCK_96M = 0,
+--
+2.53.0
+
--- /dev/null
+From aa9d774931b4a12931516beb2e1225855c4ed4c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 11:12:44 +0100
+Subject: ASoC: wm_adsp: Fix NULL dereference when removing firmware controls
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 7d3fb78b550301e43fdc60312aed733069694426 ]
+
+In wm_adsp_control_remove() check that the priv pointer is not NULL
+before attempting to cleanup what it points to.
+
+When cs_dsp creates a control it calls wm_adsp_control_add_cb() so that
+wm_adsp can create its own private control data. There are two cases
+where private data is not created:
+
+1. The control is a SYSTEM control, so an ALSA control is not created.
+
+2. The codec driver has registered a control_add() callback that
+ hides the control, so wm_adsp_control_add() is not called.
+
+When cs_dsp_remove destroys its control list it calls
+wm_adsp_control_remove() for each control. But wm_adsp_control_remove()
+was attempting to cleanup the private data pointed to by cs_ctl->priv
+without checking the pointer for NULL.
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Fixes: 0700bc2fb94c ("ASoC: wm_adsp: Separate generic cs_dsp_coeff_ctl handling")
+Link: https://patch.msgid.link/20260604101244.1402862-1-rf@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/wm_adsp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
+index 2e23848e1dce94..d7ba14ce613b74 100644
+--- a/sound/soc/codecs/wm_adsp.c
++++ b/sound/soc/codecs/wm_adsp.c
+@@ -666,6 +666,9 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl)
+ {
+ struct wm_coeff_ctl *ctl = cs_ctl->priv;
+
++ if (!ctl)
++ return;
++
+ cancel_work_sync(&ctl->work);
+
+ kfree(ctl->name);
+--
+2.53.0
+
--- /dev/null
+From 8fd69150b979dbe2ec16f60f7107243e241824c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 22:07:09 +0530
+Subject: bnge: fix context mem iteration
+
+From: Vikas Gupta <vikas.gupta@broadcom.com>
+
+[ Upstream commit 3847d94783c0b893c27ff0b26a3325796d9444c6 ]
+
+The firmware advertises context memory (backing store) types
+through a linked list, with BNGE_CTX_INV serving as the
+end-of-list sentinel.
+However, the driver incorrectly assumes that the list is strictly
+ordered and prematurely terminates traversal when it encounters
+an unrecognized type (>=BNGE_CTX_V2_MAX). As a result, any valid
+context types that appear later in the chain are silently skipped,
+leading to incomplete memory configuration and eventual driver load
+failure.
+
+Fix this by traversing the entire list until the BNGE_CTX_INV sentinel
+is reached, while safely ignoring only those context types that fall
+outside the supported range.
+
+Fixes: 29c5b358f385 ("bng_en: Add backing store support")
+Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
+Reviewed-by: Dharmender Garg <dharmender.garg@broadcom.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
+index c46da34134179c..3f07311d065e24 100644
+--- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
++++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
+@@ -259,7 +259,7 @@ int bnge_hwrm_func_backing_store_qcaps(struct bnge_dev *bd)
+ struct hwrm_func_backing_store_qcaps_v2_output *resp;
+ struct hwrm_func_backing_store_qcaps_v2_input *req;
+ struct bnge_ctx_mem_info *ctx;
+- u16 type;
++ u16 type, next_type;
+ int rc;
+
+ if (bd->ctx)
+@@ -276,8 +276,8 @@ int bnge_hwrm_func_backing_store_qcaps(struct bnge_dev *bd)
+
+ resp = bnge_hwrm_req_hold(bd, req);
+
+- for (type = 0; type < BNGE_CTX_V2_MAX; ) {
+- struct bnge_ctx_mem_type *ctxm = &ctx->ctx_arr[type];
++ for (type = 0; type < BNGE_CTX_INV; type = next_type) {
++ struct bnge_ctx_mem_type *ctxm;
+ u8 init_val, init_off, i;
+ __le32 *p;
+ u32 flags;
+@@ -286,8 +286,14 @@ int bnge_hwrm_func_backing_store_qcaps(struct bnge_dev *bd)
+ rc = bnge_hwrm_req_send(bd, req);
+ if (rc)
+ goto ctx_done;
++
++ next_type = le16_to_cpu(resp->next_valid_type);
++ if (type >= BNGE_CTX_V2_MAX)
++ continue;
++
++ ctxm = &ctx->ctx_arr[type];
+ flags = le32_to_cpu(resp->flags);
+- type = le16_to_cpu(resp->next_valid_type);
++
+ if (!(flags &
+ FUNC_BACKING_STORE_QCAPS_V2_RESP_FLAGS_TYPE_VALID))
+ continue;
+--
+2.53.0
+
--- /dev/null
+From aed42bd943c4e7f97b0ba49190414c0a60a3ba3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 20:37:08 +0800
+Subject: dma-debug: fix physical address retrieval in
+ debug_dma_sync_sg_for_device
+
+From: Li RongQing <lirongqing@baidu.com>
+
+[ Upstream commit 9bfaa86b405381326c971984fd6da184c289713f ]
+
+In debug_dma_sync_sg_for_device(), when iterating over a scatterlist,
+the debug entry population mistakenly uses the head of the scatterlist
+'sg' to fetch the physical address via sg_phys(), instead of using the
+current iterator variable 's'.
+
+This causes dma-debug to track the physical address of the very first
+scatterlist entry for all subsequent entries in the list.
+
+Fix this by passing the correct loop iterator 's' to sg_phys()
+
+Fixes: 9d4f645a1fd49ee ("dma-debug: store a phys_addr_t in struct dma_debug_entry")
+Signed-off-by: Li RongQing <lirongqing@baidu.com>
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20260603123708.1665-1-lirongqing@baidu.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/dma/debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c
+index 3248f8b4d096de..2c0e2cd89b5ed7 100644
+--- a/kernel/dma/debug.c
++++ b/kernel/dma/debug.c
+@@ -1556,7 +1556,7 @@ void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+ struct dma_debug_entry ref = {
+ .type = dma_debug_sg,
+ .dev = dev,
+- .paddr = sg_phys(sg),
++ .paddr = sg_phys(s),
+ .dev_addr = sg_dma_address(s),
+ .size = sg_dma_len(s),
+ .direction = direction,
+--
+2.53.0
+
--- /dev/null
+From 45bb23a1cb92455d7449fe2fc69a9505197f850a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 09:37:23 +0800
+Subject: dma-mapping: direct: fix missing mapping for THRU_HOST_BRIDGE
+ segments
+
+From: Li RongQing <lirongqing@baidu.com>
+
+[ Upstream commit 560000d619ef162568746ce287f0c725e24ea967 ]
+
+In dma_direct_map_sg(), the case PCI_P2PDMA_MAP_THRU_HOST_BRIDGE
+incorrectly used 'break' instead of falling through to MAP_NONE.
+As a result, segments traversing the host bridge skipped the required
+dma_direct_map_phys() call entirely, leaving sg->dma_address
+uninitialized and leading to DMA failures. Fix this by using
+'fallthrough;'.
+
+Fixes: a25e7962db0d79 ("PCI/P2PDMA: Refactor the p2pdma mapping helpers")
+Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
+Signed-off-by: Li RongQing <lirongqing@baidu.com>
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20260603013723.2439-1-lirongqing@baidu.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/dma/direct.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
+index 8f43a930716d46..306afebf54ef06 100644
+--- a/kernel/dma/direct.c
++++ b/kernel/dma/direct.c
+@@ -466,7 +466,7 @@ int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
+ * must be mapped with CPU physical address and not PCI
+ * bus addresses.
+ */
+- break;
++ fallthrough;
+ case PCI_P2PDMA_MAP_NONE:
+ sg->dma_address = dma_direct_map_phys(dev, sg_phys(sg),
+ sg->length, dir, attrs);
+--
+2.53.0
+
--- /dev/null
+From 8ecadcac3eec210ffe0d3cc1551a6609fb0afc35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 14:22:15 +0200
+Subject: esp: fix page frag reference leak on skb_to_sgvec failure
+
+From: Alessandro Schino <7991aleschino@gmail.com>
+
+[ Upstream commit 2982e599fff6faa21c8df147d96fc7af6c1a2f24 ]
+
+In esp_output_tail(), when esp->inplace is false, the old skb page frags
+are replaced with a new page from the xfrm page_frag cache. The source
+scatterlist (sg) is built from the old frags before the replacement, and
+esp_ssg_unref() is responsible for releasing the old page references
+after the crypto operation completes.
+
+However, if the second skb_to_sgvec() call (which builds the destination
+scatterlist from the new page) fails, the code jumps to error_free which
+only calls kfree(tmp). The old page frag references captured in the
+source scatterlist are never released:
+
+ 1. sg[] is built from old frags via skb_to_sgvec() (no extra get_page)
+ 2. nr_frags is set to 1 and frag[0] is replaced with the new page
+ 3. Second skb_to_sgvec() fails -> goto error_free
+ 4. kfree(tmp) frees the sg[] memory but old frags are not unref'd
+ 5. kfree_skb() only releases frag[0] (the new page), not the old ones
+
+Fix this by adding a bool parameter to esp_ssg_unref() that, when true,
+unconditionally unrefs the source scatterlist frags without checking
+req->src and req->dst, since those fields are not yet initialized by
+aead_request_set_crypt() at the point of the error. Existing callers
+pass false to preserve the original behavior.
+
+The same issue exists in both esp4 and esp6 as the code is identical.
+
+Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible")
+Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible")
+
+Signed-off-by: Alessandro Schino <7991aleschino@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Stable-dep-of: 26aad08a9289 ("esp: fix page frag reference leak on skb_to_sgvec failure")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/esp4.c | 17 +++++++++++------
+ net/ipv6/esp6.c | 17 +++++++++++------
+ 2 files changed, 22 insertions(+), 12 deletions(-)
+
+diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
+index 513c8215c947f1..dfc81ee969ae03 100644
+--- a/net/ipv4/esp4.c
++++ b/net/ipv4/esp4.c
+@@ -96,7 +96,7 @@ static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
+ __alignof__(struct scatterlist));
+ }
+
+-static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
++static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb, bool already_unref)
+ {
+ struct crypto_aead *aead = x->data;
+ int extralen = 0;
+@@ -113,10 +113,13 @@ static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
+ /* Unref skb_frag_pages in the src scatterlist if necessary.
+ * Skip the first sg which comes from skb->data.
+ */
+- if (req->src != req->dst)
+- for (sg = sg_next(req->src); sg; sg = sg_next(sg))
++ if (already_unref || req->src != req->dst) {
++ struct scatterlist *src = already_unref ? esp_req_sg(aead, req) : req->src;
++
++ for (sg = sg_next(src); sg; sg = sg_next(sg))
+ skb_page_unref(page_to_netmem(sg_page(sg)),
+ skb->pp_recycle);
++ }
+ }
+
+ #ifdef CONFIG_INET_ESPINTCP
+@@ -220,7 +223,7 @@ static void esp_output_done(void *data, int err)
+ }
+
+ tmp = ESP_SKB_CB(skb)->tmp;
+- esp_ssg_unref(x, tmp, skb);
++ esp_ssg_unref(x, tmp, skb, false);
+ kfree(tmp);
+
+ if (xo && (xo->flags & XFRM_DEV_RESUME)) {
+@@ -569,8 +572,10 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
+ err = skb_to_sgvec(skb, dsg,
+ (unsigned char *)esph - skb->data,
+ assoclen + ivlen + esp->clen + alen);
+- if (unlikely(err < 0))
++ if (unlikely(err < 0)) {
++ esp_ssg_unref(x, tmp, skb, true);
+ goto error_free;
++ }
+ }
+
+ if ((x->props.flags & XFRM_STATE_ESN))
+@@ -602,7 +607,7 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
+ }
+
+ if (sg != dsg)
+- esp_ssg_unref(x, tmp, skb);
++ esp_ssg_unref(x, tmp, skb, false);
+
+ if (!err && x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
+ err = esp_output_tail_tcp(x, skb);
+diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
+index 57481e423e59e6..296b57926abb98 100644
+--- a/net/ipv6/esp6.c
++++ b/net/ipv6/esp6.c
+@@ -113,7 +113,7 @@ static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
+ __alignof__(struct scatterlist));
+ }
+
+-static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
++static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb, bool already_unref)
+ {
+ struct crypto_aead *aead = x->data;
+ int extralen = 0;
+@@ -130,10 +130,13 @@ static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
+ /* Unref skb_frag_pages in the src scatterlist if necessary.
+ * Skip the first sg which comes from skb->data.
+ */
+- if (req->src != req->dst)
+- for (sg = sg_next(req->src); sg; sg = sg_next(sg))
++ if (already_unref || req->src != req->dst) {
++ struct scatterlist *src = already_unref ? esp_req_sg(aead, req) : req->src;
++
++ for (sg = sg_next(src); sg; sg = sg_next(sg))
+ skb_page_unref(page_to_netmem(sg_page(sg)),
+ skb->pp_recycle);
++ }
+ }
+
+ #ifdef CONFIG_INET6_ESPINTCP
+@@ -254,7 +257,7 @@ static void esp_output_done(void *data, int err)
+ }
+
+ tmp = ESP_SKB_CB(skb)->tmp;
+- esp_ssg_unref(x, tmp, skb);
++ esp_ssg_unref(x, tmp, skb, false);
+ kfree(tmp);
+
+ esp_output_encap_csum(skb);
+@@ -600,8 +603,10 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
+ err = skb_to_sgvec(skb, dsg,
+ (unsigned char *)esph - skb->data,
+ assoclen + ivlen + esp->clen + alen);
+- if (unlikely(err < 0))
++ if (unlikely(err < 0)) {
++ esp_ssg_unref(x, tmp, skb, true);
+ goto error_free;
++ }
+ }
+
+ if ((x->props.flags & XFRM_STATE_ESN))
+@@ -634,7 +639,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
+ }
+
+ if (sg != dsg)
+- esp_ssg_unref(x, tmp, skb);
++ esp_ssg_unref(x, tmp, skb, false);
+
+ if (!err && x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
+ err = esp_output_tail_tcp(x, skb);
+--
+2.53.0
+
--- /dev/null
+From 2a156afc582e3b984f00d23468ee10268458cbac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 16:43:34 +0800
+Subject: gpio: mvebu: fix NULL pointer dereference in suspend/resume
+
+From: Yun Zhou <yun.zhou@windriver.com>
+
+[ Upstream commit b9ad50d7505ebd48282ec3630258dc820fc85c81 ]
+
+mvebu_pwm_suspend() and mvebu_pwm_resume() are called for all GPIO
+banks during suspend/resume, but not all banks have PWM functionality.
+GPIO banks without PWM have mvchip->mvpwm set to NULL.
+
+Calling mvebu_pwm_suspend() with mvpwm == NULL causes a NULL pointer
+dereference when it tries to access mvpwm->blink_select.
+
+ Unable to handle kernel NULL pointer dereference at virtual address 00000020 when write
+ [00000020] *pgd=00000000
+ Internal error: Oops: 815 [#1] PREEMPT ARM
+ Modules linked in:
+ CPU: 0 UID: 0 PID: 406 Comm: sh Not tainted 6.12.74-rt12-yocto-standard-g4e96f98fb7db-dirty #353
+ Hardware name: Marvell Armada 370/XP (Device Tree)
+ PC is at regmap_mmio_read+0x38/0x54
+ LR is at regmap_mmio_read+0x38/0x54
+ pc : [<c05fd2ac>] lr : [<c05fd2ac>] psr: 200f0013
+ sp : f0c11d10 ip : 00000000 fp : c100d2f0
+ r10: c14fb854 r9 : 00000000 r8 : 00000000
+ r7 : c1799c00 r6 : 00000020 r5 : 00000020 r4 : c179c7c0
+ r3 : f0a231a0 r2 : 00000020 r1 : 00000020 r0 : 00000000
+ Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
+ Control: 10c5387d Table: 135ec059 DAC: 00000051
+ Call trace:
+ regmap_mmio_read from _regmap_bus_reg_read+0x78/0xac
+ _regmap_bus_reg_read from _regmap_read+0x60/0x154
+ _regmap_read from regmap_read+0x3c/0x60
+ regmap_read from mvebu_gpio_suspend+0xa4/0x14c
+ mvebu_gpio_suspend from dpm_run_callback+0x54/0x180
+ dpm_run_callback from device_suspend+0x124/0x630
+ device_suspend from dpm_suspend+0x124/0x270
+ dpm_suspend from dpm_suspend_start+0x64/0x6c
+ dpm_suspend_start from suspend_devices_and_enter+0x140/0x8e8
+ suspend_devices_and_enter from pm_suspend+0x2fc/0x308
+ pm_suspend from state_store+0x6c/0xc8
+ state_store from kernfs_fop_write_iter+0x10c/0x1f8
+ kernfs_fop_write_iter from vfs_write+0x270/0x468
+ vfs_write from ksys_write+0x70/0xf0
+ ksys_write from ret_fast_syscall+0x0/0x54
+
+Add a NULL check for mvchip->mvpwm before calling the PWM
+suspend/resume functions.
+
+Fixes: 757642f9a584 ("gpio: mvebu: Add limited PWM support")
+Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
+Link: https://patch.msgid.link/20260608084334.2960803-1-yun.zhou@windriver.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-mvebu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
+index 22c36b79e249ff..c030d1f00abcae 100644
+--- a/drivers/gpio/gpio-mvebu.c
++++ b/drivers/gpio/gpio-mvebu.c
+@@ -996,7 +996,7 @@ static int mvebu_gpio_suspend(struct platform_device *pdev, pm_message_t state)
+ BUG();
+ }
+
+- if (IS_REACHABLE(CONFIG_PWM))
++ if (IS_REACHABLE(CONFIG_PWM) && mvchip->mvpwm)
+ mvebu_pwm_suspend(mvchip);
+
+ return 0;
+@@ -1048,7 +1048,7 @@ static int mvebu_gpio_resume(struct platform_device *pdev)
+ BUG();
+ }
+
+- if (IS_REACHABLE(CONFIG_PWM))
++ if (IS_REACHABLE(CONFIG_PWM) && mvchip->mvpwm)
+ mvebu_pwm_resume(mvchip);
+
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From 4e081bf14408ae9448bc39f31bb61795f0ff32bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 01:05:02 +0200
+Subject: gpio: rockchip: fix generic IRQ chip leak on remove
+
+From: Marco Scardovi <scardracs@disroot.org>
+
+[ Upstream commit 1c1e0fc88d6ef65bf15d517853251f75ab9d18c3 ]
+
+The driver allocates domain generic chips using
+irq_alloc_domain_generic_chips() during probe. However, on driver
+remove/teardown, the generic chips are not automatically freed when the
+IRQ domain is removed because the domain flags do not include
+IRQ_DOMAIN_FLAG_DESTROY_GC.
+
+This causes both the domain generic chips structure and the associated
+generic chips to be leaked. Additionally, the generic chips remain on
+the global gc_list and may later be visited by generic IRQ chip suspend,
+resume, or shutdown callbacks after the GPIO bank has been removed,
+potentially resulting in a use-after-free and kernel crash.
+
+Fix the resource leak by explicitly calling
+irq_domain_remove_generic_chips() before removing the IRQ domain in
+rockchip_gpio_remove().
+
+Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
+Assisted-by: Antigravity:gemini-3.5-flash
+Signed-off-by: Marco Scardovi <scardracs@disroot.org>
+Link: https://patch.msgid.link/20260607230504.35392-2-scardracs@disroot.org
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-rockchip.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index 1ef0ba956cfd8c..46dd9085d9c8cd 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -802,8 +802,10 @@ static void rockchip_gpio_remove(struct platform_device *pdev)
+ struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);
+
+ irq_set_chained_handler_and_data(bank->irq, NULL, NULL);
+- if (bank->domain)
++ if (bank->domain) {
++ irq_domain_remove_generic_chips(bank->domain);
+ irq_domain_remove(bank->domain);
++ }
+ gpiochip_remove(&bank->gpio_chip);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From bdeab3eabdbca4132323f4cf81bc7d59df0793a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 15:33:13 +0800
+Subject: gpio: zynq: fix runtime PM leak on remove
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+[ Upstream commit 6edb934de9bda3b7abcec856eaee6fc8b4278dd1 ]
+
+pm_runtime_get_sync() increments the runtime PM usage counter even when it
+returns an error. zynq_gpio_remove() uses it to keep the controller active
+while removing the GPIO chip, but never drops the usage counter again.
+
+Balance the get with pm_runtime_put_noidle() after disabling runtime PM.
+
+Fixes: 3242ba117e9b ("gpio: Add driver for Zynq GPIO controller")
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Link: https://patch.msgid.link/20260609073313.5-1-ruoyuw560@gmail.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-zynq.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c
+index 571e366624d2af..fafca91128b2e6 100644
+--- a/drivers/gpio/gpio-zynq.c
++++ b/drivers/gpio/gpio-zynq.c
+@@ -1014,6 +1014,7 @@ static void zynq_gpio_remove(struct platform_device *pdev)
+ gpiochip_remove(&gpio->chip);
+ device_set_wakeup_capable(&pdev->dev, 0);
+ pm_runtime_disable(&pdev->dev);
++ pm_runtime_put_noidle(&pdev->dev);
+ }
+
+ static struct platform_driver zynq_gpio_driver = {
+--
+2.53.0
+
--- /dev/null
+From 1e8bb78c4d40b90ed7fb211fd20366c9d8625b3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 15:55:10 -0700
+Subject: ice: fix missing priority callbacks for U.FL DPLL pins
+
+From: Petr Oros <poros@redhat.com>
+
+[ Upstream commit f1fa677e428e8873486938086bd934dc18169b47 ]
+
+The U.FL2 input pin advertises DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE
+in its capability mask, but ice_dpll_pin_ufl_ops does not provide
+.prio_get and .prio_set callbacks. As a result the DPLL subsystem
+cannot report or accept priority for U.FL pins: pin-get omits the prio
+field on U.FL2 and pin-set with prio is rejected as invalid, even
+though the capability is present. This prevents user space from using
+priority to select or disable U.FL2 as a DPLL input source.
+
+Reproducer with iproute2 (dpll command):
+
+ # dpll pin show board-label U.FL2
+ pin id 16:
+ module-name ice
+ board-label U.FL2
+ type ext
+ capabilities priority-can-change|state-can-change
+ parent-device:
+ id 0 direction input state selectable phase-offset 0
+ /* note: no "prio" between "direction" and "state",
+ even though priority-can-change is advertised */
+
+ # dpll pin set id 16 parent-device 0 prio 5
+ RTNETLINK answers: Operation not supported
+
+After the fix the prio field is reported by pin show and pin set with
+prio is accepted on U.FL2.
+
+Add the missing .prio_get and .prio_set callbacks to
+ice_dpll_pin_ufl_ops, reusing ice_dpll_sw_input_prio_{get,set}. The
+same ops struct is shared by U.FL1 and U.FL2: U.FL2 (input) delegates
+to the backing hardware input pin, while U.FL1 (output) does not
+advertise DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE so the dpll core
+capability gate never invokes prio_set for it, and prio_get reports
+the OUTPUT sentinel (ICE_DPLL_PIN_PRIO_OUTPUT) on the output side
+exactly like the SMA path does today.
+
+Fixes: 2dd5d03c77e2 ("ice: redesign dpll sma/u.fl pins control")
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Petr Oros <poros@redhat.com>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Link: https://patch.msgid.link/20260602225513.393338-3-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_dpll.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
+index 892bc7c2e28b46..0704e92ab04305 100644
+--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
++++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
+@@ -2633,6 +2633,8 @@ static const struct dpll_pin_ops ice_dpll_pin_ufl_ops = {
+ .state_on_dpll_set = ice_dpll_ufl_pin_state_set,
+ .state_on_dpll_get = ice_dpll_sw_pin_state_get,
+ .direction_get = ice_dpll_pin_sw_direction_get,
++ .prio_get = ice_dpll_sw_input_prio_get,
++ .prio_set = ice_dpll_sw_input_prio_set,
+ .frequency_get = ice_dpll_sw_pin_frequency_get,
+ .frequency_set = ice_dpll_sw_pin_frequency_set,
+ .esync_set = ice_dpll_sw_esync_set,
+--
+2.53.0
+
--- /dev/null
+From f1a8a74339a10d71327b25f986d160133a199d59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 15:55:11 -0700
+Subject: idpf: fix mailbox capability for set device clock time
+
+From: Alok Tiwari <alok.a.tiwari@oracle.com>
+
+[ Upstream commit 85b0cbc1f38bc1e38956a9e6d7b04d309b435697 ]
+
+The current code incorrectly uses VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME
+for both direct and mailbox capabilities, causing mailbox-only support
+to be ignored and potentially reporting IDPF_PTP_NONE.
+
+Fixes: d5dba8f7206da ("idpf: add PTP clock configuration")
+Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Link: https://patch.msgid.link/20260602225513.393338-4-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/idpf/idpf_ptp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_ptp.c b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
+index 4a51d2727547d9..71fe8b2a8b4e42 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_ptp.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_ptp.c
+@@ -51,7 +51,7 @@ void idpf_ptp_get_features_access(const struct idpf_adapter *adapter)
+
+ /* Set the device clock time */
+ direct = VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME;
+- mailbox = VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME;
++ mailbox = VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME_MB;
+ ptp->set_dev_clk_time_access = idpf_ptp_get_access(adapter,
+ direct,
+ mailbox);
+--
+2.53.0
+
--- /dev/null
+From eb383192b8aa69f4c6af88879c3b729ba8eb1be9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 16:46:13 +0000
+Subject: ip6_vti: fix incorrect tunnel matching in vti6_tnl_lookup()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit a5c0359f5cbc51a2e2b114d6041e0f3c73f903e9 ]
+
+In vti6_tnl_lookup(), when an exact match for a tunnel fails,
+the code falls back to searching for wildcard tunnels:
+
+- Tunnels matching the packet's local address, with any remote address
+ wildcard remote).
+
+- Tunnels matching the packet's remote address, with any local address
+ (wildcard local).
+
+However, vti6 stores all these different types of tunnels in the same
+hash table (ip6n->tnls_r_l) prone to hash collisions.
+
+The bug is that the fallback search loops in vti6_tnl_lookup() were
+missing checks to ensure that the candidate tunnel actually has
+a wildcard address.
+
+Fixes: fbe68ee87522 ("vti6: Add a lookup method for tunnels with wildcard endpoints.")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260608164613.933023-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_vti.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
+index d2b74a6f2cf62d..d871cab6938d36 100644
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -106,6 +106,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(&any, local);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(local, &t->parms.laddr) &&
++ ipv6_addr_any(&t->parms.raddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+@@ -113,6 +114,7 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
+ hash = HASH(remote, &any);
+ for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ if (ipv6_addr_equal(remote, &t->parms.raddr) &&
++ ipv6_addr_any(&t->parms.laddr) &&
+ (t->dev->flags & IFF_UP))
+ return t;
+ }
+--
+2.53.0
+
--- /dev/null
+From 14a20bf2464090e96138c7b210b7c6b5a5e931b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 15:59:18 +0000
+Subject: ip6_vti: set netns_immutable on the fallback device.
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit d289d5307762d1838aaece22c6b6fcad9e8865f9 ]
+
+john1988 and Noam Rathaus reported that vti6_init_net() does not set the
+netns_immutable flag on the per-netns fallback tunnel device (ip6_vti0).
+
+Other similar tunnel drivers (like ip6_tunnel, sit, ip6_gre, and ip_tunnel)
+correctly set this flag during their fallback device initialization to
+prevent them from being moved to another network namespace.
+
+Fixes: 61220ab34948 ("vti6: Enable namespace changing")
+Reported-by: Noam Rathaus <noamr@ssd-disclosure.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260608155918.787644-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_vti.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
+index df793c8bfffb0a..d2b74a6f2cf62d 100644
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -1159,6 +1159,7 @@ static int __net_init vti6_init_net(struct net *net)
+ goto err_alloc_dev;
+ dev_net_set(ip6n->fb_tnl_dev, net);
+ ip6n->fb_tnl_dev->rtnl_link_ops = &vti6_link_ops;
++ ip6n->fb_tnl_dev->netns_immutable = true;
+
+ err = vti6_fb_tnl_dev_init(ip6n->fb_tnl_dev);
+ if (err < 0)
+--
+2.53.0
+
--- /dev/null
+From 59cada4b6a56df47896b295316cba8acf30a1680 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 17:54:48 +0300
+Subject: ipv6: Fix a potential NPD in cleanup_prefix_route()
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit b70c687b7cf267fb08586667a3946c8851cad672 ]
+
+addrconf_get_prefix_route() can return the fib6_null_entry sentinel
+entry which has a NULL fib6_table pointer. Therefore, before setting the
+route's expiration time, check that we are not working with this entry,
+as otherwise a NPD will be triggered [1].
+
+Note that the other callers of addrconf_get_prefix_route() are not
+susceptible to this bug:
+
+1. addrconf_prefix_rcv(): Requests a route with the 'RTF_ADDRCONF |
+ RTF_PREFIX_RT' flags which are not set on fib6_null_entry.
+
+2. modify_prefix_route(): Fixed by commit a747e02430df ("ipv6: avoid
+ possible NULL deref in modify_prefix_route()").
+
+3. __ipv6_ifa_notify(): Calls ip6_del_rt() which specifically checks for
+ fib6_null_entry and returns an error.
+
+[1]
+Oops: general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] SMP KASAN
+KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037]
+[...]
+Call Trace:
+<TASK>
+__kasan_check_byte (mm/kasan/common.c:573)
+lock_acquire.part.0 (kernel/locking/lockdep.c:5842 (discriminator 1))
+_raw_spin_lock_bh (kernel/locking/spinlock.c:182 (discriminator 1))
+cleanup_prefix_route (net/ipv6/addrconf.c:1280)
+ipv6_del_addr (net/ipv6/addrconf.c:1342)
+inet6_addr_del.isra.0 (net/ipv6/addrconf.c:3119)
+inet6_rtm_deladdr (net/ipv6/addrconf.c:4812)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6997)
+netlink_rcv_skb (net/netlink/af_netlink.c:2555)
+netlink_unicast (net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1899)
+__sock_sendmsg (net/socket.c:802 (discriminator 4))
+____sys_sendmsg (net/socket.c:2698)
+___sys_sendmsg (net/socket.c:2752)
+__sys_sendmsg (net/socket.c:2784)
+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)
+
+Fixes: 5eb902b8e719 ("net/ipv6: Remove expired routes with a separated list of routes.")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Reviewed-by: David Ahern <dahern@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260609145448.768318-1-idosch@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/addrconf.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index e5276be71062a3..8f8fdc9cfce224 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1264,6 +1264,7 @@ static void
+ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires,
+ bool del_rt, bool del_peer)
+ {
++ struct net *net = dev_net(ifp->idev->dev);
+ struct fib6_table *table;
+ struct fib6_info *f6i;
+
+@@ -1272,9 +1273,10 @@ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires,
+ ifp->idev->dev, 0, RTF_DEFAULT, true);
+ if (f6i) {
+ if (del_rt)
+- ip6_del_rt(dev_net(ifp->idev->dev), f6i, false);
++ ip6_del_rt(net, f6i, false);
+ else {
+- if (!(f6i->fib6_flags & RTF_EXPIRES)) {
++ if (f6i != net->ipv6.fib6_null_entry &&
++ !(f6i->fib6_flags & RTF_EXPIRES)) {
+ table = f6i->fib6_table;
+ spin_lock_bh(&table->tb6_lock);
+
+--
+2.53.0
+
--- /dev/null
+From ce6f178ffc48afac053971430712436298d1d270 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 00:34:48 -0700
+Subject: ipv6: sit: reload inner IPv6 header after GSO offloads
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f0e42f0c4337b1f220de1ddd63f47197c7dee4de ]
+
+ipip6_tunnel_xmit() caches the inner IPv6 header pointer at function
+entry and continues using it after iptunnel_handle_offloads().
+
+For GSO skbs, iptunnel_handle_offloads() calls skb_header_unclone().
+When the skb header is cloned, skb_header_unclone() can call
+pskb_expand_head(), which may move the skb head. The pskb_expand_head()
+contract requires pointers into the skb header to be reloaded after the
+call.
+
+If the later skb_realloc_headroom() branch is not taken, SIT uses the
+stale iph6 pointer to read the inner hop limit and DS field. That can
+read from a freed skb head after the old head's remaining clone is
+released.
+
+Reload iph6 after the offload helper succeeds and before subsequent
+reads from the inner IPv6 header. Keep the existing reload after
+skb_realloc_headroom(), since that branch can also replace the skb.
+
+Fixes: 14909664e4e1 ("sit: Setup and TX path for sit/UDP foo-over-udp encapsulation")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot+6eb9ca986d80f6f88cf9@syzkaller.appspotmail.com
+Link: https://patch.msgid.link/20260605073448.6524-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/sit.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index 6a7b8abb047727..7c317c105bdcbe 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -960,6 +960,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ ip_rt_put(rt);
+ goto tx_error;
+ }
++ iph6 = ipv6_hdr(skb);
+
+ if (df) {
+ mtu = dst4_mtu(&rt->dst) - t_hlen;
+--
+2.53.0
+
--- /dev/null
+From 2940c2b651745a89bb3799c1ca2567d64bf9fe27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:46:25 +0000
+Subject: net: add pskb_may_pull() to skb_gro_receive_list()
+
+From: HanQuan <eilaimemedsnaimel@gmail.com>
+
+[ Upstream commit f2bb3434544454099a5b6dec213567267b05d79d ]
+
+skb_gro_receive_list() calls skb_pull(skb, skb_gro_offset(skb)) without
+first ensuring the data is in the linear area via pskb_may_pull(). When
+the skb arrives via napi_gro_frags(), skb_headlen can be 0 (all data in
+page fragments) while skb_gro_offset is non-zero (after IP+TCP header
+parsing). The skb_pull() then decrements skb->len by skb_gro_offset
+but skb->data_len stays unchanged, hitting BUG_ON(skb->len < skb->data_len)
+in __skb_pull().
+
+The UDP fraglist GRO path already contains this guard at
+udp_offload.c:749. Adding it to skb_gro_receive_list() itself provides
+centralized protection for all callers (TCP, UDP, and any future
+protocols), and ensures the precondition of skb_pull() is satisfied
+before it is called.
+
+On pskb_may_pull() failure, set NAPI_GRO_CB(skb)->flush = 1 so the
+skb is not held as a new GRO head and is instead delivered through the
+normal receive path, matching the UDP handling.
+
+Fixes: 8d95dc474f85 ("net: add code for TCP fraglist GRO")
+Reported-by: HanQuan <eilaimemedsnaimel@gmail.com>
+Reported-by: MingXuan <bwnie0730@outlook.com>
+Signed-off-by: HanQuan <eilaimemedsnaimel@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/gro.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/core/gro.c b/net/core/gro.c
+index a847539834679c..35f2f708f01052 100644
+--- a/net/core/gro.c
++++ b/net/core/gro.c
+@@ -232,6 +232,11 @@ int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
+ if (unlikely(p->len + skb->len >= 65536))
+ return -E2BIG;
+
++ if (!pskb_may_pull(skb, skb_gro_offset(skb))) {
++ NAPI_GRO_CB(skb)->flush = 1;
++ return -ENOMEM;
++ }
++
+ if (NAPI_GRO_CB(p)->last == p)
+ skb_shinfo(p)->frag_list = skb;
+ else
+--
+2.53.0
+
--- /dev/null
+From ff50811358e8e8e1b3b305c9cc10e83aa3d62269 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 08:07:04 +0000
+Subject: net: ena: PHC: Add missing barrier
+
+From: Arthur Kiyanovski <akiyano@amazon.com>
+
+[ Upstream commit 954981dbbfbd78f21d2fbac1ac0742dbf38b4e69 ]
+
+Add dma_rmb() barrier after req_id completion check in
+ena_com_phc_get_timestamp(). On weakly-ordered architectures,
+payload fields may be read before req_id is observed as updated.
+
+Fixes: e0ea34158ee8 ("net: ena: Add PHC support in the ENA driver")
+Closes: https://sashiko.dev/#/patchset/20260430032507.11586-1-akiyano%40amazon.com
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c
+index 8c86789d867a5f..297fb36ab8c16f 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_com.c
++++ b/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -1880,6 +1880,11 @@ int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp)
+ continue;
+ }
+
++ /* Ensure PHC payload (timestamp, error_flags) is read
++ * after req_id update is observed
++ */
++ dma_rmb();
++
+ /* req_id was updated by the device which indicates that
+ * PHC timestamp and error_flags are updated too,
+ * checking errors before retrieving timestamp
+--
+2.53.0
+
--- /dev/null
+From 0fd56f6fad761355130a5b9eda5a0b4343132491 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 19:18:19 -0700
+Subject: net: guard timestamp cmsgs to real error queue skbs
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit 1ee90b77b727df903033db873c75caac5c27ec98 ]
+
+skb_is_err_queue() treats PACKET_OUTGOING as the sole marker for an skb
+from sk_error_queue. That assumption is not true for AF_PACKET sockets:
+outgoing packet taps are also delivered to packet sockets with
+skb->pkt_type == PACKET_OUTGOING, but their skb->cb is owned by AF_PACKET
+instead of struct sock_exterr_skb.
+
+If such an skb is received with timestamping enabled, the generic
+timestamp cmsg path can read AF_PACKET control-buffer state as
+sock_exterr_skb::opt_stats. With SO_RXQ_OVFL enabled, the packet drop
+counter overlaps opt_stats. An odd drop count makes the path emit
+SCM_TIMESTAMPING_OPT_STATS with skb->len and skb->data. For non-linear
+skbs this copies past the linear head and can trigger hardened usercopy or
+disclose adjacent heap contents.
+
+Keep skb_is_err_queue() local to net/socket.c, but make it verify that
+the PACKET_OUTGOING marker is paired with the sock_rmem_free destructor
+installed by sock_queue_err_skb(). AF_PACKET receive skbs use normal
+receive ownership and no longer pass as error-queue skbs, while legitimate
+sk_error_queue entries keep the PACKET_OUTGOING marker and sock_rmem_free
+ownership.
+
+Fixes: 8605330aac5a ("tcp: fix SCM_TIMESTAMPING_OPT_STATS for normal skbs")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260607021819.49698-1-kylebot@openai.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 1 +
+ net/core/skbuff.c | 6 +++---
+ net/socket.c | 11 ++++++-----
+ 3 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 6c9a83016e9551..24aab97f1bcae7 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1853,6 +1853,7 @@ struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size,
+ gfp_t priority);
+ void skb_orphan_partial(struct sk_buff *skb);
+ void sock_rfree(struct sk_buff *skb);
++void sock_rmem_free(struct sk_buff *skb);
+ void sock_efree(struct sk_buff *skb);
+ #ifdef CONFIG_INET
+ void sock_edemux(struct sk_buff *skb);
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 9edad9b88433bb..6bee1a9d128bf2 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -5474,7 +5474,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
+ }
+ EXPORT_SYMBOL_GPL(skb_cow_data);
+
+-static void sock_rmem_free(struct sk_buff *skb)
++void sock_rmem_free(struct sk_buff *skb)
+ {
+ struct sock *sk = skb->sk;
+
+@@ -5483,8 +5483,8 @@ static void sock_rmem_free(struct sk_buff *skb)
+
+ static void skb_set_err_queue(struct sk_buff *skb)
+ {
+- /* pkt_type of skbs received on local sockets is never PACKET_OUTGOING.
+- * So, it is safe to (mis)use it to mark skbs on the error queue.
++ /* The error-queue test in skb_is_err_queue() matches this marker
++ * with the sock_rmem_free destructor installed by sock_queue_err_skb().
+ */
+ skb->pkt_type = PACKET_OUTGOING;
+ BUILD_BUG_ON(PACKET_OUTGOING == 0);
+diff --git a/net/socket.c b/net/socket.c
+index 05952188127f5b..86dc88f5b76983 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -792,12 +792,13 @@ EXPORT_SYMBOL(kernel_sendmsg);
+
+ static bool skb_is_err_queue(const struct sk_buff *skb)
+ {
+- /* pkt_type of skbs enqueued on the error queue are set to
+- * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
+- * in recvmsg, since skbs received on a local socket will never
+- * have a pkt_type of PACKET_OUTGOING.
++ /* Error-queue skbs are marked as PACKET_OUTGOING in
++ * skb_set_err_queue() and use the destructor installed by
++ * sock_queue_err_skb(). PACKET_OUTGOING alone is not unique:
++ * AF_PACKET outgoing taps use the same pkt_type.
+ */
+- return skb->pkt_type == PACKET_OUTGOING;
++ return skb->pkt_type == PACKET_OUTGOING &&
++ skb->destructor == sock_rmem_free;
+ }
+
+ /* On transmit, software and hardware timestamps are returned independently.
+--
+2.53.0
+
--- /dev/null
+From 13b4960deaec9b552514fe42574be007416d6237 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 15:12:17 -0700
+Subject: net: ibm: emac: Fix use-after-free during device removal
+
+From: Rosen Penev <rosenp@gmail.com>
+
+[ Upstream commit a0130d682222ae21afc395aead7cd2d87e1a8358 ]
+
+The driver was using devm_register_netdev() which causes unregister_netdev()
+to be deferred until the devres cleanup phase, which runs after emac_remove()
+returns. This creates a use-after-free window where:
+
+1. emac_remove() is called, which tears down hardware (cancels work, detaches
+ modules, unregisters from MAL)
+2. emac_remove() returns
+3. devres cleanup runs and finally calls unregister_netdev()
+
+During step 3, the network stack might still process packets, triggering
+emac_irq(), emac_poll(), or other handlers that access now-freed hardware
+resources (dev->emacp, dev->mal, etc.).
+
+Fix this by replacing devm_register_netdev() with manual register_netdev()
+and calling unregister_netdev() at the beginning of emac_remove(), before
+any hardware teardown. This ensures the network device is fully stopped and
+unregistered before hardware resources are released.
+
+The change is safe because:
+- dev->ndev is assigned very early in probe (before any error paths that
+ could bypass emac_remove)
+- platform_set_drvdata() is only called after successful registration, so
+ emac_remove() only runs for fully registered devices
+- unregister_netdev() is idempotent and safe to call on any registered device
+
+Fixes: a4dd8535a527 ("net: ibm: emac: use devm for register_netdev")
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/emac/core.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
+index 417dfa18daae3a..4e503b3d0d2d34 100644
+--- a/drivers/net/ethernet/ibm/emac/core.c
++++ b/drivers/net/ethernet/ibm/emac/core.c
+@@ -3144,7 +3144,7 @@ static int emac_probe(struct platform_device *ofdev)
+
+ netif_carrier_off(ndev);
+
+- err = devm_register_netdev(&ofdev->dev, ndev);
++ err = register_netdev(ndev);
+ if (err) {
+ printk(KERN_ERR "%pOF: failed to register net device (%d)!\n",
+ np, err);
+@@ -3197,6 +3197,13 @@ static void emac_remove(struct platform_device *ofdev)
+
+ DBG(dev, "remove" NL);
+
++ /* Unregister network device before tearing down hardware
++ * to prevent use-after-free during deferred cleanup. This ensures
++ * the network stack stops all operations before hardware resources
++ * are released.
++ */
++ unregister_netdev(dev->ndev);
++
+ cancel_work_sync(&dev->reset_work);
+
+ if (emac_has_feature(dev, EMAC_FTR_HAS_TAH))
+--
+2.53.0
+
--- /dev/null
+From 9ac7093dbb537750052c8ab0afffa26262ddba49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 09:25:41 +0800
+Subject: net: mctp: usb: don't fail mctp_usb_rx_queue on a deferred submission
+
+From: Jeremy Kerr <jk@codeconstruct.com.au>
+
+[ Upstream commit 881a3113b74964918cdd72747e3bc119c02b0c0c ]
+
+In the ndo_open path, a deferred queue open will report a failure, and
+so the netdev will not be ndo_stop()ed, leaving us with the rx_retry
+work potentially pending.
+
+Don't report a deferred queue as an error, as we are still operational.
+This means we use the ndo_stop() path for future cleanup, which handles
+rx_retry_work cancellation.
+
+Fixes: 0791c0327a6e ("net: mctp: Add MCTP USB transport driver")
+Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
+Link: https://patch.msgid.link/20260608-dev-mctp-usb-rx-requeue-v2-2-29a3aa507609@codeconstruct.com.au
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/mctp/mctp-usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/mctp/mctp-usb.c b/drivers/net/mctp/mctp-usb.c
+index cf6f6a93a45112..fade65f2f26995 100644
+--- a/drivers/net/mctp/mctp-usb.c
++++ b/drivers/net/mctp/mctp-usb.c
+@@ -154,7 +154,7 @@ static int mctp_usb_rx_queue(struct mctp_usb *mctp_usb, gfp_t gfp)
+ if (!mctp_usb->rx_stopped)
+ schedule_delayed_work(&mctp_usb->rx_retry_work, RX_RETRY_DELAY);
+ spin_unlock_irqrestore(&mctp_usb->rx_lock, flags);
+- return rc;
++ return 0;
+ }
+
+ static void mctp_usb_in_complete(struct urb *urb)
+--
+2.53.0
+
--- /dev/null
+From c85c7bc5a3959ec1cea870cfd378a89a53700ac4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 09:25:40 +0800
+Subject: net: mctp: usb: fix race between urb completion and rx_retry
+ cancellation
+
+From: Jeremy Kerr <jk@codeconstruct.com.au>
+
+[ Upstream commit 54665dce982689e2fd99b32e9a0dcc204fda8a51 ]
+
+It's possible that sequencing between setting ->stopped and cancelling
+the rx_retry work (in ndo_stop) could leave us with an urb queued:
+
+ T1: ndo_stop T2: rx_retry_work
+ ------------ ----------------
+ LD: ->stopped => false
+ ST: ->stopped <= true
+ usb_kill_urb()
+ mctp_usb_rx_queue()
+ usb_submit_urb()
+ cancel_delayed_work_sync()
+
+That urb completion can then re-schedule rx_retry_work.
+
+Strenghen the sequencing between the stop (preventing another requeue)
+and the cancel by updating both atomically under a new rx lock. After
+setting ->rx_stopped, and cancelling pending work, we know that the
+requeue cannot occur, so all that's left is killing any pending urb.
+
+Fixes: 0791c0327a6e ("net: mctp: Add MCTP USB transport driver")
+Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
+Link: https://patch.msgid.link/20260608-dev-mctp-usb-rx-requeue-v2-1-29a3aa507609@codeconstruct.com.au
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/mctp/mctp-usb.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/mctp/mctp-usb.c b/drivers/net/mctp/mctp-usb.c
+index 3b5dff14417747..cf6f6a93a45112 100644
+--- a/drivers/net/mctp/mctp-usb.c
++++ b/drivers/net/mctp/mctp-usb.c
+@@ -22,7 +22,6 @@
+ struct mctp_usb {
+ struct usb_device *usbdev;
+ struct usb_interface *intf;
+- bool stopped;
+
+ struct net_device *netdev;
+
+@@ -32,6 +31,9 @@ struct mctp_usb {
+ struct urb *tx_urb;
+ struct urb *rx_urb;
+
++ /* enforces atomic access to rx_stopped and requeuing the retry work */
++ spinlock_t rx_lock;
++ bool rx_stopped;
+ struct delayed_work rx_retry_work;
+ };
+
+@@ -122,6 +124,7 @@ static const unsigned long RX_RETRY_DELAY = HZ / 4;
+
+ static int mctp_usb_rx_queue(struct mctp_usb *mctp_usb, gfp_t gfp)
+ {
++ unsigned long flags;
+ struct sk_buff *skb;
+ int rc;
+
+@@ -147,7 +150,10 @@ static int mctp_usb_rx_queue(struct mctp_usb *mctp_usb, gfp_t gfp)
+ return rc;
+
+ err_retry:
+- schedule_delayed_work(&mctp_usb->rx_retry_work, RX_RETRY_DELAY);
++ spin_lock_irqsave(&mctp_usb->rx_lock, flags);
++ if (!mctp_usb->rx_stopped)
++ schedule_delayed_work(&mctp_usb->rx_retry_work, RX_RETRY_DELAY);
++ spin_unlock_irqrestore(&mctp_usb->rx_lock, flags);
+ return rc;
+ }
+
+@@ -248,9 +254,6 @@ static void mctp_usb_rx_retry_work(struct work_struct *work)
+ struct mctp_usb *mctp_usb = container_of(work, struct mctp_usb,
+ rx_retry_work.work);
+
+- if (READ_ONCE(mctp_usb->stopped))
+- return;
+-
+ mctp_usb_rx_queue(mctp_usb, GFP_KERNEL);
+ }
+
+@@ -258,7 +261,7 @@ static int mctp_usb_open(struct net_device *dev)
+ {
+ struct mctp_usb *mctp_usb = netdev_priv(dev);
+
+- WRITE_ONCE(mctp_usb->stopped, false);
++ WRITE_ONCE(mctp_usb->rx_stopped, false);
+
+ netif_start_queue(dev);
+
+@@ -268,17 +271,21 @@ static int mctp_usb_open(struct net_device *dev)
+ static int mctp_usb_stop(struct net_device *dev)
+ {
+ struct mctp_usb *mctp_usb = netdev_priv(dev);
++ unsigned long flags;
+
+ netif_stop_queue(dev);
+
+ /* prevent RX submission retry */
+- WRITE_ONCE(mctp_usb->stopped, true);
++ spin_lock_irqsave(&mctp_usb->rx_lock, flags);
++ mctp_usb->rx_stopped = true;
++ cancel_delayed_work(&mctp_usb->rx_retry_work);
++ spin_unlock_irqrestore(&mctp_usb->rx_lock, flags);
++
++ flush_delayed_work(&mctp_usb->rx_retry_work);
+
+ usb_kill_urb(mctp_usb->rx_urb);
+ usb_kill_urb(mctp_usb->tx_urb);
+
+- cancel_delayed_work_sync(&mctp_usb->rx_retry_work);
+-
+ return 0;
+ }
+
+@@ -331,6 +338,7 @@ static int mctp_usb_probe(struct usb_interface *intf,
+ dev->netdev = netdev;
+ dev->usbdev = interface_to_usbdev(intf);
+ dev->intf = intf;
++ spin_lock_init(&dev->rx_lock);
+ usb_set_intfdata(intf, dev);
+
+ dev->ep_in = ep_in->bEndpointAddress;
+--
+2.53.0
+
--- /dev/null
+From b0f46b5881a472f70a2cd870f254c19fda9527bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 14:10:44 +0800
+Subject: net/mlx4: avoid GCC 10 __bad_copy_from() false positive
+
+From: Yao Sang <sangyao@kylinos.cn>
+
+[ Upstream commit 2365343f4aad3e1b1e7a2e87e98cf66d5e590589 ]
+
+mlx4_init_user_cqes() fills a scratch buffer with the CQE
+initialization pattern and then copies from that buffer to userspace.
+
+In the single-copy path, the copy length is array_size(entries,
+cqe_size), but the scratch buffer is allocated with PAGE_SIZE. GCC 10
+does not carry the branch invariant strongly enough through the object
+size checks and falsely triggers __bad_copy_from().
+
+Size the scratch buffer to the actual copy length for the active path,
+keep array_size() for the single-copy case, and retain a WARN_ON_ONCE()
+guard for the PAGE_SIZE invariant before allocating the buffer.
+
+Fixes: f69bf5dee7ef ("net/mlx4: Use array_size() helper in copy_to_user()")
+Signed-off-by: Yao Sang <sangyao@kylinos.cn>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx4/cq.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c
+index e130e7259275a3..5c55971abbf072 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
++++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
+@@ -290,6 +290,7 @@ static void mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
+ static int mlx4_init_user_cqes(void *buf, int entries, int cqe_size)
+ {
+ int entries_per_copy = PAGE_SIZE / cqe_size;
++ size_t copy_bytes;
+ void *init_ents;
+ int err = 0;
+ int i;
+@@ -314,8 +315,14 @@ static int mlx4_init_user_cqes(void *buf, int entries, int cqe_size)
+ buf += PAGE_SIZE;
+ }
+ } else {
++ copy_bytes = array_size(entries, cqe_size);
++ if (WARN_ON_ONCE(copy_bytes > PAGE_SIZE)) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ err = copy_to_user((void __user *)buf, init_ents,
+- array_size(entries, cqe_size)) ?
++ copy_bytes) ?
+ -EFAULT : 0;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From a50f4f622c6da0a064d186023bf269695caee49a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 16:58:49 +0300
+Subject: net/mlx5: Fix slab-out-of-bounds in mlx5_query_nic_vport_mac_list
+
+From: Dragos Tatulea <dtatulea@nvidia.com>
+
+[ Upstream commit 894e036a24a26a6dd7b17d8d3fb5c53ab48a6074 ]
+
+mlx5_query_nic_vport_mac_list() sizes its firmware command buffer using
+the PF's log_max_current_uc/mc_list capabilities. When querying a VF
+vport with a larger configured max (via devlink), the firmware response
+can overflow this buffer:
+
+ BUG: KASAN: slab-out-of-bounds in mlx5_query_nic_vport_mac_list+0x453/0x4c0 [mlx5_core]
+ Read of size 4 at addr ff1100013ffc8a12 by task kworker/u96:2/385
+
+ CPU: 12 UID: 0 PID: 385 Comm: kworker/u96:2 Not tainted 7.0.0-rc6+ #1 PREEMPT
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009)
+ Workqueue: mlx5_esw_wq esw_vport_change_handler [mlx5_core]
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x69/0xa0
+ print_report+0x176/0x4e4
+ kasan_report+0xc8/0x100
+ mlx5_query_nic_vport_mac_list+0x453/0x4c0 [mlx5_core]
+ esw_update_vport_addr_list+0x2e3/0xda0 [mlx5_core]
+ esw_vport_change_handle_locked+0xa1f/0x1060 [mlx5_core]
+ esw_vport_change_handler+0x6a/0x90 [mlx5_core]
+ process_one_work+0x87f/0x15e0
+ worker_thread+0x62b/0x1020
+ kthread+0x375/0x490
+ ret_from_fork+0x4dc/0x810
+ ret_from_fork_asm+0x11/0x20
+ </TASK>
+
+Fix by querying the vport's own HCA caps to size the buffer correctly.
+Refactor the function to allocate and return the MAC list internally,
+removing the caller's dependency on knowing the correct max.
+
+Fixes: e16aea2744ab ("net/mlx5: Introduce access functions to modify/query vport mac lists")
+Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
+Reviewed-by: Carolina Jubran <cjubran@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20260604135849.458060-1-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/eswitch.c | 13 +---
+ .../net/ethernet/mellanox/mlx5/core/vport.c | 72 ++++++++++++++-----
+ include/linux/mlx5/vport.h | 4 +-
+ 3 files changed, 59 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+index 7c8311f4123237..236f89a6483af1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+@@ -533,23 +533,16 @@ static void esw_update_vport_addr_list(struct mlx5_eswitch *esw,
+ struct mlx5_vport *vport, int list_type)
+ {
+ bool is_uc = list_type == MLX5_NVPRT_LIST_TYPE_UC;
+- u8 (*mac_list)[ETH_ALEN];
++ u8 (*mac_list)[ETH_ALEN] = NULL;
+ struct l2addr_node *node;
+ struct vport_addr *addr;
+ struct hlist_head *hash;
+ struct hlist_node *tmp;
+- int size;
++ int size = 0;
+ int err;
+ int hi;
+ int i;
+
+- size = is_uc ? MLX5_MAX_UC_PER_VPORT(esw->dev) :
+- MLX5_MAX_MC_PER_VPORT(esw->dev);
+-
+- mac_list = kcalloc(size, ETH_ALEN, GFP_KERNEL);
+- if (!mac_list)
+- return;
+-
+ hash = is_uc ? vport->uc_list : vport->mc_list;
+
+ for_each_l2hash_node(node, tmp, hash, hi) {
+@@ -561,7 +554,7 @@ static void esw_update_vport_addr_list(struct mlx5_eswitch *esw,
+ goto out;
+
+ err = mlx5_query_nic_vport_mac_list(esw->dev, vport->vport, list_type,
+- mac_list, &size);
++ &mac_list, &size);
+ if (err)
+ goto out;
+ esw_debug(esw->dev, "vport[%d] context update %s list size (%d)\n",
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+index 4effe37fd4552e..d63b0e8806b544 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+@@ -324,35 +324,63 @@ int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu)
+ }
+ EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mtu);
+
++static int mlx5_vport_max_mac_list_size(struct mlx5_core_dev *dev, u16 vport,
++ enum mlx5_list_type list_type)
++{
++ void *query_ctx, *hca_caps;
++ int ret = 0;
++
++ if (!vport && !mlx5_core_is_ecpf(dev))
++ return list_type == MLX5_NVPRT_LIST_TYPE_UC ?
++ 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
++ 1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
++
++ query_ctx = kzalloc(MLX5_ST_SZ_BYTES(query_hca_cap_out), GFP_KERNEL);
++ if (!query_ctx)
++ return -ENOMEM;
++
++ ret = mlx5_vport_get_other_func_general_cap(dev, vport, query_ctx);
++ if (ret)
++ goto out;
++
++ hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
++ ret = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
++ 1 << MLX5_GET(cmd_hca_cap, hca_caps, log_max_current_uc_list) :
++ 1 << MLX5_GET(cmd_hca_cap, hca_caps, log_max_current_mc_list);
++
++out:
++ kfree(query_ctx);
++
++ return ret;
++}
++
+ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+ u16 vport,
+ enum mlx5_list_type list_type,
+- u8 addr_list[][ETH_ALEN],
+- int *list_size)
++ u8 (**addr_list)[ETH_ALEN],
++ int *addr_list_size)
+ {
+ u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
++ int allowed_list_size;
+ void *nic_vport_ctx;
+ int max_list_size;
+- int req_list_size;
+ int out_sz;
+ void *out;
+ int err;
+ int i;
+
+- req_list_size = *list_size;
++ if (!addr_list || !addr_list_size)
++ return -EINVAL;
+
+- max_list_size = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
+- 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
+- 1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
++ *addr_list = NULL;
++ *addr_list_size = 0;
+
+- if (req_list_size > max_list_size) {
+- mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
+- req_list_size, max_list_size);
+- req_list_size = max_list_size;
+- }
++ max_list_size = mlx5_vport_max_mac_list_size(dev, vport, list_type);
++ if (max_list_size < 0)
++ return max_list_size;
+
+ out_sz = MLX5_ST_SZ_BYTES(query_nic_vport_context_out) +
+- req_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
++ max_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
+
+ out = kvzalloc(out_sz, GFP_KERNEL);
+ if (!out)
+@@ -371,16 +399,24 @@ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+
+ nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
+ nic_vport_context);
+- req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
+- allowed_list_size);
++ allowed_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
++ allowed_list_size);
++ if (!allowed_list_size)
++ goto out;
++
++ *addr_list = kcalloc(allowed_list_size, ETH_ALEN, GFP_KERNEL);
++ if (!*addr_list) {
++ err = -ENOMEM;
++ goto out;
++ }
+
+- *list_size = req_list_size;
+- for (i = 0; i < req_list_size; i++) {
++ for (i = 0; i < allowed_list_size; i++) {
+ u8 *mac_addr = MLX5_ADDR_OF(nic_vport_context,
+ nic_vport_ctx,
+ current_uc_mac_address[i]) + 2;
+- ether_addr_copy(addr_list[i], mac_addr);
++ ether_addr_copy((*addr_list)[i], mac_addr);
+ }
++ *addr_list_size = allowed_list_size;
+ out:
+ kvfree(out);
+ return err;
+diff --git a/include/linux/mlx5/vport.h b/include/linux/mlx5/vport.h
+index dfa2fe32217af0..282ed54422826d 100644
+--- a/include/linux/mlx5/vport.h
++++ b/include/linux/mlx5/vport.h
+@@ -102,8 +102,8 @@ int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *dev,
+ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
+ u16 vport,
+ enum mlx5_list_type list_type,
+- u8 addr_list[][ETH_ALEN],
+- int *list_size);
++ u8 (**mac_list)[ETH_ALEN],
++ int *mac_list_size);
+ int mlx5_modify_nic_vport_mac_list(struct mlx5_core_dev *dev,
+ enum mlx5_list_type list_type,
+ u8 addr_list[][ETH_ALEN],
+--
+2.53.0
+
--- /dev/null
+From b2cb61630edda856a2103585919881859434ae4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 18:21:12 +0800
+Subject: net/mlx5: Use effective affinity mask for IRQ selection
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fushuai Wang <wangfushuai@baidu.com>
+
+[ Upstream commit a7767290e77ca2e926b49f8bfa29daa12262c612 ]
+
+When a sf is created after a CPU has been taken offline, the IRQ pool may
+contain IRQs with affinity masks that include the offline CPU. Since only
+online CPUs should be considered for IRQ placement, cpumask_subset() check
+would fail because the iter_mask contains offline CPUs that are not present
+in req_mask, causing sf creation to fail.
+
+This is an example:
+ 1. When mlx5 driver loads, it initializes the IRQ pools.
+ For sf_ctrl_pool with ≤64 sf:
+ - xa_num_irqs = {N, N} (There is only one slot)
+ 2. When the first SF is created:
+ - The ctrl IRQ is allocated with mask=cpu_online_mask={0-191}
+ 2. We take CPU 20 offline
+ 3. Existing ctl irq still have mask={0-191}
+ 4. Create a new SF:
+ - req_mask={0-19,21-191}
+ - iter_mask={0-191}
+ - {0-191} is NOT a subset of {0-19,21-191}
+ - least_loaded_irq=NULL
+ 5. Try to allocate a new irq via irq_pool_request_irq()
+ 6. xa_alloc() fails because the pool is full(There is only one slot)
+ 7. sf creation fails with error
+
+Use irq_get_effective_affinity_mask() instead, which returns the IRQ's
+actual effective affinity that already excludes offline CPUs.
+
+Fixes: 061f5b23588a ("net/mlx5: SF, Use all available cpu for setting cpu affinity")
+Suggested-by: Shay Drory <shayd@nvidia.com>
+Signed-off-by: Fushuai Wang <wangfushuai@baidu.com>
+Reviewed-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20260605102112.91772-1-fushuai.wang@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c b/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
+index 994fe83da4bed8..a0bb8ee44e3550 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
+@@ -105,9 +105,12 @@ irq_pool_find_least_loaded(struct mlx5_irq_pool *pool, const struct cpumask *req
+
+ lockdep_assert_held(&pool->lock);
+ xa_for_each_range(&pool->irqs, index, iter, start, end) {
+- struct cpumask *iter_mask = mlx5_irq_get_affinity_mask(iter);
+ int iter_refcount = mlx5_irq_read_locked(iter);
++ const struct cpumask *iter_mask;
+
++ iter_mask = irq_get_effective_affinity_mask(mlx5_irq_get_irq(iter));
++ if (!iter_mask)
++ continue;
+ if (!cpumask_subset(iter_mask, req_mask))
+ /* skip IRQs with a mask which is not subset of req_mask */
+ continue;
+--
+2.53.0
+
--- /dev/null
+From b1452b361dcc5a15cc0de478d648f6f95b953067 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 16:54:46 +0300
+Subject: net/mlx5e: xsk: Fix DMA and xdp_frame leak on XDP_TX xmit failure
+
+From: Dragos Tatulea <dtatulea@nvidia.com>
+
+[ Upstream commit b69004f5a6ad32da84d8aa5b23b9c0caafe6252e ]
+
+In the XSK branch of mlx5e_xmit_xdp_buff(), when sq->xmit_xdp_frame()
+returns false (e.g. XDPSQ is full), the function returns without
+unmapping the DMA address or freeing the xdp_frame allocated by
+xdp_convert_zc_to_xdp_frame(). The xdpi_fifo push only happens on
+success, so the completion path cannot recover these entries.
+
+With CONFIG_DMA_API_DEBUG=y, the leak surfaces on driver unbind:
+
+ DMA-API: pci 0000:08:00.0: device driver has pending DMA
+ allocations while released from device [count=1116]
+ One of leaked entries details: [device address=0x000000010ffd7028]
+ [size=1534 bytes] [mapped with DMA_TO_DEVICE] [mapped as phy]
+ WARNING: kernel/dma/debug.c:881 at dma_debug_device_change+0x127/0x180
+ ...
+ DMA-API: Mapped at:
+ debug_dma_map_phys+0x4b/0xd0
+ dma_map_phys+0xfd/0x2d0
+ mlx5e_xdp_handle+0x5ae/0xac0 [mlx5_core]
+ mlx5e_xsk_skb_from_cqe_mpwrq_linear+0xc4/0x170 [mlx5_core]
+ mlx5e_handle_rx_cqe_mpwrq+0xc1/0x290 [mlx5_core]
+
+Add the missing unmap + xdp_return_frame, matching the cleanup already
+done in mlx5e_xdp_xmit(). has_frags is rejected earlier in this branch,
+so no per-frag unmap is needed.
+
+Fixes: 84a0a2310d6d ("net/mlx5e: XDP_TX from UMEM support")
+Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20260604135446.456119-1-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
+index 80f9fc10877ad9..7b335da1d0cd22 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
+@@ -102,9 +102,15 @@ mlx5e_xmit_xdp_buff(struct mlx5e_xdpsq *sq, struct mlx5e_rq *rq,
+
+ xdptxd->dma_addr = dma_addr;
+
+- if (unlikely(!INDIRECT_CALL_2(sq->xmit_xdp_frame, mlx5e_xmit_xdp_frame_mpwqe,
+- mlx5e_xmit_xdp_frame, sq, xdptxd, 0, NULL)))
++ if (unlikely(!INDIRECT_CALL_2(sq->xmit_xdp_frame,
++ mlx5e_xmit_xdp_frame_mpwqe,
++ mlx5e_xmit_xdp_frame,
++ sq, xdptxd, 0, NULL))) {
++ dma_unmap_single(sq->pdev, dma_addr, xdptxd->len,
++ DMA_TO_DEVICE);
++ xdp_return_frame(xdpf);
+ return false;
++ }
+
+ /* xmit_mode == MLX5E_XDP_XMIT_MODE_FRAME */
+ mlx5e_xdpi_fifo_push(&sq->db.xdpi_fifo,
+--
+2.53.0
+
--- /dev/null
+From 5615c6fe2fbad464d9710785da99848ee3f5994e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:43 +0200
+Subject: net: mvpp2: build skb from XDP-adjusted data on XDP_PASS
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 77a6b90ce56bc982dcfa94229b8e28e6abb16e95 ]
+
+When an XDP program uses bpf_xdp_adjust_head() or bpf_xdp_adjust_tail()
+and then returns XDP_PASS, mvpp2 still builds the skb from fixed offsets
+derived from the original RX descriptor. Packet geometry changes made by
+the XDP program are therefore discarded before the skb reaches the stack.
+
+Update rx_offset and rx_bytes from xdp.data and xdp.data_end for
+XDP_PASS. This makes skb_reserve() and skb_put() reflect the packet seen
+by XDP, and makes RX byte accounting for XDP_PASS follow the length of the
+skb passed to the network stack.
+
+Keep a separate rx_sync_size for page-pool recycling on skb allocation
+failure, which must stay tied to the received buffer range.
+
+Non-PASS verdicts continue to account the descriptor length because no skb
+is passed up in those cases.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-5-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 21 +++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 481daafdc1cbc7..ccc24a1301f22d 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3917,10 +3917,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ struct mvpp2_bm_pool *bm_pool;
+ struct page_pool *pp = NULL;
+ struct sk_buff *skb;
+- unsigned int frag_size;
++ unsigned int frag_size, rx_sync_size;
+ dma_addr_t dma_addr;
+ phys_addr_t phys_addr;
+- int pool, rx_bytes, err, ret;
++ int pool, rx_bytes, rx_offset, err, ret;
+ struct page *page;
+ void *data;
+
+@@ -3933,6 +3933,8 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ rx_status = mvpp2_rxdesc_status_get(port, rx_desc);
+ rx_bytes = mvpp2_rxdesc_size_get(port, rx_desc);
+ rx_bytes -= MVPP2_MH_SIZE;
++ rx_sync_size = rx_bytes + MVPP2_MH_SIZE;
++ rx_offset = MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM;
+ dma_addr = mvpp2_rxdesc_dma_addr_get(port, rx_desc);
+
+ pool = (rx_status & MVPP2_RXD_BM_POOL_ID_MASK) >>
+@@ -3948,7 +3950,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
+ MVPP2_SKB_HEADROOM,
+- rx_bytes + MVPP2_MH_SIZE,
++ rx_sync_size,
+ dma_dir);
+
+ /* Buffer header not supported */
+@@ -3999,6 +4001,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ continue;
+ }
+
++ rx_sync_size = max_t(unsigned int, rx_sync_size,
++ xdp.data_end - xdp.data_hard_start -
++ MVPP2_SKB_HEADROOM);
++
++ /* Update offset and length to reflect any XDP adjustments. */
++ rx_offset = xdp.data - data;
++ rx_bytes = xdp.data_end - xdp.data;
++
+ metasize = xdp.data - xdp.data_meta;
+ }
+
+@@ -4010,8 +4020,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ netdev_warn(port->dev, "skb build failed\n");
+ if (pp) {
+ page_pool_put_page(pp, virt_to_head_page(data),
+- rx_bytes + MVPP2_MH_SIZE,
+- true);
++ rx_sync_size, true);
+ } else {
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size,
+@@ -4041,7 +4050,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
+
+- skb_reserve(skb, MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM);
++ skb_reserve(skb, rx_offset);
+ skb_put(skb, rx_bytes);
+ if (metasize)
+ skb_metadata_set(skb, metasize);
+--
+2.53.0
+
--- /dev/null
+From 614f1b384b5f87656cff2dae69d78105cb0efa1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:41 +0200
+Subject: net: mvpp2: limit XDP frame size to the RX buffer
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit f3c6aa078927e6fe8121c9c591ddee8716c5305a ]
+
+mvpp2 has short and long BM pools, and short pool buffers can be smaller
+than PAGE_SIZE. The XDP path nevertheless initializes every xdp_buff with
+PAGE_SIZE as frame size.
+
+XDP helpers use frame_sz to validate tail growth and to derive the hard
+end of the data area. Advertising PAGE_SIZE for short buffers can let
+bpf_xdp_adjust_tail() grow a packet past the real allocation, corrupting
+memory or later tripping skb tailroom checks.
+
+Initialize the XDP buffer with bm_pool->frag_size so XDP tailroom matches
+the actual buffer backing the packet.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-3-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 92a701f4fe3f57..3372ed27cc8d67 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3979,7 +3979,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ else
+ xdp_rxq = &rxq->xdp_rxq_long;
+
+- xdp_init_buff(&xdp, PAGE_SIZE, xdp_rxq);
++ xdp_init_buff(&xdp, bm_pool->frag_size, xdp_rxq);
+ xdp_prepare_buff(&xdp, data,
+ MVPP2_MH_SIZE + MVPP2_SKB_HEADROOM,
+ rx_bytes, true);
+--
+2.53.0
+
--- /dev/null
+From 559275ddbc5d21bdaf4cc0c25b3ec1840c00cc02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:42 +0200
+Subject: net: mvpp2: refill RX buffers before XDP or skb use
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 5e8e2a9624df72fca7c736b2966b2cbf6c9c3ff6 ]
+
+The RX error path returns the current descriptor buffer to the hardware
+BM pool. That is only valid while the driver still owns the buffer.
+
+mvpp2_rx_refill() can fail after the current buffer has been handed to
+XDP or attached to an skb. In those cases mvpp2_run_xdp() may have
+recycled, redirected, or queued the page for XDP_TX, and an skb free also
+retires the data buffer. Returning such a buffer to BM lets hardware DMA
+into memory that is no longer owned by the RX ring.
+
+Refill the BM pool before handing the current buffer to XDP or to the
+skb. If the allocation fails there, drop the packet and return the
+still-owned current buffer to BM, preserving the pool depth. Once the
+refill succeeds, later local drops retire/free the current buffer instead
+of returning it to BM.
+
+Fixes: 07dd0a7aae7f ("mvpp2: add basic XDP support")
+Fixes: d6526926de73 ("net: mvpp2: fix memory leak in mvpp2_rx")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-4-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 43 +++++++++++--------
+ 1 file changed, 24 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index 3372ed27cc8d67..481daafdc1cbc7 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3971,6 +3971,12 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ else
+ frag_size = bm_pool->frag_size;
+
++ err = mvpp2_rx_refill(port, bm_pool, pp, pool);
++ if (err) {
++ netdev_err(port->dev, "failed to refill BM pools\n");
++ goto err_drop_frame;
++ }
++
+ if (xdp_prog) {
+ struct xdp_rxq_info *xdp_rxq;
+
+@@ -3988,12 +3994,6 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+
+ if (ret) {
+ xdp_ret |= ret;
+- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+- if (err) {
+- netdev_err(port->dev, "failed to refill BM pools\n");
+- goto err_drop_frame;
+- }
+-
+ ps.rx_packets++;
+ ps.rx_bytes += rx_bytes;
+ continue;
+@@ -4008,8 +4008,21 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ skb = slab_build_skb(data);
+ if (!skb) {
+ netdev_warn(port->dev, "skb build failed\n");
+- goto err_drop_frame;
++ if (pp) {
++ page_pool_put_page(pp, virt_to_head_page(data),
++ rx_bytes + MVPP2_MH_SIZE,
++ true);
++ } else {
++ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
++ bm_pool->buf_size,
++ DMA_FROM_DEVICE,
++ DMA_ATTR_SKIP_CPU_SYNC);
++ mvpp2_frag_free(bm_pool, pp, data);
++ }
++ goto err_drop_frame_retired;
+ }
++ if (pp)
++ skb_mark_for_recycle(skb);
+
+ /* If we have RX hardware timestamping enabled, grab the
+ * timestamp from the queue and convert.
+@@ -4020,16 +4033,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ skb_hwtstamps(skb));
+ }
+
+- err = mvpp2_rx_refill(port, bm_pool, pp, pool);
+- if (err) {
+- netdev_err(port->dev, "failed to refill BM pools\n");
+- dev_kfree_skb_any(skb);
+- goto err_drop_frame;
+- }
+-
+- if (pp)
+- skb_mark_for_recycle(skb);
+- else
++ if (!pp)
+ dma_unmap_single_attrs(dev->dev.parent, dma_addr,
+ bm_pool->buf_size, DMA_FROM_DEVICE,
+ DMA_ATTR_SKIP_CPU_SYNC);
+@@ -4048,13 +4052,14 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ continue;
+
+ err_drop_frame:
+- dev->stats.rx_errors++;
+- mvpp2_rx_error(port, rx_desc);
+ /* Return the buffer to the pool */
+ if (rx_status & MVPP2_RXD_BUF_HDR)
+ mvpp2_buff_hdr_pool_put(port, rx_desc, pool, rx_status);
+ else
+ mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);
++err_drop_frame_retired:
++ dev->stats.rx_errors++;
++ mvpp2_rx_error(port, rx_desc);
+ }
+
+ if (xdp_ret & MVPP2_XDP_REDIR)
+--
+2.53.0
+
--- /dev/null
+From b0962a4c4512de840d5615e7a35df7f05890fda6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 15:49:40 +0200
+Subject: net: mvpp2: sync RX data at the hardware packet offset
+
+From: Til Kaiser <mail@tk154.de>
+
+[ Upstream commit 180235600934bef6add3be637c296d6cf3272e67 ]
+
+mvpp2 programs the RX queue packet offset, so hardware writes received
+data at dma_addr + MVPP2_SKB_HEADROOM. The current CPU sync starts at
+dma_addr and only covers rx_bytes + MVPP2_MH_SIZE bytes, which syncs the
+unused headroom and misses the same number of bytes at the packet tail.
+
+On non-coherent DMA systems this can leave the CPU reading stale cache
+contents for the end of the received frame.
+
+Use dma_sync_single_range_for_cpu() with MVPP2_SKB_HEADROOM as the range
+offset so the sync covers the Marvell header and packet data actually
+written by hardware.
+
+Fixes: e1921168bbd4 ("mvpp2: sync only the received frame")
+Signed-off-by: Til Kaiser <mail@tk154.de>
+Link: https://patch.msgid.link/20260607134943.21996-2-mail@tk154.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index f442b874bb5933..92a701f4fe3f57 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -3946,9 +3946,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
+ dma_dir = DMA_FROM_DEVICE;
+ }
+
+- dma_sync_single_for_cpu(dev->dev.parent, dma_addr,
+- rx_bytes + MVPP2_MH_SIZE,
+- dma_dir);
++ dma_sync_single_range_for_cpu(dev->dev.parent, dma_addr,
++ MVPP2_SKB_HEADROOM,
++ rx_bytes + MVPP2_MH_SIZE,
++ dma_dir);
+
+ /* Buffer header not supported */
+ if (rx_status & MVPP2_RXD_BUF_HDR)
+--
+2.53.0
+
--- /dev/null
+From 1b070ebb6b604159173156dc76e94f783122eda7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:19:46 +0200
+Subject: net: openvswitch: fix possible kfree_skb of ERR_PTR
+
+From: Adrian Moreno <amorenoz@redhat.com>
+
+[ Upstream commit ee30dd2909d8b98619f4341c70ec8dc8e155ab02 ]
+
+After the patch in the "Fixes" tag, the allocation of the "reply" skb
+can happen either before or after locking the ovs_mutex.
+
+However, error cleanups still follow the classical reversed order,
+assuming "reply" is allocated before locking: it is freed after unlocking.
+
+If "reply" allocation happens after locking the mutex and it fails,
+"reply" is left with an ERR_PTR, and execution jumps to the correspondent
+cleanup stage which will try to free an invalid pointer.
+
+Fix this by setting the pointer to NULL after having saved its error
+value.
+
+Fixes: 893f139b9a6c ("openvswitch: Minimize ovs_flow_cmd_new|set critical sections.")
+Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Acked-by: Eelco Chaudron <echaudro@redhat.com>
+Link: https://patch.msgid.link/20260604121946.942164-1-amorenoz@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/datapath.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index bbbde50fc6498f..f0164817d9b723 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -1316,6 +1316,7 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
+
+ if (IS_ERR(reply)) {
+ error = PTR_ERR(reply);
++ reply = NULL;
+ goto err_unlock_ovs;
+ }
+ }
+--
+2.53.0
+
--- /dev/null
+From 6afd28acc1d6b6f29918404aa0ed64c8c209551c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 11:28:17 +0200
+Subject: net: phy: Clean the phy_ports after unregistering the downstream SFP
+ bus
+
+From: Maxime Chevallier <maxime.chevallier@bootlin.com>
+
+[ Upstream commit 4497f5028675b7e51c4aa59c3f4df01f29424277 ]
+
+As reported by sashiko when looking a other patches, we need to ensure
+that the downstream SFP bus gets unregistered prior to destroying the
+phy_ports attached to a phy_device, as the SFP code may reference these
+ports. Let's make sure we follow that ordering in phy_remove().
+
+Fixes: 589e934d2735 ("net: phy: Introduce PHY ports representation")
+Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
+Link: https://patch.msgid.link/20260604092819.723505-4-maxime.chevallier@bootlin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/phy_device.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 111e3f3deb96f4..8b7e2789047694 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -3822,11 +3822,11 @@ static int phy_remove(struct device *dev)
+
+ phydev->state = PHY_DOWN;
+
+- phy_cleanup_ports(phydev);
+-
+ sfp_bus_del_upstream(phydev->sfp_bus);
+ phydev->sfp_bus = NULL;
+
++ phy_cleanup_ports(phydev);
++
+ if (phydev->drv && phydev->drv->remove)
+ phydev->drv->remove(phydev);
+
+--
+2.53.0
+
--- /dev/null
+From bc47612d50e91f840059a96d3c83160fb26c7517 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 11:28:15 +0200
+Subject: net: phy: clean the sfp upstream if phy probing fails
+
+From: Maxime Chevallier <maxime.chevallier@bootlin.com>
+
+[ Upstream commit 48774e87bbaa0056819d4b52301e4692e50e3252 ]
+
+Sashiko reported that we don't call sfp_bus_del_upstream() in the probe
+failure path, so let's add it, otherwise the sfp-bus is left with a
+dangling 'upstream' field, that may be used later on during SFP events.
+
+This issue existed before the generic phylib sfp support, back when
+drivers were calling phy_sfp_probe themselves.
+
+Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
+Fixes: 298e54fa810e ("net: phy: add core phylib sfp support")
+Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260604092819.723505-2-maxime.chevallier@bootlin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/phy_device.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index cfb505ed9a3a09..c6722592f8672a 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -1710,6 +1710,9 @@ static int phy_sfp_probe(struct phy_device *phydev)
+
+ ret = sfp_bus_add_upstream(bus, phydev, &sfp_phydev_ops);
+ sfp_bus_put(bus);
++
++ if (ret)
++ phydev->sfp_bus = NULL;
+ }
+
+ if (!ret && phydev->sfp_bus)
+@@ -3791,6 +3794,9 @@ static int phy_probe(struct device *dev)
+ return 0;
+
+ out:
++ sfp_bus_del_upstream(phydev->sfp_bus);
++ phydev->sfp_bus = NULL;
++
+ if (!phydev->is_on_sfp_module)
+ phy_led_triggers_unregister(phydev);
+
+--
+2.53.0
+
--- /dev/null
+From 97d8c58c01eae5fc002c5a43dc1631a553c087c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 11:28:18 +0200
+Subject: net: phy: don't try to setup PHY-driven SFP cages when using genphy
+
+From: Maxime Chevallier <maxime.chevallier@bootlin.com>
+
+[ Upstream commit 5a0082ec20a05ef2378410323a5089a8f1786f4a ]
+
+We don't have support for PHY-driver SFP cages with the genphy code.
+
+On top of that, it was found by sashiko that running
+sfp_bus_add_upstream() for genphy deadlocks, as for genphy the PHY
+probing runs under RTNL, which isn't the case for non-genphy drivers.
+
+This problem was reproduced, and does lead to a deadlock on RTNL.
+
+Before the blamed commit, the phy_sfp_probe() call was made by
+individual PHY drivers, so there was no way to get to the SFP probing
+path when using genphy.
+
+Let's therefore only run phy_sfp_probe when not using genphy.
+
+Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
+Fixes: bad869b5e41a ("net: phy: Only rely on phy_port for PHY-driven SFP")
+Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260604092819.723505-5-maxime.chevallier@bootlin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/phy_device.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 8b7e2789047694..830d6fb36c6409 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -3528,9 +3528,15 @@ static int phy_setup_ports(struct phy_device *phydev)
+ if (ret)
+ return ret;
+
+- ret = phy_sfp_probe(phydev);
+- if (ret)
+- goto out;
++ /* We don't support SFP with genphy drivers. Also, genphy driver
++ * binding occurs with RTNL help, which will deadlock the call to
++ * sfp_bus_add_upstream().
++ */
++ if (!phydev->is_genphy_driven) {
++ ret = phy_sfp_probe(phydev);
++ if (ret)
++ goto out;
++ }
+
+ if (phydev->n_ports < phydev->max_n_ports) {
+ ret = phy_default_setup_single_port(phydev);
+--
+2.53.0
+
--- /dev/null
+From 5d92776cc8b479b32a6ac9d764f514b81be9ce14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 11:28:16 +0200
+Subject: net: phy: remove phy ports upon probe failure
+
+From: Maxime Chevallier <maxime.chevallier@bootlin.com>
+
+[ Upstream commit b1e780bb37c641d8291c51d7b4bde33450d18fb4 ]
+
+When phy_probe fails, let's clean the phy_ports that were successfully
+added already.
+
+Suggested-by: Nicolai Buchwitz <nb@tipi-net.de>
+Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
+Fixes: 589e934d2735 ("net: phy: Introduce PHY ports representation")
+Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260604092819.723505-3-maxime.chevallier@bootlin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/phy_device.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index c6722592f8672a..111e3f3deb96f4 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -3797,6 +3797,8 @@ static int phy_probe(struct device *dev)
+ sfp_bus_del_upstream(phydev->sfp_bus);
+ phydev->sfp_bus = NULL;
+
++ phy_cleanup_ports(phydev);
++
+ if (!phydev->is_on_sfp_module)
+ phy_led_triggers_unregister(phydev);
+
+--
+2.53.0
+
--- /dev/null
+From 452284d6b3a327c53b50eb86dfed367ee776d6b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 14:48:01 +0800
+Subject: net: qrtr: fix refcount saturation and potential UAF in
+ qrtr_port_remove
+
+From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+
+[ Upstream commit a2171131ecda1ed61a594a1eb715e75fdad0fef5 ]
+
+In qrtr_port_remove(), the socket reference count is decremented via
+__sock_put() before the port is removed from the qrtr_ports XArray and
+before the RCU grace period elapses.
+
+This breaks the fundamental RCU update paradigm. It exposes a race
+window where a concurrent RCU reader (such as qrtr_reset_ports() or
+qrtr_port_lookup()) can obtain a pointer to the socket from the XArray,
+and attempt to call sock_hold() on a socket whose reference count has
+already dropped to zero.
+
+This exact race condition was hit during syzkaller fuzzing, leading to
+the following refcount saturation warning and a potential Use-After-Free:
+
+ refcount_t: saturated; leaking memory.
+ WARNING: CPU: 3 PID: 1273 at lib/refcount.c:22 refcount_warn_saturate+0xae/0x1d0
+ Modules linked in: qrtr(+) bochs drm_shmem_helper ...
+ Call Trace:
+ <TASK>
+ qrtr_reset_ports net/qrtr/af_qrtr.c:768 [inline] [qrtr]
+ __qrtr_bind.isra.0+0x48b/0x570 net/qrtr/af_qrtr.c:805 [qrtr]
+ qrtr_bind+0x17d/0x210 net/qrtr/af_qrtr.c:901 [qrtr]
+ kernel_bind+0xe4/0x120 net/socket.c:3592
+ qrtr_ns_init+0x1a6/0x380 net/qrtr/ns.c:715 [qrtr]
+ qrtr_proto_init+0x3b/0xff0 net/qrtr/af_qrtr.c:169 [qrtr]
+ do_one_initcall+0xf5/0x5e0 init/main.c:1283
+ ...
+ </TASK>
+
+Fix this by deferring the reference count decrement until after the
+xa_erase() and the synchronize_rcu() complete.
+
+(Note: The v1 of this patch incorrectly replaced __sock_put() with
+sock_put(). As Simon Horman pointed out, the callers of qrtr_port_remove()
+still hold a reference to the socket, so freeing the socket memory here
+would lead to a subsequent UAF in the caller. Thus, the __sock_put() is
+kept, but only repositioned to close the RCU race.)
+
+Fixes: bdabad3e363d ("net: Add Qualcomm IPC router")
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260604064801.1180388-1-w15303746062@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/af_qrtr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c
+index d77e9c8212da51..7087bb57aeac18 100644
+--- a/net/qrtr/af_qrtr.c
++++ b/net/qrtr/af_qrtr.c
+@@ -707,13 +707,13 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
+ if (port == QRTR_PORT_CTRL)
+ port = 0;
+
+- __sock_put(&ipc->sk);
+-
+ xa_erase(&qrtr_ports, port);
+
+ /* Ensure that if qrtr_port_lookup() did enter the RCU read section we
+ * wait for it to up increment the refcount */
+ synchronize_rcu();
++
++ __sock_put(&ipc->sk);
+ }
+
+ /* Assign port number to socket.
+--
+2.53.0
+
--- /dev/null
+From 6b7b8f533ec34b37273a19bd70c62734ea45388f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 12:24:48 -0700
+Subject: net/rds: fix NULL deref in rds_ib_send_cqe_handler() on masked atomic
+ completion
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 34080db3e70ddf94c38512ad2331e3c3afca6cc1 ]
+
+rds_ib_xmit_atomic() always programs a masked atomic opcode
+(IB_WR_MASKED_ATOMIC_CMP_AND_SWP or IB_WR_MASKED_ATOMIC_FETCH_AND_ADD)
+for every RDS atomic cmsg. But the completion-side switch in
+rds_ib_send_unmap_op() only handles the non-masked opcodes, so a masked
+atomic completion falls through to default and returns rm == NULL while
+send->s_op is left set. rds_ib_send_cqe_handler() then dereferences the
+NULL rm via rm->m_final_op, oopsing in softirq context. An unprivileged
+AF_RDS sendmsg() of an atomic cmsg over an active RDS/IB connection
+triggers it; on hardware that natively accepts masked atomics (mlx4,
+mlx5) no extra setup is needed.
+
+ RDS/IB: rds_ib_send_unmap_op: unexpected opcode 0xd in WR!
+ Oops: general protection fault [#1] SMP KASAN
+ KASAN: null-ptr-deref in range [0x0000000000000190-0x0000000000000197]
+ RIP: rds_ib_send_cqe_handler+0x25c/0xb10 (net/rds/ib_send.c:282)
+ Call Trace:
+ <IRQ>
+ rds_ib_send_cqe_handler (net/rds/ib_send.c:282)
+ poll_scq (net/rds/ib_cm.c:274)
+ rds_ib_tasklet_fn_send (net/rds/ib_cm.c:294)
+ tasklet_action_common (kernel/softirq.c:943)
+ handle_softirqs (kernel/softirq.c:573)
+ run_ksoftirqd (kernel/softirq.c:479)
+ </IRQ>
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Handle the masked atomic opcodes in the same case as the non-masked
+ones: they map to the same struct rds_message.atomic union member, so
+the existing container_of()/rds_ib_send_unmap_atomic() body is correct
+for them.
+
+Fixes: 20c72bd5f5f9 ("RDS: Implement masked atomic operations")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260606192447.1179255-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/ib_send.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
+index fcd04c29f543e6..d6be95542119f6 100644
+--- a/net/rds/ib_send.c
++++ b/net/rds/ib_send.c
+@@ -170,6 +170,8 @@ static struct rds_message *rds_ib_send_unmap_op(struct rds_ib_connection *ic,
+ break;
+ case IB_WR_ATOMIC_FETCH_AND_ADD:
+ case IB_WR_ATOMIC_CMP_AND_SWP:
++ case IB_WR_MASKED_ATOMIC_FETCH_AND_ADD:
++ case IB_WR_MASKED_ATOMIC_CMP_AND_SWP:
+ if (send->s_op) {
+ rm = container_of(send->s_op, struct rds_message, atomic);
+ rds_ib_send_unmap_atomic(ic, send->s_op, wc_status);
+--
+2.53.0
+
--- /dev/null
+From 7b234ebc79398ffceadc1a23bb744157de5c3b03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 15:08:41 +0800
+Subject: net: txgbe: distinguish module types by checking identifier
+
+From: Jiawen Wu <jiawenwu@trustnetic.com>
+
+[ Upstream commit f2df54ddbfb04a006ee326a5d8270434a414e0af ]
+
+Rework txgbe_identify_module() to validate module identifiers through
+explicit type checks instead of relying on transceiver_type heuristics.
+When using the SFP module, transceiver_type could be a random value,
+because it was read from an invalid register.
+
+Fixes: 57d39faed4c9 ("net: txgbe: improve functions of AML 40G devices")
+Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
+Link: https://patch.msgid.link/20260608070842.36504-3-jiawenwu@trustnetic.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+index a7e81f9e1be148..bdac654a236465 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+@@ -357,18 +357,16 @@ int txgbe_identify_module(struct wx *wx)
+ }
+
+ id = &buffer.id;
+- if (id->identifier != TXGBE_SFF_IDENTIFIER_SFP &&
+- id->identifier != TXGBE_SFF_IDENTIFIER_QSFP &&
+- id->identifier != TXGBE_SFF_IDENTIFIER_QSFP_PLUS &&
+- id->identifier != TXGBE_SFF_IDENTIFIER_QSFP28) {
+- wx_err(wx, "Invalid module\n");
+- return -ENODEV;
+- }
+-
+- if (id->transceiver_type == 0xFF)
++ if (id->identifier == TXGBE_SFF_IDENTIFIER_SFP)
+ return txgbe_sfp_to_linkmodes(wx, id);
+
+- return txgbe_qsfp_to_linkmodes(wx, id);
++ if (id->identifier == TXGBE_SFF_IDENTIFIER_QSFP ||
++ id->identifier == TXGBE_SFF_IDENTIFIER_QSFP_PLUS ||
++ id->identifier == TXGBE_SFF_IDENTIFIER_QSFP28)
++ return txgbe_qsfp_to_linkmodes(wx, id);
++
++ wx_err(wx, "Invalid module\n");
++ return -EINVAL;
+ }
+
+ void txgbe_setup_link(struct wx *wx)
+--
+2.53.0
+
--- /dev/null
+From 500f8e5c79857c0b8905064ea29af70d2247f679 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 15:08:40 +0800
+Subject: net: txgbe: initialize module info buffer
+
+From: Jiawen Wu <jiawenwu@trustnetic.com>
+
+[ Upstream commit 0487cfca46517ff6699c72dc1a8872b0af3c31a9 ]
+
+The module info buffer should be initialized to 0 before the firmware
+returns information. Otherwise, there is a risk that the buffer field
+not filled by the firmware is random value.
+
+Fixes: 343929799ace ("net: txgbe: Support to handle GPIO IRQs for AML devices")
+Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
+Link: https://patch.msgid.link/20260608070842.36504-2-jiawenwu@trustnetic.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+index f0514251d4f342..a7e81f9e1be148 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+@@ -335,7 +335,7 @@ static int txgbe_qsfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id)
+
+ int txgbe_identify_module(struct wx *wx)
+ {
+- struct txgbe_hic_get_module_info buffer;
++ struct txgbe_hic_get_module_info buffer = { 0 };
+ struct txgbe_sff_id *id;
+ int err = 0;
+ u32 mod_abs;
+--
+2.53.0
+
--- /dev/null
+From 79ac67cdf18b10480e7931d76787dfe13fdaa7e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 15:08:42 +0800
+Subject: net: txgbe: initialize PHY interface to 0
+
+From: Jiawen Wu <jiawenwu@trustnetic.com>
+
+[ Upstream commit 47f848aac4e79bdb197f849fa86e71fff1ad36ef ]
+
+DECLARE_PHY_INTERFACE_MASK() does not guarantee zeroed contents. Add a
+new macro DECLARE_PHY_INTERFACE_MASK_ZERO(), make the stack variable to
+be zeroed before setting supported interfaces.
+
+Fixes: 57d39faed4c9 ("net: txgbe: improve functions of AML 40G devices")
+Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
+Link: https://patch.msgid.link/20260608070842.36504-4-jiawenwu@trustnetic.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c | 4 ++--
+ drivers/net/ethernet/wangxun/txgbe/txgbe_type.h | 3 +++
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+index bdac654a236465..8fc32df8e49a44 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
+@@ -204,7 +204,7 @@ int txgbe_set_phy_link(struct wx *wx)
+ static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id)
+ {
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
+- DECLARE_PHY_INTERFACE_MASK(interfaces);
++ DECLARE_PHY_INTERFACE_MASK_ZERO(interfaces);
+ struct txgbe *txgbe = wx->priv;
+
+ if (id->cable_tech & TXGBE_SFF_DA_PASSIVE_CABLE) {
+@@ -271,7 +271,7 @@ static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id)
+ static int txgbe_qsfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id)
+ {
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
+- DECLARE_PHY_INTERFACE_MASK(interfaces);
++ DECLARE_PHY_INTERFACE_MASK_ZERO(interfaces);
+ struct txgbe *txgbe = wx->priv;
+
+ if (id->transceiver_type & TXGBE_SFF_ETHERNET_40G_CR4) {
+diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
+index 6b05f32b4a0109..877234e3fdc2b6 100644
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
+@@ -315,6 +315,9 @@ void txgbe_up(struct wx *wx);
+ int txgbe_setup_tc(struct net_device *dev, u8 tc);
+ void txgbe_do_reset(struct net_device *netdev);
+
++#define DECLARE_PHY_INTERFACE_MASK_ZERO(name) \
++ unsigned long name[PHY_INTERFACE_MODE_MAX] = { 0, }
++
+ #define TXGBE_LINK_SPEED_UNKNOWN 0
+ #define TXGBE_LINK_SPEED_10GB_FULL 4
+ #define TXGBE_LINK_SPEED_25GB_FULL 0x10
+--
+2.53.0
+
--- /dev/null
+From 4795b0f93ab942c57186a9d3fbf6bf7b7bf5a54a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 18:21:24 -0700
+Subject: netdev: fix double-free in netdev_nl_bind_rx_doit()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit c849de7d8757a7af801fc4a4058f71d481d367f2 ]
+
+Sashiko flags that genlmsg_reply() always consumes the skb.
+The error path calls nlmsg_free(rsp) so we can't jump directly
+to it. Let's not unbind, just propagate the error to the user.
+This is the typical way of handling genlmsg_reply() failures.
+They shouldn't happen unless user does something silly like
+calling the kernel with an already-full rcvbuf.
+
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Fixes: 170aafe35cb9 ("netdev: support binding dma-buf to netdevice")
+Reviewed-by: Bobby Eshleman <bobbyeshleman@meta.com>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/netdev-genl.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
+index 470fabbeacd9bd..93ea09bd1e7bab 100644
+--- a/net/core/netdev-genl.c
++++ b/net/core/netdev-genl.c
+@@ -1019,8 +1019,6 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
+ genlmsg_end(rsp, hdr);
+
+ err = genlmsg_reply(rsp, info);
+- if (err)
+- goto err_unbind;
+
+ bitmap_free(rxq_bitmap);
+
+@@ -1028,7 +1026,7 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
+
+ mutex_unlock(&priv->lock);
+
+- return 0;
++ return err < 0 ? err : 0;
+
+ err_unbind:
+ net_devmem_unbind_dmabuf(binding);
+--
+2.53.0
+
--- /dev/null
+From f6fa29f0f6abf6a5b8fb8de0927c0aee20d7efca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 00:38:17 -0700
+Subject: netfilter: nf_conntrack: destroy stale expectfn expectations on
+ unregister
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit c3009418f9fa1dcb3eb86f4d8c92583537b5faa3 ]
+
+NAT helpers such as nf_nat_h323 store a raw pointer to module text in
+exp->expectfn (e.g. ip_nat_q931_expect). nf_ct_helper_expectfn_unregister()
+only unlinks the callback descriptor and never walks the expectation table,
+so an expectation pending at module removal survives with a dangling
+exp->expectfn into freed module text.
+
+When the expected connection arrives, init_conntrack() invokes
+exp->expectfn(), now a stale pointer into the unloaded module. Reproduced
+on a KASAN build by loading the H.323 helpers, creating a Q.931
+expectation, unloading nf_nat_h323, then connecting to the expected port:
+
+ Oops: int3: 0000 [#1] SMP KASAN NOPTI
+ RIP: 0010:0xffffffffa06102d1
+ init_conntrack.isra.0 (net/netfilter/nf_conntrack_core.c:1862)
+ nf_conntrack_in (net/netfilter/nf_conntrack_core.c:2049)
+ ipv4_conntrack_local (net/netfilter/nf_conntrack_proto.c:223)
+ nf_hook_slow (net/netfilter/core.c:619)
+ __ip_local_out (net/ipv4/ip_output.c:120)
+ __tcp_transmit_skb (net/ipv4/tcp_output.c:1715)
+ tcp_connect (net/ipv4/tcp_output.c:4374)
+ tcp_v4_connect (net/ipv4/tcp_ipv4.c:345)
+ __sys_connect (net/socket.c:2167)
+ Modules linked in: nf_conntrack_h323 [last unloaded: nf_nat_h323]
+
+Reaching the dangling state requires CAP_SYS_MODULE in the initial user
+namespace to remove a NAT helper that still has live expectations, so this
+is a robustness fix; leaving an expectation pointing at freed text is wrong
+regardless.
+
+Add nf_ct_helper_expectfn_destroy(), which walks the expectation table and
+drops every expectation whose ->expectfn matches the descriptor being torn
+down. Call it from each NAT helper's exit path after the existing RCU grace
+period, so no expectation outlives the code it points at and no extra
+synchronize_rcu() is introduced. With the fix, the same reproducer runs to
+completion without the Oops.
+
+Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netfilter/nf_conntrack_helper.h | 1 +
+ net/ipv4/netfilter/nf_nat_h323.c | 2 ++
+ net/netfilter/nf_conntrack_helper.c | 19 +++++++++++++++++++
+ net/netfilter/nf_nat_core.c | 2 ++
+ net/netfilter/nf_nat_sip.c | 1 +
+ 5 files changed, 25 insertions(+)
+
+diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
+index de2f956abf3480..24cf3d2d97450f 100644
+--- a/include/net/netfilter/nf_conntrack_helper.h
++++ b/include/net/netfilter/nf_conntrack_helper.h
+@@ -155,6 +155,7 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
+
+ void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n);
+ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n);
++void nf_ct_helper_expectfn_destroy(const struct nf_ct_helper_expectfn *n);
+ struct nf_ct_helper_expectfn *
+ nf_ct_helper_expectfn_find_by_name(const char *name);
+ struct nf_ct_helper_expectfn *
+diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
+index faee20af485613..10e1b0837731b7 100644
+--- a/net/ipv4/netfilter/nf_nat_h323.c
++++ b/net/ipv4/netfilter/nf_nat_h323.c
+@@ -555,6 +555,8 @@ static void __exit nf_nat_h323_fini(void)
+ nf_ct_helper_expectfn_unregister(&q931_nat);
+ nf_ct_helper_expectfn_unregister(&callforwarding_nat);
+ synchronize_rcu();
++ nf_ct_helper_expectfn_destroy(&q931_nat);
++ nf_ct_helper_expectfn_destroy(&callforwarding_nat);
+ }
+
+ /****************************************************************************/
+diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
+index b594cd244fe1d4..ea0cdb7ec91512 100644
+--- a/net/netfilter/nf_conntrack_helper.c
++++ b/net/netfilter/nf_conntrack_helper.c
+@@ -283,6 +283,25 @@ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n)
+ }
+ EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_unregister);
+
++static bool expect_iter_expectfn(struct nf_conntrack_expect *exp, void *data)
++{
++ const struct nf_ct_helper_expectfn *n = data;
++
++ /* Relies on registered expectfn descriptors having unique ->expectfn
++ * pointers, which holds for the in-tree NAT helpers.
++ */
++ return exp->expectfn == n->expectfn;
++}
++
++/* Destroy expectations still pointing at @n->expectfn; call after the
++ * caller's RCU grace period so none outlives the (often modular) callback.
++ */
++void nf_ct_helper_expectfn_destroy(const struct nf_ct_helper_expectfn *n)
++{
++ nf_ct_expect_iterate_destroy(expect_iter_expectfn, (void *)n);
++}
++EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_destroy);
++
+ /* Caller should hold the rcu lock */
+ struct nf_ct_helper_expectfn *
+ nf_ct_helper_expectfn_find_by_name(const char *name)
+diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
+index b30ca94c2bb7ff..4f41311b868b47 100644
+--- a/net/netfilter/nf_nat_core.c
++++ b/net/netfilter/nf_nat_core.c
+@@ -1347,6 +1347,7 @@ static int __init nf_nat_init(void)
+ RCU_INIT_POINTER(nf_nat_hook, NULL);
+ nf_ct_helper_expectfn_unregister(&follow_master_nat);
+ synchronize_net();
++ nf_ct_helper_expectfn_destroy(&follow_master_nat);
+ unregister_pernet_subsys(&nat_net_ops);
+ kvfree(nf_nat_bysource);
+ }
+@@ -1364,6 +1365,7 @@ static void __exit nf_nat_cleanup(void)
+ RCU_INIT_POINTER(nf_nat_hook, NULL);
+
+ synchronize_net();
++ nf_ct_helper_expectfn_destroy(&follow_master_nat);
+ kvfree(nf_nat_bysource);
+ unregister_pernet_subsys(&nat_net_ops);
+ }
+diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c
+index 9fbfc6bff0c221..00838c0cc5bb28 100644
+--- a/net/netfilter/nf_nat_sip.c
++++ b/net/netfilter/nf_nat_sip.c
+@@ -655,6 +655,7 @@ static void __exit nf_nat_sip_fini(void)
+ RCU_INIT_POINTER(nf_nat_sip_hooks, NULL);
+ nf_ct_helper_expectfn_unregister(&sip_nat);
+ synchronize_rcu();
++ nf_ct_helper_expectfn_destroy(&sip_nat);
+ }
+
+ static const struct nf_nat_sip_hooks sip_hooks = {
+--
+2.53.0
+
--- /dev/null
+From 4f4e7bf8118c08b08a35a414e5e6d79f0c48df81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 15:55:02 -0700
+Subject: netfilter: nf_log: validate MAC header was set before dumping it
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit a84b6fedbc97078788be78dbdd7517d143ad1a77 ]
+
+The fallback path of dump_mac_header() guards the MAC header access
+only with "skb->mac_header != skb->network_header", without checking
+skb_mac_header_was_set(). When the MAC header is unset, mac_header is
+0xffff, so the test passes and skb_mac_header(skb) returns
+skb->head + 0xffff, ~64 KiB past the buffer; the loop then reads
+dev->hard_header_len bytes out of bounds into the kernel log.
+
+This is reachable via the netdev logger: nf_log_unknown_packet() calls
+dump_mac_header() unconditionally, and an skb sent through AF_PACKET
+with PACKET_QDISC_BYPASS reaches the egress hook with mac_header still
+unset (__dev_queue_xmit(), which would reset it, is bypassed).
+
+Add the skb_mac_header_was_set() check the ARPHRD_ETHER path already
+uses, and replace the open-coded MAC header length test with
+skb_mac_header_len(). Only skbs with an unset MAC header are affected;
+valid ones are dumped as before.
+
+ BUG: KASAN: slab-out-of-bounds in dump_mac_header (net/netfilter/nf_log_syslog.c:831)
+ Read of size 1 at addr ffff88800ea49d3f by task exploit/148
+ Call Trace:
+ kasan_report (mm/kasan/report.c:595)
+ dump_mac_header (net/netfilter/nf_log_syslog.c:831)
+ nf_log_netdev_packet (net/netfilter/nf_log_syslog.c:938 net/netfilter/nf_log_syslog.c:963)
+ nf_log_packet (net/netfilter/nf_log.c:260)
+ nft_log_eval (net/netfilter/nft_log.c:60)
+ nft_do_chain (net/netfilter/nf_tables_core.c:285)
+ nft_do_chain_netdev (net/netfilter/nft_chain_filter.c:307)
+ nf_hook_slow (net/netfilter/core.c:619)
+ nf_hook_direct_egress (net/packet/af_packet.c:257)
+ packet_xmit (net/packet/af_packet.c:280)
+ packet_sendmsg (net/packet/af_packet.c:3114)
+ __sys_sendto (net/socket.c:2265)
+
+Fixes: 7eb9282cd0ef ("netfilter: ipt_LOG/ip6t_LOG: add option to print decoded MAC header")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_log_syslog.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
+index 41503847d9d7fb..c0462d403157a9 100644
+--- a/net/netfilter/nf_log_syslog.c
++++ b/net/netfilter/nf_log_syslog.c
+@@ -801,8 +801,8 @@ static void dump_mac_header(struct nf_log_buf *m,
+
+ fallback:
+ nf_log_buf_add(m, "MAC=");
+- if (dev->hard_header_len &&
+- skb->mac_header != skb->network_header) {
++ if (dev->hard_header_len && skb_mac_header_was_set(skb) &&
++ skb_mac_header_len(skb) != 0) {
+ const unsigned char *p = skb_mac_header(skb);
+ unsigned int i;
+
+--
+2.53.0
+
--- /dev/null
+From bd5008db248ba89bc69acd20cfda26c2d1ac7531 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 21:28:09 +0200
+Subject: netfilter: nft_exthdr: fix register tracking for F_PRESENT flag
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 772cecf198da732faebb5dcfc46d66a505be8495 ]
+
+nft_exthdr_init() passes user-controlled priv->len to
+nft_parse_register_store(), which marks that many bytes in the
+register bitmap as initialized. However, when NFT_EXTHDR_F_PRESENT
+is set, the eval paths write only 1 byte (nft_reg_store8) or
+4 bytes (*dest = 0 on TCP/DCCP error path). When len > 4,
+registers beyond the first are never written, retaining
+uninitialized stack data from nft_regs.
+
+Bail out if userspace requests too much data when F_PRESENT is set.
+
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Fixes: c078ca3b0c5b ("netfilter: nft_exthdr: Add support for existence check")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_exthdr.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
+index 7eedf4e3ae9c75..9471328802d3b7 100644
+--- a/net/netfilter/nft_exthdr.c
++++ b/net/netfilter/nft_exthdr.c
+@@ -532,6 +532,9 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
+ return err;
+ }
+
++ if ((flags & NFT_EXTHDR_F_PRESENT) && len != 1)
++ return -EINVAL;
++
+ priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
+ priv->offset = offset;
+ priv->len = len;
+--
+2.53.0
+
--- /dev/null
+From 2307548fa1ef4d384bcc0459bc20cd7252dd6946 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 17:04:25 +0200
+Subject: netfilter: revalidate bridge ports
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit ccb9fd4b87538ccf19ccff78ee26700526d94867 ]
+
+ebt_redirect_tg() dereferences br_port_get_rcu() return without a
+NULL check, causing a kernel panic when the bridge port has been
+removed between the original hook invocation and an NFQUEUE
+reinject.
+
+A mere NULL check isn't sufficient, however. As sashiko review
+points out userspace can not only remove the port from the bridge,
+it could also place the device in a different virtual device, e.g.
+macvlan.
+
+If this happens, we must drop the packet, there is no way for us to
+reinject it into the bridge path.
+
+Switch to _upper API, we don't need the bridge port structure.
+Also, this fix keeps another bug intact:
+
+Both nfnetlink_log and nfnetlink_queue use CONFIG_BRIDGE_NETFILTER
+too aggressive, which prevents certain logging features when queueing
+in bridge family: NETFILTER_FAMILY_BRIDGE can be enabled while the old
+CONFIG_BRIDGE_NETFILTER cruft is off.
+
+Fixes tag is a common ancestor, this was always broken.
+
+Fixes: f350a0a87374 ("bridge: use rx_handler_data pointer to store net_bridge_port pointer")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Assisted-by: Claude:claude-sonnet-4-6
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/netfilter/ebt_dnat.c | 4 +-
+ net/bridge/netfilter/ebt_redirect.c | 16 +++++---
+ net/netfilter/nfnetlink_log.c | 23 +++++++++--
+ net/netfilter/nfnetlink_queue.c | 64 +++++++++++++++++++++++++----
+ 4 files changed, 89 insertions(+), 18 deletions(-)
+
+diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c
+index 3fda71a8579d13..73f185cccd63df 100644
+--- a/net/bridge/netfilter/ebt_dnat.c
++++ b/net/bridge/netfilter/ebt_dnat.c
+@@ -39,7 +39,9 @@ ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ dev = xt_in(par);
+ break;
+ case NF_BR_PRE_ROUTING:
+- dev = br_port_get_rcu(xt_in(par))->br->dev;
++ dev = netdev_master_upper_dev_get_rcu(xt_in(par));
++ if (!dev) /* bridge port removed? */
++ return EBT_DROP;
+ break;
+ default:
+ dev = NULL;
+diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c
+index 307790562b4929..83486cd4d564b1 100644
+--- a/net/bridge/netfilter/ebt_redirect.c
++++ b/net/bridge/netfilter/ebt_redirect.c
+@@ -24,12 +24,18 @@ ebt_redirect_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ if (skb_ensure_writable(skb, 0))
+ return EBT_DROP;
+
+- if (xt_hooknum(par) != NF_BR_BROUTING)
+- /* rcu_read_lock()ed by nf_hook_thresh */
+- ether_addr_copy(eth_hdr(skb)->h_dest,
+- br_port_get_rcu(xt_in(par))->br->dev->dev_addr);
+- else
++ if (xt_hooknum(par) != NF_BR_BROUTING) {
++ const struct net_device *dev;
++
++ dev = netdev_master_upper_dev_get_rcu(xt_in(par));
++ if (!dev)
++ return EBT_DROP;
++
++ ether_addr_copy(eth_hdr(skb)->h_dest, dev->dev_addr);
++ } else {
+ ether_addr_copy(eth_hdr(skb)->h_dest, xt_in(par)->dev_addr);
++ }
++
+ skb->pkt_type = PACKET_HOST;
+ return info->target;
+ }
+diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
+index 0db908518b2fa2..f9bfc34d9ad355 100644
+--- a/net/netfilter/nfnetlink_log.c
++++ b/net/netfilter/nfnetlink_log.c
+@@ -450,6 +450,23 @@ static int nfulnl_put_bridge(struct nfulnl_instance *inst, const struct sk_buff
+ return -1;
+ }
+
++#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
++static int nflog_put_master_ifindex(struct sk_buff *nlskb, int attr,
++ const struct net_device *dev)
++{
++ const struct net_device *upper;
++
++ if (dev && !netif_is_bridge_port(dev))
++ return 0;
++
++ upper = netdev_master_upper_dev_get_rcu((struct net_device *)dev);
++ if (upper && nla_put_be32(nlskb, attr, htonl(upper->ifindex)))
++ return -EMSGSIZE;
++
++ return 0;
++}
++#endif
++
+ /* This is an inline function, we don't really care about a long
+ * list of arguments */
+ static inline int
+@@ -504,8 +521,7 @@ __build_packet_message(struct nfnl_log_net *log,
+ /* rcu_read_lock()ed by nf_hook_thresh or
+ * nf_log_packet.
+ */
+- nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
+- htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
++ nflog_put_master_ifindex(inst->skb, NFULA_IFINDEX_INDEV, indev))
+ goto nla_put_failure;
+ } else {
+ int physinif;
+@@ -541,8 +557,7 @@ __build_packet_message(struct nfnl_log_net *log,
+ /* rcu_read_lock()ed by nf_hook_thresh or
+ * nf_log_packet.
+ */
+- nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
+- htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
++ nflog_put_master_ifindex(inst->skb, NFULA_IFINDEX_OUTDEV, outdev))
+ goto nla_put_failure;
+ } else {
+ struct net_device *physoutdev;
+diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
+index 0529a19ca9a838..69038d946fc243 100644
+--- a/net/netfilter/nfnetlink_queue.c
++++ b/net/netfilter/nfnetlink_queue.c
+@@ -426,10 +426,47 @@ static bool nf_ct_drop_unconfirmed(const struct nf_queue_entry *entry, bool *is_
+ return false;
+ }
+
++static bool nf_bridge_port_valid(const struct net_device *dev)
++{
++ if (!dev)
++ return true;
++
++ return netif_is_bridge_port(dev);
++}
++
++/* queued skbs leave rcu protection. We bump device refcount so that
++ * the device cannot go away. However, while packet was out the port
++ * could have been removed from the bridge.
++ *
++ * Ensure in+outdev are still part of a bridge at reinject time.
++ *
++ * The device rx_handler_data could even be pointing at data that is
++ * not a net_bridge_port structure.
++ */
++static bool nf_bridge_ports_valid(const struct nf_queue_entry *entry)
++{
++#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
++ if (!nf_bridge_port_valid(entry->physin) ||
++ !nf_bridge_port_valid(entry->physout))
++ return false;
++#endif
++ if (entry->state.pf != PF_BRIDGE)
++ return true;
++
++ if (!nf_bridge_port_valid(entry->state.in) ||
++ !nf_bridge_port_valid(entry->state.out))
++ return false;
++
++ return true;
++}
++
+ static void nfqnl_reinject(struct nf_queue_entry *entry, unsigned int verdict)
+ {
+ const struct nf_ct_hook *ct_hook;
+
++ if (!nf_bridge_ports_valid(entry))
++ verdict = NF_DROP;
++
+ if (verdict == NF_ACCEPT ||
+ verdict == NF_REPEAT ||
+ verdict == NF_STOP) {
+@@ -622,6 +659,23 @@ static int nf_queue_checksum_help(struct sk_buff *entskb)
+ return skb_checksum_help(entskb);
+ }
+
++#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
++static int nfqnl_put_master_ifindex(struct sk_buff *nlskb, int attr,
++ const struct net_device *dev)
++{
++ const struct net_device *upper;
++
++ if (dev && !netif_is_bridge_port(dev))
++ return 0;
++
++ upper = netdev_master_upper_dev_get_rcu((struct net_device *)dev);
++ if (upper && nla_put_be32(nlskb, attr, htonl(upper->ifindex)))
++ return -EMSGSIZE;
++
++ return 0;
++}
++#endif
++
+ static struct sk_buff *
+ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
+ struct nf_queue_entry *entry,
+@@ -757,10 +811,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
+ * netfilter_bridge) */
+ if (nla_put_be32(skb, NFQA_IFINDEX_PHYSINDEV,
+ htonl(indev->ifindex)) ||
+- /* this is the bridge group "brX" */
+- /* rcu_read_lock()ed by __nf_queue */
+- nla_put_be32(skb, NFQA_IFINDEX_INDEV,
+- htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
++ nfqnl_put_master_ifindex(skb, NFQA_IFINDEX_INDEV, indev))
+ goto nla_put_failure;
+ } else {
+ int physinif;
+@@ -791,10 +842,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
+ * netfilter_bridge) */
+ if (nla_put_be32(skb, NFQA_IFINDEX_PHYSOUTDEV,
+ htonl(outdev->ifindex)) ||
+- /* this is the bridge group "brX" */
+- /* rcu_read_lock()ed by __nf_queue */
+- nla_put_be32(skb, NFQA_IFINDEX_OUTDEV,
+- htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
++ nfqnl_put_master_ifindex(skb, NFQA_IFINDEX_OUTDEV, outdev))
+ goto nla_put_failure;
+ } else {
+ int physoutif;
+--
+2.53.0
+
--- /dev/null
+From 79929e522bc788c0b442aadf7361c5ce591ae6db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 01:10:31 -0700
+Subject: netfilter: x_tables: avoid leaking percpu counter pointers
+
+From: Kyle Zeng <kylebot@openai.com>
+
+[ Upstream commit f7f2fbb0e893a0238dc464f8d8c0f5609bec584f ]
+
+The native and compat get-entries paths copy the fixed rule entry header
+from the kernelized rule blob to userspace before overwriting the entry's
+counter fields with a sanitized counter snapshot.
+
+On SMP kernels, entry->counters.pcnt contains the percpu allocation
+address used by x_tables rule counters. A caller can provide a userspace
+buffer that faults during the initial fixed-header copy after pcnt has
+been copied but before the later sanitized counter copy runs. The syscall
+then returns -EFAULT while leaving the raw percpu pointer in userspace.
+
+Copy only the fixed entry prefix before counters from the kernelized rule
+blob, then copy the sanitized counter snapshot into the counter field.
+Apply this ordering to the IPv4, IPv6, and ARP native and compat
+get-entries implementations so a fault cannot expose the internal percpu
+counter pointer.
+
+Fixes: 71ae0dff02d7 ("netfilter: xtables: use percpu rule counters")
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/netfilter/arp_tables.c | 15 ++++++---------
+ net/ipv4/netfilter/ip_tables.c | 15 ++++++---------
+ net/ipv6/netfilter/ip6_tables.c | 15 ++++++---------
+ 3 files changed, 18 insertions(+), 27 deletions(-)
+
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+index ad2259678c7854..0ea513bf77fb6a 100644
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -702,14 +702,12 @@ static int copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct arpt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct arpt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1327,9 +1325,8 @@ static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct arpt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_arpt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_arpt_entry);
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
+index 5cbdb0815857f4..ca8ff0ae6cdb9f 100644
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -832,14 +832,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ipt_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ipt_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1228,9 +1226,8 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ipt_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ipt_entry);
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+index 9d9c3763f2f5e9..e34d5ba1460ca7 100644
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -848,14 +848,12 @@ copy_entries_to_user(unsigned int total_size,
+ const struct xt_entry_target *t;
+
+ e = loc_cpu_entry + off;
+- if (copy_to_user(userptr + off, e, sizeof(*e))) {
+- ret = -EFAULT;
+- goto free_counters;
+- }
+- if (copy_to_user(userptr + off
++ if (copy_to_user(userptr + off, e,
++ offsetof(struct ip6t_entry, counters)) ||
++ copy_to_user(userptr + off
+ + offsetof(struct ip6t_entry, counters),
+ &counters[num],
+- sizeof(counters[num])) != 0) {
++ sizeof(counters[num]))) {
+ ret = -EFAULT;
+ goto free_counters;
+ }
+@@ -1244,9 +1242,8 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
+
+ origsize = *size;
+ ce = *dstptr;
+- if (copy_to_user(ce, e, sizeof(struct ip6t_entry)) != 0 ||
+- copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ if (copy_to_user(ce, e, offsetof(struct compat_ip6t_entry, counters)) ||
++ copy_to_user(&ce->counters, &counters[i], sizeof(counters[i])))
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ip6t_entry);
+--
+2.53.0
+
--- /dev/null
+From 55a549f38f046e65707b9b4df86b3949b8067724 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2026 09:13:53 +0800
+Subject: netlabel: validate unlabeled address and mask attribute lengths
+
+From: Chenguang Zhao <zhaochenguang@kylinos.cn>
+
+[ Upstream commit 9772589b57e44aedc240211c5c3f7a684a034d3a ]
+
+netlbl_unlabel_addrinfo_get() used the address attribute length to
+determine whether the attribute data could be read as an IPv4 or IPv6
+address, but did not independently validate the corresponding mask
+attribute length. A crafted Generic Netlink request could therefore
+provide a valid IPv4/IPv6 address attribute with a shorter mask
+attribute, which would later be read as a full struct in_addr or
+struct in6_addr.
+
+NLA_BINARY policy lengths are maximum lengths by default, so use
+NLA_POLICY_EXACT_LEN() for the unlabeled IPv4/IPv6 address and mask
+attributes. This rejects short attributes during policy validation and
+also exposes the exact length requirements through policy introspection.
+
+Fixes: 8cc44579d1bd ("NetLabel: Introduce static network labels for unlabeled connections")
+Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlabel/netlabel_unlabeled.c | 30 ++++++++++--------------------
+ 1 file changed, 10 insertions(+), 20 deletions(-)
+
+diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
+index ca7a9e2a3de781..870e7699326a4a 100644
+--- a/net/netlabel/netlabel_unlabeled.c
++++ b/net/netlabel/netlabel_unlabeled.c
+@@ -114,14 +114,14 @@ static struct genl_family netlbl_unlabel_gnl_family;
+ /* NetLabel Netlink attribute policy */
+ static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = {
+ [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 },
+- [NLBL_UNLABEL_A_IPV6ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV6MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in6_addr) },
+- [NLBL_UNLABEL_A_IPV4ADDR] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
+- [NLBL_UNLABEL_A_IPV4MASK] = { .type = NLA_BINARY,
+- .len = sizeof(struct in_addr) },
++ [NLBL_UNLABEL_A_IPV6ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV6MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
++ [NLBL_UNLABEL_A_IPV4ADDR] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
++ [NLBL_UNLABEL_A_IPV4MASK] =
++ NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
+ [NLBL_UNLABEL_A_IFACE] = { .type = NLA_NUL_STRING,
+ .len = IFNAMSIZ - 1 },
+ [NLBL_UNLABEL_A_SECCTX] = { .type = NLA_BINARY }
+@@ -757,24 +757,14 @@ static int netlbl_unlabel_addrinfo_get(struct genl_info *info,
+ void **mask,
+ u32 *len)
+ {
+- u32 addr_len;
+-
+ if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR] &&
+ info->attrs[NLBL_UNLABEL_A_IPV4MASK]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+- if (addr_len != sizeof(struct in_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV4MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4MASK]);
+ return 0;
+ } else if (info->attrs[NLBL_UNLABEL_A_IPV6ADDR]) {
+- addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+- if (addr_len != sizeof(struct in6_addr) &&
+- addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV6MASK]))
+- return -EINVAL;
+- *len = addr_len;
++ *len = sizeof(struct in6_addr);
+ *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]);
+ *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6MASK]);
+ return 0;
+--
+2.53.0
+
--- /dev/null
+From 8aafacd7393e0bedb2121e487492529fc38ad785 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 15:59:52 +0000
+Subject: ptp: ocp: fix resource freeing order
+
+From: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+
+[ Upstream commit 627366c51145a07f675b1800fb5ea2ec960bd900 ]
+
+Commit a60fc3294a37 ("ptp: rework ptp_clock_unregister() to disable
+events") added a call to ptp_disable_all_events() which changes the
+configuration of pins if they support EXTTS events. In ptp_ocp_detach()
+pins resources are freed before ptp_clock_unregister() and it leads to
+use-after-free during driver removal. Fix it by changing the order of
+free/unregister calls. To avoid irq handler running on the other core
+while ptp device unregistering, call synchronize_irq() after HW is
+configured to stop producing irqs and no irqs are in-flight.
+
+Fixes: a60fc3294a37 ("ptp: rework ptp_clock_unregister() to disable events")
+Signed-off-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Link: https://patch.msgid.link/20260608155952.240304-1-vadim.fedorenko@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_ocp.c | 24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
+index d88ab2f86b1bf6..fcfa671bd6897c 100644
+--- a/drivers/ptp/ptp_ocp.c
++++ b/drivers/ptp/ptp_ocp.c
+@@ -2216,8 +2216,13 @@ ptp_ocp_ts_enable(void *priv, u32 req, bool enable)
+ iowrite32(1, ®->intr_mask);
+ iowrite32(1, ®->intr);
+ } else {
++ int irq_vec = pci_irq_vector(bp->pdev, ext->irq_vec);
++
+ iowrite32(0, ®->intr_mask);
+ iowrite32(0, ®->enable);
++ ioread32(®->intr_mask);
++ if (irq_vec > 0)
++ synchronize_irq(irq_vec);
+ }
+
+ return 0;
+@@ -4558,6 +4563,22 @@ ptp_ocp_detach(struct ptp_ocp *bp)
+ ptp_ocp_detach_sysfs(bp);
+ ptp_ocp_attr_group_del(bp);
+ timer_delete_sync(&bp->watchdog);
++ /* Disable interrupts on all timestampers */
++ if (bp->ts0)
++ ptp_ocp_ts_enable(bp->ts0, 0, false);
++ if (bp->ts1)
++ ptp_ocp_ts_enable(bp->ts1, 0, false);
++ if (bp->ts2)
++ ptp_ocp_ts_enable(bp->ts2, 0, false);
++ if (bp->ts3)
++ ptp_ocp_ts_enable(bp->ts3, 0, false);
++ if (bp->ts4)
++ ptp_ocp_ts_enable(bp->ts4, 0, false);
++ if (bp->pps)
++ ptp_ocp_ts_enable(bp->pps, ~0, false);
++ if (bp->ptp)
++ ptp_clock_unregister(bp->ptp);
++ kfree(bp->ptp_info.pin_config);
+ ptp_ocp_unregister_ext(bp->ts0);
+ ptp_ocp_unregister_ext(bp->ts1);
+ ptp_ocp_unregister_ext(bp->ts2);
+@@ -4575,9 +4596,6 @@ ptp_ocp_detach(struct ptp_ocp *bp)
+ clk_hw_unregister_fixed_rate(bp->i2c_clk);
+ if (bp->n_irqs)
+ pci_free_irq_vectors(bp->pdev);
+- if (bp->ptp)
+- ptp_clock_unregister(bp->ptp);
+- kfree(bp->ptp_info.pin_config);
+ device_unregister(&bp->dev);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 79eaa654df97c32f3452472a7aeb4be9e1d9e183 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 17:22:47 +0800
+Subject: r8152: handle the return value of usb_reset_device()
+
+From: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+
+[ Upstream commit 19440600e729d4f74a42591a872099cf25c7d28a ]
+
+If usb_reset_device() returns a negative error code, stop the
+process of probing.
+
+Fixes: 10c3271712f5 ("r8152: disable the ECM mode")
+Signed-off-by: Chih Kai Hsu <hsu.chih.kai@realtek.com>
+Reviewed-by: Hayes Wang <hayeswang@realtek.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20260604092247.27158-450-nic_swsd@realtek.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/r8152.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index f69e7e1ab7788d..240265746990ec 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -9775,7 +9775,12 @@ static int rtl8152_probe_once(struct usb_interface *intf,
+ struct net_device *netdev;
+ int ret;
+
+- usb_reset_device(udev);
++ ret = usb_reset_device(udev);
++ if (ret < 0) {
++ dev_err(&intf->dev, "USB reset failed, errno=%d\n", ret);
++ return ret;
++ }
++
+ netdev = alloc_etherdev(sizeof(struct r8152));
+ if (!netdev) {
+ dev_err(&intf->dev, "Out of memory\n");
+--
+2.53.0
+
--- /dev/null
+From d463ea6d6e82dc0adef5ff9191d2f1ccd8755f4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 02:32:05 -0700
+Subject: rds: mark snapshot pages dirty in rds_info_getsockopt()
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 512db8267b73a220a64180d95ab5eebe7c4964a8 ]
+
+rds_info_getsockopt() pins the destination user pages with FOLL_WRITE and
+the RDS_INFO_* producers memcpy the snapshot into them through
+kmap_atomic(). Because that copy goes through the kernel direct map, the
+dirty bit on the user PTE is never set, so unpin_user_pages() releases the
+pages without marking them dirty. A file-backed destination page can then
+be reclaimed without writeback, silently discarding the copied data.
+
+Use unpin_user_pages_dirty_lock() with make_dirty=true so the modified
+pages are marked dirty before they are unpinned.
+
+Fixes: a8c879a7ee98 ("RDS: Info and stats")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260608-rds_fix-v1-1-006c88543408@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/info.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/rds/info.c b/net/rds/info.c
+index f1b29994934a03..17061f6ff74e58 100644
+--- a/net/rds/info.c
++++ b/net/rds/info.c
+@@ -235,7 +235,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
+
+ out:
+ if (pages)
+- unpin_user_pages(pages, nr_pages);
++ unpin_user_pages_dirty_lock(pages, nr_pages, true);
+ kfree(pages);
+
+ return ret;
+--
+2.53.0
+
--- /dev/null
+From 8e14091ecf1262d7e1383f8b428175b5edcead3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jun 2026 08:22:34 -0400
+Subject: sctp: fix uninit-value in __sctp_rcv_asconf_lookup()
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit f8373d7090b745728de66308deeecc67e8d319ce ]
+
+__sctp_rcv_asconf_lookup() in net/sctp/input.c only checks that the ASCONF
+chunk can hold the ADDIP header and a parameter header, then calls
+af->from_addr_param(), which reads the full address (16 bytes for IPv6)
+trusting the parameter's declared length.
+
+An unauthenticated peer can send a truncated trailing ASCONF chunk that
+declares an IPv6 address parameter but stops after the 4-byte parameter
+header; reached from the no-association lookup path, from_addr_param() then
+reads uninitialized bytes past the parameter.
+
+Impact: an unauthenticated SCTP peer makes the receive path read up to 16
+bytes of uninitialized memory past a truncated ASCONF address parameter.
+
+The sibling __sctp_rcv_init_lookup() bounds parameters with
+sctp_walk_params(); this path open-codes the fetch and omits the bound.
+Verify the whole address parameter lies within the chunk before
+from_addr_param() reads it, the same class of fix as commit 51e5ad549c43
+("net: sctp: fix KMSAN uninit-value in sctp_inq_pop").
+
+Fixes: df2185771439 ("[SCTP]: Update association lookup to look at ASCONF chunks as well")
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260608122234.459098-1-michael.bommarito@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/input.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/sctp/input.c b/net/sctp/input.c
+index e119e460ccde0b..864741fae4187e 100644
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -1204,6 +1204,14 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
+ /* Skip over the ADDIP header and find the Address parameter */
+ param = (union sctp_addr_param *)(asconf + 1);
+
++ /* The whole address parameter must lie within the chunk before
++ * af->from_addr_param() reads the variable-length address; otherwise a
++ * truncated trailing ASCONF chunk lets it read uninitialized bytes past
++ * the parameter.
++ */
++ if (sizeof(*asconf) + ntohs(param->p.length) > ntohs(ch->length))
++ return NULL;
++
+ af = sctp_get_af_specific(param_type2af(param->p.type));
+ if (unlikely(!af))
+ return NULL;
+--
+2.53.0
+
--- /dev/null
+From d7e0c478d50c3399925be74af3afcba8f2213867 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jun 2026 19:03:47 -0400
+Subject: sctp: validate embedded INIT chunk and address list lengths in cookie
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 6f4c80a2a7e6d06753b89a578b710a2499a5e62b ]
+
+sctp_unpack_cookie() only checked that the embedded INIT chunk length
+did not exceed the remaining cookie payload, but did not ensure that the
+INIT chunk is large enough to contain a complete INIT header.
+
+A malformed COOKIE_ECHO can therefore carry a truncated INIT chunk whose
+length field is smaller than sizeof(struct sctp_init_chunk). Later,
+sctp_process_init() accesses INIT parameters unconditionally, which may
+lead to out-of-bounds reads.
+
+In addition, raw_addr_list_len is not fully validated against the
+remaining cookie payload. When cookie authentication is disabled, an
+attacker can supply an oversized raw_addr_list_len and cause
+sctp_raw_to_bind_addrs() to read beyond the end of the cookie. The
+address parser also lacks sufficient bounds checks for parameter headers
+and lengths, allowing malformed address parameters to trigger
+out-of-bounds reads.
+
+Fix this by:
+
+- requiring the embedded INIT chunk length to be at least sizeof(struct
+ sctp_init_chunk);
+- validating that the INIT chunk and raw address list together fit
+ within the cookie payload;
+- verifying sufficient data exists for each address parameter header and
+ payload before parsing it.
+
+Note that sctp_verify_init() must be called after sctp_unpack_cookie()
+and before sctp_process_init() when cookie authentication is disabled.
+This will be addressed in a separate patch.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/75af23a89adf881a0895d511775e4770da367cbf.1780873427.git.lucien.xin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/bind_addr.c | 11 ++++++++++-
+ net/sctp/sm_make_chunk.c | 9 +++++++--
+ 2 files changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
+index 75e3e61d494e0f..31737f144c7f03 100644
+--- a/net/sctp/bind_addr.c
++++ b/net/sctp/bind_addr.c
+@@ -275,6 +275,16 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
+ param = (struct sctp_paramhdr *)raw_addr_list;
+ rawaddr = (union sctp_addr_param *)raw_addr_list;
+
++ if (addrs_len < sizeof(*param)) {
++ retval = -EINVAL;
++ goto out_err;
++ }
++ len = ntohs(param->length);
++ if (addrs_len < len) {
++ retval = -EINVAL;
++ goto out_err;
++ }
++
+ af = sctp_get_af_specific(param_type2af(param->type));
+ if (unlikely(!af) ||
+ !af->from_addr_param(&addr, rawaddr, htons(port), 0)) {
+@@ -291,7 +301,6 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
+ goto out_err;
+
+ next:
+- len = ntohs(param->length);
+ addrs_len -= len;
+ raw_addr_list += len;
+ }
+diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
+index 9014b095f52ddb..51affa4fd396b7 100644
+--- a/net/sctp/sm_make_chunk.c
++++ b/net/sctp/sm_make_chunk.c
+@@ -1731,8 +1731,8 @@ struct sctp_association *sctp_unpack_cookie(
+ struct sk_buff *skb = chunk->skb;
+ struct sctp_cookie *bear_cookie;
+ struct sctp_chunkhdr *ch;
++ unsigned int len, chlen;
+ enum sctp_scope scope;
+- unsigned int len;
+ ktime_t kt;
+
+ /* Header size is static data prior to the actual cookie, including
+@@ -1761,7 +1761,12 @@ struct sctp_association *sctp_unpack_cookie(
+ bear_cookie = &cookie->c;
+
+ ch = (struct sctp_chunkhdr *)(bear_cookie + 1);
+- if (ntohs(ch->length) > len - fixed_size)
++ chlen = ntohs(ch->length);
++ if (chlen < sizeof(struct sctp_init_chunk))
++ goto malformed;
++ if (chlen > len - fixed_size)
++ goto malformed;
++ if (bear_cookie->raw_addr_list_len > len - fixed_size - chlen)
+ goto malformed;
+
+ /* Verify the cookie's MAC, if cookie authentication is enabled. */
+--
+2.53.0
+
verification-rvgen-fix-ltl2k-writing-true-as-a-liter.patch
riscv-ptrace-use-user_regset_note_type-for-regset_cf.patch
riscv-cfi-reject-unknown-flags-in-pr_set_cfi.patch
+xfrm-iptfs-fix-use-after-free-on-first_skb-in-__inpu.patch
+dma-mapping-direct-fix-missing-mapping-for-thru_host.patch
+dma-debug-fix-physical-address-retrieval-in-debug_dm.patch
+xfrm-policy-fix-use-after-free-on-inexact-bin-in-xfr.patch
+ice-fix-missing-priority-callbacks-for-u.fl-dpll-pin.patch
+idpf-fix-mailbox-capability-for-set-device-clock-tim.patch
+net-ena-phc-add-missing-barrier.patch
+bnge-fix-context-mem-iteration.patch
+netlabel-validate-unlabeled-address-and-mask-attribu.patch
+gpio-mvebu-fix-null-pointer-dereference-in-suspend-r.patch
+asoc-wm_adsp-fix-null-dereference-when-removing-firm.patch
+tcp-restrict-so_attach_filter-to-priv-users.patch
+net-add-pskb_may_pull-to-skb_gro_receive_list.patch
+net-mlx4-avoid-gcc-10-__bad_copy_from-false-positive.patch
+net-ibm-emac-fix-use-after-free-during-device-remova.patch
+netdev-fix-double-free-in-netdev_nl_bind_rx_doit.patch
+net-phy-clean-the-sfp-upstream-if-phy-probing-fails.patch
+net-phy-remove-phy-ports-upon-probe-failure.patch
+net-phy-clean-the-phy_ports-after-unregistering-the-.patch
+net-phy-don-t-try-to-setup-phy-driven-sfp-cages-when.patch
+net-qrtr-fix-refcount-saturation-and-potential-uaf-i.patch
+net-mlx5-fix-slab-out-of-bounds-in-mlx5_query_nic_vp.patch
+net-mlx5e-xsk-fix-dma-and-xdp_frame-leak-on-xdp_tx-x.patch
+net-mlx5-use-effective-affinity-mask-for-irq-selecti.patch
+ipv6-sit-reload-inner-ipv6-header-after-gso-offloads.patch
+net-openvswitch-fix-possible-kfree_skb-of-err_ptr.patch
+r8152-handle-the-return-value-of-usb_reset_device.patch
+gpio-zynq-fix-runtime-pm-leak-on-remove.patch
+gpio-rockchip-fix-generic-irq-chip-leak-on-remove.patch
+net-mctp-usb-fix-race-between-urb-completion-and-rx_.patch
+net-mctp-usb-don-t-fail-mctp_usb_rx_queue-on-a-defer.patch
+esp-fix-page-frag-reference-leak-on-skb_to_sgvec-fai.patch
+asoc-sof-amd-fix-for-ipc-flags-check.patch
+sctp-fix-uninit-value-in-__sctp_rcv_asconf_lookup.patch
+ip6_vti-set-netns_immutable-on-the-fallback-device.patch
+sctp-validate-embedded-init-chunk-and-address-list-l.patch
+net-guard-timestamp-cmsgs-to-real-error-queue-skbs.patch
+net-rds-fix-null-deref-in-rds_ib_send_cqe_handler-on.patch
+tun-zero-the-whole-vnet-header-in-tun_put_user.patch
+ptp-ocp-fix-resource-freeing-order.patch
+ip6_vti-fix-incorrect-tunnel-matching-in-vti6_tnl_lo.patch
+rds-mark-snapshot-pages-dirty-in-rds_info_getsockopt.patch
+spi-rzv2h-rspi-fix-spdr-read-access-width-for-16-bit.patch
+netfilter-revalidate-bridge-ports.patch
+netfilter-nf_conntrack-destroy-stale-expectfn-expect.patch
+netfilter-x_tables-avoid-leaking-percpu-counter-poin.patch
+netfilter-nf_log-validate-mac-header-was-set-before-.patch
+netfilter-nft_exthdr-fix-register-tracking-for-f_pre.patch
+net-mvpp2-sync-rx-data-at-the-hardware-packet-offset.patch
+net-mvpp2-limit-xdp-frame-size-to-the-rx-buffer.patch
+net-mvpp2-refill-rx-buffers-before-xdp-or-skb-use.patch
+net-mvpp2-build-skb-from-xdp-adjusted-data-on-xdp_pa.patch
+net-txgbe-initialize-module-info-buffer.patch
+net-txgbe-distinguish-module-types-by-checking-ident.patch
+net-txgbe-initialize-phy-interface-to-0.patch
+ipv6-fix-a-potential-npd-in-cleanup_prefix_route.patch
+asoc-sdca-fix-null-pointer-dereference-in-sdca_dev_u.patch
--- /dev/null
+From 7b73751f13da4144f1db9ab4991ac02b93ae77b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jun 2026 20:08:17 +0800
+Subject: spi: rzv2h-rspi: Fix SPDR read access width for 16-bit RX
+
+From: Felix Gu <ustc.gu@gmail.com>
+
+[ Upstream commit 310628484ef06f95c5589374fade917a5689787b ]
+
+The RZ/V2H hardware manual (section 7.5.2.2.1) specifies that read access
+size for the SPI Data Register (SPDR) are fixed at 32 bits. The
+RZV2H_RSPI_RX macro for the 16-bit data path used readw(), violating
+this requirement.
+
+Switch to readl() for the 16-bit RX path to conform to the hardware
+specification.
+
+Fixes: 8b61c8919dff ("spi: Add driver for the RZ/V2H(P) RSPI IP")
+Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Felix Gu <ustc.gu@gmail.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+Link: https://patch.msgid.link/20260610-rzv2h-rspi-v2-1-40c80b4a2c90@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-rzv2h-rspi.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
+index 53c44799fab71d..6fc81ccbcad5a2 100644
+--- a/drivers/spi/spi-rzv2h-rspi.c
++++ b/drivers/spi/spi-rzv2h-rspi.c
+@@ -133,8 +133,9 @@ static inline void rzv2h_rspi_rx_##type(struct rzv2h_rspi_priv *rspi, \
+ RZV2H_RSPI_TX(writel, u32)
+ RZV2H_RSPI_TX(writew, u16)
+ RZV2H_RSPI_TX(writeb, u8)
++/* The read access size for RSPI_SPDR is fixed at 32 bits */
+ RZV2H_RSPI_RX(readl, u32)
+-RZV2H_RSPI_RX(readw, u16)
++RZV2H_RSPI_RX(readl, u16)
+ RZV2H_RSPI_RX(readl, u8)
+
+ static void rzv2h_rspi_reg_rmw(const struct rzv2h_rspi_priv *rspi,
+--
+2.53.0
+
--- /dev/null
+From 504888b2191dd25c0b63d5054c75ca8422efbc11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 11:21:34 +0000
+Subject: tcp: restrict SO_ATTACH_FILTER to priv users
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 5d39580f68e6ddeedd15e587282207489dfb3da2 ]
+
+This patch restricts the use of SO_ATTACH_FILTER (cBPF) on TCP sockets
+to users with CAP_NET_ADMIN capability.
+
+This blocks potential side-channel attack where an unprivileged application
+attaches a filter to leak TCP sequence/acknowledgment numbers.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Tamir Shahar <tamirthesis@gmail.com>
+Reported-by: Amit Klein <aksecurity@gmail.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Andrii Nakryiko <andrii@kernel.org>
+Cc: Martin KaFai Lau <martin.lau@linux.dev>
+Cc: Eduard Zingerman <eddyz87@gmail.com>
+Cc: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Cc: Song Liu <song@kernel.org>
+Cc: Yonghong Song <yonghong.song@linux.dev>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: Stanislav Fomichev <sdf@fomichev.me>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/core/sock.c b/net/core/sock.c
+index b197a795306392..d317b4a8b85a25 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1463,6 +1463,11 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
+ case SO_ATTACH_FILTER: {
+ struct sock_fprog fprog;
+
++ if (sk_is_tcp(sk) &&
++ !sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
++ ret = -EPERM;
++ break;
++ }
+ ret = copy_bpf_fprog_from_user(&fprog, optval, optlen);
+ if (!ret)
+ ret = sk_attach_filter(&fprog, sk);
+--
+2.53.0
+
--- /dev/null
+From 88c468a539d7387564f56753d8e2c008b2b21447 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jun 2026 22:44:28 -0700
+Subject: tun: zero the whole vnet header in tun_put_user()
+
+From: Xiang Mei <xmei5@asu.edu>
+
+[ Upstream commit 7f2fcff15e99bb852f6967396ed12b38376e2c8d ]
+
+tun_put_user() declares an on-stack struct virtio_net_hdr_v1_hash_tunnel
+without zeroing it. For a non-tunnel skb, virtio_net_hdr_tnl_from_skb()
+only initializes the first 10 bytes (sizeof(struct virtio_net_hdr)),
+leaving bytes 10..23 (num_buffers and the hash/tunnel fields) as stack
+garbage.
+
+An unprivileged user can set the vnet header size to 24 with
+TUNSETVNETHDRSZ, so __tun_vnet_hdr_put() copies all 24 bytes of the
+partially-initialized struct to userspace, leaking 14 bytes of kernel
+stack on every read of a non-tunnel packet.
+
+Fix it the same way tun_get_user() already does by zeroing the whole
+header right after declaration.
+
+Fixes: 288f30435132 ("tun: enable gso over UDP tunnel support.")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260607054428.3050243-1-xmei5@asu.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index ca0ae5df73af78..a0bd803e5fb4d5 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2068,6 +2068,7 @@ static ssize_t tun_put_user(struct tun_struct *tun,
+ struct virtio_net_hdr_v1_hash_tunnel hdr;
+ struct virtio_net_hdr *gso;
+
++ memset(&hdr, 0, sizeof(hdr));
+ ret = tun_vnet_hdr_tnl_from_skb(tun->flags, tun->dev, skb,
+ &hdr);
+ if (ret)
+--
+2.53.0
+
--- /dev/null
+From db3862c70913c6fda4f2071a715ef0b2ab18128c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 18:53:28 +0800
+Subject: xfrm: iptfs: fix use-after-free on first_skb in
+ __input_process_payload
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit eb48730bb827d1550401a5d391903f9d90b493c8 ]
+
+__input_process_payload() stores first_skb into xtfs->ra_newskb under
+drop_lock when starting partial reassembly, then unlocks and breaks out
+of the processing loop. The post-loop check reads xtfs->ra_newskb
+without the lock to decide whether first_skb is still owned:
+
+ if (first_skb && first_iplen && !defer && first_skb != xtfs->ra_newskb)
+
+Between spin_unlock and this read, a concurrent CPU running
+iptfs_reassem_cont() (or the drop_timer hrtimer) can complete
+reassembly, NULL xtfs->ra_newskb, and free the skb. The check then
+evaluates first_skb != NULL as true, and pskb_trim/ip_summed/consume_skb
+operate on the freed skb — a use-after-free in skbuff_head_cache.
+
+Replace the unlocked read with a local bool that records whether
+first_skb was handed to the reassembly state in the current call. The
+flag is set after the existing spin_unlock, before the break, using the
+pointer equality that is stable at that point (first_skb == skb iff
+first_skb was stored in ra_newskb).
+
+Fixes: 3f3339885fb3 ("xfrm: iptfs: add reusing received skb for the tunnel egress packet")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_iptfs.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/xfrm/xfrm_iptfs.c b/net/xfrm/xfrm_iptfs.c
+index 6c6bbc0405170c..f25504610d8b23 100644
+--- a/net/xfrm/xfrm_iptfs.c
++++ b/net/xfrm/xfrm_iptfs.c
+@@ -954,6 +954,7 @@ static bool __input_process_payload(struct xfrm_state *x, u32 data,
+ u32 first_iplen, iphlen, iplen, remaining, tail;
+ u32 capturelen;
+ u64 seq;
++ bool first_skb_partial = false;
+
+ xtfs = x->mode_data;
+ net = xs_net(x);
+@@ -1161,6 +1162,7 @@ static bool __input_process_payload(struct xfrm_state *x, u32 data,
+
+ spin_unlock(&xtfs->drop_lock);
+
++ first_skb_partial = (first_skb == skb);
+ break;
+ }
+
+@@ -1172,7 +1174,7 @@ static bool __input_process_payload(struct xfrm_state *x, u32 data,
+ /* this should not happen from the above code */
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINIPTFSERROR);
+
+- if (first_skb && first_iplen && !defer && first_skb != xtfs->ra_newskb) {
++ if (first_skb && first_iplen && !defer && !first_skb_partial) {
+ /* first_skb is queued b/c !defer and not partial */
+ if (pskb_trim(first_skb, first_iplen)) {
+ /* error trimming */
+--
+2.53.0
+
--- /dev/null
+From 9643d2d718b22bf55bfaed5306b895742c17facf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2026 18:49:05 +0900
+Subject: xfrm: policy: fix use-after-free on inexact bin in
+ xfrm_policy_bysel_ctx()
+
+From: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+
+[ Upstream commit 7f2d76c9c03257c0782afef9d95321fa04096f60 ]
+
+Fix the race by pruning the bin while still holding xfrm_policy_lock,
+before dropping it. Use __xfrm_policy_inexact_prune_bin() directly since
+the lock is already held. The wrapper xfrm_policy_inexact_prune_bin()
+becomes unused and is removed.
+
+Race:
+
+ CPU0 (XFRM_MSG_DELPOLICY) CPU1 (XFRM_MSG_NEWSPDINFO)
+ ========================== ==========================
+ xfrm_policy_bysel_ctx():
+ spin_lock_bh(xfrm_policy_lock)
+ bin = xfrm_policy_inexact_lookup()
+ __xfrm_policy_unlink(pol)
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_kill(ret)
+ // wide window, lock not held
+ xfrm_hash_rebuild():
+ spin_lock_bh(xfrm_policy_lock)
+ __xfrm_policy_inexact_flush():
+ kfree_rcu(bin) // bin freed
+ spin_unlock_bh(xfrm_policy_lock)
+ xfrm_policy_inexact_prune_bin(bin)
+ // UAF: bin is freed
+
+Fixes: 6be3b0db6db8 ("xfrm: policy: add inexact policy search tree infrastructure")
+Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index d904352fb24276..97b5ff9687a30c 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1156,15 +1156,6 @@ static void __xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b, bool
+ }
+ }
+
+-static void xfrm_policy_inexact_prune_bin(struct xfrm_pol_inexact_bin *b)
+-{
+- struct net *net = read_pnet(&b->k.net);
+-
+- spin_lock_bh(&net->xfrm.xfrm_policy_lock);
+- __xfrm_policy_inexact_prune_bin(b, false);
+- spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+-}
+-
+ static void __xfrm_policy_inexact_flush(struct net *net)
+ {
+ struct xfrm_pol_inexact_bin *bin, *t;
+@@ -1707,12 +1698,12 @@ xfrm_policy_bysel_ctx(struct net *net, const struct xfrm_mark *mark, u32 if_id,
+ }
+ ret = pol;
+ }
++ if (bin && delete)
++ __xfrm_policy_inexact_prune_bin(bin, false);
+ spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+
+ if (ret && delete)
+ xfrm_policy_kill(ret);
+- if (bin && delete)
+- xfrm_policy_inexact_prune_bin(bin);
+ return ret;
+ }
+ EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
+--
+2.53.0
+