From: Greg Kroah-Hartman Date: Thu, 28 May 2026 11:30:57 +0000 (+0200) Subject: 7.0-stable patches X-Git-Tag: v5.10.258~37 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=5be439679acfd869056f7303e51dd95ce8f45294;p=thirdparty%2Fkernel%2Fstable-queue.git 7.0-stable patches added patches: af_unix-fix-uaf-read-of-tail-len-in-unix_stream_data_wait.patch ice-fix-locking-around-wait_event_interruptible_locked_irq.patch ice-fix-setting-promisc-mode-while-adding-vid-filter.patch ice-fix-vf-queue-configuration-with-low-mtu-values.patch ice-restore-ptp-rx-timestamp-config-after-ethtool-set-channels.patch igc-fix-potential-skb-leak-in-igc_fpe_xmit_smd_frame.patch ipv4-raw-reject-ip_hdrincl-packets-with-ihl-5.patch ipv6-ioam-add-null-check-for-idev-in-ipv6_hop_ioam.patch ixgbevf-fix-use-after-free-in-vepa-multicast-source-pruning.patch l2tp-use-list_del_rcu-in-l2tp_session_unhash.patch lsm-hold-cred_guard_mutex-for-lsm_set_self_attr.patch mptcp-do-not-drop-partial-packets.patch mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch mptcp-reset-rcv-wnd-on-disconnect.patch octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.patch octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch octeontx2-pf-fix-double-free-in-rvu_rep_rsrc_init.patch qed-fix-double-free-in-qed_cxt_tables_alloc.patch rbd-eliminate-a-race-in-lock_dwork-draining-on-unmap.patch ring-buffer-fix-reporting-of-missed-events-in-iterator.patch ring-buffer-flush-and-stop-persistent-ring-buffer-on-panic.patch selftests-mptcp-drop-nanoseconds-width-specifier.patch vsock-virtio-reset-connection-on-receiving-queue-overflow.patch vsock-vmci-fix-uaf-when-peer-resets-connection-during-handshake.patch wifi-ath11k-clear-shared-srng-pointer-state-on-restart.patch wifi-cfg80211-advance-loop-vars-in-cfg80211_merge_profile.patch wifi-iwlwifi-mld-stop-tx-during-firmware-restart.patch wifi-iwlwifi-mvm-fix-driver-set-tx-rates-on-old-devices.patch wifi-mac80211-capture-fast-rx-rate-before-mesh-reuses-skb-cb.patch wifi-mac80211-consume-only-present-negotiated-ttlm-maps.patch --- diff --git a/queue-7.0/af_unix-fix-uaf-read-of-tail-len-in-unix_stream_data_wait.patch b/queue-7.0/af_unix-fix-uaf-read-of-tail-len-in-unix_stream_data_wait.patch new file mode 100644 index 0000000000..d7369a9afb --- /dev/null +++ b/queue-7.0/af_unix-fix-uaf-read-of-tail-len-in-unix_stream_data_wait.patch @@ -0,0 +1,163 @@ +From be309f8eae8b474a4a617eaae01324da996fc719 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Mon, 18 May 2026 18:51:30 +0200 +Subject: af_unix: Fix UAF read of tail->len in unix_stream_data_wait() + +From: Jann Horn + +commit be309f8eae8b474a4a617eaae01324da996fc719 upstream. + +unix_stream_data_wait() does skb_peek_tail(&sk->sk_receive_queue) without +holding any lock that prevents SKBs on that queue from being dequeued and +freed. +This has been the case since commit 79f632c71bea ("unix/stream: fix +peeking with an offset larger than data in queue"). +The first consequence of this is that the pointer comparison +`tail != last` can be false even if `last` semantically refers to an +already-freed SKB while `tail` is a new SKB allocated at the same address; +which can cause unix_stream_data_wait() to wrongly keep blocking after new +data has arrived, but only in a weird scenario where a peeking recv() and +a normal recv() on the same socket are racing, which is probably not a +real problem. + +But since commit 2b514574f7e8 ("net: af_unix: implement splice for stream +af_unix sockets"), `tail` is actually dereferenced, which can cause UAF in +the following race scenario (where test_setup() runs single-threaded, +and afterwards, test_thread1() and test_thread2() run concurrently in +two threads: +``` +static int socks[2]; +void test_setup(void) { + socketpair(AF_UNIX, SOCK_STREAM, 0, socks); + send(socks[1], "A", 1, 0); + int peekoff = 1; + setsockopt(socks[0], SOL_SOCKET, SO_PEEK_OFF, &peekoff, sizeof(peekoff)); +} +void test_thread1(void) { + char dummy; + recv(socks[0], &dummy, 1, MSG_PEEK); +} +void test_thread2(void) { + char dummy; + recv(socks[0], &dummy, 1, 0); + shutdown(socks[1], SHUT_WR); +} +``` + +when racing like this: +``` +thread1 thread2 +unix_stream_read_generic + mutex_lock(&u->iolock) + skb_peek(&sk->sk_receive_queue) + skb_peek_next(skb, &sk->sk_receive_queue) + mutex_unlock(&u->iolock) + unix_stream_read_generic + unix_state_lock(sk) + skb_peek(&sk->sk_receive_queue) + unix_state_unlock(sk) + unix_stream_data_wait + unix_state_lock(sk) + tail = skb_peek_tail(&sk->sk_receive_queue) + spin_lock(&sk->sk_receive_queue.lock) + __skb_unlink(skb, &sk->sk_receive_queue) + spin_unlock(&sk->sk_receive_queue.lock) + consume_skb(skb) [frees the SKB] + `tail != last`: false + `tail`: true + `tail->len != last_len` ***UAF*** +``` + +Fix the UAF by removing the read of tail->len; checking tail->len would +only make sense if SKBs in the receive queue of a UNIX socket could grow, +which can no longer happen. + +Kuniyuki explained: + +> When commit 869e7c62486e ("net: af_unix: implement stream sendpage +> support") added sendpage() support, data could be appended to the last +> skb in the receiver's queue. +> +> That's why we needed to check if the length of the last skb was changed +> while waiting for new data in unix_stream_data_wait(). +> +> However, commit a0dbf5f818f9 ("af_unix: Support MSG_SPLICE_PAGES") and +> commit 57d44a354a43 ("unix: Convert unix_stream_sendpage() to use +> MSG_SPLICE_PAGES") refactored sendmsg(), and now data is always added +> to a new skb. + +That means this fix is not suitable for kernels before 6.5. + +Fixes: 2b514574f7e8 ("net: af_unix: implement splice for stream af_unix sockets") +Cc: stable@vger.kernel.org # 6.5.x +Signed-off-by: Jann Horn +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20260518-b4-unix-recv-wait-hotfix-v2-1-83e29ce8ad31@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/unix/af_unix.c | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -2707,8 +2707,7 @@ static int unix_read_skb(struct sock *sk + * Sleep until more data has arrived. But check for races.. + */ + static long unix_stream_data_wait(struct sock *sk, long timeo, +- struct sk_buff *last, unsigned int last_len, +- bool freezable) ++ struct sk_buff *last, bool freezable) + { + unsigned int state = TASK_INTERRUPTIBLE | freezable * TASK_FREEZABLE; + struct sk_buff *tail; +@@ -2721,7 +2720,6 @@ static long unix_stream_data_wait(struct + + tail = skb_peek_tail(&sk->sk_receive_queue); + if (tail != last || +- (tail && tail->len != last_len) || + sk->sk_err || + (sk->sk_shutdown & RCV_SHUTDOWN) || + signal_pending(current) || +@@ -2917,7 +2915,6 @@ static int unix_stream_read_generic(stru + int flags = state->flags; + bool check_creds = false; + struct scm_cookie scm; +- unsigned int last_len; + struct unix_sock *u; + int copied = 0; + int err = 0; +@@ -2963,7 +2960,6 @@ redo: + goto unlock; + } + last = skb = skb_peek(&sk->sk_receive_queue); +- last_len = last ? last->len : 0; + + again: + #if IS_ENABLED(CONFIG_AF_UNIX_OOB) +@@ -2997,8 +2993,7 @@ again: + + mutex_unlock(&u->iolock); + +- timeo = unix_stream_data_wait(sk, timeo, last, +- last_len, freezable); ++ timeo = unix_stream_data_wait(sk, timeo, last, freezable); + + if (signal_pending(current)) { + err = sock_intr_errno(timeo); +@@ -3015,7 +3010,6 @@ unlock: + while (skip >= unix_skb_len(skb)) { + skip -= unix_skb_len(skb); + last = skb; +- last_len = skb->len; + skb = skb_peek_next(skb, &sk->sk_receive_queue); + if (!skb) + goto again; +@@ -3090,7 +3084,6 @@ unlock: + + skip = 0; + last = skb; +- last_len = skb->len; + unix_state_lock(sk); + skb = skb_peek_next(skb, &sk->sk_receive_queue); + if (skb) diff --git a/queue-7.0/ice-fix-locking-around-wait_event_interruptible_locked_irq.patch b/queue-7.0/ice-fix-locking-around-wait_event_interruptible_locked_irq.patch new file mode 100644 index 0000000000..75bc4c4d2c --- /dev/null +++ b/queue-7.0/ice-fix-locking-around-wait_event_interruptible_locked_irq.patch @@ -0,0 +1,82 @@ +From 89bbff099bfc94888eb942d5b981592bbbe0c856 Mon Sep 17 00:00:00 2001 +From: Jacob Keller +Date: Fri, 15 May 2026 11:24:08 -0700 +Subject: ice: fix locking around wait_event_interruptible_locked_irq + +From: Jacob Keller + +commit 89bbff099bfc94888eb942d5b981592bbbe0c856 upstream. + +Commit 50327223a8bb ("ice: add lock to protect low latency interface") +introduced a wait queue used to protect the low latency timer interface. +The queue is used with the wait_event_interruptible_locked_irq macro, which +unlocks the wait queue lock while sleeping. The irq variant uses +spin_lock_irq and spin_unlock_irq to manage this. The wait queue lock was +previously locked using spin_lock_irqsave. This difference in lock variants +could lead to issues, since wait_event would unlock the wait queue and +restore interrupts while sleeping. + +The ice_read_phy_tstamp_ll_e810() function is ultimately called through +ice_read_phy_tstamp, which is called from ice_ptp_process_tx_tstamp or +ice_ptp_clear_unexpected_tx_ready. The former is called through the +miscellaneous IRQ thread function, while the latter is called from the +service task work queue thread. Neither of these functions has interrupts +disabled, so use spin_lock_irq instead of spin_lock_irqsave. + +Fixes: 50327223a8bb ("ice: add lock to protect low latency interface") +Cc: stable@vger.kernel.org +Reported-by: Jakub Kicinski +Closes: https://lore.kernel.org/netdev/20250109181823.77f44c69@kernel.org/ +Signed-off-by: Jacob Keller +Signed-off-by: Aleksandr Loktionov +Reviewed-by: Simon Horman +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Link: https://patch.msgid.link/20260515182419.1597859-2-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +@@ -4503,18 +4503,17 @@ static int + ice_read_phy_tstamp_ll_e810(struct ice_hw *hw, u8 idx, u8 *hi, u32 *lo) + { + struct ice_e810_params *params = &hw->ptp.phy.e810; +- unsigned long flags; + u32 val; + int err; + +- spin_lock_irqsave(¶ms->atqbal_wq.lock, flags); ++ spin_lock_irq(¶ms->atqbal_wq.lock); + + /* Wait for any pending in-progress low latency interrupt */ + err = wait_event_interruptible_locked_irq(params->atqbal_wq, + !(params->atqbal_flags & + ATQBAL_FLAGS_INTR_IN_PROGRESS)); + if (err) { +- spin_unlock_irqrestore(¶ms->atqbal_wq.lock, flags); ++ spin_unlock_irq(¶ms->atqbal_wq.lock); + return err; + } + +@@ -4529,7 +4528,7 @@ ice_read_phy_tstamp_ll_e810(struct ice_h + REG_LL_PROXY_H); + if (err) { + ice_debug(hw, ICE_DBG_PTP, "Failed to read PTP timestamp using low latency read\n"); +- spin_unlock_irqrestore(¶ms->atqbal_wq.lock, flags); ++ spin_unlock_irq(¶ms->atqbal_wq.lock); + return err; + } + +@@ -4539,7 +4538,7 @@ ice_read_phy_tstamp_ll_e810(struct ice_h + /* Read the low 32 bit value and set the TS valid bit */ + *lo = rd32(hw, REG_LL_PROXY_L) | TS_VALID; + +- spin_unlock_irqrestore(¶ms->atqbal_wq.lock, flags); ++ spin_unlock_irq(¶ms->atqbal_wq.lock); + + return 0; + } diff --git a/queue-7.0/ice-fix-setting-promisc-mode-while-adding-vid-filter.patch b/queue-7.0/ice-fix-setting-promisc-mode-while-adding-vid-filter.patch new file mode 100644 index 0000000000..f52f82484c --- /dev/null +++ b/queue-7.0/ice-fix-setting-promisc-mode-while-adding-vid-filter.patch @@ -0,0 +1,56 @@ +From ebc8de716c9ec2be384abdc2dd866da26c6580d1 Mon Sep 17 00:00:00 2001 +From: Marcin Szycik +Date: Fri, 15 May 2026 11:24:10 -0700 +Subject: ice: fix setting promisc mode while adding VID filter + +From: Marcin Szycik + +commit ebc8de716c9ec2be384abdc2dd866da26c6580d1 upstream. + +There are at least two paths through which VSI promiscuous mode can be +independently configured via ice_fltr_set_vsi_promisc(): +- ice_vlan_rx_add_vid() (netdev op) +- ice_service_task() -> ... -> ice_set_promisc() + +Both paths may try to program promiscuous mode concurrently. One such +scenario is: + +1. Add ice netdev to bond +2. Add the bond netdev to bridge +3. ice netdev enters allmulticast mode (IFF_ALLMULTI) +4. Service task programs promisc mode filter +5. Bridge -> bond calls ice_vlan_rx_add_vid() + +Crucially, ice_vlan_rx_add_vid() fails if ice_fltr_set_vsi_promisc() +returns any error, including -EEXIST. This causes VLAN filtering setup +to fail on the bond interface. ice_set_promisc() already handles -EEXIST +correctly. + +Fix by adding the same -EEXIST check to ice_vlan_rx_add_vid(): if the +promisc filter is already programmed, continue without returning error. + +Fixes: 1273f89578f2 ("ice: Fix broken IFF_ALLMULTI handling") +Cc: stable@vger.kernel.org +Signed-off-by: Marcin Szycik +Signed-off-by: Aleksandr Loktionov +Reviewed-by: Simon Horman +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Link: https://patch.msgid.link/20260515182419.1597859-4-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/ice/ice_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -3682,7 +3682,7 @@ int ice_vlan_rx_add_vid(struct net_devic + ret = ice_fltr_set_vsi_promisc(&vsi->back->hw, vsi->idx, + ICE_MCAST_VLAN_PROMISC_BITS, + vid); +- if (ret) ++ if (ret && ret != -EEXIST) + goto finish; + } + diff --git a/queue-7.0/ice-fix-vf-queue-configuration-with-low-mtu-values.patch b/queue-7.0/ice-fix-vf-queue-configuration-with-low-mtu-values.patch new file mode 100644 index 0000000000..19b1ceec7b --- /dev/null +++ b/queue-7.0/ice-fix-vf-queue-configuration-with-low-mtu-values.patch @@ -0,0 +1,58 @@ +From 3ba4dd024d26372733d1c02e13e076c6016e3320 Mon Sep 17 00:00:00 2001 +From: Jose Ignacio Tornos Martinez +Date: Fri, 15 May 2026 11:24:09 -0700 +Subject: ice: fix VF queue configuration with low MTU values + +From: Jose Ignacio Tornos Martinez + +commit 3ba4dd024d26372733d1c02e13e076c6016e3320 upstream. + +The ice driver's VF queue configuration validation rejects +databuffer_size values below 1024 bytes, which prevents VFs from +using MTU values below 871 bytes. + +The iavf driver calculates databuffer_size based on the MTU using: + databuffer_size = ALIGN(MTU + LIBETH_RX_LL_LEN, 128) + +where LIBETH_RX_LL_LEN = 26 (ETH_HLEN + 2*VLAN_HLEN + ETH_FCS_LEN). + +For MTU values below 871: + MTU 870: 870 + 26 = 896, aligned to 128 = 896 (< 1024, rejected) + MTU 871: 871 + 26 = 897, aligned to 128 = 1024 (>= 1024, accepted) + +The 1024-byte minimum seems unnecessarily restrictive, because the hardware +supports databuffer_size as low as 128 bytes (the alignment boundary), +which should allow MTU values down to the standard minimum of 68 bytes. + +I haven't found the reason why the limit was configured in the commit +9c7dd7566d18 ("ice: add validation in OP_CONFIG_VSI_QUEUES VF message"), so +with no more information and since it is working, change the minimum +databuffer_size validation from 1024 to 128 bytes to allow standard low +MTU values while still preventing invalid configurations. + +Fixes: 9c7dd7566d18 ("ice: add validation in OP_CONFIG_VSI_QUEUES VF message") +cc: stable@vger.kernel.org +Signed-off-by: Jose Ignacio Tornos Martinez +Reviewed-by: Jacob Keller +Reviewed-by: Michal Swiatkowski +Reviewed-by: Paul Menzel +Tested-by: Rafal Romanowski +Signed-off-by: Tony Nguyen +Link: https://patch.msgid.link/20260515182419.1597859-3-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/ice/virt/queues.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/intel/ice/virt/queues.c ++++ b/drivers/net/ethernet/intel/ice/virt/queues.c +@@ -840,7 +840,7 @@ int ice_vc_cfg_qs_msg(struct ice_vf *vf, + + if (qpi->rxq.databuffer_size != 0 && + (qpi->rxq.databuffer_size > ((16 * 1024) - 128) || +- qpi->rxq.databuffer_size < 1024)) ++ qpi->rxq.databuffer_size < 128)) + goto error_param; + + ring->rx_buf_len = qpi->rxq.databuffer_size; diff --git a/queue-7.0/ice-restore-ptp-rx-timestamp-config-after-ethtool-set-channels.patch b/queue-7.0/ice-restore-ptp-rx-timestamp-config-after-ethtool-set-channels.patch new file mode 100644 index 0000000000..e7118733de --- /dev/null +++ b/queue-7.0/ice-restore-ptp-rx-timestamp-config-after-ethtool-set-channels.patch @@ -0,0 +1,56 @@ +From 975b564d195b13ca6ee1ef5e6a9561734898eb17 Mon Sep 17 00:00:00 2001 +From: Grzegorz Nitka +Date: Fri, 15 May 2026 11:24:13 -0700 +Subject: ice: restore PTP Rx timestamp config after ethtool set-channels + +From: Grzegorz Nitka + +commit 975b564d195b13ca6ee1ef5e6a9561734898eb17 upstream. + +When ethtool -L changes queue counts, ice_vsi_recfg_qs() closes and +rebuilds the VSI, reallocating Rx rings. The newly allocated rings have +ptp_rx cleared, so RX hardware timestamps are no longer attached to skb +until hwtstamp configuration is applied again. + +Restore timestamp mode after ice_vsi_open() in the queue reconfiguration +path, matching reset/rebuild behavior and ensuring newly rebuilt Rx rings +have PTP RX timestamping re-enabled. + +Testing hints: +- run ptp4l application in client synchronization mode: + ptp4l -i ethX -m -s +- run PTP traffic +- change queue number on ethX netdev interface: + ethtool -L ethX combined new_queue_size +- observe ptp4l output +- expected result: no "received DELAY_REQ without timestamp" messages + +Fixes: 77a781155a65 ("ice: enable receive hardware timestamping") +Cc: stable@vger.kernel.org +Reviewed-by: Aleksandr Loktionov +Signed-off-by: Grzegorz Nitka +Reviewed-by: Simon Horman +Tested-by: Alexander Nowlin +Signed-off-by: Tony Nguyen +Link: https://patch.msgid.link/20260515182419.1597859-7-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/ice/ice_main.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -4104,6 +4104,12 @@ int ice_vsi_recfg_qs(struct ice_vsi *vsi + } + ice_pf_dcb_recfg(pf, locked); + ice_vsi_open(vsi); ++ /* Rx rings are reallocated during VSI rebuild and lose their ptp_rx ++ * flag. Restore timestamp mode so newly allocated rings are set up ++ * for hardware Rx timestamping. ++ */ ++ if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags)) ++ ice_ptp_restore_timestamp_mode(pf); + goto done; + + rebuild_err: diff --git a/queue-7.0/igc-fix-potential-skb-leak-in-igc_fpe_xmit_smd_frame.patch b/queue-7.0/igc-fix-potential-skb-leak-in-igc_fpe_xmit_smd_frame.patch new file mode 100644 index 0000000000..9a10065a85 --- /dev/null +++ b/queue-7.0/igc-fix-potential-skb-leak-in-igc_fpe_xmit_smd_frame.patch @@ -0,0 +1,61 @@ +From e935c37b8a94bb256fada6395a5d05e1c0c6bdaf Mon Sep 17 00:00:00 2001 +From: Kohei Enju +Date: Fri, 15 May 2026 11:24:16 -0700 +Subject: igc: fix potential skb leak in igc_fpe_xmit_smd_frame() + +From: Kohei Enju + +commit e935c37b8a94bb256fada6395a5d05e1c0c6bdaf upstream. + +When igc_fpe_init_tx_descriptor() fails, no one takes care of an +allocated skb, leaking it. [1] +Use dev_kfree_skb_any() on failure. + +Tested on an I226 adapter with the following command, while injecting +faults in igc_fpe_init_tx_descriptor() to trigger the error path. + # ethtool --set-mm $DEV verify-enabled on tx-enabled on pmac-enabled on + +[1] +unreferenced object 0xffff888113c6cdc0 (size 224): +... + backtrace (crc be3d3fda): + kmem_cache_alloc_node_noprof+0x3b1/0x410 + __alloc_skb+0xde/0x830 + igc_fpe_xmit_smd_frame.isra.0+0xad/0x1b0 + igc_fpe_send_mpacket+0x37/0x90 + ethtool_mmsv_verify_timer+0x15e/0x300 + +Cc: stable@vger.kernel.org +Fixes: 5422570c0010 ("igc: add support for frame preemption verification") +Signed-off-by: Kohei Enju +Reviewed-by: Simon Horman +Reviewed-by: Faizal Rahim +Tested-by: Avigail Dahan +Signed-off-by: Tony Nguyen +Link: https://patch.msgid.link/20260515182419.1597859-10-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/igc/igc_tsn.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/intel/igc/igc_tsn.c ++++ b/drivers/net/ethernet/intel/igc/igc_tsn.c +@@ -109,10 +109,16 @@ static int igc_fpe_xmit_smd_frame(struct + __netif_tx_lock(nq, cpu); + + err = igc_fpe_init_tx_descriptor(ring, skb, type); +- igc_flush_tx_descriptors(ring); ++ if (err) ++ goto err_free_skb_any; + ++ igc_flush_tx_descriptors(ring); + __netif_tx_unlock(nq); ++ return 0; + ++err_free_skb_any: ++ __netif_tx_unlock(nq); ++ dev_kfree_skb_any(skb); + return err; + } + diff --git a/queue-7.0/ipv4-raw-reject-ip_hdrincl-packets-with-ihl-5.patch b/queue-7.0/ipv4-raw-reject-ip_hdrincl-packets-with-ihl-5.patch new file mode 100644 index 0000000000..964adc8ac1 --- /dev/null +++ b/queue-7.0/ipv4-raw-reject-ip_hdrincl-packets-with-ihl-5.patch @@ -0,0 +1,86 @@ +From 915fab69823a14c170dbaa3b41978768e0fe62fc Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Tue, 12 May 2026 16:51:14 -0400 +Subject: ipv4: raw: reject IP_HDRINCL packets with ihl < 5 + +From: Michael Bommarito + +commit 915fab69823a14c170dbaa3b41978768e0fe62fc upstream. + +raw_send_hdrinc() validates that the caller-supplied IPv4 header +fits within the message length: + + iphlen = iph->ihl * 4; + err = -EINVAL; + if (iphlen > length) + goto error_free; + + if (iphlen >= sizeof(*iph)) { + /* fix up saddr, tot_len, id, csum, transport_header */ + } + +It does not, however, reject ihl < 5. For such a packet the +"if (iphlen >= sizeof(*iph))" branch is skipped, leaving the +crafted iphdr untouched, but the packet is still handed to +__ip_local_out() and onward. Downstream consumers that read +iph->ihl assume a sane value: net/ipv4/ah4.c:ah_output() in +particular subtracts sizeof(struct iphdr) from top_iph->ihl * 4 +and passes the (signed-int-negative, then cast to size_t) +result to memcpy(), producing an OOB access of length close to +SIZE_MAX and a host kernel panic. + +An IPv4 header with ihl < 5 is malformed by definition (RFC 791: +"Internet Header Length is the length of the internet header in +32 bit words ... Note that the minimum value for a correct header +is 5."). The kernel should not be willing to inject such a +packet into its own output path. + +Reject "iphlen < sizeof(*iph)" alongside the existing +"iphlen > length" check. This matches the principle that locally +constructed packets that re-enter the IP stack must pass the same +basic sanity tests that a foreign packet would be subjected to. + +Once this lands, the "if (iphlen >= sizeof(*iph))" wrapper around +the fixup branch becomes redundant; left in place to keep the +patch minimal and backport-friendly. A follow-up can unwrap it. + +Note that commit 86f4c90a1c5c ("ipv4, ipv6: ensure raw socket +message is big enough to hold an IP header") ensures the message +buffer is large enough to hold an iphdr, but does not constrain +the self-reported iph->ihl. + +Reachability: the malformed packet source is any caller with +CAP_NET_RAW, including an unprivileged process in a user+net +namespace on a kernel with CONFIG_USER_NS=y. The reproduced AH +crash also requires a matching xfrm AH policy on the outgoing +route; a container granted CAP_NET_ADMIN can install that state +and policy in its netns. Loopback bypasses xfrm_output, so the +trigger uses a real netdev. + +Reproduced on UML + KASAN: kernel-mode fault at addr 0x0 with +memcpy_orig at the crash site. Same shape reproduces inside a +rootless Docker container with --cap-add NET_ADMIN on a stock +distro kernel. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org +Suggested-by: Herbert Xu +Signed-off-by: Michael Bommarito +Link: https://patch.msgid.link/77ec2b5e8111961c2c39883c92e8aa2709039c17.1778614451.git.michael.bommarito@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/raw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -390,7 +390,7 @@ static int raw_send_hdrinc(struct sock * + * in, reject the frame as invalid + */ + err = -EINVAL; +- if (iphlen > length) ++ if (iphlen > length || iphlen < sizeof(*iph)) + goto error_free; + + if (iphlen >= sizeof(*iph)) { diff --git a/queue-7.0/ipv6-ioam-add-null-check-for-idev-in-ipv6_hop_ioam.patch b/queue-7.0/ipv6-ioam-add-null-check-for-idev-in-ipv6_hop_ioam.patch new file mode 100644 index 0000000000..cfbfdc82c0 --- /dev/null +++ b/queue-7.0/ipv6-ioam-add-null-check-for-idev-in-ipv6_hop_ioam.patch @@ -0,0 +1,71 @@ +From d4ea0dfd75011b78cebf3808f98ac4c4f51a6fb9 Mon Sep 17 00:00:00 2001 +From: Justin Iurman +Date: Sun, 17 May 2026 20:30:59 +0200 +Subject: ipv6: ioam: add NULL check for idev in ipv6_hop_ioam() + +From: Justin Iurman + +commit d4ea0dfd75011b78cebf3808f98ac4c4f51a6fb9 upstream. + +Reported by Sashiko: + +The function ipv6_hop_ioam() accesses +__in6_dev_get(skb->dev)->cnf.ioam6_enabled without validating the returned +idev pointer. Because addrconf_ifdown() can concurrently clear dev->ip6_ptr +via RCU, __in6_dev_get() can return NULL during interface teardown, which +could cause a NULL pointer dereference when processing an IOAM Hop-by-Hop +option. + +Let's add a check and use SKB_DROP_REASON_IPV6DISABLED accordingly. + +Fixes: 9ee11f0fff20 ("ipv6: ioam: Data plane support for Pre-allocated Trace") +Cc: stable@vger.kernel.org +Signed-off-by: Justin Iurman +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20260517183059.29140-1-justin.iurman@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/exthdrs.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/net/ipv6/exthdrs.c ++++ b/net/ipv6/exthdrs.c +@@ -910,16 +910,27 @@ static bool ipv6_hop_ra(struct sk_buff * + + static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff) + { ++ enum skb_drop_reason drop_reason; + struct ioam6_trace_hdr *trace; + struct ioam6_namespace *ns; ++ struct inet6_dev *idev; + struct ioam6_hdr *hdr; + ++ drop_reason = SKB_DROP_REASON_IP_INHDR; ++ + /* Bad alignment (must be 4n-aligned) */ + if (optoff & 3) + goto drop; + ++ /* Does the device still have IPv6 configuration? */ ++ idev = __in6_dev_get(skb->dev); ++ if (!idev) { ++ drop_reason = SKB_DROP_REASON_IPV6DISABLED; ++ goto drop; ++ } ++ + /* Ignore if IOAM is not enabled on ingress */ +- if (!READ_ONCE(__in6_dev_get(skb->dev)->cnf.ioam6_enabled)) ++ if (!READ_ONCE(idev->cnf.ioam6_enabled)) + goto ignore; + + /* Truncated Option header */ +@@ -972,7 +983,7 @@ ignore: + return true; + + drop: +- kfree_skb_reason(skb, SKB_DROP_REASON_IP_INHDR); ++ kfree_skb_reason(skb, drop_reason); + return false; + } + diff --git a/queue-7.0/ixgbevf-fix-use-after-free-in-vepa-multicast-source-pruning.patch b/queue-7.0/ixgbevf-fix-use-after-free-in-vepa-multicast-source-pruning.patch new file mode 100644 index 0000000000..b09780a07d --- /dev/null +++ b/queue-7.0/ixgbevf-fix-use-after-free-in-vepa-multicast-source-pruning.patch @@ -0,0 +1,62 @@ +From 5d49b568c188dc77199d8d2b959c91da8cc27cf1 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Fri, 15 May 2026 11:24:14 -0700 +Subject: ixgbevf: fix use-after-free in VEPA multicast source pruning + +From: Michael Bommarito + +commit 5d49b568c188dc77199d8d2b959c91da8cc27cf1 upstream. + +ixgbevf_clean_rx_irq() prunes frames whose source MAC matches the VF's +own address (VEPA multicast workaround) by freeing the skb and +continuing to the next descriptor: + + dev_kfree_skb_irq(skb); + continue; + +The skb pointer is declared outside the while loop and persists across +iterations. Because the continue skips the "skb = NULL" reset at the +bottom of the loop, the next iteration enters the "else if (skb)" path +and calls ixgbevf_add_rx_frag() on the freed skb, dereferencing +skb_shinfo(skb)->nr_frags - a use-after-free in NAPI softirq context. + +The sibling driver iavf already handles this correctly by nulling the +pointer before continuing. Apply the same pattern here. + +I do not have ixgbevf hardware; the bug was found by static analysis +(scan_drop_continue_loops.py + semgrep drop_continue_in_loop, multi-tool +corroboration with the highest score in the scan). The UAF was confirmed +under KASAN by loading a test module that reproduces the exact code +pattern (alloc skb, kfree_skb, then read skb_shinfo(skb)->nr_frags): + + BUG: KASAN: slab-use-after-free in ixgbevf_uaf_test_init+0x100/0x1000 + Read of size 8 at addr 000000006163ae78 by task insmod/30 + freed 208-byte region [000000006163adc0, 000000006163ae90) + +QEMU emulates igb (82576) but not ixgbe (82599), and the igbvf VF +driver does not include the VEPA source pruning path, so a full +end-to-end reproduction with emulated hardware was not possible. + +Fixes: bad17234ba70 ("ixgbevf: Change receive model to use double buffered page based receives") +Cc: stable@vger.kernel.org +Signed-off-by: Michael Bommarito +Reviewed-by: Simon Horman +Tested-by: Rafal Romanowski +Signed-off-by: Tony Nguyen +Link: https://patch.msgid.link/20260515182419.1597859-8-anthony.l.nguyen@intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c ++++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +@@ -1221,6 +1221,7 @@ static int ixgbevf_clean_rx_irq(struct i + ether_addr_equal(rx_ring->netdev->dev_addr, + eth_hdr(skb)->h_source)) { + dev_kfree_skb_irq(skb); ++ skb = NULL; + continue; + } + diff --git a/queue-7.0/l2tp-use-list_del_rcu-in-l2tp_session_unhash.patch b/queue-7.0/l2tp-use-list_del_rcu-in-l2tp_session_unhash.patch new file mode 100644 index 0000000000..5d29c4d687 --- /dev/null +++ b/queue-7.0/l2tp-use-list_del_rcu-in-l2tp_session_unhash.patch @@ -0,0 +1,61 @@ +From 979c017803c40829b03acd9e5236e354b7622360 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Mon, 18 May 2026 14:34:47 -0400 +Subject: l2tp: use list_del_rcu in l2tp_session_unhash + +From: Michael Bommarito + +commit 979c017803c40829b03acd9e5236e354b7622360 upstream. + +An unprivileged local user can pin a host CPU indefinitely in +l2tp_session_get_by_ifname() by issuing L2TP_CMD_SESSION_GET on +L2TP_ATTR_IFNAME concurrently with L2TP_CMD_SESSION_CREATE and +L2TP_CMD_SESSION_DELETE on the same tunnel. All three commands take +GENL_UNS_ADMIN_PERM, so CAP_NET_ADMIN in the netns user namespace +suffices; on any host that has l2tp_core loaded the trigger is +reachable from a standard `unshare -Urn` sandbox. + +l2tp_session_unhash() removes a session from tunnel->session_list +with list_del_init(), but that list is walked by +l2tp_session_get_by_ifname() with list_for_each_entry_rcu() under +rcu_read_lock_bh(). list_del_init() leaves the deleted entry's +next/prev self-pointing; a reader that has loaded the entry and +then advances pos->list.next reads &session->list, container_of()s +back to the same session, and list_for_each_entry_rcu() never +reaches the list head. The CPU stays in strcmp() inside the +walker, with BH and preemption disabled, so RCU grace periods on +the host stall behind it and the wedged thread cannot be killed +(SIGKILL is delivered on syscall return). + +Use list_del_rcu() to match the existing list_add_rcu() in +l2tp_session_register(); the deleted session remains visible to +in-flight walkers with consistent next/prev pointers until +kfree_rcu() in l2tp_session_free() releases it. tunnel->session_list +has exactly one list_del_init() call site; the list_del_init +(&session->clist) at l2tp_core.c:533 operates on the per-collision +list, which is not walked under RCU. list_empty(&session->list) is +not used anywhere in net/l2tp/ after the unhash point, so dropping +the post-delete self-init is safe; the fix has no userspace-visible +behavior change. + +Fixes: 89b768ec2dfef ("l2tp: use rcu list add/del when updating lists") +Cc: stable@vger.kernel.org # 6.11+ +Signed-off-by: Michael Bommarito +Link: https://patch.msgid.link/20260518183447.64078-1-michael.bommarito@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -1360,7 +1360,7 @@ static void l2tp_session_unhash(struct l + spin_lock_bh(&pn->l2tp_session_idr_lock); + + /* Remove from the per-tunnel list */ +- list_del_init(&session->list); ++ list_del_rcu(&session->list); + + /* Remove from per-net IDR */ + if (tunnel->version == L2TP_HDR_VER_3) { diff --git a/queue-7.0/lsm-hold-cred_guard_mutex-for-lsm_set_self_attr.patch b/queue-7.0/lsm-hold-cred_guard_mutex-for-lsm_set_self_attr.patch new file mode 100644 index 0000000000..03182e84b6 --- /dev/null +++ b/queue-7.0/lsm-hold-cred_guard_mutex-for-lsm_set_self_attr.patch @@ -0,0 +1,41 @@ +From 4a9b16541ad3faf8bccb398532bf3f8b6bbf1188 Mon Sep 17 00:00:00 2001 +From: Stephen Smalley +Date: Wed, 13 May 2026 14:05:06 -0400 +Subject: lsm: hold cred_guard_mutex for lsm_set_self_attr() + +From: Stephen Smalley + +commit 4a9b16541ad3faf8bccb398532bf3f8b6bbf1188 upstream. + +Just as proc_pid_attr_write() already does before calling the LSM +hook. This only matters for SELinux and AppArmor which check +whether the process is being ptraced and if so, whether to +allow the transition. + +Cc: stable@vger.kernel.org +Signed-off-by: Stephen Smalley +Acked-by: Casey Schaufler +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman +--- + security/lsm_syscalls.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/security/lsm_syscalls.c ++++ b/security/lsm_syscalls.c +@@ -57,7 +57,14 @@ u64 lsm_name_to_attr(const char *name) + SYSCALL_DEFINE4(lsm_set_self_attr, unsigned int, attr, struct lsm_ctx __user *, + ctx, u32, size, u32, flags) + { +- return security_setselfattr(attr, ctx, size, flags); ++ int rc; ++ ++ rc = mutex_lock_interruptible(¤t->signal->cred_guard_mutex); ++ if (rc < 0) ++ return rc; ++ rc = security_setselfattr(attr, ctx, size, flags); ++ mutex_unlock(¤t->signal->cred_guard_mutex); ++ return rc; + } + + /** diff --git a/queue-7.0/mptcp-do-not-drop-partial-packets.patch b/queue-7.0/mptcp-do-not-drop-partial-packets.patch new file mode 100644 index 0000000000..aa4a8eed78 --- /dev/null +++ b/queue-7.0/mptcp-do-not-drop-partial-packets.patch @@ -0,0 +1,74 @@ +From 50c2d91c5dfa0e465826ec1f8dbad9cdc254bd85 Mon Sep 17 00:00:00 2001 +From: Shardul Bankar +Date: Fri, 15 May 2026 06:27:32 +0200 +Subject: mptcp: do not drop partial packets + +From: Shardul Bankar + +commit 50c2d91c5dfa0e465826ec1f8dbad9cdc254bd85 upstream. + +When a packet arrives with map_seq < ack_seq < end_seq, the beginning +of the packet has already been acknowledged but the end contains new +data. Currently the entire packet is dropped as "old data," forcing +the sender to retransmit. + +Instead, skip the already-acked bytes by adjusting the skb offset and +enqueue only the new portion. Update bytes_received and ack_seq to +reflect the new data consumed. + +A previous attempt at this fix has been sent by Paolo Abeni [1], but had +issues [2]: it also added a zero-window check and changed rcv_wnd_sent +initialization, which caused test regressions. This version addresses +only the partial packet handling without modifying receive window +accounting. + +Fixes: ab174ad8ef76 ("mptcp: move ooo skbs into msk out of order queue.") +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/c9b426a4e163aa3c4fe8b80c79f1a610f47ae7d8.1763075056.git.pabeni@redhat.com [1] +Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/600 [2] +Signed-off-by: Shardul Bankar +[pabeni@redhat.com: update map] +Signed-off-by: Paolo Abeni +Reviewed-by: Matthieu Baerts (NGI0) +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-1-701e96419f2f@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/protocol.c | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -397,12 +397,26 @@ static bool __mptcp_move_skb(struct sock + return false; + } + +- /* old data, keep it simple and drop the whole pkt, sender +- * will retransmit as needed, if needed. ++ /* Completely old data? */ ++ if (!after64(MPTCP_SKB_CB(skb)->end_seq, msk->ack_seq)) { ++ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DUPDATA); ++ mptcp_drop(sk, skb); ++ return false; ++ } ++ ++ /* Partial packet: map_seq < ack_seq < end_seq. ++ * Skip the already-acked bytes and enqueue the new data. + */ +- MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DUPDATA); +- mptcp_drop(sk, skb); +- return false; ++ copy_len = MPTCP_SKB_CB(skb)->end_seq - msk->ack_seq; ++ MPTCP_SKB_CB(skb)->offset += msk->ack_seq - MPTCP_SKB_CB(skb)->map_seq; ++ MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq - ++ MPTCP_SKB_CB(skb)->map_seq; ++ msk->bytes_received += copy_len; ++ WRITE_ONCE(msk->ack_seq, msk->ack_seq + copy_len); ++ ++ skb_set_owner_r(skb, sk); ++ __skb_queue_tail(&sk->sk_receive_queue, skb); ++ return true; + } + + static void mptcp_stop_rtx_timer(struct sock *sk) diff --git a/queue-7.0/mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch b/queue-7.0/mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch new file mode 100644 index 0000000000..2204596098 --- /dev/null +++ b/queue-7.0/mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch @@ -0,0 +1,143 @@ +From 51e398a3b8961b26a8c0a4ba9a777c5339791707 Mon Sep 17 00:00:00 2001 +From: Li Xiasong +Date: Fri, 15 May 2026 06:27:33 +0200 +Subject: mptcp: pm: fix ADD_ADDR timer infinite retry on option space insufficient + +From: Li Xiasong + +commit 51e398a3b8961b26a8c0a4ba9a777c5339791707 upstream. + +When TCP option space is insufficient (e.g., when sending ADD_ADDR with an +IPv6 address and port while tcp_timestamps is enabled), the original code +jumped to out_unlock without clearing the addr_signal flag. This caused +mptcp_pm_add_timer to keep rescheduling indefinitely, not sending ADD_ADDR, +preventing subsequent addresses in the endpoint list from being announced. + +Handle this case by clearing the ADD_ADDR signal and skipping the matching +ADD_ADDR retransmission entry. The skip path cancels the matching timer +(with id check) and advances PM state progression, preserving forward +progress to subsequent PM work. + +This cancellation is inherently best-effort. A concurrent add_timer +callback may already be running and may acquire pm.lock before the +cancel path updates entry state. In that case, one final ADD_ADDR +transmit attempt can still be executed. + +Once the cancel path sets entry->retrans_times to ADD_ADDR_RETRANS_MAX, +the callback-side retrans_times check suppresses further ADD_ADDR +retransmissions. + +Note that when an ADD_ADDR is being prepared, a pure-ACK is queued. On +the output side, it means that it is fine to skip non-pure-ACK packets, +when drop_other_suboptions is set: a pure-ACK will be processed soon +after. + +Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout") +Cc: stable@vger.kernel.org +Signed-off-by: Li Xiasong +Reviewed-by: Matthieu Baerts (NGI0) +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-2-701e96419f2f@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/pm.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 46 insertions(+), 10 deletions(-) + +--- a/net/mptcp/pm.c ++++ b/net/mptcp/pm.c +@@ -364,7 +364,13 @@ static void mptcp_pm_add_timer(struct ti + + spin_lock_bh(&msk->pm.lock); + +- if (!mptcp_pm_should_add_signal_addr(msk)) { ++ /* The cancel path (mptcp_pm_del_add_timer()) can race with this ++ * callback. Once cancel updates retrans_times to MAX, suppress further ++ * retransmissions here. If this callback acquires pm.lock first, one ++ * final transmit attempt is still possible. ++ */ ++ if (entry->retrans_times < ADD_ADDR_RETRANS_MAX && ++ !mptcp_pm_should_add_signal_addr(msk)) { + pr_debug("retransmit ADD_ADDR id=%d\n", entry->addr.id); + mptcp_pm_announce_addr(msk, &entry->addr, false); + mptcp_pm_add_addr_send_ack(msk); +@@ -414,8 +420,12 @@ mptcp_pm_del_add_timer(struct mptcp_sock + /* Note: entry might have been removed by another thread. + * We hold rcu_read_lock() to ensure it is not freed under us. + */ +- if (stop_timer) +- sk_stop_timer_sync(sk, &entry->add_timer); ++ if (stop_timer) { ++ if (check_id) ++ sk_stop_timer(sk, &entry->add_timer); ++ else ++ sk_stop_timer_sync(sk, &entry->add_timer); ++ } + + rcu_read_unlock(); + return entry; +@@ -882,6 +892,7 @@ bool mptcp_pm_add_addr_signal(struct mpt + struct mptcp_addr_info *addr, bool *echo, + bool *drop_other_suboptions) + { ++ bool skip_add_addr = false; + int ret = false; + u8 add_addr; + u8 family; +@@ -903,24 +914,49 @@ bool mptcp_pm_add_addr_signal(struct mpt + } + + *echo = mptcp_pm_should_add_signal_echo(msk); +- port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port); +- +- family = *echo ? msk->pm.remote.family : msk->pm.local.family; +- if (remaining < mptcp_add_addr_len(family, *echo, port)) +- goto out_unlock; +- + if (*echo) { + *addr = msk->pm.remote; + add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_ECHO); ++ port = !!msk->pm.remote.port; ++ family = msk->pm.remote.family; + } else { + *addr = msk->pm.local; + add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_SIGNAL); ++ port = !!msk->pm.local.port; ++ family = msk->pm.local.family; + } +- WRITE_ONCE(msk->pm.addr_signal, add_addr); ++ ++ if (remaining < mptcp_add_addr_len(family, *echo, port)) { ++ struct net *net = sock_net((struct sock *)msk); ++ ++ if (!*drop_other_suboptions) ++ goto out_unlock; ++ ++ if (*echo) { ++ MPTCP_INC_STATS(net, MPTCP_MIB_ECHOADDTXDROP); ++ } else { ++ skip_add_addr = true; ++ MPTCP_INC_STATS(net, MPTCP_MIB_ADDADDRTXDROP); ++ } ++ goto drop_signal_mark; ++ } ++ + ret = true; + ++drop_signal_mark: ++ WRITE_ONCE(msk->pm.addr_signal, add_addr); ++ + out_unlock: + spin_unlock_bh(&msk->pm.lock); ++ ++ /* On pure-ACK option-space exhaustion, stop retrying this ADD_ADDR: ++ * clear the signal bit, cancel the matching retransmission timer, and ++ * let the PM state machine progress. ++ */ ++ if (skip_add_addr) { ++ mptcp_pm_del_add_timer(msk, addr, true); ++ mptcp_pm_subflow_established(msk); ++ } + return ret; + } + diff --git a/queue-7.0/mptcp-reset-rcv-wnd-on-disconnect.patch b/queue-7.0/mptcp-reset-rcv-wnd-on-disconnect.patch new file mode 100644 index 0000000000..340c0987a9 --- /dev/null +++ b/queue-7.0/mptcp-reset-rcv-wnd-on-disconnect.patch @@ -0,0 +1,43 @@ +From 0981f90e1a05773a4c29c6e720f5ea1e3c8f1876 Mon Sep 17 00:00:00 2001 +From: Paolo Abeni +Date: Fri, 15 May 2026 06:27:35 +0200 +Subject: mptcp: reset rcv wnd on disconnect + +From: Paolo Abeni + +commit 0981f90e1a05773a4c29c6e720f5ea1e3c8f1876 upstream. + +If the MPTCP socket fallback to TCP before the MP handshake completion, +the IASN remain 0, and the rcv_wnd_sent field is not explicitly +initialized, just incremented over time with the data transfer. + +At disconnect time such value is not cleared. If the next connection falls +back to TCP before the MP handshake completion, the data transfer will +keep incrementing the receive window end sequence starting from the last +value used in the previous connection: the announced window will be +unrelated from the actual receiver buffer size and likely too big. + +Address the issue zeroing the field at disconnect time. + +Fixes: b29fcfb54cd7 ("mptcp: full disconnect implementation") +Cc: stable@vger.kernel.org +Signed-off-by: Paolo Abeni +Reviewed-by: Matthieu Baerts (NGI0) +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-4-701e96419f2f@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/protocol.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -3470,6 +3470,7 @@ static int mptcp_disconnect(struct sock + + /* for fallback's sake */ + WRITE_ONCE(msk->ack_seq, 0); ++ atomic64_set(&msk->rcv_wnd_sent, 0); + + WRITE_ONCE(sk->sk_shutdown, 0); + sk_error_report(sk); diff --git a/queue-7.0/octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.patch b/queue-7.0/octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.patch new file mode 100644 index 0000000000..ba5423ced0 --- /dev/null +++ b/queue-7.0/octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.patch @@ -0,0 +1,56 @@ +From c0bf0a4f3f1f5f57aa83e1400ba4f56f0abfd542 Mon Sep 17 00:00:00 2001 +From: Sam Daly +Date: Wed, 13 May 2026 18:42:53 +0200 +Subject: octeontx2-af: CGX: add bounds check to cgx_speed_mbps index +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Sam Daly + +commit c0bf0a4f3f1f5f57aa83e1400ba4f56f0abfd542 upstream. + +cgx_speed_mbps has 13 elements but RESP_LINKSTAT_SPEED can yield values +0-15. If it returns a value >= 13, this causes an out-of-bounds array +access. Add a bounds check and default to speed 0 if the index is out of +range. + +Fixes: 61071a871ea6 ("octeontx2-af: Forward CGX link notifications to PFs") +Cc: Sunil Goutham +Cc: Linu Cherian +Cc: Geetha sowjanya +Cc: hariprasad +Cc: Subbaraya Sundeep +Cc: Andrew Lunn +Cc: stable +Signed-off-by: Sam Daly +Signed-off-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/2026051352-refined-demise-e88d@gregkh +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/marvell/octeontx2/af/cgx.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +@@ -1294,13 +1294,18 @@ static inline void link_status_user_form + struct cgx_link_user_info *linfo, + struct cgx *cgx, u8 lmac_id) + { ++ unsigned int speed; ++ + linfo->link_up = FIELD_GET(RESP_LINKSTAT_UP, lstat); + linfo->full_duplex = FIELD_GET(RESP_LINKSTAT_FDUPLEX, lstat); +- linfo->speed = cgx_speed_mbps[FIELD_GET(RESP_LINKSTAT_SPEED, lstat)]; + linfo->an = FIELD_GET(RESP_LINKSTAT_AN, lstat); + linfo->fec = FIELD_GET(RESP_LINKSTAT_FEC, lstat); + linfo->lmac_type_id = FIELD_GET(RESP_LINKSTAT_LMAC_TYPE, lstat); + ++ speed = FIELD_GET(RESP_LINKSTAT_SPEED, lstat); ++ linfo->speed = speed < ARRAY_SIZE(cgx_speed_mbps) ? ++ cgx_speed_mbps[speed] : 0; ++ + if (linfo->lmac_type_id >= LMAC_MODE_MAX) { + dev_err(&cgx->pdev->dev, "Unknown lmac_type_id %d reported by firmware on cgx port%d:%d", + linfo->lmac_type_id, cgx->cgx_id, lmac_id); diff --git a/queue-7.0/octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch b/queue-7.0/octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch new file mode 100644 index 0000000000..6196aafa77 --- /dev/null +++ b/queue-7.0/octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch @@ -0,0 +1,75 @@ +From 9b244c242bec48b37e82b89787afd6a4c43457e1 Mon Sep 17 00:00:00 2001 +From: Dawei Feng +Date: Fri, 15 May 2026 23:18:26 +0800 +Subject: octeontx2-pf: avoid double free of pool->stack on AQ init failure + +From: Dawei Feng + +commit 9b244c242bec48b37e82b89787afd6a4c43457e1 upstream. + +otx2_pool_aq_init() frees pool->stack when mailbox sync or retry +allocation fails, but leaves the pointer unchanged. Later, +otx2_sq_aura_pool_init() unwinds the partial setup through +otx2_aura_pool_free(), which frees pool->stack again. The CN20K-specific +cn20k_pool_aq_init() implementation has the same bug in +its corresponding error path. + +Set pool->stack to NULL immediately after the local free so the shared +cleanup path does not free the same stack again while cleaning up +partially initialized pool state. + +The bug was first flagged by an experimental analysis tool we are +developing for kernel memory-management bugs while analyzing +v6.13-rc1. The tool is still under development and is not yet publicly +available. Manual inspection confirms that the bug is still present in +v7.1-rc3. + +Runtime validation was not performed because reproducing this path +requires OcteonTX2/CN20K hardware. + +Fixes: caa2da34fd25 ("octeontx2-pf: Initialize and config queues") +Fixes: d322fbd17203 ("octeontx2-pf: Initialize cn20k specific aura and pool contexts") +Cc: stable@vger.kernel.org +Signed-off-by: Zilin Guan +Signed-off-by: Dawei Feng +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260515151826.1005397-1-dawei.feng@seu.edu.cn +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/marvell/octeontx2/nic/cn20k.c | 2 ++ + drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 2 ++ + 2 files changed, 4 insertions(+) + +--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.c +@@ -353,11 +353,13 @@ static int cn20k_pool_aq_init(struct otx + err = otx2_sync_mbox_msg(&pfvf->mbox); + if (err) { + qmem_free(pfvf->dev, pool->stack); ++ pool->stack = NULL; + return err; + } + aq = otx2_mbox_alloc_msg_npa_cn20k_aq_enq(&pfvf->mbox); + if (!aq) { + qmem_free(pfvf->dev, pool->stack); ++ pool->stack = NULL; + return -ENOMEM; + } + } +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +@@ -1482,11 +1482,13 @@ int otx2_pool_aq_init(struct otx2_nic *p + err = otx2_sync_mbox_msg(&pfvf->mbox); + if (err) { + qmem_free(pfvf->dev, pool->stack); ++ pool->stack = NULL; + return err; + } + aq = otx2_mbox_alloc_msg_npa_aq_enq(&pfvf->mbox); + if (!aq) { + qmem_free(pfvf->dev, pool->stack); ++ pool->stack = NULL; + return -ENOMEM; + } + } diff --git a/queue-7.0/octeontx2-pf-fix-double-free-in-rvu_rep_rsrc_init.patch b/queue-7.0/octeontx2-pf-fix-double-free-in-rvu_rep_rsrc_init.patch new file mode 100644 index 0000000000..abce443cdf --- /dev/null +++ b/queue-7.0/octeontx2-pf-fix-double-free-in-rvu_rep_rsrc_init.patch @@ -0,0 +1,61 @@ +From e8fb3de2a8effcaf62bec2c56b93d8bb480371d1 Mon Sep 17 00:00:00 2001 +From: Dawei Feng +Date: Wed, 13 May 2026 23:13:20 +0800 +Subject: octeontx2-pf: fix double free in rvu_rep_rsrc_init() + +From: Dawei Feng + +commit e8fb3de2a8effcaf62bec2c56b93d8bb480371d1 upstream. + +rvu_rep_rsrc_init() allocates queue memory before calling +otx2_init_hw_resources(). When hardware resource setup fails, +otx2_init_hw_resources() already unwinds the partially initialized +SQ, CQ, and aura state before returning an error. The representor +error path then calls otx2_free_hw_resources() again and can free +the same resources a second time. + +Fix this by splitting the cleanup labels so that a failure from +otx2_init_hw_resources() only releases queue memory. Keep the +otx2_free_hw_resources() call for failures that happen after +hardware resource initialization completed successfully. + +The bug was first flagged by an experimental analysis tool we are +developing for kernel memory-management bugs while analyzing +v6.13-rc1. The tool is still under development and is not yet publicly +available. Manual inspection confirms that the bug is still +present in v7.1-rc3. + +Runtime validation was not performed because reproducing this path +requires OcteonTX2 representor hardware. + +Fixes: 3937b7308d4f ("octeontx2-pf: Create representor netdev") +Cc: stable@vger.kernel.org # v6.13+ +Signed-off-by: Zilin Guan +Signed-off-by: Dawei Feng +Reviewed-by: Geetha sowjanya +Link: https://patch.msgid.link/20260513151320.213260-1-dawei.feng@seu.edu.cn +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/marvell/octeontx2/nic/rep.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c +@@ -609,7 +609,7 @@ static int rvu_rep_rsrc_init(struct otx2 + + err = otx2_init_hw_resources(priv); + if (err) +- goto err_free_rsrc; ++ goto err_free_mem; + + /* Set maximum frame size allowed in HW */ + err = otx2_hw_set_mtu(priv, priv->hw.max_mtu); +@@ -621,6 +621,7 @@ static int rvu_rep_rsrc_init(struct otx2 + + err_free_rsrc: + otx2_free_hw_resources(priv); ++err_free_mem: + otx2_free_queue_mem(qset); + return err; + } diff --git a/queue-7.0/qed-fix-double-free-in-qed_cxt_tables_alloc.patch b/queue-7.0/qed-fix-double-free-in-qed_cxt_tables_alloc.patch new file mode 100644 index 0000000000..20347af4cb --- /dev/null +++ b/queue-7.0/qed-fix-double-free-in-qed_cxt_tables_alloc.patch @@ -0,0 +1,54 @@ +From 2bccfb8476ca5f3548afbd623dc7a6980d4e77de Mon Sep 17 00:00:00 2001 +From: Dawei Feng +Date: Wed, 20 May 2026 15:03:23 +0800 +Subject: qed: fix double free in qed_cxt_tables_alloc() + +From: Dawei Feng + +commit 2bccfb8476ca5f3548afbd623dc7a6980d4e77de upstream. + +If one of the later PF or VF CID bitmap allocations fails, +qed_cid_map_alloc() jumps to cid_map_fail and frees the previously +allocated CID bitmaps before returning an error. qed_cxt_tables_alloc() +then calls qed_cxt_mngr_free(), which invokes qed_cid_map_free() +again. + +Fix this by setting each CID bitmap pointer to NULL after bitmap_free() +to avoid double free. + +The bug was first flagged by an experimental analysis tool we are +developing for kernel memory-management bugs while analyzing +v6.13-rc1. The tool is still under development and is not yet publicly +available. Manual inspection confirms that the bug is still +present in v7.1-rc3. + +Runtime reproduction was not attempted because exercising the failing +allocation path requires device-specific setup. + +Fixes: fe56b9e6a8d9 ("qed: Add module with basic common support") +Cc: stable@vger.kernel.org +Signed-off-by: Zilin Guan +Signed-off-by: Dawei Feng +Link: https://patch.msgid.link/20260520070323.2762379-1-dawei.feng@seu.edu.cn +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/qlogic/qed/qed_cxt.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c +@@ -1036,11 +1036,13 @@ static void qed_cid_map_free(struct qed_ + + for (type = 0; type < MAX_CONN_TYPES; type++) { + bitmap_free(p_mngr->acquired[type].cid_map); ++ p_mngr->acquired[type].cid_map = NULL; + p_mngr->acquired[type].max_count = 0; + p_mngr->acquired[type].start_cid = 0; + + for (vf = 0; vf < MAX_NUM_VFS; vf++) { + bitmap_free(p_mngr->acquired_vf[type][vf].cid_map); ++ p_mngr->acquired_vf[type][vf].cid_map = NULL; + p_mngr->acquired_vf[type][vf].max_count = 0; + p_mngr->acquired_vf[type][vf].start_cid = 0; + } diff --git a/queue-7.0/rbd-eliminate-a-race-in-lock_dwork-draining-on-unmap.patch b/queue-7.0/rbd-eliminate-a-race-in-lock_dwork-draining-on-unmap.patch new file mode 100644 index 0000000000..a5ca2ccf31 --- /dev/null +++ b/queue-7.0/rbd-eliminate-a-race-in-lock_dwork-draining-on-unmap.patch @@ -0,0 +1,101 @@ +From 9fc75b71fdd38465c76c6f6a884cdd4ae3c72d90 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Tue, 19 May 2026 23:07:26 +0200 +Subject: rbd: eliminate a race in lock_dwork draining on unmap + +From: Ilya Dryomov + +commit 9fc75b71fdd38465c76c6f6a884cdd4ae3c72d90 upstream. + +Given how rbd_lock_add_request() and rbd_img_exclusive_lock() are +written, lock_dwork may be (re)queued more than it's actually needed: +for example in case a new I/O request comes in while we are in the +middle of rbd_acquire_lock() on behalf of another I/O request. This is +expected and with rbd_release_lock() preemptively canceling lock_dwork +is benign under normal operation. + +A more problematic example is maybe_kick_acquire(): + + if (have_requests || delayed_work_pending(&rbd_dev->lock_dwork)) { + dout("%s rbd_dev %p kicking lock_dwork\n", __func__, rbd_dev); + mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); + } + +It's not unrealistic for lock_dwork to get canceled right after +delayed_work_pending() returns true and for mod_delayed_work() to +requeue it right there anyway. This is a classic TOCTOU race. + +When it comes to unmapping the image, there is an implicit assumption +of no self-initiated exclusive lock activity past the point of return +from rbd_dev_image_unlock() which unlocks the lock if it happens to be +held. This unlock is assumed to be final and lock_dwork (as well as +all other exclusive lock tasks, really) isn't expected to get queued +again. However, lock_dwork is canceled only in cancel_tasks_sync() +(i.e. later in the unmap sequence) and on top of that the cancellation +can get in effect nullified by maybe_kick_acquire(). This may result +in rbd_acquire_lock() executing after rbd_dev_device_release() and +rbd_dev_image_release() run and free and/or reset a bunch of things. +One of the possible failure modes then is a violated + + rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); + +in rbd_dev_header_info() which is called via rbd_dev_refresh() from +rbd_post_acquire_action(). + +Redo exclusive lock task draining to provide saner semantics and try +to meet the assumptions around rbd_dev_image_unlock(). + +Cc: stable@vger.kernel.org +Signed-off-by: Ilya Dryomov +Reviewed-by: Viacheslav Dubeyko +Signed-off-by: Greg Kroah-Hartman +--- + drivers/block/rbd.c | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +--- a/drivers/block/rbd.c ++++ b/drivers/block/rbd.c +@@ -4565,24 +4565,12 @@ out: + return ret; + } + +-static void cancel_tasks_sync(struct rbd_device *rbd_dev) +-{ +- dout("%s rbd_dev %p\n", __func__, rbd_dev); +- +- cancel_work_sync(&rbd_dev->acquired_lock_work); +- cancel_work_sync(&rbd_dev->released_lock_work); +- cancel_delayed_work_sync(&rbd_dev->lock_dwork); +- cancel_work_sync(&rbd_dev->unlock_work); +-} +- + /* + * header_rwsem must not be held to avoid a deadlock with + * rbd_dev_refresh() when flushing notifies. + */ + static void rbd_unregister_watch(struct rbd_device *rbd_dev) + { +- cancel_tasks_sync(rbd_dev); +- + mutex_lock(&rbd_dev->watch_mutex); + if (rbd_dev->watch_state == RBD_WATCH_STATE_REGISTERED) + __rbd_unregister_watch(rbd_dev); +@@ -6548,10 +6536,18 @@ out_err: + + static void rbd_dev_image_unlock(struct rbd_device *rbd_dev) + { ++ dout("%s rbd_dev %p\n", __func__, rbd_dev); ++ ++ disable_delayed_work_sync(&rbd_dev->lock_dwork); ++ disable_work_sync(&rbd_dev->unlock_work); ++ + down_write(&rbd_dev->lock_rwsem); + if (__rbd_is_lock_owner(rbd_dev)) + __rbd_release_lock(rbd_dev); + up_write(&rbd_dev->lock_rwsem); ++ ++ flush_work(&rbd_dev->acquired_lock_work); ++ flush_work(&rbd_dev->released_lock_work); + } + + /* diff --git a/queue-7.0/ring-buffer-fix-reporting-of-missed-events-in-iterator.patch b/queue-7.0/ring-buffer-fix-reporting-of-missed-events-in-iterator.patch new file mode 100644 index 0000000000..7e5504871c --- /dev/null +++ b/queue-7.0/ring-buffer-fix-reporting-of-missed-events-in-iterator.patch @@ -0,0 +1,72 @@ +From a254b6d13b0edd6272926674d2afc46d46e496b7 Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Wed, 20 May 2026 22:08:01 -0400 +Subject: ring-buffer: Fix reporting of missed events in iterator + +From: Steven Rostedt + +commit a254b6d13b0edd6272926674d2afc46d46e496b7 upstream. + +When tracing is active while reading the trace file, if the iterator +reading the buffer detects that the writer has passed the iterator head, +it will reset and set a "missed events" flag. This flag is passed to the +output processing to show the user that events were missed: + + CPU:4 [LOST EVENTS] + +The problem is that the flag is reset after it is checked in +ring_buffer_iter_dropped(). But the "trace" file iterates over all the CPU +ring buffers and it will check if they are dropped when figuring out which +buffer to print next. This prematurely clears the missed_events flag if +the CPU buffer with the missed events is not the one that is printed next. + +On the iteration where the CPU buffer with the missed events is printed, +the check if it had missed events would return false and the output does +not show that events were missed. + +Do not reset the missed_events flag when checking if there were missed +events, but instead clear it when moving the iterator head to the next +event. + +Cc: stable@vger.kernel.org +Cc: Mathieu Desnoyers +Link: https://patch.msgid.link/20260520220801.4fd09d13@fedora +Fixes: c9b7a4a72ff64 ("ring-buffer/tracing: Have iterator acknowledge dropped events") +Acked-by: Masami Hiramatsu (Google) +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/ring_buffer.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -5283,6 +5283,7 @@ static void rb_iter_reset(struct ring_bu + iter->head_page = cpu_buffer->reader_page; + iter->head = cpu_buffer->reader_page->read; + iter->next_event = iter->head; ++ iter->missed_events = 0; + + iter->cache_reader_page = iter->head_page; + iter->cache_read = cpu_buffer->read; +@@ -5897,10 +5898,7 @@ ring_buffer_peek(struct trace_buffer *bu + */ + bool ring_buffer_iter_dropped(struct ring_buffer_iter *iter) + { +- bool ret = iter->missed_events != 0; +- +- iter->missed_events = 0; +- return ret; ++ return iter->missed_events != 0; + } + EXPORT_SYMBOL_GPL(ring_buffer_iter_dropped); + +@@ -6062,7 +6060,7 @@ void ring_buffer_iter_advance(struct rin + unsigned long flags; + + raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); +- ++ iter->missed_events = 0; + rb_advance_iter(iter); + + raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); diff --git a/queue-7.0/ring-buffer-flush-and-stop-persistent-ring-buffer-on-panic.patch b/queue-7.0/ring-buffer-flush-and-stop-persistent-ring-buffer-on-panic.patch new file mode 100644 index 0000000000..a5e04d4b34 --- /dev/null +++ b/queue-7.0/ring-buffer-flush-and-stop-persistent-ring-buffer-on-panic.patch @@ -0,0 +1,327 @@ +From a494d3c8d5392bcdff83c2a593df0c160ff9f322 Mon Sep 17 00:00:00 2001 +From: "Masami Hiramatsu (Google)" +Date: Thu, 30 Apr 2026 12:28:16 +0900 +Subject: ring-buffer: Flush and stop persistent ring buffer on panic + +From: Masami Hiramatsu (Google) + +commit a494d3c8d5392bcdff83c2a593df0c160ff9f322 upstream. + +On real hardware, panic and machine reboot may not flush hardware cache +to memory. This means the persistent ring buffer, which relies on a +coherent state of memory, may not have its events written to the buffer +and they may be lost. Moreover, there may be inconsistency with the +counters which are used for validation of the integrity of the +persistent ring buffer which may cause all data to be discarded. + +To avoid this issue, stop recording of the ring buffer on panic and +flush the cache of the ring buffer's memory. + +Fixes: e645535a954a ("tracing: Add option to use memmapped memory for trace boot instance") +Cc: stable@vger.kernel.org +Cc: Will Deacon +Cc: Mathieu Desnoyers +Cc: Ian Rogers +Link: https://patch.msgid.link/177751969602.2136606.12031934362587643488.stgit@mhiramat.tok.corp.google.com +Signed-off-by: Masami Hiramatsu (Google) +Acked-by: Catalin Marinas +Acked-by: Geert Uytterhoeven +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman +--- + arch/alpha/include/asm/Kbuild | 1 + + arch/arc/include/asm/Kbuild | 1 + + arch/arm/include/asm/Kbuild | 1 + + arch/arm64/include/asm/ring_buffer.h | 10 ++++++++++ + arch/csky/include/asm/Kbuild | 1 + + arch/hexagon/include/asm/Kbuild | 1 + + arch/loongarch/include/asm/Kbuild | 1 + + arch/m68k/include/asm/Kbuild | 1 + + arch/microblaze/include/asm/Kbuild | 1 + + arch/mips/include/asm/Kbuild | 1 + + arch/nios2/include/asm/Kbuild | 1 + + arch/openrisc/include/asm/Kbuild | 1 + + arch/parisc/include/asm/Kbuild | 1 + + arch/powerpc/include/asm/Kbuild | 1 + + arch/riscv/include/asm/Kbuild | 1 + + arch/s390/include/asm/Kbuild | 1 + + arch/sh/include/asm/Kbuild | 1 + + arch/sparc/include/asm/Kbuild | 1 + + arch/um/include/asm/Kbuild | 1 + + arch/x86/include/asm/Kbuild | 1 + + arch/xtensa/include/asm/Kbuild | 1 + + include/asm-generic/ring_buffer.h | 13 +++++++++++++ + kernel/trace/ring_buffer.c | 22 ++++++++++++++++++++++ + 23 files changed, 65 insertions(+) + create mode 100644 arch/arm64/include/asm/ring_buffer.h + create mode 100644 include/asm-generic/ring_buffer.h + +--- a/arch/alpha/include/asm/Kbuild ++++ b/arch/alpha/include/asm/Kbuild +@@ -5,4 +5,5 @@ generic-y += agp.h + generic-y += asm-offsets.h + generic-y += kvm_para.h + generic-y += mcs_spinlock.h ++generic-y += ring_buffer.h + generic-y += text-patching.h +--- a/arch/arc/include/asm/Kbuild ++++ b/arch/arc/include/asm/Kbuild +@@ -5,5 +5,6 @@ generic-y += extable.h + generic-y += kvm_para.h + generic-y += mcs_spinlock.h + generic-y += parport.h ++generic-y += ring_buffer.h + generic-y += user.h + generic-y += text-patching.h +--- a/arch/arm/include/asm/Kbuild ++++ b/arch/arm/include/asm/Kbuild +@@ -3,6 +3,7 @@ generic-y += early_ioremap.h + generic-y += extable.h + generic-y += flat.h + generic-y += parport.h ++generic-y += ring_buffer.h + + generated-y += mach-types.h + generated-y += unistd-nr.h +--- /dev/null ++++ b/arch/arm64/include/asm/ring_buffer.h +@@ -0,0 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++#ifndef _ASM_ARM64_RING_BUFFER_H ++#define _ASM_ARM64_RING_BUFFER_H ++ ++#include ++ ++/* Flush D-cache on persistent ring buffer */ ++#define arch_ring_buffer_flush_range(start, end) dcache_clean_pop(start, end) ++ ++#endif /* _ASM_ARM64_RING_BUFFER_H */ +--- a/arch/csky/include/asm/Kbuild ++++ b/arch/csky/include/asm/Kbuild +@@ -9,6 +9,7 @@ generic-y += qrwlock.h + generic-y += qrwlock_types.h + generic-y += qspinlock.h + generic-y += parport.h ++generic-y += ring_buffer.h + generic-y += user.h + generic-y += vmlinux.lds.h + generic-y += text-patching.h +--- a/arch/hexagon/include/asm/Kbuild ++++ b/arch/hexagon/include/asm/Kbuild +@@ -5,4 +5,5 @@ generic-y += extable.h + generic-y += iomap.h + generic-y += kvm_para.h + generic-y += mcs_spinlock.h ++generic-y += ring_buffer.h + generic-y += text-patching.h +--- a/arch/loongarch/include/asm/Kbuild ++++ b/arch/loongarch/include/asm/Kbuild +@@ -10,5 +10,6 @@ generic-y += qrwlock.h + generic-y += user.h + generic-y += ioctl.h + generic-y += mmzone.h ++generic-y += ring_buffer.h + generic-y += statfs.h + generic-y += text-patching.h +--- a/arch/m68k/include/asm/Kbuild ++++ b/arch/m68k/include/asm/Kbuild +@@ -3,5 +3,6 @@ generated-y += syscall_table.h + generic-y += extable.h + generic-y += kvm_para.h + generic-y += mcs_spinlock.h ++generic-y += ring_buffer.h + generic-y += spinlock.h + generic-y += text-patching.h +--- a/arch/microblaze/include/asm/Kbuild ++++ b/arch/microblaze/include/asm/Kbuild +@@ -5,6 +5,7 @@ generic-y += extable.h + generic-y += kvm_para.h + generic-y += mcs_spinlock.h + generic-y += parport.h ++generic-y += ring_buffer.h + generic-y += syscalls.h + generic-y += tlb.h + generic-y += user.h +--- a/arch/mips/include/asm/Kbuild ++++ b/arch/mips/include/asm/Kbuild +@@ -12,5 +12,6 @@ generic-y += mcs_spinlock.h + generic-y += parport.h + generic-y += qrwlock.h + generic-y += qspinlock.h ++generic-y += ring_buffer.h + generic-y += user.h + generic-y += text-patching.h +--- a/arch/nios2/include/asm/Kbuild ++++ b/arch/nios2/include/asm/Kbuild +@@ -5,6 +5,7 @@ generic-y += cmpxchg.h + generic-y += extable.h + generic-y += kvm_para.h + generic-y += mcs_spinlock.h ++generic-y += ring_buffer.h + generic-y += spinlock.h + generic-y += user.h + generic-y += text-patching.h +--- a/arch/openrisc/include/asm/Kbuild ++++ b/arch/openrisc/include/asm/Kbuild +@@ -8,4 +8,5 @@ generic-y += spinlock_types.h + generic-y += spinlock.h + generic-y += qrwlock_types.h + generic-y += qrwlock.h ++generic-y += ring_buffer.h + generic-y += user.h +--- a/arch/parisc/include/asm/Kbuild ++++ b/arch/parisc/include/asm/Kbuild +@@ -4,4 +4,5 @@ generated-y += syscall_table_64.h + generic-y += agp.h + generic-y += kvm_para.h + generic-y += mcs_spinlock.h ++generic-y += ring_buffer.h + generic-y += user.h +--- a/arch/powerpc/include/asm/Kbuild ++++ b/arch/powerpc/include/asm/Kbuild +@@ -5,4 +5,5 @@ generated-y += syscall_table_spu.h + generic-y += agp.h + generic-y += mcs_spinlock.h + generic-y += qrwlock.h ++generic-y += ring_buffer.h + generic-y += early_ioremap.h +--- a/arch/riscv/include/asm/Kbuild ++++ b/arch/riscv/include/asm/Kbuild +@@ -14,5 +14,6 @@ generic-y += ticket_spinlock.h + generic-y += qrwlock.h + generic-y += qrwlock_types.h + generic-y += qspinlock.h ++generic-y += ring_buffer.h + generic-y += user.h + generic-y += vmlinux.lds.h +--- a/arch/s390/include/asm/Kbuild ++++ b/arch/s390/include/asm/Kbuild +@@ -7,3 +7,4 @@ generated-y += unistd_nr.h + generic-y += asm-offsets.h + generic-y += mcs_spinlock.h + generic-y += mmzone.h ++generic-y += ring_buffer.h +--- a/arch/sh/include/asm/Kbuild ++++ b/arch/sh/include/asm/Kbuild +@@ -3,4 +3,5 @@ generated-y += syscall_table.h + generic-y += kvm_para.h + generic-y += mcs_spinlock.h + generic-y += parport.h ++generic-y += ring_buffer.h + generic-y += text-patching.h +--- a/arch/sparc/include/asm/Kbuild ++++ b/arch/sparc/include/asm/Kbuild +@@ -4,4 +4,5 @@ generated-y += syscall_table_64.h + generic-y += agp.h + generic-y += kvm_para.h + generic-y += mcs_spinlock.h ++generic-y += ring_buffer.h + generic-y += text-patching.h +--- a/arch/um/include/asm/Kbuild ++++ b/arch/um/include/asm/Kbuild +@@ -17,6 +17,7 @@ generic-y += module.lds.h + generic-y += parport.h + generic-y += percpu.h + generic-y += preempt.h ++generic-y += ring_buffer.h + generic-y += runtime-const.h + generic-y += softirq_stack.h + generic-y += switch_to.h +--- a/arch/x86/include/asm/Kbuild ++++ b/arch/x86/include/asm/Kbuild +@@ -14,3 +14,4 @@ generic-y += early_ioremap.h + generic-y += fprobe.h + generic-y += mcs_spinlock.h + generic-y += mmzone.h ++generic-y += ring_buffer.h +--- a/arch/xtensa/include/asm/Kbuild ++++ b/arch/xtensa/include/asm/Kbuild +@@ -6,5 +6,6 @@ generic-y += mcs_spinlock.h + generic-y += parport.h + generic-y += qrwlock.h + generic-y += qspinlock.h ++generic-y += ring_buffer.h + generic-y += user.h + generic-y += text-patching.h +--- /dev/null ++++ b/include/asm-generic/ring_buffer.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Generic arch dependent ring_buffer macros. ++ */ ++#ifndef __ASM_GENERIC_RING_BUFFER_H__ ++#define __ASM_GENERIC_RING_BUFFER_H__ ++ ++#include ++ ++/* Flush cache on ring buffer range if needed. Do nothing by default. */ ++#define arch_ring_buffer_flush_range(start, end) do { } while (0) ++ ++#endif /* __ASM_GENERIC_RING_BUFFER_H__ */ +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -6,6 +6,7 @@ + */ + #include + #include ++#include + #include + #include + #include +@@ -30,6 +31,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -589,6 +591,7 @@ struct trace_buffer { + + unsigned long range_addr_start; + unsigned long range_addr_end; ++ struct notifier_block flush_nb; + + struct ring_buffer_meta *meta; + +@@ -2472,6 +2475,16 @@ static void rb_free_cpu_buffer(struct ri + kfree(cpu_buffer); + } + ++/* Stop recording on a persistent buffer and flush cache if needed. */ ++static int rb_flush_buffer_cb(struct notifier_block *nb, unsigned long event, void *data) ++{ ++ struct trace_buffer *buffer = container_of(nb, struct trace_buffer, flush_nb); ++ ++ ring_buffer_record_off(buffer); ++ arch_ring_buffer_flush_range(buffer->range_addr_start, buffer->range_addr_end); ++ return NOTIFY_DONE; ++} ++ + static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags, + int order, unsigned long start, + unsigned long end, +@@ -2591,6 +2604,12 @@ static struct trace_buffer *alloc_buffer + + mutex_init(&buffer->mutex); + ++ /* Persistent ring buffer needs to flush cache before reboot. */ ++ if (start && end) { ++ buffer->flush_nb.notifier_call = rb_flush_buffer_cb; ++ atomic_notifier_chain_register(&panic_notifier_list, &buffer->flush_nb); ++ } ++ + return_ptr(buffer); + + fail_free_buffers: +@@ -2678,6 +2697,9 @@ ring_buffer_free(struct trace_buffer *bu + { + int cpu; + ++ if (buffer->range_addr_start && buffer->range_addr_end) ++ atomic_notifier_chain_unregister(&panic_notifier_list, &buffer->flush_nb); ++ + cpuhp_state_remove_instance(CPUHP_TRACE_RB_PREPARE, &buffer->node); + + irq_work_sync(&buffer->irq_work.work); diff --git a/queue-7.0/selftests-mptcp-drop-nanoseconds-width-specifier.patch b/queue-7.0/selftests-mptcp-drop-nanoseconds-width-specifier.patch new file mode 100644 index 0000000000..57c2e8e829 --- /dev/null +++ b/queue-7.0/selftests-mptcp-drop-nanoseconds-width-specifier.patch @@ -0,0 +1,107 @@ +From 01ff78e4b3d98689184c52d97f9575dfbdc3b10f Mon Sep 17 00:00:00 2001 +From: "Matthieu Baerts (NGI0)" +Date: Fri, 15 May 2026 06:27:37 +0200 +Subject: selftests: mptcp: drop nanoseconds width specifier + +From: Matthieu Baerts (NGI0) + +commit 01ff78e4b3d98689184c52d97f9575dfbdc3b10f upstream. + +Using the format specifier +%s%3N with GNU date is honoured, and only +prints 3 digits of the nanoseconds portion of the seconds since epoch, +which corresponds to the milliseconds. + +The uutils implementation of date currently does not honour this, and +always prints all 9 digits. This is a known issue [1], but can be worked +around by adapting this test to use nanoseconds instead of microseconds, +and then divide it by 1e6. + +This fix is similar to what has been done on systemd side [2], and it is +needed to run the selftests on Ubuntu 26.04, containing uutils 0.8.0. + +Note that the Fixes tag is there even if this patch doesn't fix an issue +in the kernel selftests, but it is useful for those using uutils 0.8.0. + +Fixes: 048d19d444be ("mptcp: add basic kselftest for mptcp") +Cc: stable@vger.kernel.org +Link: https://github.com/uutils/coreutils/issues/11658 [1] +Link: https://github.com/systemd/systemd/pull/41627 [2] +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-6-701e96419f2f@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/net/mptcp/mptcp_connect.sh | 6 +++--- + tools/testing/selftests/net/mptcp/mptcp_lib.sh | 10 +++++----- + 2 files changed, 8 insertions(+), 8 deletions(-) + +--- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh ++++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh +@@ -401,7 +401,7 @@ do_transfer() + mptcp_lib_wait_local_port_listen "${listener_ns}" "${port}" + + local start +- start=$(date +%s%3N) ++ start=$(date +%s%N) + ip netns exec ${connector_ns} \ + ./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \ + $extra_args $connect_addr < "$cin" > "$cout" & +@@ -423,7 +423,7 @@ do_transfer() + fi + + local stop +- stop=$(date +%s%3N) ++ stop=$(date +%s%N) + + if $capture; then + sleep 1 +@@ -439,7 +439,7 @@ do_transfer() + fi + + local duration +- duration=$((stop-start)) ++ duration=$(((stop-start) / 1000000)) + printf "(duration %05sms) " "${duration}" + if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ] || [ ${timeout_pid} -ne 0 ]; then + mptcp_lib_pr_fail "client exit code $retc, server $rets" +--- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh ++++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh +@@ -28,7 +28,7 @@ declare -rx MPTCP_LIB_AF_INET6=10 + MPTCP_LIB_SUBTESTS=() + MPTCP_LIB_SUBTESTS_DUPLICATED=0 + MPTCP_LIB_SUBTEST_FLAKY=0 +-MPTCP_LIB_SUBTESTS_LAST_TS_MS= ++MPTCP_LIB_SUBTESTS_LAST_TS_NS= + MPTCP_LIB_TEST_COUNTER=0 + MPTCP_LIB_TEST_FORMAT="%02u %-50s" + MPTCP_LIB_IP_MPTCP=0 +@@ -236,7 +236,7 @@ mptcp_lib_kversion_ge() { + } + + mptcp_lib_subtests_last_ts_reset() { +- MPTCP_LIB_SUBTESTS_LAST_TS_MS="$(date +%s%3N)" ++ MPTCP_LIB_SUBTESTS_LAST_TS_NS="$(date +%s%N)" + } + mptcp_lib_subtests_last_ts_reset + +@@ -255,7 +255,7 @@ __mptcp_lib_result_check_duplicated() { + __mptcp_lib_result_add() { + local result="${1}" + local time="time=" +- local ts_prev_ms ++ local ts_prev_ns + shift + + local id=$((${#MPTCP_LIB_SUBTESTS[@]} + 1)) +@@ -265,9 +265,9 @@ __mptcp_lib_result_add() { + # not to add two '#' + [[ "${*}" != *"#"* ]] && time="# ${time}" + +- ts_prev_ms="${MPTCP_LIB_SUBTESTS_LAST_TS_MS}" ++ ts_prev_ns="${MPTCP_LIB_SUBTESTS_LAST_TS_NS}" + mptcp_lib_subtests_last_ts_reset +- time+="$((MPTCP_LIB_SUBTESTS_LAST_TS_MS - ts_prev_ms))ms" ++ time+="$(((MPTCP_LIB_SUBTESTS_LAST_TS_NS - ts_prev_ns) / 1000000))ms" + + MPTCP_LIB_SUBTESTS+=("${result} ${id} - ${KSFT_TEST}: ${*} ${time}") + } diff --git a/queue-7.0/series b/queue-7.0/series index 2bda4ffcae..57af450de6 100644 --- a/queue-7.0/series +++ b/queue-7.0/series @@ -63,3 +63,33 @@ net-ethtool-phy-avoid-null-deref-when-phy-driver-is-unbound.patch acpi-driver-check-acpi_companion-against-null-during-probe.patch sched_ext-fix-missing-warning-in-scx_set_task_state-default-case.patch sched_ext-avoid-uaf-in-scx_root_enable_workfn-init-failure-path.patch +l2tp-use-list_del_rcu-in-l2tp_session_unhash.patch +qed-fix-double-free-in-qed_cxt_tables_alloc.patch +ring-buffer-fix-reporting-of-missed-events-in-iterator.patch +ring-buffer-flush-and-stop-persistent-ring-buffer-on-panic.patch +wifi-mac80211-capture-fast-rx-rate-before-mesh-reuses-skb-cb.patch +ipv6-ioam-add-null-check-for-idev-in-ipv6_hop_ioam.patch +selftests-mptcp-drop-nanoseconds-width-specifier.patch +mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch +vsock-vmci-fix-uaf-when-peer-resets-connection-during-handshake.patch +vsock-virtio-reset-connection-on-receiving-queue-overflow.patch +ice-fix-vf-queue-configuration-with-low-mtu-values.patch +wifi-ath11k-clear-shared-srng-pointer-state-on-restart.patch +wifi-iwlwifi-mvm-fix-driver-set-tx-rates-on-old-devices.patch +wifi-iwlwifi-mld-stop-tx-during-firmware-restart.patch +ipv4-raw-reject-ip_hdrincl-packets-with-ihl-5.patch +ixgbevf-fix-use-after-free-in-vepa-multicast-source-pruning.patch +rbd-eliminate-a-race-in-lock_dwork-draining-on-unmap.patch +mptcp-do-not-drop-partial-packets.patch +mptcp-reset-rcv-wnd-on-disconnect.patch +lsm-hold-cred_guard_mutex-for-lsm_set_self_attr.patch +octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.patch +octeontx2-pf-fix-double-free-in-rvu_rep_rsrc_init.patch +igc-fix-potential-skb-leak-in-igc_fpe_xmit_smd_frame.patch +ice-fix-locking-around-wait_event_interruptible_locked_irq.patch +ice-fix-setting-promisc-mode-while-adding-vid-filter.patch +ice-restore-ptp-rx-timestamp-config-after-ethtool-set-channels.patch +wifi-cfg80211-advance-loop-vars-in-cfg80211_merge_profile.patch +af_unix-fix-uaf-read-of-tail-len-in-unix_stream_data_wait.patch +wifi-mac80211-consume-only-present-negotiated-ttlm-maps.patch +octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch diff --git a/queue-7.0/vsock-virtio-reset-connection-on-receiving-queue-overflow.patch b/queue-7.0/vsock-virtio-reset-connection-on-receiving-queue-overflow.patch new file mode 100644 index 0000000000..4dda8893eb --- /dev/null +++ b/queue-7.0/vsock-virtio-reset-connection-on-receiving-queue-overflow.patch @@ -0,0 +1,85 @@ +From a4f0b001782b21663d10df983b4b208195bec66c Mon Sep 17 00:00:00 2001 +From: Stefano Garzarella +Date: Mon, 18 May 2026 11:06:55 +0200 +Subject: vsock/virtio: reset connection on receiving queue overflow + +From: Stefano Garzarella + +commit a4f0b001782b21663d10df983b4b208195bec66c upstream. + +When there is no more space to queue an incoming packet, the packet is +silently dropped. This causes data loss without any notification to +either peer, since there is no retransmission. + +Under normal circumstances, this should never happen. However, it could +happen if the other peer doesn't respect the credit, or if the skb +overhead, which we recently began to take into account with commit +059b7dbd20a6 ("vsock/virtio: fix potential unbounded skb queue"), +is too high. + +Fix this by resetting the connection and setting the local socket error +to ENOBUFS when virtio_transport_recv_enqueue() can no longer queue a +packet, so both peers are explicitly notified of the failure rather than +silently losing data. + +Fixes: ae6fcfbf5f03 ("vsock/virtio: discard packets if credit is not respected") +Cc: stable@vger.kernel.org +Signed-off-by: Stefano Garzarella +Link: https://patch.msgid.link/20260518090656.134588-2-sgarzare@redhat.com +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + net/vmw_vsock/virtio_transport_common.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +--- a/net/vmw_vsock/virtio_transport_common.c ++++ b/net/vmw_vsock/virtio_transport_common.c +@@ -1350,7 +1350,7 @@ destroy: + return err; + } + +-static void ++static bool + virtio_transport_recv_enqueue(struct vsock_sock *vsk, + struct sk_buff *skb) + { +@@ -1365,10 +1365,8 @@ virtio_transport_recv_enqueue(struct vso + spin_lock_bh(&vvs->rx_lock); + + can_enqueue = virtio_transport_inc_rx_pkt(vvs, len); +- if (!can_enqueue) { +- free_pkt = true; ++ if (!can_enqueue) + goto out; +- } + + if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SEQ_EOM) + vvs->msg_count++; +@@ -1408,6 +1406,8 @@ out: + spin_unlock_bh(&vvs->rx_lock); + if (free_pkt) + kfree_skb(skb); ++ ++ return can_enqueue; + } + + static int +@@ -1420,7 +1420,17 @@ virtio_transport_recv_connected(struct s + + switch (le16_to_cpu(hdr->op)) { + case VIRTIO_VSOCK_OP_RW: +- virtio_transport_recv_enqueue(vsk, skb); ++ if (!virtio_transport_recv_enqueue(vsk, skb)) { ++ /* There is no more space to queue the packet, so let's ++ * close the connection; otherwise, we'll lose data. ++ */ ++ (void)virtio_transport_reset(vsk, skb); ++ virtio_transport_do_close(vsk, true); ++ sk->sk_err = ENOBUFS; ++ sk_error_report(sk); ++ vsock_remove_sock(vsk); ++ break; ++ } + vsock_data_ready(sk); + return err; + case VIRTIO_VSOCK_OP_CREDIT_REQUEST: diff --git a/queue-7.0/vsock-vmci-fix-uaf-when-peer-resets-connection-during-handshake.patch b/queue-7.0/vsock-vmci-fix-uaf-when-peer-resets-connection-during-handshake.patch new file mode 100644 index 0000000000..8e92394017 --- /dev/null +++ b/queue-7.0/vsock-vmci-fix-uaf-when-peer-resets-connection-during-handshake.patch @@ -0,0 +1,64 @@ +From 99e22ddf4edb63dc8382bc028af928056d3450cf Mon Sep 17 00:00:00 2001 +From: Minh Nguyen +Date: Tue, 19 May 2026 17:23:10 +0700 +Subject: vsock/vmci: fix UAF when peer resets connection during handshake + +From: Minh Nguyen + +commit 99e22ddf4edb63dc8382bc028af928056d3450cf upstream. + +vmci_transport_recv_connecting_server() returned err = 0 for a peer +RST in its default switch arm: + + err = pkt->type == VMCI_TRANSPORT_PACKET_TYPE_RST ? 0 : -EINVAL; + +That made vmci_transport_recv_listen() skip vsock_remove_pending(), +leaving the pending socket on the listener's pending_links with +sk_state = TCP_CLOSE while destroy: still dropped the explicit +reference taken before schedule_delayed_work(). + +One second later vsock_pending_work() observed is_pending=true and +performed full cleanup: vsock_remove_pending() then the two trailing +sock_put(sk) calls -- the first reached refcount 0 and __sk_freed +the socket, and the second wrote into the freed object: + + BUG: KASAN: slab-use-after-free in refcount_warn_saturate + Write of size 4 at addr ffff88800b1cac80 by task kworker + Workqueue: events vsock_pending_work + +Treat peer RST like any other unexpected packet type (err = -EINVAL). +All destroy: arms now return err < 0, so vmci_transport_recv_listen() +removes pending from pending_links synchronously and +vsock_pending_work() takes the is_pending=false / !rejected branch, +dropping only its own work reference. This also closes the +multi-packet race Sashiko reported on v2: pending is removed from +the list before any subsequent packet can find it. + +The pre-existing sk_acceptq_removed() gap on the err < 0 path of +vmci_transport_recv_listen() that Sashiko also noted is not +introduced or changed by this patch. + +Tested on lts-6.12.79 with KASAN: 52/100 unpatched -> 0/100 patched. + +Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") +Cc: stable@vger.kernel.org +Signed-off-by: Minh Nguyen +Acked-by: Bryan Tan +Link: https://patch.msgid.link/20260519102310.237181-1-minhnguyen.080505@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/vmw_vsock/vmci_transport.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/vmw_vsock/vmci_transport.c ++++ b/net/vmw_vsock/vmci_transport.c +@@ -1164,7 +1164,7 @@ vmci_transport_recv_connecting_server(st + /* Close and cleanup the connection. */ + vmci_transport_send_reset(pending, pkt); + skerr = EPROTO; +- err = pkt->type == VMCI_TRANSPORT_PACKET_TYPE_RST ? 0 : -EINVAL; ++ err = -EINVAL; + goto destroy; + } + diff --git a/queue-7.0/wifi-ath11k-clear-shared-srng-pointer-state-on-restart.patch b/queue-7.0/wifi-ath11k-clear-shared-srng-pointer-state-on-restart.patch new file mode 100644 index 0000000000..1645817931 --- /dev/null +++ b/queue-7.0/wifi-ath11k-clear-shared-srng-pointer-state-on-restart.patch @@ -0,0 +1,60 @@ +From f51e4b3b5574ad8cb5b16b11f8a1452147ece87a Mon Sep 17 00:00:00 2001 +From: Kyle Farnung +Date: Wed, 13 May 2026 21:52:12 -0700 +Subject: wifi: ath11k: clear shared SRNG pointer state on restart + +From: Kyle Farnung + +commit f51e4b3b5574ad8cb5b16b11f8a1452147ece87a upstream. + +LMAC rings reuse the shared rdp/wrp pointer buffers without going +through the normal SRNG hw-init path that zeros non-LMAC ring +pointers. After restart, ath11k_hal_srng_clear() can therefore hand +stale hp/tp state from the previous firmware instance back to the new +one. + +Clear the shared pointer buffers while keeping the allocations in +place so restart still avoids reallocating SRNG DMA memory, but starts +with fresh ring-pointer state. + +Fixes: 32be3ca4cf78b ("wifi: ath11k: HAL SRNG: don't deinitialize and re-initialize again") +Cc: stable@vger.kernel.org +Closes: https://lore.kernel.org/all/CAOPSVF04q6uvVdq8GTRLHBrVMdpt9=o9wVcFMc6f-yhmSBcZqQ@mail.gmail.com/ +Signed-off-by: Kyle Farnung +Reviewed-by: Rameshkumar Sundaram +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20260513-kfarnung-ath11k-srng-clear-pointer-state-v1-1-bc700dd8b333@gmail.com +Signed-off-by: Jeff Johnson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath11k/hal.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/hal.c ++++ b/drivers/net/wireless/ath/ath11k/hal.c +@@ -1387,14 +1387,22 @@ EXPORT_SYMBOL(ath11k_hal_srng_deinit); + + void ath11k_hal_srng_clear(struct ath11k_base *ab) + { +- /* No need to memset rdp and wrp memory since each individual +- * segment would get cleared in ath11k_hal_srng_src_hw_init() +- * and ath11k_hal_srng_dst_hw_init(). ++ /* ++ * Preserve the shared pointer buffers, but clear the previous ++ * firmware instance's hp/tp state before handing them back to FW. ++ * LMAC rings reuse this shared memory without going through the ++ * normal SRNG hw-init path that zeros non-LMAC ring pointers. + */ + memset(ab->hal.srng_list, 0, + sizeof(ab->hal.srng_list)); + memset(ab->hal.shadow_reg_addr, 0, + sizeof(ab->hal.shadow_reg_addr)); ++ if (ab->hal.rdp.vaddr) ++ memset(ab->hal.rdp.vaddr, 0, ++ sizeof(*ab->hal.rdp.vaddr) * HAL_SRNG_RING_ID_MAX); ++ if (ab->hal.wrp.vaddr) ++ memset(ab->hal.wrp.vaddr, 0, ++ sizeof(*ab->hal.wrp.vaddr) * HAL_SRNG_NUM_LMAC_RINGS); + ab->hal.avail_blk_resource = 0; + ab->hal.current_blk_index = 0; + ab->hal.num_shadow_reg_configured = 0; diff --git a/queue-7.0/wifi-cfg80211-advance-loop-vars-in-cfg80211_merge_profile.patch b/queue-7.0/wifi-cfg80211-advance-loop-vars-in-cfg80211_merge_profile.patch new file mode 100644 index 0000000000..9d2a3ba7f9 --- /dev/null +++ b/queue-7.0/wifi-cfg80211-advance-loop-vars-in-cfg80211_merge_profile.patch @@ -0,0 +1,52 @@ +From 7666dbb1bacc4ba522b96740cba7283d243d16e1 Mon Sep 17 00:00:00 2001 +From: John Walker +Date: Thu, 7 May 2026 17:07:20 -0600 +Subject: wifi: cfg80211: advance loop vars in cfg80211_merge_profile() + +From: John Walker + +commit 7666dbb1bacc4ba522b96740cba7283d243d16e1 upstream. + +cfg80211_merge_profile() reassembles a Multi-BSSID non-transmitted BSS +profile that has been split across multiple consecutive MBSSID elements. +Its while-loop calls + + cfg80211_get_profile_continuation(ie, ielen, mbssid_elem, sub_elem) + +but never advances mbssid_elem or sub_elem inside the body. Each +iteration therefore searches for a continuation that follows the same +fixed pair; the helper returns the same next_mbssid; and the same +next_sub bytes are memcpy()'d into merged_ie at a growing offset until +the buffer fills. + +Advance both mbssid_elem and sub_elem to the just-consumed continuation +so the next call to cfg80211_get_profile_continuation() searches for a +further continuation beyond it (or returns NULL when none exists). + +A specially-crafted malicious beacon can take advantage of this bug +to cause the kernel to spend an excessive amount of time in +cfg80211_merge_profile (up to as much as 2ms per beacon received), +which could theoretically be abused in some way. + +Cc: stable@vger.kernel.org +Fixes: fe806e4992c9 ("cfg80211: support profile split between elements") +Signed-off-by: John Walker +Link: https://patch.msgid.link/20260507230720.64783-1-johnwalker0@gmail.com +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/wireless/scan.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -2462,6 +2462,9 @@ size_t cfg80211_merge_profile(const u8 * + memcpy(merged_ie + copied_len, next_sub->data, + next_sub->datalen); + copied_len += next_sub->datalen; ++ ++ mbssid_elem = next_mbssid; ++ sub_elem = next_sub; + } + + return copied_len; diff --git a/queue-7.0/wifi-iwlwifi-mld-stop-tx-during-firmware-restart.patch b/queue-7.0/wifi-iwlwifi-mld-stop-tx-during-firmware-restart.patch new file mode 100644 index 0000000000..d51fa318a1 --- /dev/null +++ b/queue-7.0/wifi-iwlwifi-mld-stop-tx-during-firmware-restart.patch @@ -0,0 +1,64 @@ +From 2becb38a3e217ef2b2f42fddd7db7a25905ec291 Mon Sep 17 00:00:00 2001 +From: Sheroz Juraev +Date: Sun, 15 Mar 2026 13:12:21 +0500 +Subject: wifi: iwlwifi: mld: stop TX during firmware restart + +From: Sheroz Juraev + +commit 2becb38a3e217ef2b2f42fddd7db7a25905ec291 upstream. + +When iwlwifi firmware crashes (e.g., NMI_INTERRUPT_UNKNOWN on Intel +BE201/Wi-Fi 7), iwl_mld_nic_error() sets mld->fw_status.in_hw_restart +to true. However, iwl_mld_tx_from_txq() does not check this flag before +dequeuing frames from mac80211 and pushing them to the transport layer. + +Since the firmware is dead, iwl_trans_tx() returns -EIO for each frame, +which then gets freed immediately. Under high-throughput conditions +(e.g., Tailscale UDP traffic or active SSH sessions), this creates a +tight dequeue-send-fail-free loop that wastes CPU cycles and generates +rapid skb allocation churn, leading to memory pressure from slab +fragmentation. + +The RX path already has this guard (iwl_mld_rx_mpdu checks +in_hw_restart at rx.c:1906), and so does the TXQ allocation worker +(iwl_mld_add_txqs_wk at tx.c:156). Add the same guard to +iwl_mld_tx_from_txq() to stop all TX during firmware restart. + +Frames left in mac80211's TXQs are naturally drained after restart +completes, when queue reallocation triggers iwl_mld_tx_from_txq() +via iwl_mld_add_txq_list(), or when new upper-layer traffic invokes +wake_tx_queue. + +Tested on ASUS Zenbook 14 UX3405CA with Intel BE201 (Wi-Fi 7) on +kernel 6.19.5 where the firmware crashes approximately every 10-15 +minutes under Tailscale traffic. + +Fixes: d1e879ec600f ("wifi: iwlwifi: add iwlmld sub-driver") +Cc: stable@vger.kernel.org +Signed-off-by: Sheroz Juraev +Link: https://patch.msgid.link/20260315081221.2678478-1-goodmartiandev@gmail.com +Signed-off-by: Miri Korenblit +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/intel/iwlwifi/mld/tx.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c +@@ -971,6 +971,16 @@ void iwl_mld_tx_from_txq(struct iwl_mld + u8 zero_addr[ETH_ALEN] = {}; + + /* ++ * Don't transmit during firmware restart. The firmware is dead, ++ * so iwl_trans_tx() would return -EIO for each frame. Avoid the ++ * overhead of dequeuing from mac80211 only to immediately free ++ * the skbs, and the potential memory pressure from rapid skb ++ * allocation churn during high-throughput restart scenarios. ++ */ ++ if (unlikely(mld->fw_status.in_hw_restart)) ++ return; ++ ++ /* + * No need for threads to be pending here, they can leave the first + * taker all the work. + * diff --git a/queue-7.0/wifi-iwlwifi-mvm-fix-driver-set-tx-rates-on-old-devices.patch b/queue-7.0/wifi-iwlwifi-mvm-fix-driver-set-tx-rates-on-old-devices.patch new file mode 100644 index 0000000000..a303a9447a --- /dev/null +++ b/queue-7.0/wifi-iwlwifi-mvm-fix-driver-set-tx-rates-on-old-devices.patch @@ -0,0 +1,135 @@ +From fb84b5cbcaab3ca0f4e961d92a40ed7f3aac483b Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Fri, 15 May 2026 15:14:57 +0300 +Subject: wifi: iwlwifi: mvm: fix driver-set TX rates on old devices + +From: Johannes Berg + +commit fb84b5cbcaab3ca0f4e961d92a40ed7f3aac483b upstream. + +On old devices such as 7265D, rates are still encoded in version 1 +format, which doesn't use the CCK/OFDM rate index (0-3/0-7) but +rather their PLCP value (e.g. 10 for 1 Mbps CCK rate.) + +While introducing v3 rates, I changed the driver from internally +handling v1 rates and converting to v2, to internally handling v3 +and converting to v1 or v2 according to the firmware. I accordingly +changed the code in iwl_mvm_mac80211_idx_to_hwrate() to no longer +have different values for different APIs. This was correct. + +However, I later reverted this part of the change, because it was +reported that I had broken beacon rates, causing a FW assert/crash. +This caused TX_CMD rates to be set incorrectly, potentially causing +a warning when reported back from the device as having been used. + +Fix this (hopefully correctly now) by handling beacon rates in the +TX_CMD that's embedded in the beacon template command separately. +Restore iwl_mvm_mac80211_idx_to_hwrate() to return only the rate +index, not PLCP value, fixing the real TX_CMD. + +Cc: stable@vger.kernel.org +Signed-off-by: Johannes Berg +Link: https://patch.msgid.link/20260515151351.7407e293dff7.I4ea1a17f8fe99c933d3f3e30d077cf4246125c3e@changeid +Signed-off-by: Miri Korenblit +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 27 ++++++++++++++-------- + drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 14 +++-------- + 2 files changed, 22 insertions(+), 19 deletions(-) + +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + /* +- * Copyright (C) 2012-2014, 2018-2025 Intel Corporation ++ * Copyright (C) 2012-2014, 2018-2026 Intel Corporation + * Copyright (C) 2013-2014 Intel Mobile Communications GmbH + * Copyright (C) 2015-2017 Intel Deutschland GmbH + */ +@@ -927,13 +927,18 @@ u8 iwl_mvm_mac_ctxt_get_lowest_rate(stru + + u16 iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw *fw, u8 rate_idx) + { +- u16 flags = iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx); + bool is_new_rate = iwl_fw_lookup_cmd_ver(fw, BEACON_TEMPLATE_CMD, 0) > 10; ++ u16 flags = 0; + + if (rate_idx <= IWL_LAST_CCK_RATE) + flags |= is_new_rate ? IWL_MAC_BEACON_CCK + : IWL_MAC_BEACON_CCK_V1; + ++ if (iwl_fw_lookup_cmd_ver(fw, TX_CMD, 0) > 8) ++ flags |= iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx); ++ else ++ flags |= iwl_fw_rate_idx_to_plcp(rate_idx); ++ + return flags; + } + +@@ -962,6 +967,7 @@ static void iwl_mvm_mac_ctxt_set_tx(stru + { + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct ieee80211_tx_info *info; ++ u32 rate_n_flags = 0; + u8 rate; + u32 tx_flags; + +@@ -981,18 +987,21 @@ static void iwl_mvm_mac_ctxt_set_tx(stru + IWL_UCODE_TLV_CAPA_BEACON_ANT_SELECTION)) { + iwl_mvm_toggle_tx_ant(mvm, &mvm->mgmt_last_antenna_idx); + +- tx_params->rate_n_flags = +- cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) << +- RATE_MCS_ANT_POS); ++ rate_n_flags |= BIT(mvm->mgmt_last_antenna_idx) << ++ RATE_MCS_ANT_POS; + } + + rate = iwl_mvm_mac_ctxt_get_beacon_rate(mvm, info, vif); + +- tx_params->rate_n_flags |= +- cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate)); +- if (rate == IWL_FIRST_CCK_RATE) +- tx_params->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK_V1); ++ if (rate < IWL_FIRST_OFDM_RATE) ++ rate_n_flags |= RATE_MCS_MOD_TYPE_CCK; ++ else ++ rate_n_flags |= RATE_MCS_MOD_TYPE_LEGACY_OFDM; ++ ++ rate_n_flags |= iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate); + ++ tx_params->rate_n_flags = iwl_mvm_v3_rate_to_fw(rate_n_flags, ++ mvm->fw_rates_ver); + } + + int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm, +--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + /* +- * Copyright (C) 2012-2014, 2018-2025 Intel Corporation ++ * Copyright (C) 2012-2014, 2018-2026 Intel Corporation + * Copyright (C) 2013-2014 Intel Mobile Communications GmbH + * Copyright (C) 2015-2017 Intel Deutschland GmbH + */ +@@ -159,15 +159,9 @@ int iwl_mvm_legacy_rate_to_mac80211_idx( + + u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx) + { +- if (iwl_fw_lookup_cmd_ver(fw, TX_CMD, 0) > 8) +- /* In the new rate legacy rates are indexed: +- * 0 - 3 for CCK and 0 - 7 for OFDM. +- */ +- return (rate_idx >= IWL_FIRST_OFDM_RATE ? +- rate_idx - IWL_FIRST_OFDM_RATE : +- rate_idx); +- +- return iwl_fw_rate_idx_to_plcp(rate_idx); ++ return rate_idx >= IWL_FIRST_OFDM_RATE ? ++ rate_idx - IWL_FIRST_OFDM_RATE : ++ rate_idx; + } + + u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac) diff --git a/queue-7.0/wifi-mac80211-capture-fast-rx-rate-before-mesh-reuses-skb-cb.patch b/queue-7.0/wifi-mac80211-capture-fast-rx-rate-before-mesh-reuses-skb-cb.patch new file mode 100644 index 0000000000..15d48f266c --- /dev/null +++ b/queue-7.0/wifi-mac80211-capture-fast-rx-rate-before-mesh-reuses-skb-cb.patch @@ -0,0 +1,64 @@ +From d71c841be5d9e586ee7f36c0dc8ed4db0d9a1349 Mon Sep 17 00:00:00 2001 +From: Zhao Li +Date: Sat, 9 May 2026 12:34:28 +0800 +Subject: wifi: mac80211: capture fast-RX rate before mesh reuses skb->cb + +From: Zhao Li + +commit d71c841be5d9e586ee7f36c0dc8ed4db0d9a1349 upstream. + +ieee80211_invoke_fast_rx() reads RX status through +IEEE80211_SKB_RXCB(skb), which aliases the same skb->cb storage +that ieee80211_rx_mesh_data() reuses as IEEE80211_TX_INFO. In the +unicast forward path, mesh_data does: + + info = IEEE80211_SKB_CB(fwd_skb); + memset(info, 0, sizeof(*info)); + +on the same skb the caller still names via rx->skb, then either +queues the skb for TX (success) or kfree_skb()'s it (no-route) +before returning RX_QUEUED. The caller's RX_QUEUED arm then +calls sta_stats_encode_rate(status) on memory that is either +zeroed (success path) or freed (no-route path). The latter is +KASAN slab-use-after-free in ieee80211_prepare_and_rx_handle. + +Fix by encoding the rate from status before invoking +ieee80211_rx_mesh_data(), so the RX_QUEUED arm consumes a value +captured while status was still backed by valid memory. + +Fixes: 3468e1e0c639 ("wifi: mac80211: add mesh fast-rx support") +Cc: stable@vger.kernel.org +Signed-off-by: Zhao Li +Link: https://patch.msgid.link/20260509043427.60322-2-enderaoelyther@gmail.com +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/rx.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -4941,6 +4941,7 @@ static bool ieee80211_invoke_fast_rx(str + u8 sa[ETH_ALEN]; + } addrs __aligned(2); + struct ieee80211_sta_rx_stats *stats; ++ u32 encoded_rate; + + /* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write + * to a common data structure; drivers can implement that per queue +@@ -5048,11 +5049,14 @@ static bool ieee80211_invoke_fast_rx(str + /* push the addresses in front */ + memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs)); + ++ /* capture before mesh forward may memset or free skb->cb */ ++ encoded_rate = sta_stats_encode_rate(status); ++ + res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb); + switch (res) { + case RX_QUEUED: + stats->last_rx = jiffies; +- stats->last_rate = sta_stats_encode_rate(status); ++ stats->last_rate = encoded_rate; + return true; + case RX_CONTINUE: + break; diff --git a/queue-7.0/wifi-mac80211-consume-only-present-negotiated-ttlm-maps.patch b/queue-7.0/wifi-mac80211-consume-only-present-negotiated-ttlm-maps.patch new file mode 100644 index 0000000000..352be22297 --- /dev/null +++ b/queue-7.0/wifi-mac80211-consume-only-present-negotiated-ttlm-maps.patch @@ -0,0 +1,56 @@ +From a6e6ccd5bd07155c2add6c74ce1a5e68ad3b95ea Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Fri, 15 May 2026 11:17:18 -0400 +Subject: wifi: mac80211: consume only present negotiated TTLM maps + +From: Michael Bommarito + +commit a6e6ccd5bd07155c2add6c74ce1a5e68ad3b95ea upstream. + +ieee80211_tid_to_link_map_size_ok() validates negotiated TTLM elements +against the number of link-map entries indicated by link_map_presence. +ieee80211_parse_neg_ttlm() must consume the same layout. + +The parser advanced its cursor for every TID, including TIDs whose +presence bit is clear and therefore have no map bytes in the element. +A sparse map can then make a later present TID read past the validated +element. + +The bad bytes land in neg_ttlm->{up,down}link[tid] but are gated by +valid_links before being applied to driver state, so a peer cannot +turn the read into a policy change. Under KUnit + KASAN with an +exact-sized element allocation the OOB read is reported as a +slab-out-of-bounds; whether the same trigger fires under the +production RX path depends on surrounding allocator state. + +Advance the cursor only when the current TID has a map present. + +Fixes: 8f500fbc6c65 ("wifi: mac80211: process and save negotiated TID to Link mapping request") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-7 +Signed-off-by: Michael Bommarito +Link: https://patch.msgid.link/20260515151719.1317659-2-michael.bommarito@gmail.com +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/mlme.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -8070,6 +8070,7 @@ ieee80211_parse_neg_ttlm(struct ieee8021 + "No active links for TID %d", tid); + return -EINVAL; + } ++ pos += map_size; + } else { + map = 0; + } +@@ -8088,7 +8089,6 @@ ieee80211_parse_neg_ttlm(struct ieee8021 + default: + return -EINVAL; + } +- pos += map_size; + } + return 0; + }