From: Greg Kroah-Hartman Date: Thu, 28 May 2026 11:31:15 +0000 (+0200) Subject: 6.18-stable patches X-Git-Tag: v5.10.258~36 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=045eb898e1caf54b4a1f82640d9a23cdcdc7e22e;p=thirdparty%2Fkernel%2Fstable-queue.git 6.18-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-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.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 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-consume-only-present-negotiated-ttlm-maps.patch --- diff --git a/queue-6.18/af_unix-fix-uaf-read-of-tail-len-in-unix_stream_data_wait.patch b/queue-6.18/af_unix-fix-uaf-read-of-tail-len-in-unix_stream_data_wait.patch new file mode 100644 index 0000000000..cf2fe9e794 --- /dev/null +++ b/queue-6.18/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 +@@ -2716,8 +2716,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; +@@ -2730,7 +2729,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) || +@@ -2923,7 +2921,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; +@@ -2969,7 +2966,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) +@@ -3003,8 +2999,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); +@@ -3021,7 +3016,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; +@@ -3096,7 +3090,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-6.18/ice-fix-locking-around-wait_event_interruptible_locked_irq.patch b/queue-6.18/ice-fix-locking-around-wait_event_interruptible_locked_irq.patch new file mode 100644 index 0000000000..75bc4c4d2c --- /dev/null +++ b/queue-6.18/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-6.18/ice-fix-setting-promisc-mode-while-adding-vid-filter.patch b/queue-6.18/ice-fix-setting-promisc-mode-while-adding-vid-filter.patch new file mode 100644 index 0000000000..edde082ffd --- /dev/null +++ b/queue-6.18/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 +@@ -3764,7 +3764,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-6.18/ice-fix-vf-queue-configuration-with-low-mtu-values.patch b/queue-6.18/ice-fix-vf-queue-configuration-with-low-mtu-values.patch new file mode 100644 index 0000000000..080fa245cc --- /dev/null +++ b/queue-6.18/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; + if (qpi->rxq.max_pkt_size > max_frame_size || diff --git a/queue-6.18/ice-restore-ptp-rx-timestamp-config-after-ethtool-set-channels.patch b/queue-6.18/ice-restore-ptp-rx-timestamp-config-after-ethtool-set-channels.patch new file mode 100644 index 0000000000..c0dcbda619 --- /dev/null +++ b/queue-6.18/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 +@@ -4186,6 +4186,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-6.18/igc-fix-potential-skb-leak-in-igc_fpe_xmit_smd_frame.patch b/queue-6.18/igc-fix-potential-skb-leak-in-igc_fpe_xmit_smd_frame.patch new file mode 100644 index 0000000000..9a10065a85 --- /dev/null +++ b/queue-6.18/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-6.18/ipv4-raw-reject-ip_hdrincl-packets-with-ihl-5.patch b/queue-6.18/ipv4-raw-reject-ip_hdrincl-packets-with-ihl-5.patch new file mode 100644 index 0000000000..964adc8ac1 --- /dev/null +++ b/queue-6.18/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-6.18/ipv6-ioam-add-null-check-for-idev-in-ipv6_hop_ioam.patch b/queue-6.18/ipv6-ioam-add-null-check-for-idev-in-ipv6_hop_ioam.patch new file mode 100644 index 0000000000..cfbfdc82c0 --- /dev/null +++ b/queue-6.18/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-6.18/ixgbevf-fix-use-after-free-in-vepa-multicast-source-pruning.patch b/queue-6.18/ixgbevf-fix-use-after-free-in-vepa-multicast-source-pruning.patch new file mode 100644 index 0000000000..b09780a07d --- /dev/null +++ b/queue-6.18/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-6.18/l2tp-use-list_del_rcu-in-l2tp_session_unhash.patch b/queue-6.18/l2tp-use-list_del_rcu-in-l2tp_session_unhash.patch new file mode 100644 index 0000000000..5d29c4d687 --- /dev/null +++ b/queue-6.18/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-6.18/lsm-hold-cred_guard_mutex-for-lsm_set_self_attr.patch b/queue-6.18/lsm-hold-cred_guard_mutex-for-lsm_set_self_attr.patch new file mode 100644 index 0000000000..54f0292123 --- /dev/null +++ b/queue-6.18/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 +@@ -55,7 +55,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-6.18/mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch b/queue-6.18/mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch new file mode 100644 index 0000000000..9b653ba9c0 --- /dev/null +++ b/queue-6.18/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; +@@ -880,6 +890,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; +@@ -901,24 +912,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-6.18/octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.patch b/queue-6.18/octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.patch new file mode 100644 index 0000000000..ba5423ced0 --- /dev/null +++ b/queue-6.18/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-6.18/octeontx2-pf-fix-double-free-in-rvu_rep_rsrc_init.patch b/queue-6.18/octeontx2-pf-fix-double-free-in-rvu_rep_rsrc_init.patch new file mode 100644 index 0000000000..abce443cdf --- /dev/null +++ b/queue-6.18/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-6.18/qed-fix-double-free-in-qed_cxt_tables_alloc.patch b/queue-6.18/qed-fix-double-free-in-qed_cxt_tables_alloc.patch new file mode 100644 index 0000000000..681cadbe75 --- /dev/null +++ b/queue-6.18/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 +@@ -1038,11 +1038,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-6.18/rbd-eliminate-a-race-in-lock_dwork-draining-on-unmap.patch b/queue-6.18/rbd-eliminate-a-race-in-lock_dwork-draining-on-unmap.patch new file mode 100644 index 0000000000..a5ca2ccf31 --- /dev/null +++ b/queue-6.18/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-6.18/ring-buffer-fix-reporting-of-missed-events-in-iterator.patch b/queue-6.18/ring-buffer-fix-reporting-of-missed-events-in-iterator.patch new file mode 100644 index 0000000000..b8ad5201e7 --- /dev/null +++ b/queue-6.18/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 +@@ -5249,6 +5249,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; +@@ -5863,10 +5864,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); + +@@ -6028,7 +6026,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-6.18/ring-buffer-flush-and-stop-persistent-ring-buffer-on-panic.patch b/queue-6.18/ring-buffer-flush-and-stop-persistent-ring-buffer-on-panic.patch new file mode 100644 index 0000000000..24de1a7399 --- /dev/null +++ b/queue-6.18/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 +@@ -9,5 +9,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 +@@ -8,3 +8,4 @@ generic-y += asm-offsets.h + generic-y += kvm_types.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 +@@ -18,6 +18,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 +@@ -5,6 +5,7 @@ + * Copyright (C) 2008 Steven Rostedt + */ + #include ++#include + #include + #include + #include +@@ -29,6 +30,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -553,6 +555,7 @@ struct trace_buffer { + + unsigned long range_addr_start; + unsigned long range_addr_end; ++ struct notifier_block flush_nb; + + struct ring_buffer_meta *meta; + +@@ -2455,6 +2458,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, +@@ -2574,6 +2587,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: +@@ -2661,6 +2680,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-6.18/series b/queue-6.18/series index 6b9747503a..d4adcd1ab5 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -76,3 +76,28 @@ cgroup-cpuset-reset-dl-migration-state-on-can_attach-failure.patch net-ethtool-fix-null-pointer-dereference-in-phy_reply_size.patch net-ethtool-phy-avoid-null-deref-when-phy-driver-is-unbound.patch fs-ntfs3-handle-attr_set_size-errors-when-truncating-files.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 +ipv6-ioam-add-null-check-for-idev-in-ipv6_hop_ioam.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 +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 diff --git a/queue-6.18/vsock-virtio-reset-connection-on-receiving-queue-overflow.patch b/queue-6.18/vsock-virtio-reset-connection-on-receiving-queue-overflow.patch new file mode 100644 index 0000000000..a45d9f743b --- /dev/null +++ b/queue-6.18/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 +@@ -1335,7 +1335,7 @@ destroy: + return err; + } + +-static void ++static bool + virtio_transport_recv_enqueue(struct vsock_sock *vsk, + struct sk_buff *skb) + { +@@ -1350,10 +1350,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++; +@@ -1393,6 +1391,8 @@ out: + spin_unlock_bh(&vvs->rx_lock); + if (free_pkt) + kfree_skb(skb); ++ ++ return can_enqueue; + } + + static int +@@ -1405,7 +1405,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-6.18/vsock-vmci-fix-uaf-when-peer-resets-connection-during-handshake.patch b/queue-6.18/vsock-vmci-fix-uaf-when-peer-resets-connection-during-handshake.patch new file mode 100644 index 0000000000..ea1c32a8e6 --- /dev/null +++ b/queue-6.18/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 +@@ -1156,7 +1156,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-6.18/wifi-ath11k-clear-shared-srng-pointer-state-on-restart.patch b/queue-6.18/wifi-ath11k-clear-shared-srng-pointer-state-on-restart.patch new file mode 100644 index 0000000000..577db50c75 --- /dev/null +++ b/queue-6.18/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 +@@ -1388,14 +1388,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-6.18/wifi-cfg80211-advance-loop-vars-in-cfg80211_merge_profile.patch b/queue-6.18/wifi-cfg80211-advance-loop-vars-in-cfg80211_merge_profile.patch new file mode 100644 index 0000000000..e69126ec18 --- /dev/null +++ b/queue-6.18/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 +@@ -2475,6 +2475,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-6.18/wifi-iwlwifi-mld-stop-tx-during-firmware-restart.patch b/queue-6.18/wifi-iwlwifi-mld-stop-tx-during-firmware-restart.patch new file mode 100644 index 0000000000..dd63a21b3a --- /dev/null +++ b/queue-6.18/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 +@@ -965,6 +965,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-6.18/wifi-iwlwifi-mvm-fix-driver-set-tx-rates-on-old-devices.patch b/queue-6.18/wifi-iwlwifi-mvm-fix-driver-set-tx-rates-on-old-devices.patch new file mode 100644 index 0000000000..91a95f3b31 --- /dev/null +++ b/queue-6.18/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 + */ +@@ -938,13 +938,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; + } + +@@ -973,6 +978,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; + +@@ -992,18 +998,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-6.18/wifi-mac80211-consume-only-present-negotiated-ttlm-maps.patch b/queue-6.18/wifi-mac80211-consume-only-present-negotiated-ttlm-maps.patch new file mode 100644 index 0000000000..3ff17f29db --- /dev/null +++ b/queue-6.18/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 +@@ -7959,6 +7959,7 @@ ieee80211_parse_neg_ttlm(struct ieee8021 + "No active links for TID %d", tid); + return -EINVAL; + } ++ pos += map_size; + } else { + map = 0; + } +@@ -7977,7 +7978,6 @@ ieee80211_parse_neg_ttlm(struct ieee8021 + default: + return -EINVAL; + } +- pos += map_size; + } + return 0; + }