]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for all trees master
authorSasha Levin <sashal@kernel.org>
Sat, 20 Dec 2025 09:28:55 +0000 (04:28 -0500)
committerSasha Levin <sashal@kernel.org>
Sat, 20 Dec 2025 09:28:55 +0000 (04:28 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
189 files changed:
queue-5.10/broadcom-b44-prevent-uninitialized-value-usage.patch [new file with mode: 0644]
queue-5.10/caif-fix-integer-underflow-in-cffrml_receive.patch [new file with mode: 0644]
queue-5.10/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch [new file with mode: 0644]
queue-5.10/ethtool-use-phydev-variable.patch [new file with mode: 0644]
queue-5.10/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch [new file with mode: 0644]
queue-5.10/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch [new file with mode: 0644]
queue-5.10/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch [new file with mode: 0644]
queue-5.10/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch [new file with mode: 0644]
queue-5.10/net-ethtool-ioctl-remove-if-n_stats-checks-from-etht.patch [new file with mode: 0644]
queue-5.10/net-ethtool-ioctl-split-ethtool_get_phy_stats-into-m.patch [new file with mode: 0644]
queue-5.10/net-hns3-add-vlan-id-validation-before-using.patch [new file with mode: 0644]
queue-5.10/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch [new file with mode: 0644]
queue-5.10/net-mlx5-fw_tracer-add-support-for-unrecognized-stri.patch [new file with mode: 0644]
queue-5.10/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch [new file with mode: 0644]
queue-5.10/net-mlx5-fw_tracer-validate-format-string-parameters.patch [new file with mode: 0644]
queue-5.10/net-openvswitch-fix-middle-attribute-validation-in-p.patch [new file with mode: 0644]
queue-5.10/net-sched-ets-always-remove-class-from-active-list-b.patch [new file with mode: 0644]
queue-5.10/net-sched-ets-remove-drr-class-from-the-active-list-.patch [new file with mode: 0644]
queue-5.10/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch [new file with mode: 0644]
queue-5.10/netrom-fix-memory-leak-in-nr_sendmsg.patch [new file with mode: 0644]
queue-5.10/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch [new file with mode: 0644]
queue-5.10/series
queue-5.15/broadcom-b44-prevent-uninitialized-value-usage.patch [new file with mode: 0644]
queue-5.15/caif-fix-integer-underflow-in-cffrml_receive.patch [new file with mode: 0644]
queue-5.15/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch [new file with mode: 0644]
queue-5.15/ethtool-use-phydev-variable.patch [new file with mode: 0644]
queue-5.15/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch [new file with mode: 0644]
queue-5.15/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch [new file with mode: 0644]
queue-5.15/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch [new file with mode: 0644]
queue-5.15/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch [new file with mode: 0644]
queue-5.15/net-ethtool-ioctl-remove-if-n_stats-checks-from-etht.patch [new file with mode: 0644]
queue-5.15/net-ethtool-ioctl-split-ethtool_get_phy_stats-into-m.patch [new file with mode: 0644]
queue-5.15/net-hns3-add-vlan-id-validation-before-using.patch [new file with mode: 0644]
queue-5.15/net-hns3-align-type-of-some-variables-with-their-pri.patch [new file with mode: 0644]
queue-5.15/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch [new file with mode: 0644]
queue-5.15/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch [new file with mode: 0644]
queue-5.15/net-mlx5-fw_tracer-add-support-for-unrecognized-stri.patch [new file with mode: 0644]
queue-5.15/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch [new file with mode: 0644]
queue-5.15/net-mlx5-fw_tracer-validate-format-string-parameters.patch [new file with mode: 0644]
queue-5.15/net-openvswitch-fix-middle-attribute-validation-in-p.patch [new file with mode: 0644]
queue-5.15/net-sched-ets-always-remove-class-from-active-list-b.patch [new file with mode: 0644]
queue-5.15/net-sched-ets-remove-drr-class-from-the-active-list-.patch [new file with mode: 0644]
queue-5.15/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch [new file with mode: 0644]
queue-5.15/netrom-fix-memory-leak-in-nr_sendmsg.patch [new file with mode: 0644]
queue-5.15/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch [new file with mode: 0644]
queue-5.15/series
queue-6.1/broadcom-b44-prevent-uninitialized-value-usage.patch [new file with mode: 0644]
queue-6.1/caif-fix-integer-underflow-in-cffrml_receive.patch [new file with mode: 0644]
queue-6.1/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch [new file with mode: 0644]
queue-6.1/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch [new file with mode: 0644]
queue-6.1/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch [new file with mode: 0644]
queue-6.1/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch [new file with mode: 0644]
queue-6.1/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch [new file with mode: 0644]
queue-6.1/net-ethtool-ioctl-remove-if-n_stats-checks-from-etht.patch [new file with mode: 0644]
queue-6.1/net-ethtool-ioctl-split-ethtool_get_phy_stats-into-m.patch [new file with mode: 0644]
queue-6.1/net-hns3-add-vlan-id-validation-before-using.patch [new file with mode: 0644]
queue-6.1/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch [new file with mode: 0644]
queue-6.1/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch [new file with mode: 0644]
queue-6.1/net-mlx5-create-a-new-profile-for-sfs.patch [new file with mode: 0644]
queue-6.1/net-mlx5-drain-firmware-reset-in-shutdown-callback.patch [new file with mode: 0644]
queue-6.1/net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch [new file with mode: 0644]
queue-6.1/net-mlx5-fw_tracer-add-support-for-unrecognized-stri.patch [new file with mode: 0644]
queue-6.1/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch [new file with mode: 0644]
queue-6.1/net-mlx5-fw_tracer-validate-format-string-parameters.patch [new file with mode: 0644]
queue-6.1/net-openvswitch-fix-middle-attribute-validation-in-p.patch [new file with mode: 0644]
queue-6.1/net-sched-ets-always-remove-class-from-active-list-b.patch [new file with mode: 0644]
queue-6.1/net-sched-ets-remove-drr-class-from-the-active-list-.patch [new file with mode: 0644]
queue-6.1/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch [new file with mode: 0644]
queue-6.1/netrom-fix-memory-leak-in-nr_sendmsg.patch [new file with mode: 0644]
queue-6.1/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch [new file with mode: 0644]
queue-6.1/series
queue-6.12/bnxt_en-fix-xdp_tx-path.patch [new file with mode: 0644]
queue-6.12/broadcom-b44-prevent-uninitialized-value-usage.patch [new file with mode: 0644]
queue-6.12/caif-fix-integer-underflow-in-cffrml_receive.patch [new file with mode: 0644]
queue-6.12/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch [new file with mode: 0644]
queue-6.12/iommufd-selftest-add-coverage-for-reporting-max_pasi.patch [new file with mode: 0644]
queue-6.12/iommufd-selftest-check-for-overflow-in-iommu_test_op.patch [new file with mode: 0644]
queue-6.12/iommufd-selftest-make-it-clearer-to-gcc-that-the-acc.patch [new file with mode: 0644]
queue-6.12/iommufd-selftest-update-hw_info-coverage-for-an-inpu.patch [new file with mode: 0644]
queue-6.12/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch [new file with mode: 0644]
queue-6.12/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch [new file with mode: 0644]
queue-6.12/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch [new file with mode: 0644]
queue-6.12/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch [new file with mode: 0644]
queue-6.12/mlxsw-spectrum_router-fix-possible-neighbour-referen.patch [new file with mode: 0644]
queue-6.12/net-enetc-do-not-transmit-redirected-xdp-frames-when.patch [new file with mode: 0644]
queue-6.12/net-fec-err007885-workaround-for-xdp-tx-path.patch [new file with mode: 0644]
queue-6.12/net-handshake-duplicate-handshake-cancellations-leak.patch [new file with mode: 0644]
queue-6.12/net-hns3-add-vlan-id-validation-before-using.patch [new file with mode: 0644]
queue-6.12/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch [new file with mode: 0644]
queue-6.12/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch [new file with mode: 0644]
queue-6.12/net-mlx5-drain-firmware-reset-in-shutdown-callback.patch [new file with mode: 0644]
queue-6.12/net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch [new file with mode: 0644]
queue-6.12/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch [new file with mode: 0644]
queue-6.12/net-mlx5-fw_tracer-validate-format-string-parameters.patch [new file with mode: 0644]
queue-6.12/net-mlx5-serialize-firmware-reset-with-devlink.patch [new file with mode: 0644]
queue-6.12/net-openvswitch-fix-middle-attribute-validation-in-p.patch [new file with mode: 0644]
queue-6.12/net-sched-ets-always-remove-class-from-active-list-b.patch [new file with mode: 0644]
queue-6.12/net-sched-ets-remove-drr-class-from-the-active-list-.patch [new file with mode: 0644]
queue-6.12/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch [new file with mode: 0644]
queue-6.12/netfilter-nf_nat-remove-bogus-direction-check.patch [new file with mode: 0644]
queue-6.12/netfilter-nf_tables-remove-redundant-chain-validatio.patch [new file with mode: 0644]
queue-6.12/netrom-fix-memory-leak-in-nr_sendmsg.patch [new file with mode: 0644]
queue-6.12/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch [new file with mode: 0644]
queue-6.12/selftests-netfilter-packetdrill-avoid-failure-on-hz-.patch [new file with mode: 0644]
queue-6.12/series
queue-6.18/bnxt_en-fix-xdp_tx-path.patch [new file with mode: 0644]
queue-6.18/broadcom-b44-prevent-uninitialized-value-usage.patch [new file with mode: 0644]
queue-6.18/caif-fix-integer-underflow-in-cffrml_receive.patch [new file with mode: 0644]
queue-6.18/can-j1939-make-j1939_sk_bind-fail-if-device-is-no-lo.patch [new file with mode: 0644]
queue-6.18/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch [new file with mode: 0644]
queue-6.18/inet-frags-add-inet_frag_queue_flush.patch [new file with mode: 0644]
queue-6.18/inet-frags-avoid-theoretical-race-in-ip_frag_reinit.patch [new file with mode: 0644]
queue-6.18/inet-frags-flush-pending-skbs-in-fqdir_pre_exit.patch [new file with mode: 0644]
queue-6.18/iommufd-selftest-check-for-overflow-in-iommu_test_op.patch [new file with mode: 0644]
queue-6.18/iommufd-selftest-make-it-clearer-to-gcc-that-the-acc.patch [new file with mode: 0644]
queue-6.18/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch [new file with mode: 0644]
queue-6.18/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch [new file with mode: 0644]
queue-6.18/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch [new file with mode: 0644]
queue-6.18/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch [new file with mode: 0644]
queue-6.18/mlxsw-spectrum_router-fix-possible-neighbour-referen.patch [new file with mode: 0644]
queue-6.18/net-enetc-do-not-transmit-redirected-xdp-frames-when.patch [new file with mode: 0644]
queue-6.18/net-fec-err007885-workaround-for-xdp-tx-path.patch [new file with mode: 0644]
queue-6.18/net-handshake-duplicate-handshake-cancellations-leak.patch [new file with mode: 0644]
queue-6.18/net-hns3-add-vlan-id-validation-before-using.patch [new file with mode: 0644]
queue-6.18/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch [new file with mode: 0644]
queue-6.18/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch [new file with mode: 0644]
queue-6.18/net-mlx5-drain-firmware-reset-in-shutdown-callback.patch [new file with mode: 0644]
queue-6.18/net-mlx5-fix-double-unregister-of-hca_ports-componen.patch [new file with mode: 0644]
queue-6.18/net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch [new file with mode: 0644]
queue-6.18/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch [new file with mode: 0644]
queue-6.18/net-mlx5-fw_tracer-validate-format-string-parameters.patch [new file with mode: 0644]
queue-6.18/net-mlx5-make-enable_mpesw-idempotent.patch [new file with mode: 0644]
queue-6.18/net-mlx5-serialize-firmware-reset-with-devlink.patch [new file with mode: 0644]
queue-6.18/net-mlx5e-avoid-unregistering-psp-twice.patch [new file with mode: 0644]
queue-6.18/net-mlx5e-don-t-include-psp-in-the-hard-mtu-calculat.patch [new file with mode: 0644]
queue-6.18/net-mlx5e-trigger-neighbor-resolution-for-unresolved.patch [new file with mode: 0644]
queue-6.18/net-mlx5e-use-ip6_dst_lookup-instead-of-ipv6_dst_loo.patch [new file with mode: 0644]
queue-6.18/net-openvswitch-fix-middle-attribute-validation-in-p.patch [new file with mode: 0644]
queue-6.18/net-phy-realtek-allow-clkout-to-be-disabled-on-rtl82.patch [new file with mode: 0644]
queue-6.18/net-phy-realtek-create-rtl8211f_config_phy_eee-helpe.patch [new file with mode: 0644]
queue-6.18/net-phy-realtek-eliminate-has_phycr2-variable.patch [new file with mode: 0644]
queue-6.18/net-phy-realtek-eliminate-priv-phycr1-variable.patch [new file with mode: 0644]
queue-6.18/net-phy-realtek-eliminate-priv-phycr2-variable.patch [new file with mode: 0644]
queue-6.18/net-phy-rtl8211fvd-restore-disabling-of-phy-mode-eee.patch [new file with mode: 0644]
queue-6.18/net-sched-ets-always-remove-class-from-active-list-b.patch [new file with mode: 0644]
queue-6.18/net-sched-ets-remove-drr-class-from-the-active-list-.patch [new file with mode: 0644]
queue-6.18/net-ti-icssg-prueth-add-ptp_1588_clock_optional-depe.patch [new file with mode: 0644]
queue-6.18/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch [new file with mode: 0644]
queue-6.18/netfilter-nf_nat-remove-bogus-direction-check.patch [new file with mode: 0644]
queue-6.18/netfilter-nf_tables-remove-redundant-chain-validatio.patch [new file with mode: 0644]
queue-6.18/netrom-fix-memory-leak-in-nr_sendmsg.patch [new file with mode: 0644]
queue-6.18/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch [new file with mode: 0644]
queue-6.18/selftest-af_unix-support-compilers-without-flex-arra.patch [new file with mode: 0644]
queue-6.18/selftests-net-fix-build-warnings.patch [new file with mode: 0644]
queue-6.18/selftests-net-tfo-fix-build-warning.patch [new file with mode: 0644]
queue-6.18/selftests-netfilter-packetdrill-avoid-failure-on-hz-.patch [new file with mode: 0644]
queue-6.18/selftests-netfilter-prefer-xfail-in-case-race-wasn-t.patch [new file with mode: 0644]
queue-6.18/series
queue-6.6/broadcom-b44-prevent-uninitialized-value-usage.patch [new file with mode: 0644]
queue-6.6/caif-fix-integer-underflow-in-cffrml_receive.patch [new file with mode: 0644]
queue-6.6/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch [new file with mode: 0644]
queue-6.6/iommufd-selftest-check-for-overflow-in-iommu_test_op.patch [new file with mode: 0644]
queue-6.6/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch [new file with mode: 0644]
queue-6.6/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch [new file with mode: 0644]
queue-6.6/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch [new file with mode: 0644]
queue-6.6/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch [new file with mode: 0644]
queue-6.6/mlxsw-spectrum_router-fix-possible-neighbour-referen.patch [new file with mode: 0644]
queue-6.6/net-enetc-do-not-transmit-redirected-xdp-frames-when.patch [new file with mode: 0644]
queue-6.6/net-fec-err007885-workaround-for-xdp-tx-path.patch [new file with mode: 0644]
queue-6.6/net-handshake-duplicate-handshake-cancellations-leak.patch [new file with mode: 0644]
queue-6.6/net-hns3-add-vlan-id-validation-before-using.patch [new file with mode: 0644]
queue-6.6/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch [new file with mode: 0644]
queue-6.6/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch [new file with mode: 0644]
queue-6.6/net-mlx5-drain-firmware-reset-in-shutdown-callback.patch [new file with mode: 0644]
queue-6.6/net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch [new file with mode: 0644]
queue-6.6/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch [new file with mode: 0644]
queue-6.6/net-mlx5-fw_tracer-validate-format-string-parameters.patch [new file with mode: 0644]
queue-6.6/net-mlx5-serialize-firmware-reset-with-devlink.patch [new file with mode: 0644]
queue-6.6/net-mlx5-skip-hotplug-check-on-sync-reset-using-hot-.patch [new file with mode: 0644]
queue-6.6/net-openvswitch-fix-middle-attribute-validation-in-p.patch [new file with mode: 0644]
queue-6.6/net-sched-ets-always-remove-class-from-active-list-b.patch [new file with mode: 0644]
queue-6.6/net-sched-ets-remove-drr-class-from-the-active-list-.patch [new file with mode: 0644]
queue-6.6/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch [new file with mode: 0644]
queue-6.6/netfilter-nf_tables-allow-loads-only-when-register-i.patch [new file with mode: 0644]
queue-6.6/netfilter-nf_tables-pass-context-structure-to-nft_pa.patch [new file with mode: 0644]
queue-6.6/netfilter-nf_tables-remove-redundant-chain-validatio.patch [new file with mode: 0644]
queue-6.6/netrom-fix-memory-leak-in-nr_sendmsg.patch [new file with mode: 0644]
queue-6.6/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch [new file with mode: 0644]
queue-6.6/series

diff --git a/queue-5.10/broadcom-b44-prevent-uninitialized-value-usage.patch b/queue-5.10/broadcom-b44-prevent-uninitialized-value-usage.patch
new file mode 100644 (file)
index 0000000..490b30b
--- /dev/null
@@ -0,0 +1,45 @@
+From d434e3a21ca076ef40aa7565d08b730394a33d17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 18:58:16 +0300
+Subject: broadcom: b44: prevent uninitialized value usage
+
+From: Alexey Simakov <bigalex934@gmail.com>
+
+[ Upstream commit 50b3db3e11864cb4e18ff099cfb38e11e7f87a68 ]
+
+On execution path with raised B44_FLAG_EXTERNAL_PHY, b44_readphy()
+leaves bmcr value uninitialized and it is used later in the code.
+
+Add check of this flag at the beginning of the b44_nway_reset() and
+exit early of the function with restarting autonegotiation if an
+external PHY is used.
+
+Fixes: 753f492093da ("[B44]: port to native ssb support")
+Reviewed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Alexey Simakov <bigalex934@gmail.com>
+Reviewed-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20251205155815.4348-1-bigalex934@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/b44.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
+index 7ad9a47156912..f29a38675afb6 100644
+--- a/drivers/net/ethernet/broadcom/b44.c
++++ b/drivers/net/ethernet/broadcom/b44.c
+@@ -1809,6 +1809,9 @@ static int b44_nway_reset(struct net_device *dev)
+       u32 bmcr;
+       int r;
++      if (bp->flags & B44_FLAG_EXTERNAL_PHY)
++              return phy_ethtool_nway_reset(dev);
++
+       spin_lock_irq(&bp->lock);
+       b44_readphy(bp, MII_BMCR, &bmcr);
+       b44_readphy(bp, MII_BMCR, &bmcr);
+-- 
+2.51.0
+
diff --git a/queue-5.10/caif-fix-integer-underflow-in-cffrml_receive.patch b/queue-5.10/caif-fix-integer-underflow-in-cffrml_receive.patch
new file mode 100644 (file)
index 0000000..e0f6a01
--- /dev/null
@@ -0,0 +1,58 @@
+From 68d9a2f745456c6ac7633177d84076632efe8a1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Dec 2025 21:30:47 +0800
+Subject: caif: fix integer underflow in cffrml_receive()
+
+From: Junrui Luo <moonafterrain@outlook.com>
+
+[ Upstream commit 8a11ff0948b5ad09b71896b7ccc850625f9878d1 ]
+
+The cffrml_receive() function extracts a length field from the packet
+header and, when FCS is disabled, subtracts 2 from this length without
+validating that len >= 2.
+
+If an attacker sends a malicious packet with a length field of 0 or 1
+to an interface with FCS disabled, the subtraction causes an integer
+underflow.
+
+This can lead to memory exhaustion and kernel instability, potential
+information disclosure if padding contains uninitialized kernel memory.
+
+Fix this by validating that len >= 2 before performing the subtraction.
+
+Reported-by: Yuhao Jiang <danisjiang@gmail.com>
+Reported-by: Junrui Luo <moonafterrain@outlook.com>
+Fixes: b482cd2053e3 ("net-caif: add CAIF core protocol stack")
+Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/SYBPR01MB7881511122BAFEA8212A1608AFA6A@SYBPR01MB7881.ausprd01.prod.outlook.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/caif/cffrml.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c
+index 6651a8dc62e04..d4d63586053ad 100644
+--- a/net/caif/cffrml.c
++++ b/net/caif/cffrml.c
+@@ -92,8 +92,15 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
+       len = le16_to_cpu(tmp);
+       /* Subtract for FCS on length if FCS is not used. */
+-      if (!this->dofcs)
++      if (!this->dofcs) {
++              if (len < 2) {
++                      ++cffrml_rcv_error;
++                      pr_err("Invalid frame length (%d)\n", len);
++                      cfpkt_destroy(pkt);
++                      return -EPROTO;
++              }
+               len -= 2;
++      }
+       if (cfpkt_setlen(pkt, len) < 0) {
+               ++cffrml_rcv_error;
+-- 
+2.51.0
+
diff --git a/queue-5.10/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch b/queue-5.10/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch
new file mode 100644 (file)
index 0000000..a197f4a
--- /dev/null
@@ -0,0 +1,159 @@
+From 803f1dcc56542dbc4b2b117f9f7a746626727a91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 14:19:01 +0200
+Subject: ethtool: Avoid overflowing userspace buffer on stats query
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 7b07be1ff1cb6c49869910518650e8d0abc7d25f ]
+
+The ethtool -S command operates across three ioctl calls:
+ETHTOOL_GSSET_INFO for the size, ETHTOOL_GSTRINGS for the names, and
+ETHTOOL_GSTATS for the values.
+
+If the number of stats changes between these calls (e.g., due to device
+reconfiguration), userspace's buffer allocation will be incorrect,
+potentially leading to buffer overflow.
+
+Drivers are generally expected to maintain stable stat counts, but some
+drivers (e.g., mlx5, bnx2x, bna, ksz884x) use dynamic counters, making
+this scenario possible.
+
+Some drivers try to handle this internally:
+- bnad_get_ethtool_stats() returns early in case stats.n_stats is not
+  equal to the driver's stats count.
+- micrel/ksz884x also makes sure not to write anything beyond
+  stats.n_stats and overflow the buffer.
+
+However, both use stats.n_stats which is already assigned with the value
+returned from get_sset_count(), hence won't solve the issue described
+here.
+
+Change ethtool_get_strings(), ethtool_get_stats(),
+ethtool_get_phy_stats() to not return anything in case of a mismatch
+between userspace's size and get_sset_size(), to prevent buffer
+overflow.
+The returned n_stats value will be equal to zero, to reflect that
+nothing has been returned.
+
+This could result in one of two cases when using upstream ethtool,
+depending on when the size change is detected:
+1. When detected in ethtool_get_strings():
+    # ethtool -S eth2
+    no stats available
+
+2. When detected in get stats, all stats will be reported as zero.
+
+Both cases are presumably transient, and a subsequent ethtool call
+should succeed.
+
+Other than the overflow avoidance, these two cases are very evident (no
+output/cleared stats), which is arguably better than presenting
+incorrect/shifted stats.
+I also considered returning an error instead of a "silent" response, but
+that seems more destructive towards userspace apps.
+
+Notes:
+- This patch does not claim to fix the inherent race, it only makes sure
+  that we do not overflow the userspace buffer, and makes for a more
+  predictable behavior.
+
+- RTNL lock is held during each ioctl, the race window exists between
+  the separate ioctl calls when the lock is released.
+
+- Userspace ethtool always fills stats.n_stats, but it is likely that
+  these stats ioctls are implemented in other userspace applications
+  which might not fill it. The added code checks that it's not zero,
+  to prevent any regressions.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Link: https://patch.msgid.link/20251208121901.3203692-1-gal@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 30 ++++++++++++++++++++++++------
+ 1 file changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 2ac9cf1c36ba6..7fef4bbfb210a 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -1909,7 +1909,10 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
+               return -ENOMEM;
+       WARN_ON_ONCE(!ret);
+-      gstrings.len = ret;
++      if (gstrings.len && gstrings.len != ret)
++              gstrings.len = 0;
++      else
++              gstrings.len = ret;
+       if (gstrings.len) {
+               data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
+@@ -2010,10 +2013,13 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       if (copy_from_user(&stats, useraddr, sizeof(stats)))
+               return -EFAULT;
+-      stats.n_stats = n_stats;
++      if (stats.n_stats && stats.n_stats != n_stats)
++              stats.n_stats = 0;
++      else
++              stats.n_stats = n_stats;
+-      if (n_stats) {
+-              data = vzalloc(array_size(n_stats, sizeof(u64)));
++      if (stats.n_stats) {
++              data = vzalloc(array_size(stats.n_stats, sizeof(u64)));
+               if (!data)
+                       return -ENOMEM;
+               ops->get_ethtool_stats(dev, &stats, data);
+@@ -2025,7 +2031,9 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       if (copy_to_user(useraddr, &stats, sizeof(stats)))
+               goto out;
+       useraddr += sizeof(stats);
+-      if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
++      if (stats.n_stats &&
++          copy_to_user(useraddr, data,
++                       array_size(stats.n_stats, sizeof(u64))))
+               goto out;
+       ret = 0;
+@@ -2061,6 +2069,10 @@ static int ethtool_get_phy_stats_phydev(struct phy_device *phydev,
+               return -EOPNOTSUPP;
+       n_stats = phy_ops->get_sset_count(phydev);
++      if (stats->n_stats && stats->n_stats != n_stats) {
++              stats->n_stats = 0;
++              return 0;
++      }
+       ret = ethtool_vzalloc_stats_array(n_stats, data);
+       if (ret)
+@@ -2081,6 +2093,10 @@ static int ethtool_get_phy_stats_ethtool(struct net_device *dev,
+               return -EOPNOTSUPP;
+       n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
++      if (stats->n_stats && stats->n_stats != n_stats) {
++              stats->n_stats = 0;
++              return 0;
++      }
+       ret = ethtool_vzalloc_stats_array(n_stats, data);
+       if (ret)
+@@ -2117,7 +2133,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       }
+       useraddr += sizeof(stats);
+-      if (copy_to_user(useraddr, data, array_size(stats.n_stats, sizeof(u64))))
++      if (stats.n_stats &&
++          copy_to_user(useraddr, data,
++                       array_size(stats.n_stats, sizeof(u64))))
+               ret = -EFAULT;
+  out:
+-- 
+2.51.0
+
diff --git a/queue-5.10/ethtool-use-phydev-variable.patch b/queue-5.10/ethtool-use-phydev-variable.patch
new file mode 100644 (file)
index 0000000..4eba0da
--- /dev/null
@@ -0,0 +1,53 @@
+From 616c08618d581c1c9b0a47d9cd08e2d365e3912d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jan 2022 06:10:20 -0800
+Subject: ethtool: use phydev variable
+
+From: Tom Rix <trix@redhat.com>
+
+[ Upstream commit ccd21ec5b8dd9b8a528a70315cee95fc1dd79d20 ]
+
+In ethtool_get_phy_stats(), the phydev varaible is set to
+dev->phydev but dev->phydev is still used.  Replace
+dev->phydev uses with phydev.
+
+Signed-off-by: Tom Rix <trix@redhat.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 7b07be1ff1cb ("ethtool: Avoid overflowing userspace buffer on stats query")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 0a588545d3526..ede11854f493f 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -2046,9 +2046,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       if (!phydev && (!ops->get_ethtool_phy_stats || !ops->get_sset_count))
+               return -EOPNOTSUPP;
+-      if (dev->phydev && !ops->get_ethtool_phy_stats &&
++      if (phydev && !ops->get_ethtool_phy_stats &&
+           phy_ops && phy_ops->get_sset_count)
+-              n_stats = phy_ops->get_sset_count(dev->phydev);
++              n_stats = phy_ops->get_sset_count(phydev);
+       else
+               n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
+       if (n_stats < 0)
+@@ -2068,9 +2068,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+               if (!data)
+                       return -ENOMEM;
+-              if (dev->phydev && !ops->get_ethtool_phy_stats &&
++              if (phydev && !ops->get_ethtool_phy_stats &&
+                   phy_ops && phy_ops->get_stats) {
+-                      ret = phy_ops->get_stats(dev->phydev, &stats, data);
++                      ret = phy_ops->get_stats(phydev, &stats, data);
+                       if (ret < 0)
+                               goto out;
+               } else {
+-- 
+2.51.0
+
diff --git a/queue-5.10/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch b/queue-5.10/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch
new file mode 100644 (file)
index 0000000..86139c7
--- /dev/null
@@ -0,0 +1,48 @@
+From db048afb39a142078013fba9fd9944a58c8c0590 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 13:39:03 +0300
+Subject: ipvlan: Ignore PACKET_LOOPBACK in handle_mode_l2()
+
+From: Dmitry Skorodumov <skorodumov.dmitry@huawei.com>
+
+[ Upstream commit 0c57ff008a11f24f7f05fa760222692a00465fec ]
+
+Packets with pkt_type == PACKET_LOOPBACK are captured by
+handle_frame() function, but they don't have L2 header.
+We should not process them in handle_mode_l2().
+
+This doesn't affect old L2 functionality, since handling
+was anyway incorrect.
+
+Handle them the same way as in br_handle_frame():
+just pass the skb.
+
+To observe invalid behaviour, just start "ping -b" on bcast address
+of port-interface.
+
+Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
+Signed-off-by: Dmitry Skorodumov <skorodumov.dmitry@huawei.com>
+Link: https://patch.msgid.link/20251202103906.4087675-1-skorodumov.dmitry@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ipvlan/ipvlan_core.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
+index d04b1450875b6..a113a06c98a55 100644
+--- a/drivers/net/ipvlan/ipvlan_core.c
++++ b/drivers/net/ipvlan/ipvlan_core.c
+@@ -726,6 +726,9 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,
+       struct ethhdr *eth = eth_hdr(skb);
+       rx_handler_result_t ret = RX_HANDLER_PASS;
++      if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
++              return RX_HANDLER_PASS;
++
+       if (is_multicast_ether_addr(eth->h_dest)) {
+               if (ipvlan_external_frame(skb, port)) {
+                       struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
+-- 
+2.51.0
+
diff --git a/queue-5.10/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch b/queue-5.10/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch
new file mode 100644 (file)
index 0000000..5de033c
--- /dev/null
@@ -0,0 +1,80 @@
+From 95c52589715514f3456f72973857d1bf4dacae4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 16:52:13 +0800
+Subject: ipvs: fix ipv4 null-ptr-deref in route error path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Slavin Liu <slavin452@gmail.com>
+
+[ Upstream commit ad891bb3d079a46a821bf2b8867854645191bab0 ]
+
+The IPv4 code path in __ip_vs_get_out_rt() calls dst_link_failure()
+without ensuring skb->dev is set, leading to a NULL pointer dereference
+in fib_compute_spec_dst() when ipv4_link_failure() attempts to send
+ICMP destination unreachable messages.
+
+The issue emerged after commit ed0de45a1008 ("ipv4: recompile ip options
+in ipv4_link_failure") started calling __ip_options_compile() from
+ipv4_link_failure(). This code path eventually calls fib_compute_spec_dst()
+which dereferences skb->dev. An attempt was made to fix the NULL skb->dev
+dereference in commit 0113d9c9d1cc ("ipv4: fix null-deref in
+ipv4_link_failure"), but it only addressed the immediate dev_net(skb->dev)
+dereference by using a fallback device. The fix was incomplete because
+fib_compute_spec_dst() later in the call chain still accesses skb->dev
+directly, which remains NULL when IPVS calls dst_link_failure().
+
+The crash occurs when:
+1. IPVS processes a packet in NAT mode with a misconfigured destination
+2. Route lookup fails in __ip_vs_get_out_rt() before establishing a route
+3. The error path calls dst_link_failure(skb) with skb->dev == NULL
+4. ipv4_link_failure() â†’ ipv4_send_dest_unreach() â†’
+   __ip_options_compile() â†’ fib_compute_spec_dst()
+5. fib_compute_spec_dst() dereferences NULL skb->dev
+
+Apply the same fix used for IPv6 in commit 326bf17ea5d4 ("ipvs: fix
+ipv6 route unreach panic"): set skb->dev from skb_dst(skb)->dev before
+calling dst_link_failure().
+
+KASAN: null-ptr-deref in range [0x0000000000000328-0x000000000000032f]
+CPU: 1 PID: 12732 Comm: syz.1.3469 Not tainted 6.6.114 #2
+RIP: 0010:__in_dev_get_rcu include/linux/inetdevice.h:233
+RIP: 0010:fib_compute_spec_dst+0x17a/0x9f0 net/ipv4/fib_frontend.c:285
+Call Trace:
+  <TASK>
+  spec_dst_fill net/ipv4/ip_options.c:232
+  spec_dst_fill net/ipv4/ip_options.c:229
+  __ip_options_compile+0x13a1/0x17d0 net/ipv4/ip_options.c:330
+  ipv4_send_dest_unreach net/ipv4/route.c:1252
+  ipv4_link_failure+0x702/0xb80 net/ipv4/route.c:1265
+  dst_link_failure include/net/dst.h:437
+  __ip_vs_get_out_rt+0x15fd/0x19e0 net/netfilter/ipvs/ip_vs_xmit.c:412
+  ip_vs_nat_xmit+0x1d8/0xc80 net/netfilter/ipvs/ip_vs_xmit.c:764
+
+Fixes: ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure")
+Signed-off-by: Slavin Liu <slavin452@gmail.com>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
+index c87dbc8970023..f82834349ca2c 100644
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -420,6 +420,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+       return -1;
+ err_unreach:
++      if (!skb->dev)
++              skb->dev = skb_dst(skb)->dev;
++
+       dst_link_failure(skb);
+       return -1;
+ }
+-- 
+2.51.0
+
diff --git a/queue-5.10/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch b/queue-5.10/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch
new file mode 100644 (file)
index 0000000..83cbb75
--- /dev/null
@@ -0,0 +1,96 @@
+From e5ba72f92b3372b7a7f6c4ed51b9f7ea8b757b66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:13 +0100
+Subject: mlxsw: spectrum_mr: Fix use-after-free when updating multicast route
+ stats
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 8ac1dacec458f55f871f7153242ed6ab60373b90 ]
+
+Cited commit added a dedicated mutex (instead of RTNL) to protect the
+multicast route list, so that it will not change while the driver
+periodically traverses it in order to update the kernel about multicast
+route stats that were queried from the device.
+
+One instance of list entry deletion (during route replace) was missed
+and it can result in a use-after-free [1].
+
+Fix by acquiring the mutex before deleting the entry from the list and
+releasing it afterwards.
+
+[1]
+BUG: KASAN: slab-use-after-free in mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum]
+Read of size 8 at addr ffff8881523c2fa8 by task kworker/2:5/22043
+
+CPU: 2 UID: 0 PID: 22043 Comm: kworker/2:5 Not tainted 6.18.0-rc1-custom-g1a3d6d7cd014 #1 PREEMPT(full)
+Hardware name: Mellanox Technologies Ltd. MSN2010/SA002610, BIOS 5.6.5 08/24/2017
+Workqueue: mlxsw_core mlxsw_sp_mr_stats_update [mlxsw_spectrum]
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xba/0x110
+ print_report+0x174/0x4f5
+ kasan_report+0xdf/0x110
+ mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+Allocated by task 29933:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0x8f/0xa0
+ mlxsw_sp_mr_route_add+0xd8/0x4770 [mlxsw_spectrum]
+ mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+
+Freed by task 29933:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3b/0x70
+ __kasan_slab_free+0x43/0x70
+ kfree+0x14e/0x700
+ mlxsw_sp_mr_route_add+0x2dea/0x4770 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:444 [mlxsw_spectrum]
+ mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+
+Fixes: f38656d06725 ("mlxsw: spectrum_mr: Protect multicast route list with a lock")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/f996feecfd59fde297964bfc85040b6d83ec6089.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+index ee308d9aedcdc..d8a4bbb8e8998 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+@@ -440,7 +440,9 @@ int mlxsw_sp_mr_route_add(struct mlxsw_sp_mr_table *mr_table,
+               rhashtable_remove_fast(&mr_table->route_ht,
+                                      &mr_orig_route->ht_node,
+                                      mlxsw_sp_mr_route_ht_params);
++              mutex_lock(&mr_table->route_list_lock);
+               list_del(&mr_orig_route->node);
++              mutex_unlock(&mr_table->route_list_lock);
+               mlxsw_sp_mr_route_destroy(mr_table, mr_orig_route);
+       }
+-- 
+2.51.0
+
diff --git a/queue-5.10/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch b/queue-5.10/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch
new file mode 100644 (file)
index 0000000..726007b
--- /dev/null
@@ -0,0 +1,199 @@
+From eb4469628915ccd9c723b7df03ddd2ecd7eee30d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:12 +0100
+Subject: mlxsw: spectrum_router: Fix neighbour use-after-free
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 8b0e69763ef948fb872a7767df4be665d18f5fd4 ]
+
+We sometimes observe use-after-free when dereferencing a neighbour [1].
+The problem seems to be that the driver stores a pointer to the
+neighbour, but without holding a reference on it. A reference is only
+taken when the neighbour is used by a nexthop.
+
+Fix by simplifying the reference counting scheme. Always take a
+reference when storing a neighbour pointer in a neighbour entry. Avoid
+taking a referencing when the neighbour is used by a nexthop as the
+neighbour entry associated with the nexthop already holds a reference.
+
+Tested by running the test that uncovered the problem over 300 times.
+Without this patch the problem was reproduced after a handful of
+iterations.
+
+[1]
+BUG: KASAN: slab-use-after-free in mlxsw_sp_neigh_entry_update+0x2d4/0x310
+Read of size 8 at addr ffff88817f8e3420 by task ip/3929
+
+CPU: 3 UID: 0 PID: 3929 Comm: ip Not tainted 6.18.0-rc4-virtme-g36b21a067510 #3 PREEMPT(full)
+Hardware name: Nvidia SN5600/VMOD0013, BIOS 5.13 05/31/2023
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x6f/0xa0
+ print_address_description.constprop.0+0x6e/0x300
+ print_report+0xfc/0x1fb
+ kasan_report+0xe4/0x110
+ mlxsw_sp_neigh_entry_update+0x2d4/0x310
+ mlxsw_sp_router_rif_gone_sync+0x35f/0x510
+ mlxsw_sp_rif_destroy+0x1ea/0x730
+ mlxsw_sp_inetaddr_port_vlan_event+0xa1/0x1b0
+ __mlxsw_sp_inetaddr_lag_event+0xcc/0x130
+ __mlxsw_sp_inetaddr_event+0xf5/0x3c0
+ mlxsw_sp_router_netdevice_event+0x1015/0x1580
+ notifier_call_chain+0xcc/0x150
+ call_netdevice_notifiers_info+0x7e/0x100
+ __netdev_upper_dev_unlink+0x10b/0x210
+ netdev_upper_dev_unlink+0x79/0xa0
+ vrf_del_slave+0x18/0x50
+ do_set_master+0x146/0x7d0
+ do_setlink.isra.0+0x9a0/0x2880
+ rtnl_newlink+0x637/0xb20
+ rtnetlink_rcv_msg+0x6fe/0xb90
+ netlink_rcv_skb+0x123/0x380
+ netlink_unicast+0x4a3/0x770
+ netlink_sendmsg+0x75b/0xc90
+ __sock_sendmsg+0xbe/0x160
+ ____sys_sendmsg+0x5b2/0x7d0
+ ___sys_sendmsg+0xfd/0x180
+ __sys_sendmsg+0x124/0x1c0
+ do_syscall_64+0xbb/0xfd0
+ entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[...]
+
+Allocated by task 109:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0x7b/0x90
+ __kmalloc_noprof+0x2c1/0x790
+ neigh_alloc+0x6af/0x8f0
+ ___neigh_create+0x63/0xe90
+ mlxsw_sp_nexthop_neigh_init+0x430/0x7e0
+ mlxsw_sp_nexthop_type_init+0x212/0x960
+ mlxsw_sp_nexthop6_group_info_init.constprop.0+0x81f/0x1280
+ mlxsw_sp_nexthop6_group_get+0x392/0x6a0
+ mlxsw_sp_fib6_entry_create+0x46a/0xfd0
+ mlxsw_sp_router_fib6_replace+0x1ed/0x5f0
+ mlxsw_sp_router_fib6_event_work+0x10a/0x2a0
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Freed by task 154:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3b/0x60
+ __kasan_slab_free+0x43/0x70
+ kmem_cache_free_bulk.part.0+0x1eb/0x5e0
+ kvfree_rcu_bulk+0x1f2/0x260
+ kfree_rcu_work+0x130/0x1b0
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Last potentially related work creation:
+ kasan_save_stack+0x30/0x50
+ kasan_record_aux_stack+0x8c/0xa0
+ kvfree_call_rcu+0x93/0x5b0
+ mlxsw_sp_router_neigh_event_work+0x67d/0x860
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Fixes: 6cf3c971dc84 ("mlxsw: spectrum_router: Add private neigh table")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/92d75e21d95d163a41b5cea67a15cd33f547cba6.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlxsw/spectrum_router.c   | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index d2887ae508bb8..e22ee1336d742 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -2032,6 +2032,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
+       if (!neigh_entry)
+               return NULL;
++      neigh_hold(n);
+       neigh_entry->key.n = n;
+       neigh_entry->rif = rif;
+       INIT_LIST_HEAD(&neigh_entry->nexthop_list);
+@@ -2041,6 +2042,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
+ static void mlxsw_sp_neigh_entry_free(struct mlxsw_sp_neigh_entry *neigh_entry)
+ {
++      neigh_release(neigh_entry->key.n);
+       kfree(neigh_entry);
+ }
+@@ -3607,6 +3609,8 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
+       if (err)
+               goto err_neigh_entry_insert;
++      neigh_release(old_n);
++
+       read_lock_bh(&n->lock);
+       nud_state = n->nud_state;
+       dead = n->dead;
+@@ -3615,14 +3619,10 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
+       list_for_each_entry(nh, &neigh_entry->nexthop_list,
+                           neigh_list_node) {
+-              neigh_release(old_n);
+-              neigh_clone(n);
+               __mlxsw_sp_nexthop_neigh_update(nh, !entry_connected);
+               mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp);
+       }
+-      neigh_release(n);
+-
+       return 0;
+ err_neigh_entry_insert:
+@@ -3711,6 +3711,11 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
+               }
+       }
++      /* Release the reference taken by neigh_lookup() / neigh_create() since
++       * neigh_entry already holds one.
++       */
++      neigh_release(n);
++
+       /* If that is the first nexthop connected to that neigh, add to
+        * nexthop_neighs_list
+        */
+@@ -3737,11 +3742,9 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
+                                       struct mlxsw_sp_nexthop *nh)
+ {
+       struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
+-      struct neighbour *n;
+       if (!neigh_entry)
+               return;
+-      n = neigh_entry->key.n;
+       __mlxsw_sp_nexthop_neigh_update(nh, true);
+       list_del(&nh->neigh_list_node);
+@@ -3755,8 +3758,6 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
+       if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list))
+               mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
+-
+-      neigh_release(n);
+ }
+ static bool mlxsw_sp_ipip_netdev_ul_up(struct net_device *ol_dev)
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-ethtool-ioctl-remove-if-n_stats-checks-from-etht.patch b/queue-5.10/net-ethtool-ioctl-remove-if-n_stats-checks-from-etht.patch
new file mode 100644 (file)
index 0000000..171300d
--- /dev/null
@@ -0,0 +1,68 @@
+From 1c819f7cae8d1942df25ca7a960b0769b145daf4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Dec 2022 14:48:24 +0300
+Subject: net/ethtool/ioctl: remove if n_stats checks from
+ ethtool_get_phy_stats
+
+From: Daniil Tatianin <d-tatianin@yandex-team.ru>
+
+[ Upstream commit fd4778581d61d8848b532f8cdc9b325138748437 ]
+
+Now that we always early return if we don't have any stats we can remove
+these checks as they're no longer necessary.
+
+Signed-off-by: Daniil Tatianin <d-tatianin@yandex-team.ru>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 7b07be1ff1cb ("ethtool: Avoid overflowing userspace buffer on stats query")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 24 ++++++++++--------------
+ 1 file changed, 10 insertions(+), 14 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index ede11854f493f..8f7efe152a7bb 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -2063,28 +2063,24 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       stats.n_stats = n_stats;
+-      if (n_stats) {
+-              data = vzalloc(array_size(n_stats, sizeof(u64)));
+-              if (!data)
+-                      return -ENOMEM;
++      data = vzalloc(array_size(n_stats, sizeof(u64)));
++      if (!data)
++              return -ENOMEM;
+-              if (phydev && !ops->get_ethtool_phy_stats &&
+-                  phy_ops && phy_ops->get_stats) {
+-                      ret = phy_ops->get_stats(phydev, &stats, data);
+-                      if (ret < 0)
+-                              goto out;
+-              } else {
+-                      ops->get_ethtool_phy_stats(dev, &stats, data);
+-              }
++      if (phydev && !ops->get_ethtool_phy_stats &&
++              phy_ops && phy_ops->get_stats) {
++              ret = phy_ops->get_stats(phydev, &stats, data);
++              if (ret < 0)
++                      goto out;
+       } else {
+-              data = NULL;
++              ops->get_ethtool_phy_stats(dev, &stats, data);
+       }
+       ret = -EFAULT;
+       if (copy_to_user(useraddr, &stats, sizeof(stats)))
+               goto out;
+       useraddr += sizeof(stats);
+-      if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
++      if (copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
+               goto out;
+       ret = 0;
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-ethtool-ioctl-split-ethtool_get_phy_stats-into-m.patch b/queue-5.10/net-ethtool-ioctl-split-ethtool_get_phy_stats-into-m.patch
new file mode 100644 (file)
index 0000000..ba63806
--- /dev/null
@@ -0,0 +1,168 @@
+From 2cd5724f1934863927ee58695b4e6ef8d39db658 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Dec 2022 14:48:25 +0300
+Subject: net/ethtool/ioctl: split ethtool_get_phy_stats into multiple helpers
+
+From: Daniil Tatianin <d-tatianin@yandex-team.ru>
+
+[ Upstream commit 201ed315f9676809cd5b20a39206e964106d4f27 ]
+
+So that it's easier to follow and make sense of the branching and
+various conditions.
+
+Stats retrieval has been split into two separate functions
+ethtool_get_phy_stats_phydev & ethtool_get_phy_stats_ethtool.
+The former attempts to retrieve the stats using phydev & phy_ops, while
+the latter uses ethtool_ops.
+
+Actual n_stats validation & array allocation has been moved into a new
+ethtool_vzalloc_stats_array helper.
+
+This also fixes a potential NULL dereference of
+ops->get_ethtool_phy_stats where it was getting called in an else branch
+unconditionally without making sure it was actually present.
+
+Found by Linux Verification Center (linuxtesting.org) with the SVACE
+static analysis tool.
+
+Signed-off-by: Daniil Tatianin <d-tatianin@yandex-team.ru>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 7b07be1ff1cb ("ethtool: Avoid overflowing userspace buffer on stats query")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 102 ++++++++++++++++++++++++++++++--------------
+ 1 file changed, 69 insertions(+), 33 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 8f7efe152a7bb..2ac9cf1c36ba6 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -2034,23 +2034,8 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       return ret;
+ }
+-static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
++static int ethtool_vzalloc_stats_array(int n_stats, u64 **data)
+ {
+-      const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
+-      const struct ethtool_ops *ops = dev->ethtool_ops;
+-      struct phy_device *phydev = dev->phydev;
+-      struct ethtool_stats stats;
+-      u64 *data;
+-      int ret, n_stats;
+-
+-      if (!phydev && (!ops->get_ethtool_phy_stats || !ops->get_sset_count))
+-              return -EOPNOTSUPP;
+-
+-      if (phydev && !ops->get_ethtool_phy_stats &&
+-          phy_ops && phy_ops->get_sset_count)
+-              n_stats = phy_ops->get_sset_count(phydev);
+-      else
+-              n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
+       if (n_stats < 0)
+               return n_stats;
+       if (n_stats > S32_MAX / sizeof(u64))
+@@ -2058,31 +2043,82 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       if (WARN_ON_ONCE(!n_stats))
+               return -EOPNOTSUPP;
++      *data = vzalloc(array_size(n_stats, sizeof(u64)));
++      if (!*data)
++              return -ENOMEM;
++
++      return 0;
++}
++
++static int ethtool_get_phy_stats_phydev(struct phy_device *phydev,
++                                       struct ethtool_stats *stats,
++                                       u64 **data)
++ {
++      const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
++      int n_stats, ret;
++
++      if (!phy_ops || !phy_ops->get_sset_count || !phy_ops->get_stats)
++              return -EOPNOTSUPP;
++
++      n_stats = phy_ops->get_sset_count(phydev);
++
++      ret = ethtool_vzalloc_stats_array(n_stats, data);
++      if (ret)
++              return ret;
++
++      stats->n_stats = n_stats;
++      return phy_ops->get_stats(phydev, stats, *data);
++}
++
++static int ethtool_get_phy_stats_ethtool(struct net_device *dev,
++                                        struct ethtool_stats *stats,
++                                        u64 **data)
++{
++      const struct ethtool_ops *ops = dev->ethtool_ops;
++      int n_stats, ret;
++
++      if (!ops || !ops->get_sset_count || ops->get_ethtool_phy_stats)
++              return -EOPNOTSUPP;
++
++      n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
++
++      ret = ethtool_vzalloc_stats_array(n_stats, data);
++      if (ret)
++              return ret;
++
++      stats->n_stats = n_stats;
++      ops->get_ethtool_phy_stats(dev, stats, *data);
++
++      return 0;
++}
++
++static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
++{
++      struct phy_device *phydev = dev->phydev;
++      struct ethtool_stats stats;
++      u64 *data = NULL;
++      int ret = -EOPNOTSUPP;
++
+       if (copy_from_user(&stats, useraddr, sizeof(stats)))
+               return -EFAULT;
+-      stats.n_stats = n_stats;
++      if (phydev)
++              ret = ethtool_get_phy_stats_phydev(phydev, &stats, &data);
+-      data = vzalloc(array_size(n_stats, sizeof(u64)));
+-      if (!data)
+-              return -ENOMEM;
++      if (ret == -EOPNOTSUPP)
++              ret = ethtool_get_phy_stats_ethtool(dev, &stats, &data);
+-      if (phydev && !ops->get_ethtool_phy_stats &&
+-              phy_ops && phy_ops->get_stats) {
+-              ret = phy_ops->get_stats(phydev, &stats, data);
+-              if (ret < 0)
+-                      goto out;
+-      } else {
+-              ops->get_ethtool_phy_stats(dev, &stats, data);
+-      }
++      if (ret)
++              goto out;
+-      ret = -EFAULT;
+-      if (copy_to_user(useraddr, &stats, sizeof(stats)))
++      if (copy_to_user(useraddr, &stats, sizeof(stats))) {
++              ret = -EFAULT;
+               goto out;
++      }
++
+       useraddr += sizeof(stats);
+-      if (copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
+-              goto out;
+-      ret = 0;
++      if (copy_to_user(useraddr, data, array_size(stats.n_stats, sizeof(u64))))
++              ret = -EFAULT;
+  out:
+       vfree(data);
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-hns3-add-vlan-id-validation-before-using.patch b/queue-5.10/net-hns3-add-vlan-id-validation-before-using.patch
new file mode 100644 (file)
index 0000000..240376e
--- /dev/null
@@ -0,0 +1,46 @@
+From f3214cf7129469a5ef2b2ce8f4e235fe8502599c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:37 +0800
+Subject: net: hns3: add VLAN id validation before using
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit 6ef935e65902bfed53980ad2754b06a284ea8ac1 ]
+
+Currently, the VLAN id may be used without validation when
+receive a VLAN configuration mailbox from VF. The length of
+vlan_del_fail_bmap is BITS_TO_LONGS(VLAN_N_VID). It may cause
+out-of-bounds memory access once the VLAN id is bigger than
+or equal to VLAN_N_VID.
+
+Therefore, VLAN id needs to be checked to ensure it is within
+the range of VLAN_N_VID.
+
+Fixes: fe4144d47eef ("net: hns3: sync VLAN filter entries when kill VLAN ID failed")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-4-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index aa987cad7cadf..99b5b956ed8f9 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -9196,6 +9196,9 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
+       bool writen_to_tbl = false;
+       int ret = 0;
++      if (vlan_id >= VLAN_N_VID)
++              return -EINVAL;
++
+       /* When device is resetting or reset failed, firmware is unable to
+        * handle mailbox. Just record the vlan id, and remove it after
+        * reset finished.
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch b/queue-5.10/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch
new file mode 100644 (file)
index 0000000..f44eae1
--- /dev/null
@@ -0,0 +1,52 @@
+From 62fae79281a54afa667feed6b29c48e4bb7c20e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:35 +0800
+Subject: net: hns3: using the num_tqps in the vf driver to apply for resources
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit c2a16269742e176fccdd0ef9c016a233491a49ad ]
+
+Currently, hdev->htqp is allocated using hdev->num_tqps, and kinfo->tqp
+is allocated using kinfo->num_tqps. However, kinfo->num_tqps is set to
+min(new_tqps, hdev->num_tqps);  Therefore, kinfo->num_tqps may be smaller
+than hdev->num_tqps, which causes some hdev->htqp[i] to remain
+uninitialized in hclgevf_knic_setup().
+
+Thus, this patch allocates hdev->htqp and kinfo->tqp using hdev->num_tqps,
+ensuring that the lengths of hdev->htqp and kinfo->tqp are consistent
+and that all elements are properly initialized.
+
+Fixes: e2cb1dec9779 ("net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-2-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+index 15dca78fd736c..98abb47014b75 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -434,12 +434,12 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev)
+       new_tqps = kinfo->rss_size * num_tc;
+       kinfo->num_tqps = min(new_tqps, hdev->num_tqps);
+-      kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps,
++      kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps,
+                                 sizeof(struct hnae3_queue *), GFP_KERNEL);
+       if (!kinfo->tqp)
+               return -ENOMEM;
+-      for (i = 0; i < kinfo->num_tqps; i++) {
++      for (i = 0; i < hdev->num_tqps; i++) {
+               hdev->htqp[i].q.handle = &hdev->nic;
+               hdev->htqp[i].q.tqp_index = i;
+               kinfo->tqp[i] = &hdev->htqp[i].q;
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-mlx5-fw_tracer-add-support-for-unrecognized-stri.patch b/queue-5.10/net-mlx5-fw_tracer-add-support-for-unrecognized-stri.patch
new file mode 100644 (file)
index 0000000..b0a1c04
--- /dev/null
@@ -0,0 +1,94 @@
+From 34852bbc59913ca097789d6305b07d8019a115db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 15:24:19 +0200
+Subject: net/mlx5: fw_tracer, Add support for unrecognized string
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit f7133135235dbd11e7cb5fe62fe5d05ce5e82eeb ]
+
+In case FW is publishing a string which isn't found in the driver's
+string DBs, keep the string as raw data.
+
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: b35966042d20 ("net/mlx5: fw_tracer, Validate format string parameters")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 25 +++++++++++++++++--
+ .../mellanox/mlx5/core/diag/fw_tracer.h       |  1 +
+ 2 files changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index d49fd21f49637..1002bf0078659 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -460,6 +460,7 @@ static void poll_trace(struct mlx5_fw_tracer *tracer,
+       tracer_event->event_id = MLX5_GET(tracer_event, trace, event_id);
+       tracer_event->lost_event = MLX5_GET(tracer_event, trace, lost);
++      tracer_event->out = trace;
+       switch (tracer_event->event_id) {
+       case TRACER_EVENT_TYPE_TIMESTAMP:
+@@ -582,6 +583,26 @@ void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt,
+       mlx5_tracer_clean_message(str_frmt);
+ }
++static int mlx5_tracer_handle_raw_string(struct mlx5_fw_tracer *tracer,
++                                       struct tracer_event *tracer_event)
++{
++      struct tracer_string_format *cur_string;
++
++      cur_string = mlx5_tracer_message_insert(tracer, tracer_event);
++      if (!cur_string)
++              return -1;
++
++      cur_string->event_id = tracer_event->event_id;
++      cur_string->timestamp = tracer_event->string_event.timestamp;
++      cur_string->lost = tracer_event->lost_event;
++      cur_string->string = "0x%08x%08x";
++      cur_string->num_of_params = 2;
++      cur_string->params[0] = upper_32_bits(*tracer_event->out);
++      cur_string->params[1] = lower_32_bits(*tracer_event->out);
++      list_add_tail(&cur_string->list, &tracer->ready_strings_list);
++      return 0;
++}
++
+ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                          struct tracer_event *tracer_event)
+ {
+@@ -590,7 +611,7 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+       if (tracer_event->string_event.tdsn == 0) {
+               cur_string = mlx5_tracer_get_string(tracer, tracer_event);
+               if (!cur_string)
+-                      return -1;
++                      return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+               cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
+               cur_string->last_param_num = 0;
+@@ -605,7 +626,7 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+               if (!cur_string) {
+                       pr_debug("%s Got string event for unknown string tmsn: %d\n",
+                                __func__, tracer_event->string_event.tmsn);
+-                      return -1;
++                      return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+               }
+               cur_string->last_param_num += 1;
+               if (cur_string->last_param_num > TRACER_MAX_PARAMS) {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+index 97252a85d65e6..568efb1e2bd24 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+@@ -158,6 +158,7 @@ struct tracer_event {
+               struct tracer_string_event string_event;
+               struct tracer_timestamp_event timestamp_event;
+       };
++      u64 *out;
+ };
+ struct mlx5_ifc_tracer_event_bits {
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch b/queue-5.10/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch
new file mode 100644 (file)
index 0000000..24eda88
--- /dev/null
@@ -0,0 +1,84 @@
+From 49877eefff4e6dad5028cd074f35fd6ea45fd4e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:12 +0200
+Subject: net/mlx5: fw_tracer, Handle escaped percent properly
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit c0289f67f7d6a0dfba0e92cfe661a5c70c8c6e92 ]
+
+The firmware tracer's format string validation and parameter counting
+did not properly handle escaped percent signs (%%). This caused
+fw_tracer to count more parameters when trace format strings contained
+literal percent characters.
+
+To fix it, allow %% to pass string validation and skip %% sequences when
+counting parameters since they represent literal percent signs rather
+than format specifiers.
+
+Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reported-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 20 +++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 2645e941ef1ce..f3985421e739e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -364,11 +364,11 @@ static bool mlx5_is_valid_spec(const char *str)
+       while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l')
+               str++;
+-      /* Check if it's a valid integer/hex specifier:
++      /* Check if it's a valid integer/hex specifier or %%:
+        * Valid formats: %x, %d, %i, %u, etc.
+        */
+       if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' &&
+-          *str != 'u' && *str != 'c')
++          *str != 'u' && *str != 'c' && *str != '%')
+               return false;
+       return true;
+@@ -386,7 +386,11 @@ static bool mlx5_tracer_validate_params(const char *str)
+               if (!mlx5_is_valid_spec(substr + 1))
+                       return false;
+-              substr = strstr(substr + 1, PARAM_CHAR);
++              if (*(substr + 1) == '%')
++                      substr = strstr(substr + 2, PARAM_CHAR);
++              else
++                      substr = strstr(substr + 1, PARAM_CHAR);
++
+       }
+       return true;
+@@ -463,11 +467,15 @@ static int mlx5_tracer_get_num_of_params(char *str)
+               substr = strstr(pstr, VAL_PARM);
+       }
+-      /* count all the % characters */
++      /* count all the % characters, but skip %% (escaped percent) */
+       substr = strstr(str, PARAM_CHAR);
+       while (substr) {
+-              num_of_params += 1;
+-              str = substr + 1;
++              if (*(substr + 1) != '%') {
++                      num_of_params += 1;
++                      str = substr + 1;
++              } else {
++                      str = substr + 2;
++              }
+               substr = strstr(str, PARAM_CHAR);
+       }
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-mlx5-fw_tracer-validate-format-string-parameters.patch b/queue-5.10/net-mlx5-fw_tracer-validate-format-string-parameters.patch
new file mode 100644 (file)
index 0000000..6b938e1
--- /dev/null
@@ -0,0 +1,195 @@
+From 7f6e35f7a44526fae5ccf9dcd435fe71f072f37f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:11 +0200
+Subject: net/mlx5: fw_tracer, Validate format string parameters
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit b35966042d20b14e2d83330049f77deec5229749 ]
+
+Add validation for format string parameters in the firmware tracer to
+prevent potential security vulnerabilities and crashes from malformed
+format strings received from firmware.
+
+The firmware tracer receives format strings from the device firmware and
+uses them to format trace messages. Without proper validation, bad
+firmware could provide format strings with invalid format specifiers
+(e.g., %s, %p, %n) that could lead to crashes, or other undefined
+behavior.
+
+Add mlx5_tracer_validate_params() to validate that all format specifiers
+in trace strings are limited to safe integer/hex formats (%x, %d, %i,
+%u, %llx, %lx, etc.). Reject strings containing other format types that
+could be used to access arbitrary memory or cause crashes.
+Invalid format strings are added to the trace output for visibility with
+"BAD_FORMAT: " prefix.
+
+Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Reported-by: Breno Leitao <leitao@debian.org>
+Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-4-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 83 ++++++++++++++++---
+ .../mellanox/mlx5/core/diag/fw_tracer.h       |  1 +
+ 2 files changed, 74 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 1002bf0078659..2645e941ef1ce 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -33,6 +33,7 @@
+ #include "lib/eq.h"
+ #include "fw_tracer.h"
+ #include "fw_tracer_tracepoint.h"
++#include <linux/ctype.h>
+ static int mlx5_query_mtrc_caps(struct mlx5_fw_tracer *tracer)
+ {
+@@ -354,6 +355,43 @@ static const char *VAL_PARM               = "%llx";
+ static const char *REPLACE_64_VAL_PARM        = "%x%x";
+ static const char *PARAM_CHAR         = "%";
++static bool mlx5_is_valid_spec(const char *str)
++{
++      /* Parse format specifiers to find the actual type.
++       * Structure: %[flags][width][.precision][length]type
++       * Skip flags, width, precision & length.
++       */
++      while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l')
++              str++;
++
++      /* Check if it's a valid integer/hex specifier:
++       * Valid formats: %x, %d, %i, %u, etc.
++       */
++      if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' &&
++          *str != 'u' && *str != 'c')
++              return false;
++
++      return true;
++}
++
++static bool mlx5_tracer_validate_params(const char *str)
++{
++      const char *substr = str;
++
++      if (!str)
++              return false;
++
++      substr = strstr(substr, PARAM_CHAR);
++      while (substr) {
++              if (!mlx5_is_valid_spec(substr + 1))
++                      return false;
++
++              substr = strstr(substr + 1, PARAM_CHAR);
++      }
++
++      return true;
++}
++
+ static int mlx5_tracer_message_hash(u32 message_id)
+ {
+       return jhash_1word(message_id, 0) & (MESSAGE_HASH_SIZE - 1);
+@@ -413,6 +451,10 @@ static int mlx5_tracer_get_num_of_params(char *str)
+       char *substr, *pstr = str;
+       int num_of_params = 0;
++      /* Validate that all parameters are valid before processing */
++      if (!mlx5_tracer_validate_params(str))
++              return -EINVAL;
++
+       /* replace %llx with %x%x */
+       substr = strstr(pstr, VAL_PARM);
+       while (substr) {
+@@ -564,14 +606,17 @@ void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt,
+ {
+       char    tmp[512];
+-      snprintf(tmp, sizeof(tmp), str_frmt->string,
+-               str_frmt->params[0],
+-               str_frmt->params[1],
+-               str_frmt->params[2],
+-               str_frmt->params[3],
+-               str_frmt->params[4],
+-               str_frmt->params[5],
+-               str_frmt->params[6]);
++      if (str_frmt->invalid_string)
++              snprintf(tmp, sizeof(tmp), "BAD_FORMAT: %s", str_frmt->string);
++      else
++              snprintf(tmp, sizeof(tmp), str_frmt->string,
++                       str_frmt->params[0],
++                       str_frmt->params[1],
++                       str_frmt->params[2],
++                       str_frmt->params[3],
++                       str_frmt->params[4],
++                       str_frmt->params[5],
++                       str_frmt->params[6]);
+       trace_mlx5_fw(dev->tracer, trace_timestamp, str_frmt->lost,
+                     str_frmt->event_id, tmp);
+@@ -603,6 +648,13 @@ static int mlx5_tracer_handle_raw_string(struct mlx5_fw_tracer *tracer,
+       return 0;
+ }
++static void mlx5_tracer_handle_bad_format_string(struct mlx5_fw_tracer *tracer,
++                                               struct tracer_string_format *cur_string)
++{
++      cur_string->invalid_string = true;
++      list_add_tail(&cur_string->list, &tracer->ready_strings_list);
++}
++
+ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                          struct tracer_event *tracer_event)
+ {
+@@ -613,12 +665,18 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+               if (!cur_string)
+                       return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+-              cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
+-              cur_string->last_param_num = 0;
+               cur_string->event_id = tracer_event->event_id;
+               cur_string->tmsn = tracer_event->string_event.tmsn;
+               cur_string->timestamp = tracer_event->string_event.timestamp;
+               cur_string->lost = tracer_event->lost_event;
++              cur_string->last_param_num = 0;
++              cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
++              if (cur_string->num_of_params < 0) {
++                      pr_debug("%s Invalid format string parameters\n",
++                               __func__);
++                      mlx5_tracer_handle_bad_format_string(tracer, cur_string);
++                      return 0;
++              }
+               if (cur_string->num_of_params == 0) /* trace with no params */
+                       list_add_tail(&cur_string->list, &tracer->ready_strings_list);
+       } else {
+@@ -628,6 +686,11 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                __func__, tracer_event->string_event.tmsn);
+                       return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+               }
++              if (cur_string->num_of_params < 0) {
++                      pr_debug("%s string parameter of invalid string, dumping\n",
++                               __func__);
++                      return 0;
++              }
+               cur_string->last_param_num += 1;
+               if (cur_string->last_param_num > TRACER_MAX_PARAMS) {
+                       pr_debug("%s Number of params exceeds the max (%d)\n",
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+index 568efb1e2bd24..603ef441f1b21 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+@@ -117,6 +117,7 @@ struct tracer_string_format {
+       struct list_head list;
+       u32 timestamp;
+       bool lost;
++      bool invalid_string;
+ };
+ enum mlx5_fw_tracer_ownership_state {
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-openvswitch-fix-middle-attribute-validation-in-p.patch b/queue-5.10/net-openvswitch-fix-middle-attribute-validation-in-p.patch
new file mode 100644 (file)
index 0000000..28c21af
--- /dev/null
@@ -0,0 +1,112 @@
+From 8dd47ec012adc795feb2a2b303c91a2d4aaad279 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Dec 2025 11:53:32 +0100
+Subject: net: openvswitch: fix middle attribute validation in push_nsh()
+ action
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 5ace7ef87f059d68b5f50837ef3e8a1a4870c36e ]
+
+The push_nsh() action structure looks like this:
+
+ OVS_ACTION_ATTR_PUSH_NSH(OVS_KEY_ATTR_NSH(OVS_NSH_KEY_ATTR_BASE,...))
+
+The outermost OVS_ACTION_ATTR_PUSH_NSH attribute is OK'ed by the
+nla_for_each_nested() inside __ovs_nla_copy_actions().  The innermost
+OVS_NSH_KEY_ATTR_BASE/MD1/MD2 are OK'ed by the nla_for_each_nested()
+inside nsh_key_put_from_nlattr().  But nothing checks if the attribute
+in the middle is OK.  We don't even check that this attribute is the
+OVS_KEY_ATTR_NSH.  We just do a double unwrap with a pair of nla_data()
+calls - first time directly while calling validate_push_nsh() and the
+second time as part of the nla_for_each_nested() macro, which isn't
+safe, potentially causing invalid memory access if the size of this
+attribute is incorrect.  The failure may not be noticed during
+validation due to larger netlink buffer, but cause trouble later during
+action execution where the buffer is allocated exactly to the size:
+
+ BUG: KASAN: slab-out-of-bounds in nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch]
+ Read of size 184 at addr ffff88816459a634 by task a.out/22624
+
+ CPU: 8 UID: 0 PID: 22624 6.18.0-rc7+ #115 PREEMPT(voluntary)
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x51/0x70
+  print_address_description.constprop.0+0x2c/0x390
+  kasan_report+0xdd/0x110
+  kasan_check_range+0x35/0x1b0
+  __asan_memcpy+0x20/0x60
+  nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch]
+  push_nsh+0x82/0x120 [openvswitch]
+  do_execute_actions+0x1405/0x2840 [openvswitch]
+  ovs_execute_actions+0xd5/0x3b0 [openvswitch]
+  ovs_packet_cmd_execute+0x949/0xdb0 [openvswitch]
+  genl_family_rcv_msg_doit+0x1d6/0x2b0
+  genl_family_rcv_msg+0x336/0x580
+  genl_rcv_msg+0x9f/0x130
+  netlink_rcv_skb+0x11f/0x370
+  genl_rcv+0x24/0x40
+  netlink_unicast+0x73e/0xaa0
+  netlink_sendmsg+0x744/0xbf0
+  __sys_sendto+0x3d6/0x450
+  do_syscall_64+0x79/0x2c0
+  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+  </TASK>
+
+Let's add some checks that the attribute is properly sized and it's
+the only one attribute inside the action.  Technically, there is no
+real reason for OVS_KEY_ATTR_NSH to be there, as we know that we're
+pushing an NSH header already, it just creates extra nesting, but
+that's how uAPI works today.  So, keeping as it is.
+
+Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support")
+Reported-by: Junvy Yang <zhuque@tencent.com>
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Eelco Chaudron echaudro@redhat.com
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Link: https://patch.msgid.link/20251204105334.900379-1-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/flow_netlink.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
+index a70a87a4392ab..54f952620b214 100644
+--- a/net/openvswitch/flow_netlink.c
++++ b/net/openvswitch/flow_netlink.c
+@@ -2760,13 +2760,20 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
+       return err;
+ }
+-static bool validate_push_nsh(const struct nlattr *attr, bool log)
++static bool validate_push_nsh(const struct nlattr *a, bool log)
+ {
++      struct nlattr *nsh_key = nla_data(a);
+       struct sw_flow_match match;
+       struct sw_flow_key key;
++      /* There must be one and only one NSH header. */
++      if (!nla_ok(nsh_key, nla_len(a)) ||
++          nla_total_size(nla_len(nsh_key)) != nla_len(a) ||
++          nla_type(nsh_key) != OVS_KEY_ATTR_NSH)
++              return false;
++
+       ovs_match_init(&match, &key, true, NULL);
+-      return !nsh_key_put_from_nlattr(attr, &match, false, true, log);
++      return !nsh_key_put_from_nlattr(nsh_key, &match, false, true, log);
+ }
+ /* Return false if there are any non-masked bits set.
+@@ -3320,7 +3327,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
+                                       return -EINVAL;
+                       }
+                       mac_proto = MAC_PROTO_NONE;
+-                      if (!validate_push_nsh(nla_data(a), log))
++                      if (!validate_push_nsh(a, log))
+                               return -EINVAL;
+                       break;
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-sched-ets-always-remove-class-from-active-list-b.patch b/queue-5.10/net-sched-ets-always-remove-class-from-active-list-b.patch
new file mode 100644 (file)
index 0000000..5f4f237
--- /dev/null
@@ -0,0 +1,232 @@
+From 778fe98c6c46e3d8a512fa31fe37b72cf4786f43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Nov 2025 10:19:19 -0500
+Subject: net/sched: ets: Always remove class from active list before deleting
+ in ets_qdisc_change
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit ce052b9402e461a9aded599f5b47e76bc727f7de ]
+
+zdi-disclosures@trendmicro.com says:
+
+The vulnerability is a race condition between `ets_qdisc_dequeue` and
+`ets_qdisc_change`.  It leads to UAF on `struct Qdisc` object.
+Attacker requires the capability to create new user and network namespace
+in order to trigger the bug.
+See my additional commentary at the end of the analysis.
+
+Analysis:
+
+static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+                          struct netlink_ext_ack *extack)
+{
+...
+
+      // (1) this lock is preventing .change handler (`ets_qdisc_change`)
+      //to race with .dequeue handler (`ets_qdisc_dequeue`)
+      sch_tree_lock(sch);
+
+      for (i = nbands; i < oldbands; i++) {
+              if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
+                      list_del_init(&q->classes[i].alist);
+              qdisc_purge_queue(q->classes[i].qdisc);
+      }
+
+      WRITE_ONCE(q->nbands, nbands);
+      for (i = nstrict; i < q->nstrict; i++) {
+              if (q->classes[i].qdisc->q.qlen) {
+                     // (2) the class is added to the q->active
+                      list_add_tail(&q->classes[i].alist, &q->active);
+                      q->classes[i].deficit = quanta[i];
+              }
+      }
+      WRITE_ONCE(q->nstrict, nstrict);
+      memcpy(q->prio2band, priomap, sizeof(priomap));
+
+      for (i = 0; i < q->nbands; i++)
+              WRITE_ONCE(q->classes[i].quantum, quanta[i]);
+
+      for (i = oldbands; i < q->nbands; i++) {
+              q->classes[i].qdisc = queues[i];
+              if (q->classes[i].qdisc != &noop_qdisc)
+                      qdisc_hash_add(q->classes[i].qdisc, true);
+      }
+
+      // (3) the qdisc is unlocked, now dequeue can be called in parallel
+      // to the rest of .change handler
+      sch_tree_unlock(sch);
+
+      ets_offload_change(sch);
+      for (i = q->nbands; i < oldbands; i++) {
+             // (4) we're reducing the refcount for our class's qdisc and
+             //  freeing it
+              qdisc_put(q->classes[i].qdisc);
+             // (5) If we call .dequeue between (4) and (5), we will have
+             // a strong UAF and we can control RIP
+              q->classes[i].qdisc = NULL;
+              WRITE_ONCE(q->classes[i].quantum, 0);
+              q->classes[i].deficit = 0;
+              gnet_stats_basic_sync_init(&q->classes[i].bstats);
+              memset(&q->classes[i].qstats, 0, sizeof(q->classes[i].qstats));
+      }
+      return 0;
+}
+
+Comment:
+This happens because some of the classes have their qdiscs assigned to
+NULL, but remain in the active list. This commit fixes this issue by always
+removing the class from the active list before deleting and freeing its
+associated qdisc
+
+Reproducer Steps
+(trimmed version of what was sent by zdi-disclosures@trendmicro.com)
+
+```
+DEV="${DEV:-lo}"
+ROOT_HANDLE="${ROOT_HANDLE:-1:}"
+BAND2_HANDLE="${BAND2_HANDLE:-20:}"   # child under 1:2
+PING_BYTES="${PING_BYTES:-48}"
+PING_COUNT="${PING_COUNT:-200000}"
+PING_DST="${PING_DST:-127.0.0.1}"
+
+SLOW_TBF_RATE="${SLOW_TBF_RATE:-8bit}"
+SLOW_TBF_BURST="${SLOW_TBF_BURST:-100b}"
+SLOW_TBF_LAT="${SLOW_TBF_LAT:-1s}"
+
+cleanup() {
+  tc qdisc del dev "$DEV" root 2>/dev/null
+}
+trap cleanup EXIT
+
+ip link set "$DEV" up
+
+tc qdisc del dev "$DEV" root 2>/dev/null || true
+
+tc qdisc add dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
+
+tc qdisc add dev "$DEV" parent 1:2 handle "$BAND2_HANDLE" \
+  tbf rate "$SLOW_TBF_RATE" burst "$SLOW_TBF_BURST" latency "$SLOW_TBF_LAT"
+
+tc filter add dev "$DEV" parent 1: protocol all prio 1 u32 match u32 0 0 flowid 1:2
+tc -s qdisc ls dev $DEV
+
+ping -I "$DEV" -f -c "$PING_COUNT" -s "$PING_BYTES" -W 0.001 "$PING_DST" \
+  >/dev/null 2>&1 &
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 0
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
+tc -s qdisc ls dev $DEV
+tc qdisc del dev "$DEV" parent 1:2 || true
+tc -s qdisc ls dev $DEV
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 1 strict 1
+```
+
+KASAN report
+```
+==================================================================
+BUG: KASAN: slab-use-after-free in ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
+Read of size 8 at addr ffff8880502fc018 by task ping/12308
+>
+CPU: 0 UID: 0 PID: 12308 Comm: ping Not tainted 6.18.0-rc4-dirty #1 PREEMPT(full)
+Hardware name: QEMU Ubuntu 25.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <IRQ>
+ __dump_stack kernel/lib/dump_stack.c:94
+ dump_stack_lvl+0x100/0x190 kernel/lib/dump_stack.c:120
+ print_address_description kernel/mm/kasan/report.c:378
+ print_report+0x156/0x4c9 kernel/mm/kasan/report.c:482
+ kasan_report+0xdf/0x110 kernel/mm/kasan/report.c:595
+ ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
+ dequeue_skb kernel/net/sched/sch_generic.c:294
+ qdisc_restart kernel/net/sched/sch_generic.c:399
+ __qdisc_run+0x1c9/0x1b00 kernel/net/sched/sch_generic.c:417
+ __dev_xmit_skb kernel/net/core/dev.c:4221
+ __dev_queue_xmit+0x2848/0x4410 kernel/net/core/dev.c:4729
+ dev_queue_xmit kernel/./include/linux/netdevice.h:3365
+[...]
+
+Allocated by task 17115:
+ kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
+ kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
+ poison_kmalloc_redzone kernel/mm/kasan/common.c:400
+ __kasan_kmalloc+0xaa/0xb0 kernel/mm/kasan/common.c:417
+ kasan_kmalloc kernel/./include/linux/kasan.h:262
+ __do_kmalloc_node kernel/mm/slub.c:5642
+ __kmalloc_node_noprof+0x34e/0x990 kernel/mm/slub.c:5648
+ kmalloc_node_noprof kernel/./include/linux/slab.h:987
+ qdisc_alloc+0xb8/0xc30 kernel/net/sched/sch_generic.c:950
+ qdisc_create_dflt+0x93/0x490 kernel/net/sched/sch_generic.c:1012
+ ets_class_graft+0x4fd/0x800 kernel/net/sched/sch_ets.c:261
+ qdisc_graft+0x3e4/0x1780 kernel/net/sched/sch_api.c:1196
+[...]
+
+Freed by task 9905:
+ kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
+ kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
+ __kasan_save_free_info+0x3b/0x70 kernel/mm/kasan/generic.c:587
+ kasan_save_free_info kernel/mm/kasan/kasan.h:406
+ poison_slab_object kernel/mm/kasan/common.c:252
+ __kasan_slab_free+0x5f/0x80 kernel/mm/kasan/common.c:284
+ kasan_slab_free kernel/./include/linux/kasan.h:234
+ slab_free_hook kernel/mm/slub.c:2539
+ slab_free kernel/mm/slub.c:6630
+ kfree+0x144/0x700 kernel/mm/slub.c:6837
+ rcu_do_batch kernel/kernel/rcu/tree.c:2605
+ rcu_core+0x7c0/0x1500 kernel/kernel/rcu/tree.c:2861
+ handle_softirqs+0x1ea/0x8a0 kernel/kernel/softirq.c:622
+ __do_softirq kernel/kernel/softirq.c:656
+[...]
+
+Commentary:
+
+1. Maher Azzouzi working with Trend Micro Zero Day Initiative was reported as
+the person who found the issue. I requested to get a proper email to add to the
+reported-by tag but got no response. For this reason i will credit the person
+i exchanged emails with i.e zdi-disclosures@trendmicro.com
+
+2. Neither i nor Victor who did a much more thorough testing was able to
+reproduce a UAF with the PoC or other approaches we tried. We were both able to
+reproduce a null ptr deref. After exchange with zdi-disclosures@trendmicro.com
+they sent a small change to be made to the code to add an extra delay which
+was able to simulate the UAF. i.e, this:
+   qdisc_put(q->classes[i].qdisc);
+   mdelay(90);
+   q->classes[i].qdisc = NULL;
+
+I was informed by Thomas Gleixner(tglx@linutronix.de) that adding delays was
+acceptable approach for demonstrating the bug, quote:
+"Adding such delays is common exploit validation practice"
+The equivalent delay could happen "by virt scheduling the vCPU out, SMIs,
+NMIs, PREEMPT_RT enabled kernel"
+
+3. I asked the OP to test and report back but got no response and after a
+few days gave up and proceeded to submit this fix.
+
+Fixes: de6d25924c2a ("net/sched: sch_ets: don't peek at classes beyond 'nbands'")
+Reported-by: zdi-disclosures@trendmicro.com
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20251128151919.576920-1-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_ets.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index e38879e598721..ad5d9b27670ca 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -665,7 +665,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+       sch_tree_lock(sch);
+       for (i = nbands; i < oldbands; i++) {
+-              if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
++              if (cl_is_active(&q->classes[i]))
+                       list_del_init(&q->classes[i].alist);
+               qdisc_purge_queue(q->classes[i].qdisc);
+       }
+-- 
+2.51.0
+
diff --git a/queue-5.10/net-sched-ets-remove-drr-class-from-the-active-list-.patch b/queue-5.10/net-sched-ets-remove-drr-class-from-the-active-list-.patch
new file mode 100644 (file)
index 0000000..fc56dea
--- /dev/null
@@ -0,0 +1,88 @@
+From af368b80f80b362be4df8bb84b83a021b6fb30a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 16:01:24 -0300
+Subject: net/sched: ets: Remove drr class from the active list if it changes
+ to strict
+
+From: Victor Nogueira <victor@mojatatu.com>
+
+[ Upstream commit b1e125ae425aba9b45252e933ca8df52a843ec70 ]
+
+Whenever a user issues an ets qdisc change command, transforming a
+drr class into a strict one, the ets code isn't checking whether that
+class was in the active list and removing it. This means that, if a
+user changes a strict class (which was in the active list) back to a drr
+one, that class will be added twice to the active list [1].
+
+Doing so with the following commands:
+
+tc qdisc add dev lo root handle 1: ets bands 2 strict 1
+tc qdisc add dev lo parent 1:2 handle 20: \
+    tbf rate 8bit burst 100b latency 1s
+tc filter add dev lo parent 1: basic classid 1:2
+ping -c1 -W0.01 -s 56 127.0.0.1
+tc qdisc change dev lo root handle 1: ets bands 2 strict 2
+tc qdisc change dev lo root handle 1: ets bands 2 strict 1
+ping -c1 -W0.01 -s 56 127.0.0.1
+
+Will trigger the following splat with list debug turned on:
+
+[   59.279014][  T365] ------------[ cut here ]------------
+[   59.279452][  T365] list_add double add: new=ffff88801d60e350, prev=ffff88801d60e350, next=ffff88801d60e2c0.
+[   59.280153][  T365] WARNING: CPU: 3 PID: 365 at lib/list_debug.c:35 __list_add_valid_or_report+0x17f/0x220
+[   59.280860][  T365] Modules linked in:
+[   59.281165][  T365] CPU: 3 UID: 0 PID: 365 Comm: tc Not tainted 6.18.0-rc7-00105-g7e9f13163c13-dirty #239 PREEMPT(voluntary)
+[   59.281977][  T365] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+[   59.282391][  T365] RIP: 0010:__list_add_valid_or_report+0x17f/0x220
+[   59.282842][  T365] Code: 89 c6 e8 d4 b7 0d ff 90 0f 0b 90 90 31 c0 e9 31 ff ff ff 90 48 c7 c7 e0 a0 22 9f 48 89 f2 48 89 c1 4c 89 c6 e8 b2 b7 0d ff 90 <0f> 0b 90 90 31 c0 e9 0f ff ff ff 48 89 f7 48 89 44 24 10 4c 89 44
+...
+[   59.288812][  T365] Call Trace:
+[   59.289056][  T365]  <TASK>
+[   59.289224][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.289546][  T365]  ets_qdisc_change+0xd2b/0x1e80
+[   59.289891][  T365]  ? __lock_acquire+0x7e7/0x1be0
+[   59.290223][  T365]  ? __pfx_ets_qdisc_change+0x10/0x10
+[   59.290546][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.290898][  T365]  ? __mutex_trylock_common+0xda/0x240
+[   59.291228][  T365]  ? __pfx___mutex_trylock_common+0x10/0x10
+[   59.291655][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.291993][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.292313][  T365]  ? trace_contention_end+0xc8/0x110
+[   59.292656][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.293022][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.293351][  T365]  tc_modify_qdisc+0x63a/0x1cf0
+
+Fix this by always checking and removing an ets class from the active list
+when changing it to strict.
+
+[1] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/tree/net/sched/sch_ets.c?id=ce052b9402e461a9aded599f5b47e76bc727f7de#n663
+
+Fixes: cd9b50adc6bb9 ("net/sched: ets: fix crash when flipping from 'strict' to 'quantum'")
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/20251208190125.1868423-1-victor@mojatatu.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_ets.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index ad5d9b27670ca..c939937b2b81d 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -677,6 +677,10 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+                       q->classes[i].deficit = quanta[i];
+               }
+       }
++      for (i = q->nstrict; i < nstrict; i++) {
++              if (cl_is_active(&q->classes[i]))
++                      list_del_init(&q->classes[i].alist);
++      }
+       WRITE_ONCE(q->nstrict, nstrict);
+       memcpy(q->prio2band, priomap, sizeof(priomap));
+-- 
+2.51.0
+
diff --git a/queue-5.10/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch b/queue-5.10/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch
new file mode 100644 (file)
index 0000000..56de348
--- /dev/null
@@ -0,0 +1,90 @@
+From b7c3ff131dadb9d5c10dc1b0375fa46406d91eaa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 12:58:01 +0100
+Subject: netfilter: nf_conncount: fix leaked ct in error paths
+
+From: Fernando Fernandez Mancera <fmancera@suse.de>
+
+[ Upstream commit 2e2a720766886190a6d35c116794693aabd332b6 ]
+
+There are some situations where ct might be leaked as error paths are
+skipping the refcounted check and return immediately. In order to solve
+it make sure that the check is always called.
+
+Fixes: be102eb6a0e7 ("netfilter: nf_conncount: rework API to use sk_buff directly")
+Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conncount.c | 25 ++++++++++++++-----------
+ 1 file changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
+index 97b631a81484d..c00b8e522c5a7 100644
+--- a/net/netfilter/nf_conncount.c
++++ b/net/netfilter/nf_conncount.c
+@@ -172,14 +172,14 @@ static int __nf_conncount_add(struct net *net,
+       struct nf_conn *found_ct;
+       unsigned int collect = 0;
+       bool refcounted = false;
++      int err = 0;
+       if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted))
+               return -ENOENT;
+       if (ct && nf_ct_is_confirmed(ct)) {
+-              if (refcounted)
+-                      nf_ct_put(ct);
+-              return -EEXIST;
++              err = -EEXIST;
++              goto out_put;
+       }
+       if ((u32)jiffies == list->last_gc)
+@@ -231,12 +231,16 @@ static int __nf_conncount_add(struct net *net,
+       }
+ add_new_node:
+-      if (WARN_ON_ONCE(list->count > INT_MAX))
+-              return -EOVERFLOW;
++      if (WARN_ON_ONCE(list->count > INT_MAX)) {
++              err = -EOVERFLOW;
++              goto out_put;
++      }
+       conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC);
+-      if (conn == NULL)
+-              return -ENOMEM;
++      if (conn == NULL) {
++              err = -ENOMEM;
++              goto out_put;
++      }
+       conn->tuple = tuple;
+       conn->zone = *zone;
+@@ -249,7 +253,7 @@ static int __nf_conncount_add(struct net *net,
+ out_put:
+       if (refcounted)
+               nf_ct_put(ct);
+-      return 0;
++      return err;
+ }
+ int nf_conncount_add_skb(struct net *net,
+@@ -446,11 +450,10 @@ insert_tree(struct net *net,
+               rb_link_node_rcu(&rbconn->node, parent, rbnode);
+               rb_insert_color(&rbconn->node, root);
+-
+-              if (refcounted)
+-                      nf_ct_put(ct);
+       }
+ out_unlock:
++      if (refcounted)
++              nf_ct_put(ct);
+       spin_unlock_bh(&nf_conncount_locks[hash]);
+       return count;
+ }
+-- 
+2.51.0
+
diff --git a/queue-5.10/netrom-fix-memory-leak-in-nr_sendmsg.patch b/queue-5.10/netrom-fix-memory-leak-in-nr_sendmsg.patch
new file mode 100644 (file)
index 0000000..a24faad
--- /dev/null
@@ -0,0 +1,74 @@
+From b04e00f4169f12c2a86649a321daef741a2630b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Nov 2025 12:13:15 +0800
+Subject: netrom: Fix memory leak in nr_sendmsg()
+
+From: Wang Liang <wangliang74@huawei.com>
+
+[ Upstream commit 613d12dd794e078be8ff3cf6b62a6b9acf7f4619 ]
+
+syzbot reported a memory leak [1].
+
+When function sock_alloc_send_skb() return NULL in nr_output(), the
+original skb is not freed, which was allocated in nr_sendmsg(). Fix this
+by freeing it before return.
+
+[1]
+BUG: memory leak
+unreferenced object 0xffff888129f35500 (size 240):
+  comm "syz.0.17", pid 6119, jiffies 4294944652
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+    00 00 00 00 00 00 00 00 00 10 52 28 81 88 ff ff  ..........R(....
+  backtrace (crc 1456a3e4):
+    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
+    slab_post_alloc_hook mm/slub.c:4983 [inline]
+    slab_alloc_node mm/slub.c:5288 [inline]
+    kmem_cache_alloc_node_noprof+0x36f/0x5e0 mm/slub.c:5340
+    __alloc_skb+0x203/0x240 net/core/skbuff.c:660
+    alloc_skb include/linux/skbuff.h:1383 [inline]
+    alloc_skb_with_frags+0x69/0x3f0 net/core/skbuff.c:6671
+    sock_alloc_send_pskb+0x379/0x3e0 net/core/sock.c:2965
+    sock_alloc_send_skb include/net/sock.h:1859 [inline]
+    nr_sendmsg+0x287/0x450 net/netrom/af_netrom.c:1105
+    sock_sendmsg_nosec net/socket.c:727 [inline]
+    __sock_sendmsg net/socket.c:742 [inline]
+    sock_write_iter+0x293/0x2a0 net/socket.c:1195
+    new_sync_write fs/read_write.c:593 [inline]
+    vfs_write+0x45d/0x710 fs/read_write.c:686
+    ksys_write+0x143/0x170 fs/read_write.c:738
+    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+    do_syscall_64+0xa4/0xfa0 arch/x86/entry/syscall_64.c:94
+    entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Reported-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=d7abc36bbbb6d7d40b58
+Tested-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Wang Liang <wangliang74@huawei.com>
+Link: https://patch.msgid.link/20251129041315.1550766-1-wangliang74@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netrom/nr_out.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/netrom/nr_out.c b/net/netrom/nr_out.c
+index 5e531394a724b..2b3cbceb0b52d 100644
+--- a/net/netrom/nr_out.c
++++ b/net/netrom/nr_out.c
+@@ -43,8 +43,10 @@ void nr_output(struct sock *sk, struct sk_buff *skb)
+               frontlen = skb_headroom(skb);
+               while (skb->len > 0) {
+-                      if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL)
++                      if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL) {
++                              kfree_skb(skb);
+                               return;
++                      }
+                       skb_reserve(skbn, frontlen);
+-- 
+2.51.0
+
diff --git a/queue-5.10/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch b/queue-5.10/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch
new file mode 100644 (file)
index 0000000..9e05ce5
--- /dev/null
@@ -0,0 +1,37 @@
+From 52bd2b74377d27ca2604ff4fba2fcdda1734dcaa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 09:56:39 +0300
+Subject: nfc: pn533: Fix error code in pn533_acr122_poweron_rdr()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 885bebac9909994050bbbeed0829c727e42bd1b7 ]
+
+Set the error code if "transferred != sizeof(cmd)" instead of
+returning success.
+
+Fixes: dbafc28955fa ("NFC: pn533: don't send USB data off of the stack")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/aTfIJ9tZPmeUF4W1@stanley.mountain
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/pn533/usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c
+index 68eb1253f888f..77ada0a5c7396 100644
+--- a/drivers/nfc/pn533/usb.c
++++ b/drivers/nfc/pn533/usb.c
+@@ -411,7 +411,7 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy)
+       if (rc || (transferred != sizeof(cmd))) {
+               nfc_err(&phy->udev->dev,
+                       "Reader power on cmd error %d\n", rc);
+-              return rc;
++              return rc ?: -EINVAL;
+       }
+       rc =  usb_submit_urb(phy->in_urb, GFP_KERNEL);
+-- 
+2.51.0
+
index 0c8cddee5155bf51e550d37da4bb01ba4b57a5f5..4be0beb758aef2d0f2c185c04cd8219fa07ef4b8 100644 (file)
@@ -165,3 +165,24 @@ hfsplus-verify-inode-mode-when-loading-from-disk.patch
 hfsplus-fix-volume-corruption-issue-for-generic-073.patch
 btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch
 bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch
 hfsplus-fix-volume-corruption-issue-for-generic-073.patch
 btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch
 bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch
+netrom-fix-memory-leak-in-nr_sendmsg.patch
+net-sched-ets-always-remove-class-from-active-list-b.patch
+ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch
+mlxsw-spectrum_router-fix-neighbour-use-after-free.patch
+mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch
+net-openvswitch-fix-middle-attribute-validation-in-p.patch
+broadcom-b44-prevent-uninitialized-value-usage.patch
+netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch
+ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch
+caif-fix-integer-underflow-in-cffrml_receive.patch
+net-sched-ets-remove-drr-class-from-the-active-list-.patch
+nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch
+ethtool-use-phydev-variable.patch
+net-ethtool-ioctl-remove-if-n_stats-checks-from-etht.patch
+net-ethtool-ioctl-split-ethtool_get_phy_stats-into-m.patch
+ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch
+net-mlx5-fw_tracer-add-support-for-unrecognized-stri.patch
+net-mlx5-fw_tracer-validate-format-string-parameters.patch
+net-mlx5-fw_tracer-handle-escaped-percent-properly.patch
+net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch
+net-hns3-add-vlan-id-validation-before-using.patch
diff --git a/queue-5.15/broadcom-b44-prevent-uninitialized-value-usage.patch b/queue-5.15/broadcom-b44-prevent-uninitialized-value-usage.patch
new file mode 100644 (file)
index 0000000..b15c235
--- /dev/null
@@ -0,0 +1,45 @@
+From 73dea7e08bd4a84a3e3410ed607fe360182f0baf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 18:58:16 +0300
+Subject: broadcom: b44: prevent uninitialized value usage
+
+From: Alexey Simakov <bigalex934@gmail.com>
+
+[ Upstream commit 50b3db3e11864cb4e18ff099cfb38e11e7f87a68 ]
+
+On execution path with raised B44_FLAG_EXTERNAL_PHY, b44_readphy()
+leaves bmcr value uninitialized and it is used later in the code.
+
+Add check of this flag at the beginning of the b44_nway_reset() and
+exit early of the function with restarting autonegotiation if an
+external PHY is used.
+
+Fixes: 753f492093da ("[B44]: port to native ssb support")
+Reviewed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Alexey Simakov <bigalex934@gmail.com>
+Reviewed-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20251205155815.4348-1-bigalex934@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/b44.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
+index ce370ef641f01..3c4e0a78b8a03 100644
+--- a/drivers/net/ethernet/broadcom/b44.c
++++ b/drivers/net/ethernet/broadcom/b44.c
+@@ -1811,6 +1811,9 @@ static int b44_nway_reset(struct net_device *dev)
+       u32 bmcr;
+       int r;
++      if (bp->flags & B44_FLAG_EXTERNAL_PHY)
++              return phy_ethtool_nway_reset(dev);
++
+       spin_lock_irq(&bp->lock);
+       b44_readphy(bp, MII_BMCR, &bmcr);
+       b44_readphy(bp, MII_BMCR, &bmcr);
+-- 
+2.51.0
+
diff --git a/queue-5.15/caif-fix-integer-underflow-in-cffrml_receive.patch b/queue-5.15/caif-fix-integer-underflow-in-cffrml_receive.patch
new file mode 100644 (file)
index 0000000..239abce
--- /dev/null
@@ -0,0 +1,58 @@
+From de419bc3edb298921a4dfdf3a91a808a87b4ceda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Dec 2025 21:30:47 +0800
+Subject: caif: fix integer underflow in cffrml_receive()
+
+From: Junrui Luo <moonafterrain@outlook.com>
+
+[ Upstream commit 8a11ff0948b5ad09b71896b7ccc850625f9878d1 ]
+
+The cffrml_receive() function extracts a length field from the packet
+header and, when FCS is disabled, subtracts 2 from this length without
+validating that len >= 2.
+
+If an attacker sends a malicious packet with a length field of 0 or 1
+to an interface with FCS disabled, the subtraction causes an integer
+underflow.
+
+This can lead to memory exhaustion and kernel instability, potential
+information disclosure if padding contains uninitialized kernel memory.
+
+Fix this by validating that len >= 2 before performing the subtraction.
+
+Reported-by: Yuhao Jiang <danisjiang@gmail.com>
+Reported-by: Junrui Luo <moonafterrain@outlook.com>
+Fixes: b482cd2053e3 ("net-caif: add CAIF core protocol stack")
+Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/SYBPR01MB7881511122BAFEA8212A1608AFA6A@SYBPR01MB7881.ausprd01.prod.outlook.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/caif/cffrml.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c
+index 6651a8dc62e04..d4d63586053ad 100644
+--- a/net/caif/cffrml.c
++++ b/net/caif/cffrml.c
+@@ -92,8 +92,15 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
+       len = le16_to_cpu(tmp);
+       /* Subtract for FCS on length if FCS is not used. */
+-      if (!this->dofcs)
++      if (!this->dofcs) {
++              if (len < 2) {
++                      ++cffrml_rcv_error;
++                      pr_err("Invalid frame length (%d)\n", len);
++                      cfpkt_destroy(pkt);
++                      return -EPROTO;
++              }
+               len -= 2;
++      }
+       if (cfpkt_setlen(pkt, len) < 0) {
+               ++cffrml_rcv_error;
+-- 
+2.51.0
+
diff --git a/queue-5.15/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch b/queue-5.15/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch
new file mode 100644 (file)
index 0000000..176e5e1
--- /dev/null
@@ -0,0 +1,159 @@
+From f56ee536611f9623a54a31aa282f317031a46c5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 14:19:01 +0200
+Subject: ethtool: Avoid overflowing userspace buffer on stats query
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 7b07be1ff1cb6c49869910518650e8d0abc7d25f ]
+
+The ethtool -S command operates across three ioctl calls:
+ETHTOOL_GSSET_INFO for the size, ETHTOOL_GSTRINGS for the names, and
+ETHTOOL_GSTATS for the values.
+
+If the number of stats changes between these calls (e.g., due to device
+reconfiguration), userspace's buffer allocation will be incorrect,
+potentially leading to buffer overflow.
+
+Drivers are generally expected to maintain stable stat counts, but some
+drivers (e.g., mlx5, bnx2x, bna, ksz884x) use dynamic counters, making
+this scenario possible.
+
+Some drivers try to handle this internally:
+- bnad_get_ethtool_stats() returns early in case stats.n_stats is not
+  equal to the driver's stats count.
+- micrel/ksz884x also makes sure not to write anything beyond
+  stats.n_stats and overflow the buffer.
+
+However, both use stats.n_stats which is already assigned with the value
+returned from get_sset_count(), hence won't solve the issue described
+here.
+
+Change ethtool_get_strings(), ethtool_get_stats(),
+ethtool_get_phy_stats() to not return anything in case of a mismatch
+between userspace's size and get_sset_size(), to prevent buffer
+overflow.
+The returned n_stats value will be equal to zero, to reflect that
+nothing has been returned.
+
+This could result in one of two cases when using upstream ethtool,
+depending on when the size change is detected:
+1. When detected in ethtool_get_strings():
+    # ethtool -S eth2
+    no stats available
+
+2. When detected in get stats, all stats will be reported as zero.
+
+Both cases are presumably transient, and a subsequent ethtool call
+should succeed.
+
+Other than the overflow avoidance, these two cases are very evident (no
+output/cleared stats), which is arguably better than presenting
+incorrect/shifted stats.
+I also considered returning an error instead of a "silent" response, but
+that seems more destructive towards userspace apps.
+
+Notes:
+- This patch does not claim to fix the inherent race, it only makes sure
+  that we do not overflow the userspace buffer, and makes for a more
+  predictable behavior.
+
+- RTNL lock is held during each ioctl, the race window exists between
+  the separate ioctl calls when the lock is released.
+
+- Userspace ethtool always fills stats.n_stats, but it is likely that
+  these stats ioctls are implemented in other userspace applications
+  which might not fill it. The added code checks that it's not zero,
+  to prevent any regressions.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Link: https://patch.msgid.link/20251208121901.3203692-1-gal@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 30 ++++++++++++++++++++++++------
+ 1 file changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 33b5c3d8f2f7f..81fe585ddfa91 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -1919,7 +1919,10 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
+               return -ENOMEM;
+       WARN_ON_ONCE(!ret);
+-      gstrings.len = ret;
++      if (gstrings.len && gstrings.len != ret)
++              gstrings.len = 0;
++      else
++              gstrings.len = ret;
+       if (gstrings.len) {
+               data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
+@@ -2032,10 +2035,13 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       if (copy_from_user(&stats, useraddr, sizeof(stats)))
+               return -EFAULT;
+-      stats.n_stats = n_stats;
++      if (stats.n_stats && stats.n_stats != n_stats)
++              stats.n_stats = 0;
++      else
++              stats.n_stats = n_stats;
+-      if (n_stats) {
+-              data = vzalloc(array_size(n_stats, sizeof(u64)));
++      if (stats.n_stats) {
++              data = vzalloc(array_size(stats.n_stats, sizeof(u64)));
+               if (!data)
+                       return -ENOMEM;
+               ops->get_ethtool_stats(dev, &stats, data);
+@@ -2047,7 +2053,9 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       if (copy_to_user(useraddr, &stats, sizeof(stats)))
+               goto out;
+       useraddr += sizeof(stats);
+-      if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
++      if (stats.n_stats &&
++          copy_to_user(useraddr, data,
++                       array_size(stats.n_stats, sizeof(u64))))
+               goto out;
+       ret = 0;
+@@ -2083,6 +2091,10 @@ static int ethtool_get_phy_stats_phydev(struct phy_device *phydev,
+               return -EOPNOTSUPP;
+       n_stats = phy_ops->get_sset_count(phydev);
++      if (stats->n_stats && stats->n_stats != n_stats) {
++              stats->n_stats = 0;
++              return 0;
++      }
+       ret = ethtool_vzalloc_stats_array(n_stats, data);
+       if (ret)
+@@ -2103,6 +2115,10 @@ static int ethtool_get_phy_stats_ethtool(struct net_device *dev,
+               return -EOPNOTSUPP;
+       n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
++      if (stats->n_stats && stats->n_stats != n_stats) {
++              stats->n_stats = 0;
++              return 0;
++      }
+       ret = ethtool_vzalloc_stats_array(n_stats, data);
+       if (ret)
+@@ -2139,7 +2155,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       }
+       useraddr += sizeof(stats);
+-      if (copy_to_user(useraddr, data, array_size(stats.n_stats, sizeof(u64))))
++      if (stats.n_stats &&
++          copy_to_user(useraddr, data,
++                       array_size(stats.n_stats, sizeof(u64))))
+               ret = -EFAULT;
+  out:
+-- 
+2.51.0
+
diff --git a/queue-5.15/ethtool-use-phydev-variable.patch b/queue-5.15/ethtool-use-phydev-variable.patch
new file mode 100644 (file)
index 0000000..878d531
--- /dev/null
@@ -0,0 +1,53 @@
+From 725a9c3badcf642fc66596959d6efbe4afa86497 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jan 2022 06:10:20 -0800
+Subject: ethtool: use phydev variable
+
+From: Tom Rix <trix@redhat.com>
+
+[ Upstream commit ccd21ec5b8dd9b8a528a70315cee95fc1dd79d20 ]
+
+In ethtool_get_phy_stats(), the phydev varaible is set to
+dev->phydev but dev->phydev is still used.  Replace
+dev->phydev uses with phydev.
+
+Signed-off-by: Tom Rix <trix@redhat.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 7b07be1ff1cb ("ethtool: Avoid overflowing userspace buffer on stats query")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 1e9e70a633d1c..4b736385912ef 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -2068,9 +2068,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       if (!phydev && (!ops->get_ethtool_phy_stats || !ops->get_sset_count))
+               return -EOPNOTSUPP;
+-      if (dev->phydev && !ops->get_ethtool_phy_stats &&
++      if (phydev && !ops->get_ethtool_phy_stats &&
+           phy_ops && phy_ops->get_sset_count)
+-              n_stats = phy_ops->get_sset_count(dev->phydev);
++              n_stats = phy_ops->get_sset_count(phydev);
+       else
+               n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
+       if (n_stats < 0)
+@@ -2090,9 +2090,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+               if (!data)
+                       return -ENOMEM;
+-              if (dev->phydev && !ops->get_ethtool_phy_stats &&
++              if (phydev && !ops->get_ethtool_phy_stats &&
+                   phy_ops && phy_ops->get_stats) {
+-                      ret = phy_ops->get_stats(dev->phydev, &stats, data);
++                      ret = phy_ops->get_stats(phydev, &stats, data);
+                       if (ret < 0)
+                               goto out;
+               } else {
+-- 
+2.51.0
+
diff --git a/queue-5.15/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch b/queue-5.15/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch
new file mode 100644 (file)
index 0000000..5806390
--- /dev/null
@@ -0,0 +1,48 @@
+From e481179da9ea05144185e378c4dc4fa1e2d7715f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 13:39:03 +0300
+Subject: ipvlan: Ignore PACKET_LOOPBACK in handle_mode_l2()
+
+From: Dmitry Skorodumov <skorodumov.dmitry@huawei.com>
+
+[ Upstream commit 0c57ff008a11f24f7f05fa760222692a00465fec ]
+
+Packets with pkt_type == PACKET_LOOPBACK are captured by
+handle_frame() function, but they don't have L2 header.
+We should not process them in handle_mode_l2().
+
+This doesn't affect old L2 functionality, since handling
+was anyway incorrect.
+
+Handle them the same way as in br_handle_frame():
+just pass the skb.
+
+To observe invalid behaviour, just start "ping -b" on bcast address
+of port-interface.
+
+Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
+Signed-off-by: Dmitry Skorodumov <skorodumov.dmitry@huawei.com>
+Link: https://patch.msgid.link/20251202103906.4087675-1-skorodumov.dmitry@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ipvlan/ipvlan_core.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
+index a18b49db38ee0..35ec6d1af6ea6 100644
+--- a/drivers/net/ipvlan/ipvlan_core.c
++++ b/drivers/net/ipvlan/ipvlan_core.c
+@@ -725,6 +725,9 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,
+       struct ethhdr *eth = eth_hdr(skb);
+       rx_handler_result_t ret = RX_HANDLER_PASS;
++      if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
++              return RX_HANDLER_PASS;
++
+       if (is_multicast_ether_addr(eth->h_dest)) {
+               if (ipvlan_external_frame(skb, port)) {
+                       struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
+-- 
+2.51.0
+
diff --git a/queue-5.15/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch b/queue-5.15/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch
new file mode 100644 (file)
index 0000000..2b6fd76
--- /dev/null
@@ -0,0 +1,80 @@
+From 616c94098342374bd68709208f465ee6639edb7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 16:52:13 +0800
+Subject: ipvs: fix ipv4 null-ptr-deref in route error path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Slavin Liu <slavin452@gmail.com>
+
+[ Upstream commit ad891bb3d079a46a821bf2b8867854645191bab0 ]
+
+The IPv4 code path in __ip_vs_get_out_rt() calls dst_link_failure()
+without ensuring skb->dev is set, leading to a NULL pointer dereference
+in fib_compute_spec_dst() when ipv4_link_failure() attempts to send
+ICMP destination unreachable messages.
+
+The issue emerged after commit ed0de45a1008 ("ipv4: recompile ip options
+in ipv4_link_failure") started calling __ip_options_compile() from
+ipv4_link_failure(). This code path eventually calls fib_compute_spec_dst()
+which dereferences skb->dev. An attempt was made to fix the NULL skb->dev
+dereference in commit 0113d9c9d1cc ("ipv4: fix null-deref in
+ipv4_link_failure"), but it only addressed the immediate dev_net(skb->dev)
+dereference by using a fallback device. The fix was incomplete because
+fib_compute_spec_dst() later in the call chain still accesses skb->dev
+directly, which remains NULL when IPVS calls dst_link_failure().
+
+The crash occurs when:
+1. IPVS processes a packet in NAT mode with a misconfigured destination
+2. Route lookup fails in __ip_vs_get_out_rt() before establishing a route
+3. The error path calls dst_link_failure(skb) with skb->dev == NULL
+4. ipv4_link_failure() â†’ ipv4_send_dest_unreach() â†’
+   __ip_options_compile() â†’ fib_compute_spec_dst()
+5. fib_compute_spec_dst() dereferences NULL skb->dev
+
+Apply the same fix used for IPv6 in commit 326bf17ea5d4 ("ipvs: fix
+ipv6 route unreach panic"): set skb->dev from skb_dst(skb)->dev before
+calling dst_link_failure().
+
+KASAN: null-ptr-deref in range [0x0000000000000328-0x000000000000032f]
+CPU: 1 PID: 12732 Comm: syz.1.3469 Not tainted 6.6.114 #2
+RIP: 0010:__in_dev_get_rcu include/linux/inetdevice.h:233
+RIP: 0010:fib_compute_spec_dst+0x17a/0x9f0 net/ipv4/fib_frontend.c:285
+Call Trace:
+  <TASK>
+  spec_dst_fill net/ipv4/ip_options.c:232
+  spec_dst_fill net/ipv4/ip_options.c:229
+  __ip_options_compile+0x13a1/0x17d0 net/ipv4/ip_options.c:330
+  ipv4_send_dest_unreach net/ipv4/route.c:1252
+  ipv4_link_failure+0x702/0xb80 net/ipv4/route.c:1265
+  dst_link_failure include/net/dst.h:437
+  __ip_vs_get_out_rt+0x15fd/0x19e0 net/netfilter/ipvs/ip_vs_xmit.c:412
+  ip_vs_nat_xmit+0x1d8/0xc80 net/netfilter/ipvs/ip_vs_xmit.c:764
+
+Fixes: ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure")
+Signed-off-by: Slavin Liu <slavin452@gmail.com>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
+index c87dbc8970023..f82834349ca2c 100644
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -420,6 +420,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+       return -1;
+ err_unreach:
++      if (!skb->dev)
++              skb->dev = skb_dst(skb)->dev;
++
+       dst_link_failure(skb);
+       return -1;
+ }
+-- 
+2.51.0
+
diff --git a/queue-5.15/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch b/queue-5.15/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch
new file mode 100644 (file)
index 0000000..5e483ce
--- /dev/null
@@ -0,0 +1,96 @@
+From 0b93b10f68bbd13247b538ad4648d2062a08c578 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:13 +0100
+Subject: mlxsw: spectrum_mr: Fix use-after-free when updating multicast route
+ stats
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 8ac1dacec458f55f871f7153242ed6ab60373b90 ]
+
+Cited commit added a dedicated mutex (instead of RTNL) to protect the
+multicast route list, so that it will not change while the driver
+periodically traverses it in order to update the kernel about multicast
+route stats that were queried from the device.
+
+One instance of list entry deletion (during route replace) was missed
+and it can result in a use-after-free [1].
+
+Fix by acquiring the mutex before deleting the entry from the list and
+releasing it afterwards.
+
+[1]
+BUG: KASAN: slab-use-after-free in mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum]
+Read of size 8 at addr ffff8881523c2fa8 by task kworker/2:5/22043
+
+CPU: 2 UID: 0 PID: 22043 Comm: kworker/2:5 Not tainted 6.18.0-rc1-custom-g1a3d6d7cd014 #1 PREEMPT(full)
+Hardware name: Mellanox Technologies Ltd. MSN2010/SA002610, BIOS 5.6.5 08/24/2017
+Workqueue: mlxsw_core mlxsw_sp_mr_stats_update [mlxsw_spectrum]
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xba/0x110
+ print_report+0x174/0x4f5
+ kasan_report+0xdf/0x110
+ mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+Allocated by task 29933:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0x8f/0xa0
+ mlxsw_sp_mr_route_add+0xd8/0x4770 [mlxsw_spectrum]
+ mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+
+Freed by task 29933:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3b/0x70
+ __kasan_slab_free+0x43/0x70
+ kfree+0x14e/0x700
+ mlxsw_sp_mr_route_add+0x2dea/0x4770 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:444 [mlxsw_spectrum]
+ mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+
+Fixes: f38656d06725 ("mlxsw: spectrum_mr: Protect multicast route list with a lock")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/f996feecfd59fde297964bfc85040b6d83ec6089.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+index 1f6bc0c7e91dd..c39aca54a0d6b 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+@@ -440,7 +440,9 @@ int mlxsw_sp_mr_route_add(struct mlxsw_sp_mr_table *mr_table,
+               rhashtable_remove_fast(&mr_table->route_ht,
+                                      &mr_orig_route->ht_node,
+                                      mlxsw_sp_mr_route_ht_params);
++              mutex_lock(&mr_table->route_list_lock);
+               list_del(&mr_orig_route->node);
++              mutex_unlock(&mr_table->route_list_lock);
+               mlxsw_sp_mr_route_destroy(mr_table, mr_orig_route);
+       }
+-- 
+2.51.0
+
diff --git a/queue-5.15/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch b/queue-5.15/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch
new file mode 100644 (file)
index 0000000..b93d70c
--- /dev/null
@@ -0,0 +1,199 @@
+From 6d6359e423a6ffe4affae1affbb2c36286595733 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:12 +0100
+Subject: mlxsw: spectrum_router: Fix neighbour use-after-free
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 8b0e69763ef948fb872a7767df4be665d18f5fd4 ]
+
+We sometimes observe use-after-free when dereferencing a neighbour [1].
+The problem seems to be that the driver stores a pointer to the
+neighbour, but without holding a reference on it. A reference is only
+taken when the neighbour is used by a nexthop.
+
+Fix by simplifying the reference counting scheme. Always take a
+reference when storing a neighbour pointer in a neighbour entry. Avoid
+taking a referencing when the neighbour is used by a nexthop as the
+neighbour entry associated with the nexthop already holds a reference.
+
+Tested by running the test that uncovered the problem over 300 times.
+Without this patch the problem was reproduced after a handful of
+iterations.
+
+[1]
+BUG: KASAN: slab-use-after-free in mlxsw_sp_neigh_entry_update+0x2d4/0x310
+Read of size 8 at addr ffff88817f8e3420 by task ip/3929
+
+CPU: 3 UID: 0 PID: 3929 Comm: ip Not tainted 6.18.0-rc4-virtme-g36b21a067510 #3 PREEMPT(full)
+Hardware name: Nvidia SN5600/VMOD0013, BIOS 5.13 05/31/2023
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x6f/0xa0
+ print_address_description.constprop.0+0x6e/0x300
+ print_report+0xfc/0x1fb
+ kasan_report+0xe4/0x110
+ mlxsw_sp_neigh_entry_update+0x2d4/0x310
+ mlxsw_sp_router_rif_gone_sync+0x35f/0x510
+ mlxsw_sp_rif_destroy+0x1ea/0x730
+ mlxsw_sp_inetaddr_port_vlan_event+0xa1/0x1b0
+ __mlxsw_sp_inetaddr_lag_event+0xcc/0x130
+ __mlxsw_sp_inetaddr_event+0xf5/0x3c0
+ mlxsw_sp_router_netdevice_event+0x1015/0x1580
+ notifier_call_chain+0xcc/0x150
+ call_netdevice_notifiers_info+0x7e/0x100
+ __netdev_upper_dev_unlink+0x10b/0x210
+ netdev_upper_dev_unlink+0x79/0xa0
+ vrf_del_slave+0x18/0x50
+ do_set_master+0x146/0x7d0
+ do_setlink.isra.0+0x9a0/0x2880
+ rtnl_newlink+0x637/0xb20
+ rtnetlink_rcv_msg+0x6fe/0xb90
+ netlink_rcv_skb+0x123/0x380
+ netlink_unicast+0x4a3/0x770
+ netlink_sendmsg+0x75b/0xc90
+ __sock_sendmsg+0xbe/0x160
+ ____sys_sendmsg+0x5b2/0x7d0
+ ___sys_sendmsg+0xfd/0x180
+ __sys_sendmsg+0x124/0x1c0
+ do_syscall_64+0xbb/0xfd0
+ entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[...]
+
+Allocated by task 109:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0x7b/0x90
+ __kmalloc_noprof+0x2c1/0x790
+ neigh_alloc+0x6af/0x8f0
+ ___neigh_create+0x63/0xe90
+ mlxsw_sp_nexthop_neigh_init+0x430/0x7e0
+ mlxsw_sp_nexthop_type_init+0x212/0x960
+ mlxsw_sp_nexthop6_group_info_init.constprop.0+0x81f/0x1280
+ mlxsw_sp_nexthop6_group_get+0x392/0x6a0
+ mlxsw_sp_fib6_entry_create+0x46a/0xfd0
+ mlxsw_sp_router_fib6_replace+0x1ed/0x5f0
+ mlxsw_sp_router_fib6_event_work+0x10a/0x2a0
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Freed by task 154:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3b/0x60
+ __kasan_slab_free+0x43/0x70
+ kmem_cache_free_bulk.part.0+0x1eb/0x5e0
+ kvfree_rcu_bulk+0x1f2/0x260
+ kfree_rcu_work+0x130/0x1b0
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Last potentially related work creation:
+ kasan_save_stack+0x30/0x50
+ kasan_record_aux_stack+0x8c/0xa0
+ kvfree_call_rcu+0x93/0x5b0
+ mlxsw_sp_router_neigh_event_work+0x67d/0x860
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Fixes: 6cf3c971dc84 ("mlxsw: spectrum_router: Add private neigh table")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/92d75e21d95d163a41b5cea67a15cd33f547cba6.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlxsw/spectrum_router.c   | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index 55de90d5ae591..487ea65417b4a 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -2137,6 +2137,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
+       if (!neigh_entry)
+               return NULL;
++      neigh_hold(n);
+       neigh_entry->key.n = n;
+       neigh_entry->rif = rif;
+       INIT_LIST_HEAD(&neigh_entry->nexthop_list);
+@@ -2146,6 +2147,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
+ static void mlxsw_sp_neigh_entry_free(struct mlxsw_sp_neigh_entry *neigh_entry)
+ {
++      neigh_release(neigh_entry->key.n);
+       kfree(neigh_entry);
+ }
+@@ -3995,6 +3997,8 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
+       if (err)
+               goto err_neigh_entry_insert;
++      neigh_release(old_n);
++
+       read_lock_bh(&n->lock);
+       nud_state = n->nud_state;
+       dead = n->dead;
+@@ -4003,14 +4007,10 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
+       list_for_each_entry(nh, &neigh_entry->nexthop_list,
+                           neigh_list_node) {
+-              neigh_release(old_n);
+-              neigh_clone(n);
+               __mlxsw_sp_nexthop_neigh_update(nh, !entry_connected);
+               mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp);
+       }
+-      neigh_release(n);
+-
+       return 0;
+ err_neigh_entry_insert:
+@@ -4098,6 +4098,11 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
+               }
+       }
++      /* Release the reference taken by neigh_lookup() / neigh_create() since
++       * neigh_entry already holds one.
++       */
++      neigh_release(n);
++
+       /* If that is the first nexthop connected to that neigh, add to
+        * nexthop_neighs_list
+        */
+@@ -4124,11 +4129,9 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
+                                       struct mlxsw_sp_nexthop *nh)
+ {
+       struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
+-      struct neighbour *n;
+       if (!neigh_entry)
+               return;
+-      n = neigh_entry->key.n;
+       __mlxsw_sp_nexthop_neigh_update(nh, true);
+       list_del(&nh->neigh_list_node);
+@@ -4142,8 +4145,6 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
+       if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list))
+               mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
+-
+-      neigh_release(n);
+ }
+ static bool mlxsw_sp_ipip_netdev_ul_up(struct net_device *ol_dev)
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-ethtool-ioctl-remove-if-n_stats-checks-from-etht.patch b/queue-5.15/net-ethtool-ioctl-remove-if-n_stats-checks-from-etht.patch
new file mode 100644 (file)
index 0000000..b5bd98a
--- /dev/null
@@ -0,0 +1,68 @@
+From 14295ef870e6b879c9cd87383a9ff821e8b81348 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Dec 2022 14:48:24 +0300
+Subject: net/ethtool/ioctl: remove if n_stats checks from
+ ethtool_get_phy_stats
+
+From: Daniil Tatianin <d-tatianin@yandex-team.ru>
+
+[ Upstream commit fd4778581d61d8848b532f8cdc9b325138748437 ]
+
+Now that we always early return if we don't have any stats we can remove
+these checks as they're no longer necessary.
+
+Signed-off-by: Daniil Tatianin <d-tatianin@yandex-team.ru>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 7b07be1ff1cb ("ethtool: Avoid overflowing userspace buffer on stats query")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 24 ++++++++++--------------
+ 1 file changed, 10 insertions(+), 14 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 4b736385912ef..2ffd52d886cfc 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -2085,28 +2085,24 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       stats.n_stats = n_stats;
+-      if (n_stats) {
+-              data = vzalloc(array_size(n_stats, sizeof(u64)));
+-              if (!data)
+-                      return -ENOMEM;
++      data = vzalloc(array_size(n_stats, sizeof(u64)));
++      if (!data)
++              return -ENOMEM;
+-              if (phydev && !ops->get_ethtool_phy_stats &&
+-                  phy_ops && phy_ops->get_stats) {
+-                      ret = phy_ops->get_stats(phydev, &stats, data);
+-                      if (ret < 0)
+-                              goto out;
+-              } else {
+-                      ops->get_ethtool_phy_stats(dev, &stats, data);
+-              }
++      if (phydev && !ops->get_ethtool_phy_stats &&
++              phy_ops && phy_ops->get_stats) {
++              ret = phy_ops->get_stats(phydev, &stats, data);
++              if (ret < 0)
++                      goto out;
+       } else {
+-              data = NULL;
++              ops->get_ethtool_phy_stats(dev, &stats, data);
+       }
+       ret = -EFAULT;
+       if (copy_to_user(useraddr, &stats, sizeof(stats)))
+               goto out;
+       useraddr += sizeof(stats);
+-      if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
++      if (copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
+               goto out;
+       ret = 0;
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-ethtool-ioctl-split-ethtool_get_phy_stats-into-m.patch b/queue-5.15/net-ethtool-ioctl-split-ethtool_get_phy_stats-into-m.patch
new file mode 100644 (file)
index 0000000..644e1ac
--- /dev/null
@@ -0,0 +1,168 @@
+From b29a2eab7c9f4a9077988fdc7bb68e3f86b63d62 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Dec 2022 14:48:25 +0300
+Subject: net/ethtool/ioctl: split ethtool_get_phy_stats into multiple helpers
+
+From: Daniil Tatianin <d-tatianin@yandex-team.ru>
+
+[ Upstream commit 201ed315f9676809cd5b20a39206e964106d4f27 ]
+
+So that it's easier to follow and make sense of the branching and
+various conditions.
+
+Stats retrieval has been split into two separate functions
+ethtool_get_phy_stats_phydev & ethtool_get_phy_stats_ethtool.
+The former attempts to retrieve the stats using phydev & phy_ops, while
+the latter uses ethtool_ops.
+
+Actual n_stats validation & array allocation has been moved into a new
+ethtool_vzalloc_stats_array helper.
+
+This also fixes a potential NULL dereference of
+ops->get_ethtool_phy_stats where it was getting called in an else branch
+unconditionally without making sure it was actually present.
+
+Found by Linux Verification Center (linuxtesting.org) with the SVACE
+static analysis tool.
+
+Signed-off-by: Daniil Tatianin <d-tatianin@yandex-team.ru>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 7b07be1ff1cb ("ethtool: Avoid overflowing userspace buffer on stats query")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 102 ++++++++++++++++++++++++++++++--------------
+ 1 file changed, 69 insertions(+), 33 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 2ffd52d886cfc..33b5c3d8f2f7f 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -2056,23 +2056,8 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       return ret;
+ }
+-static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
++static int ethtool_vzalloc_stats_array(int n_stats, u64 **data)
+ {
+-      const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
+-      const struct ethtool_ops *ops = dev->ethtool_ops;
+-      struct phy_device *phydev = dev->phydev;
+-      struct ethtool_stats stats;
+-      u64 *data;
+-      int ret, n_stats;
+-
+-      if (!phydev && (!ops->get_ethtool_phy_stats || !ops->get_sset_count))
+-              return -EOPNOTSUPP;
+-
+-      if (phydev && !ops->get_ethtool_phy_stats &&
+-          phy_ops && phy_ops->get_sset_count)
+-              n_stats = phy_ops->get_sset_count(phydev);
+-      else
+-              n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
+       if (n_stats < 0)
+               return n_stats;
+       if (n_stats > S32_MAX / sizeof(u64))
+@@ -2080,31 +2065,82 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       if (WARN_ON_ONCE(!n_stats))
+               return -EOPNOTSUPP;
++      *data = vzalloc(array_size(n_stats, sizeof(u64)));
++      if (!*data)
++              return -ENOMEM;
++
++      return 0;
++}
++
++static int ethtool_get_phy_stats_phydev(struct phy_device *phydev,
++                                       struct ethtool_stats *stats,
++                                       u64 **data)
++ {
++      const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
++      int n_stats, ret;
++
++      if (!phy_ops || !phy_ops->get_sset_count || !phy_ops->get_stats)
++              return -EOPNOTSUPP;
++
++      n_stats = phy_ops->get_sset_count(phydev);
++
++      ret = ethtool_vzalloc_stats_array(n_stats, data);
++      if (ret)
++              return ret;
++
++      stats->n_stats = n_stats;
++      return phy_ops->get_stats(phydev, stats, *data);
++}
++
++static int ethtool_get_phy_stats_ethtool(struct net_device *dev,
++                                        struct ethtool_stats *stats,
++                                        u64 **data)
++{
++      const struct ethtool_ops *ops = dev->ethtool_ops;
++      int n_stats, ret;
++
++      if (!ops || !ops->get_sset_count || ops->get_ethtool_phy_stats)
++              return -EOPNOTSUPP;
++
++      n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
++
++      ret = ethtool_vzalloc_stats_array(n_stats, data);
++      if (ret)
++              return ret;
++
++      stats->n_stats = n_stats;
++      ops->get_ethtool_phy_stats(dev, stats, *data);
++
++      return 0;
++}
++
++static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
++{
++      struct phy_device *phydev = dev->phydev;
++      struct ethtool_stats stats;
++      u64 *data = NULL;
++      int ret = -EOPNOTSUPP;
++
+       if (copy_from_user(&stats, useraddr, sizeof(stats)))
+               return -EFAULT;
+-      stats.n_stats = n_stats;
++      if (phydev)
++              ret = ethtool_get_phy_stats_phydev(phydev, &stats, &data);
+-      data = vzalloc(array_size(n_stats, sizeof(u64)));
+-      if (!data)
+-              return -ENOMEM;
++      if (ret == -EOPNOTSUPP)
++              ret = ethtool_get_phy_stats_ethtool(dev, &stats, &data);
+-      if (phydev && !ops->get_ethtool_phy_stats &&
+-              phy_ops && phy_ops->get_stats) {
+-              ret = phy_ops->get_stats(phydev, &stats, data);
+-              if (ret < 0)
+-                      goto out;
+-      } else {
+-              ops->get_ethtool_phy_stats(dev, &stats, data);
+-      }
++      if (ret)
++              goto out;
+-      ret = -EFAULT;
+-      if (copy_to_user(useraddr, &stats, sizeof(stats)))
++      if (copy_to_user(useraddr, &stats, sizeof(stats))) {
++              ret = -EFAULT;
+               goto out;
++      }
++
+       useraddr += sizeof(stats);
+-      if (copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
+-              goto out;
+-      ret = 0;
++      if (copy_to_user(useraddr, data, array_size(stats.n_stats, sizeof(u64))))
++              ret = -EFAULT;
+  out:
+       vfree(data);
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-hns3-add-vlan-id-validation-before-using.patch b/queue-5.15/net-hns3-add-vlan-id-validation-before-using.patch
new file mode 100644 (file)
index 0000000..a3cdcbf
--- /dev/null
@@ -0,0 +1,46 @@
+From 9b7aaaedd59f3e52296222764f6dd3ed81777d90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:37 +0800
+Subject: net: hns3: add VLAN id validation before using
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit 6ef935e65902bfed53980ad2754b06a284ea8ac1 ]
+
+Currently, the VLAN id may be used without validation when
+receive a VLAN configuration mailbox from VF. The length of
+vlan_del_fail_bmap is BITS_TO_LONGS(VLAN_N_VID). It may cause
+out-of-bounds memory access once the VLAN id is bigger than
+or equal to VLAN_N_VID.
+
+Therefore, VLAN id needs to be checked to ensure it is within
+the range of VLAN_N_VID.
+
+Fixes: fe4144d47eef ("net: hns3: sync VLAN filter entries when kill VLAN ID failed")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-4-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index 1dffd1532bd76..dd9d5df31905a 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -10682,6 +10682,9 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
+       bool writen_to_tbl = false;
+       int ret = 0;
++      if (vlan_id >= VLAN_N_VID)
++              return -EINVAL;
++
+       /* When device is resetting or reset failed, firmware is unable to
+        * handle mailbox. Just record the vlan id, and remove it after
+        * reset finished.
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-hns3-align-type-of-some-variables-with-their-pri.patch b/queue-5.15/net-hns3-align-type-of-some-variables-with-their-pri.patch
new file mode 100644 (file)
index 0000000..2c7a334
--- /dev/null
@@ -0,0 +1,78 @@
+From 1bfb8fe035686cc26684c186f63253b24b4920cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Dec 2021 17:20:52 +0800
+Subject: net: hns3: Align type of some variables with their print type
+
+From: Hao Chen <chenhao288@hisilicon.com>
+
+[ Upstream commit 0cc25c6a14efd709f2cfcde345e3d5c6aa20f80e ]
+
+The c language has a set of implicit type conversions, when
+two variables perform bitwise or arithmetic operations.
+
+For example, variable A (type u16/u8) -1, its output is int type variable.
+u16/u8 will convert to int type implicitly before it does arithmetic
+operations. So, change 1 to unsigned type.
+
+Signed-off-by: Hao Chen <chenhao288@hisilicon.com>
+Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: d180c11aa8a6 ("net: hns3: using the num_tqps to check whether tqp_index is out of range when vf get ring info from mbx")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 2 +-
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c    | 4 ++--
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c     | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
+index 63665e8a7c718..016cd7cf11931 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
+@@ -99,7 +99,7 @@ static void hclge_dbg_fill_content(char *content, u16 len,
+ static char *hclge_dbg_get_func_id_str(char *buf, u8 id)
+ {
+       if (id)
+-              sprintf(buf, "vf%u", id - 1);
++              sprintf(buf, "vf%u", id - 1U);
+       else
+               sprintf(buf, "pf");
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index 492a754f84a94..1dffd1532bd76 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -6692,7 +6692,7 @@ static int hclge_fd_parse_ring_cookie(struct hclge_dev *hdev, u64 ring_cookie,
+               if (vf > hdev->num_req_vfs) {
+                       dev_err(&hdev->pdev->dev,
+                               "Error: vf id (%u) should be less than %u\n",
+-                              vf - 1, hdev->num_req_vfs);
++                              vf - 1U, hdev->num_req_vfs);
+                       return -EINVAL;
+               }
+@@ -6702,7 +6702,7 @@ static int hclge_fd_parse_ring_cookie(struct hclge_dev *hdev, u64 ring_cookie,
+               if (ring >= tqps) {
+                       dev_err(&hdev->pdev->dev,
+                               "Error: queue id (%u) > max tqp num (%u)\n",
+-                              ring, tqps - 1);
++                              ring, tqps - 1U);
+                       return -EINVAL;
+               }
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+index e2fe41d3972fb..e2cd0eb124bac 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+@@ -190,7 +190,7 @@ static int hclge_get_ring_chain_from_mbx(
+               if (req->msg.param[i].tqp_index >= vport->nic.kinfo.rss_size) {
+                       dev_err(&hdev->pdev->dev, "tqp index(%u) is out of range(0-%u)\n",
+                               req->msg.param[i].tqp_index,
+-                              vport->nic.kinfo.rss_size - 1);
++                              vport->nic.kinfo.rss_size - 1U);
+                       return -EINVAL;
+               }
+       }
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch b/queue-5.15/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch
new file mode 100644 (file)
index 0000000..b33afa0
--- /dev/null
@@ -0,0 +1,52 @@
+From 4d5856ca9e581bb5a1806520c17fdc4a30a98e8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:35 +0800
+Subject: net: hns3: using the num_tqps in the vf driver to apply for resources
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit c2a16269742e176fccdd0ef9c016a233491a49ad ]
+
+Currently, hdev->htqp is allocated using hdev->num_tqps, and kinfo->tqp
+is allocated using kinfo->num_tqps. However, kinfo->num_tqps is set to
+min(new_tqps, hdev->num_tqps);  Therefore, kinfo->num_tqps may be smaller
+than hdev->num_tqps, which causes some hdev->htqp[i] to remain
+uninitialized in hclgevf_knic_setup().
+
+Thus, this patch allocates hdev->htqp and kinfo->tqp using hdev->num_tqps,
+ensuring that the lengths of hdev->htqp and kinfo->tqp are consistent
+and that all elements are properly initialized.
+
+Fixes: e2cb1dec9779 ("net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-2-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+index 94e615177ff14..0f3c91afba02b 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -458,12 +458,12 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev)
+       new_tqps = kinfo->rss_size * num_tc;
+       kinfo->num_tqps = min(new_tqps, hdev->num_tqps);
+-      kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps,
++      kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps,
+                                 sizeof(struct hnae3_queue *), GFP_KERNEL);
+       if (!kinfo->tqp)
+               return -ENOMEM;
+-      for (i = 0; i < kinfo->num_tqps; i++) {
++      for (i = 0; i < hdev->num_tqps; i++) {
+               hdev->htqp[i].q.handle = &hdev->nic;
+               hdev->htqp[i].q.tqp_index = i;
+               kinfo->tqp[i] = &hdev->htqp[i].q;
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch b/queue-5.15/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch
new file mode 100644 (file)
index 0000000..3d8e2f2
--- /dev/null
@@ -0,0 +1,49 @@
+From e77f09da6500e71aa3b6c5d5078c7ff8877e42ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:36 +0800
+Subject: net: hns3: using the num_tqps to check whether tqp_index is out of
+ range when vf get ring info from mbx
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit d180c11aa8a6fa735f9ac2c72c61364a9afc2ba7 ]
+
+Currently, rss_size = num_tqps / tc_num. If tc_num is 1, then num_tqps
+equals rss_size. However, if the tc_num is greater than 1, then rss_size
+will be less than num_tqps, causing the tqp_index check for subsequent TCs
+using rss_size to always fail.
+
+This patch uses the num_tqps to check whether tqp_index is out of range,
+instead of rss_size.
+
+Fixes: 326334aad024 ("net: hns3: add a check for tqp_index in hclge_get_ring_chain_from_mbx()")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-3-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+index e2cd0eb124bac..f1823dd4473f7 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+@@ -187,10 +187,10 @@ static int hclge_get_ring_chain_from_mbx(
+               return -EINVAL;
+       for (i = 0; i < ring_num; i++) {
+-              if (req->msg.param[i].tqp_index >= vport->nic.kinfo.rss_size) {
++              if (req->msg.param[i].tqp_index >= vport->nic.kinfo.num_tqps) {
+                       dev_err(&hdev->pdev->dev, "tqp index(%u) is out of range(0-%u)\n",
+                               req->msg.param[i].tqp_index,
+-                              vport->nic.kinfo.rss_size - 1U);
++                              vport->nic.kinfo.num_tqps - 1U);
+                       return -EINVAL;
+               }
+       }
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-mlx5-fw_tracer-add-support-for-unrecognized-stri.patch b/queue-5.15/net-mlx5-fw_tracer-add-support-for-unrecognized-stri.patch
new file mode 100644 (file)
index 0000000..f51799e
--- /dev/null
@@ -0,0 +1,94 @@
+From 40ad300f327c9ed003c16bc279f19c9ec698bd8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 15:24:19 +0200
+Subject: net/mlx5: fw_tracer, Add support for unrecognized string
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit f7133135235dbd11e7cb5fe62fe5d05ce5e82eeb ]
+
+In case FW is publishing a string which isn't found in the driver's
+string DBs, keep the string as raw data.
+
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: b35966042d20 ("net/mlx5: fw_tracer, Validate format string parameters")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 25 +++++++++++++++++--
+ .../mellanox/mlx5/core/diag/fw_tracer.h       |  1 +
+ 2 files changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index efa2e0a8fa1d1..d982b468dcc1d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -460,6 +460,7 @@ static void poll_trace(struct mlx5_fw_tracer *tracer,
+       tracer_event->event_id = MLX5_GET(tracer_event, trace, event_id);
+       tracer_event->lost_event = MLX5_GET(tracer_event, trace, lost);
++      tracer_event->out = trace;
+       switch (tracer_event->event_id) {
+       case TRACER_EVENT_TYPE_TIMESTAMP:
+@@ -582,6 +583,26 @@ void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt,
+       mlx5_tracer_clean_message(str_frmt);
+ }
++static int mlx5_tracer_handle_raw_string(struct mlx5_fw_tracer *tracer,
++                                       struct tracer_event *tracer_event)
++{
++      struct tracer_string_format *cur_string;
++
++      cur_string = mlx5_tracer_message_insert(tracer, tracer_event);
++      if (!cur_string)
++              return -1;
++
++      cur_string->event_id = tracer_event->event_id;
++      cur_string->timestamp = tracer_event->string_event.timestamp;
++      cur_string->lost = tracer_event->lost_event;
++      cur_string->string = "0x%08x%08x";
++      cur_string->num_of_params = 2;
++      cur_string->params[0] = upper_32_bits(*tracer_event->out);
++      cur_string->params[1] = lower_32_bits(*tracer_event->out);
++      list_add_tail(&cur_string->list, &tracer->ready_strings_list);
++      return 0;
++}
++
+ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                          struct tracer_event *tracer_event)
+ {
+@@ -590,7 +611,7 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+       if (tracer_event->string_event.tdsn == 0) {
+               cur_string = mlx5_tracer_get_string(tracer, tracer_event);
+               if (!cur_string)
+-                      return -1;
++                      return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+               cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
+               cur_string->last_param_num = 0;
+@@ -605,7 +626,7 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+               if (!cur_string) {
+                       pr_debug("%s Got string event for unknown string tmsn: %d\n",
+                                __func__, tracer_event->string_event.tmsn);
+-                      return -1;
++                      return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+               }
+               cur_string->last_param_num += 1;
+               if (cur_string->last_param_num > TRACER_MAX_PARAMS) {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+index 97252a85d65e6..568efb1e2bd24 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+@@ -158,6 +158,7 @@ struct tracer_event {
+               struct tracer_string_event string_event;
+               struct tracer_timestamp_event timestamp_event;
+       };
++      u64 *out;
+ };
+ struct mlx5_ifc_tracer_event_bits {
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch b/queue-5.15/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch
new file mode 100644 (file)
index 0000000..858b1b2
--- /dev/null
@@ -0,0 +1,84 @@
+From b305b28d62d1b3bf9ae55c001530bec995a27186 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:12 +0200
+Subject: net/mlx5: fw_tracer, Handle escaped percent properly
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit c0289f67f7d6a0dfba0e92cfe661a5c70c8c6e92 ]
+
+The firmware tracer's format string validation and parameter counting
+did not properly handle escaped percent signs (%%). This caused
+fw_tracer to count more parameters when trace format strings contained
+literal percent characters.
+
+To fix it, allow %% to pass string validation and skip %% sequences when
+counting parameters since they represent literal percent signs rather
+than format specifiers.
+
+Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reported-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 20 +++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 6b49bda8bea2a..1779ff98b5892 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -364,11 +364,11 @@ static bool mlx5_is_valid_spec(const char *str)
+       while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l')
+               str++;
+-      /* Check if it's a valid integer/hex specifier:
++      /* Check if it's a valid integer/hex specifier or %%:
+        * Valid formats: %x, %d, %i, %u, etc.
+        */
+       if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' &&
+-          *str != 'u' && *str != 'c')
++          *str != 'u' && *str != 'c' && *str != '%')
+               return false;
+       return true;
+@@ -386,7 +386,11 @@ static bool mlx5_tracer_validate_params(const char *str)
+               if (!mlx5_is_valid_spec(substr + 1))
+                       return false;
+-              substr = strstr(substr + 1, PARAM_CHAR);
++              if (*(substr + 1) == '%')
++                      substr = strstr(substr + 2, PARAM_CHAR);
++              else
++                      substr = strstr(substr + 1, PARAM_CHAR);
++
+       }
+       return true;
+@@ -463,11 +467,15 @@ static int mlx5_tracer_get_num_of_params(char *str)
+               substr = strstr(pstr, VAL_PARM);
+       }
+-      /* count all the % characters */
++      /* count all the % characters, but skip %% (escaped percent) */
+       substr = strstr(str, PARAM_CHAR);
+       while (substr) {
+-              num_of_params += 1;
+-              str = substr + 1;
++              if (*(substr + 1) != '%') {
++                      num_of_params += 1;
++                      str = substr + 1;
++              } else {
++                      str = substr + 2;
++              }
+               substr = strstr(str, PARAM_CHAR);
+       }
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-mlx5-fw_tracer-validate-format-string-parameters.patch b/queue-5.15/net-mlx5-fw_tracer-validate-format-string-parameters.patch
new file mode 100644 (file)
index 0000000..4d3d5b3
--- /dev/null
@@ -0,0 +1,195 @@
+From c3642412cb549a43918219348a6675a5769341d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:11 +0200
+Subject: net/mlx5: fw_tracer, Validate format string parameters
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit b35966042d20b14e2d83330049f77deec5229749 ]
+
+Add validation for format string parameters in the firmware tracer to
+prevent potential security vulnerabilities and crashes from malformed
+format strings received from firmware.
+
+The firmware tracer receives format strings from the device firmware and
+uses them to format trace messages. Without proper validation, bad
+firmware could provide format strings with invalid format specifiers
+(e.g., %s, %p, %n) that could lead to crashes, or other undefined
+behavior.
+
+Add mlx5_tracer_validate_params() to validate that all format specifiers
+in trace strings are limited to safe integer/hex formats (%x, %d, %i,
+%u, %llx, %lx, etc.). Reject strings containing other format types that
+could be used to access arbitrary memory or cause crashes.
+Invalid format strings are added to the trace output for visibility with
+"BAD_FORMAT: " prefix.
+
+Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Reported-by: Breno Leitao <leitao@debian.org>
+Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-4-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 83 ++++++++++++++++---
+ .../mellanox/mlx5/core/diag/fw_tracer.h       |  1 +
+ 2 files changed, 74 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index d982b468dcc1d..6b49bda8bea2a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -33,6 +33,7 @@
+ #include "lib/eq.h"
+ #include "fw_tracer.h"
+ #include "fw_tracer_tracepoint.h"
++#include <linux/ctype.h>
+ static int mlx5_query_mtrc_caps(struct mlx5_fw_tracer *tracer)
+ {
+@@ -354,6 +355,43 @@ static const char *VAL_PARM               = "%llx";
+ static const char *REPLACE_64_VAL_PARM        = "%x%x";
+ static const char *PARAM_CHAR         = "%";
++static bool mlx5_is_valid_spec(const char *str)
++{
++      /* Parse format specifiers to find the actual type.
++       * Structure: %[flags][width][.precision][length]type
++       * Skip flags, width, precision & length.
++       */
++      while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l')
++              str++;
++
++      /* Check if it's a valid integer/hex specifier:
++       * Valid formats: %x, %d, %i, %u, etc.
++       */
++      if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' &&
++          *str != 'u' && *str != 'c')
++              return false;
++
++      return true;
++}
++
++static bool mlx5_tracer_validate_params(const char *str)
++{
++      const char *substr = str;
++
++      if (!str)
++              return false;
++
++      substr = strstr(substr, PARAM_CHAR);
++      while (substr) {
++              if (!mlx5_is_valid_spec(substr + 1))
++                      return false;
++
++              substr = strstr(substr + 1, PARAM_CHAR);
++      }
++
++      return true;
++}
++
+ static int mlx5_tracer_message_hash(u32 message_id)
+ {
+       return jhash_1word(message_id, 0) & (MESSAGE_HASH_SIZE - 1);
+@@ -413,6 +451,10 @@ static int mlx5_tracer_get_num_of_params(char *str)
+       char *substr, *pstr = str;
+       int num_of_params = 0;
++      /* Validate that all parameters are valid before processing */
++      if (!mlx5_tracer_validate_params(str))
++              return -EINVAL;
++
+       /* replace %llx with %x%x */
+       substr = strstr(pstr, VAL_PARM);
+       while (substr) {
+@@ -564,14 +606,17 @@ void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt,
+ {
+       char    tmp[512];
+-      snprintf(tmp, sizeof(tmp), str_frmt->string,
+-               str_frmt->params[0],
+-               str_frmt->params[1],
+-               str_frmt->params[2],
+-               str_frmt->params[3],
+-               str_frmt->params[4],
+-               str_frmt->params[5],
+-               str_frmt->params[6]);
++      if (str_frmt->invalid_string)
++              snprintf(tmp, sizeof(tmp), "BAD_FORMAT: %s", str_frmt->string);
++      else
++              snprintf(tmp, sizeof(tmp), str_frmt->string,
++                       str_frmt->params[0],
++                       str_frmt->params[1],
++                       str_frmt->params[2],
++                       str_frmt->params[3],
++                       str_frmt->params[4],
++                       str_frmt->params[5],
++                       str_frmt->params[6]);
+       trace_mlx5_fw(dev->tracer, trace_timestamp, str_frmt->lost,
+                     str_frmt->event_id, tmp);
+@@ -603,6 +648,13 @@ static int mlx5_tracer_handle_raw_string(struct mlx5_fw_tracer *tracer,
+       return 0;
+ }
++static void mlx5_tracer_handle_bad_format_string(struct mlx5_fw_tracer *tracer,
++                                               struct tracer_string_format *cur_string)
++{
++      cur_string->invalid_string = true;
++      list_add_tail(&cur_string->list, &tracer->ready_strings_list);
++}
++
+ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                          struct tracer_event *tracer_event)
+ {
+@@ -613,12 +665,18 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+               if (!cur_string)
+                       return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+-              cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
+-              cur_string->last_param_num = 0;
+               cur_string->event_id = tracer_event->event_id;
+               cur_string->tmsn = tracer_event->string_event.tmsn;
+               cur_string->timestamp = tracer_event->string_event.timestamp;
+               cur_string->lost = tracer_event->lost_event;
++              cur_string->last_param_num = 0;
++              cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
++              if (cur_string->num_of_params < 0) {
++                      pr_debug("%s Invalid format string parameters\n",
++                               __func__);
++                      mlx5_tracer_handle_bad_format_string(tracer, cur_string);
++                      return 0;
++              }
+               if (cur_string->num_of_params == 0) /* trace with no params */
+                       list_add_tail(&cur_string->list, &tracer->ready_strings_list);
+       } else {
+@@ -628,6 +686,11 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                __func__, tracer_event->string_event.tmsn);
+                       return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+               }
++              if (cur_string->num_of_params < 0) {
++                      pr_debug("%s string parameter of invalid string, dumping\n",
++                               __func__);
++                      return 0;
++              }
+               cur_string->last_param_num += 1;
+               if (cur_string->last_param_num > TRACER_MAX_PARAMS) {
+                       pr_debug("%s Number of params exceeds the max (%d)\n",
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+index 568efb1e2bd24..603ef441f1b21 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+@@ -117,6 +117,7 @@ struct tracer_string_format {
+       struct list_head list;
+       u32 timestamp;
+       bool lost;
++      bool invalid_string;
+ };
+ enum mlx5_fw_tracer_ownership_state {
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-openvswitch-fix-middle-attribute-validation-in-p.patch b/queue-5.15/net-openvswitch-fix-middle-attribute-validation-in-p.patch
new file mode 100644 (file)
index 0000000..2f62fcb
--- /dev/null
@@ -0,0 +1,112 @@
+From b41f0a0de980133f34a43f178e48a0baf2bfeac3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Dec 2025 11:53:32 +0100
+Subject: net: openvswitch: fix middle attribute validation in push_nsh()
+ action
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 5ace7ef87f059d68b5f50837ef3e8a1a4870c36e ]
+
+The push_nsh() action structure looks like this:
+
+ OVS_ACTION_ATTR_PUSH_NSH(OVS_KEY_ATTR_NSH(OVS_NSH_KEY_ATTR_BASE,...))
+
+The outermost OVS_ACTION_ATTR_PUSH_NSH attribute is OK'ed by the
+nla_for_each_nested() inside __ovs_nla_copy_actions().  The innermost
+OVS_NSH_KEY_ATTR_BASE/MD1/MD2 are OK'ed by the nla_for_each_nested()
+inside nsh_key_put_from_nlattr().  But nothing checks if the attribute
+in the middle is OK.  We don't even check that this attribute is the
+OVS_KEY_ATTR_NSH.  We just do a double unwrap with a pair of nla_data()
+calls - first time directly while calling validate_push_nsh() and the
+second time as part of the nla_for_each_nested() macro, which isn't
+safe, potentially causing invalid memory access if the size of this
+attribute is incorrect.  The failure may not be noticed during
+validation due to larger netlink buffer, but cause trouble later during
+action execution where the buffer is allocated exactly to the size:
+
+ BUG: KASAN: slab-out-of-bounds in nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch]
+ Read of size 184 at addr ffff88816459a634 by task a.out/22624
+
+ CPU: 8 UID: 0 PID: 22624 6.18.0-rc7+ #115 PREEMPT(voluntary)
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x51/0x70
+  print_address_description.constprop.0+0x2c/0x390
+  kasan_report+0xdd/0x110
+  kasan_check_range+0x35/0x1b0
+  __asan_memcpy+0x20/0x60
+  nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch]
+  push_nsh+0x82/0x120 [openvswitch]
+  do_execute_actions+0x1405/0x2840 [openvswitch]
+  ovs_execute_actions+0xd5/0x3b0 [openvswitch]
+  ovs_packet_cmd_execute+0x949/0xdb0 [openvswitch]
+  genl_family_rcv_msg_doit+0x1d6/0x2b0
+  genl_family_rcv_msg+0x336/0x580
+  genl_rcv_msg+0x9f/0x130
+  netlink_rcv_skb+0x11f/0x370
+  genl_rcv+0x24/0x40
+  netlink_unicast+0x73e/0xaa0
+  netlink_sendmsg+0x744/0xbf0
+  __sys_sendto+0x3d6/0x450
+  do_syscall_64+0x79/0x2c0
+  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+  </TASK>
+
+Let's add some checks that the attribute is properly sized and it's
+the only one attribute inside the action.  Technically, there is no
+real reason for OVS_KEY_ATTR_NSH to be there, as we know that we're
+pushing an NSH header already, it just creates extra nesting, but
+that's how uAPI works today.  So, keeping as it is.
+
+Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support")
+Reported-by: Junvy Yang <zhuque@tencent.com>
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Eelco Chaudron echaudro@redhat.com
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Link: https://patch.msgid.link/20251204105334.900379-1-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/flow_netlink.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
+index 7c2692f897f99..a7a9e4df3f600 100644
+--- a/net/openvswitch/flow_netlink.c
++++ b/net/openvswitch/flow_netlink.c
+@@ -2757,13 +2757,20 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
+       return err;
+ }
+-static bool validate_push_nsh(const struct nlattr *attr, bool log)
++static bool validate_push_nsh(const struct nlattr *a, bool log)
+ {
++      struct nlattr *nsh_key = nla_data(a);
+       struct sw_flow_match match;
+       struct sw_flow_key key;
++      /* There must be one and only one NSH header. */
++      if (!nla_ok(nsh_key, nla_len(a)) ||
++          nla_total_size(nla_len(nsh_key)) != nla_len(a) ||
++          nla_type(nsh_key) != OVS_KEY_ATTR_NSH)
++              return false;
++
+       ovs_match_init(&match, &key, true, NULL);
+-      return !nsh_key_put_from_nlattr(attr, &match, false, true, log);
++      return !nsh_key_put_from_nlattr(nsh_key, &match, false, true, log);
+ }
+ /* Return false if there are any non-masked bits set.
+@@ -3317,7 +3324,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
+                                       return -EINVAL;
+                       }
+                       mac_proto = MAC_PROTO_NONE;
+-                      if (!validate_push_nsh(nla_data(a), log))
++                      if (!validate_push_nsh(a, log))
+                               return -EINVAL;
+                       break;
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-sched-ets-always-remove-class-from-active-list-b.patch b/queue-5.15/net-sched-ets-always-remove-class-from-active-list-b.patch
new file mode 100644 (file)
index 0000000..6a616e9
--- /dev/null
@@ -0,0 +1,232 @@
+From 3afb391aa11b62ab453221daa5e4fa7e8f9ebaa3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Nov 2025 10:19:19 -0500
+Subject: net/sched: ets: Always remove class from active list before deleting
+ in ets_qdisc_change
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit ce052b9402e461a9aded599f5b47e76bc727f7de ]
+
+zdi-disclosures@trendmicro.com says:
+
+The vulnerability is a race condition between `ets_qdisc_dequeue` and
+`ets_qdisc_change`.  It leads to UAF on `struct Qdisc` object.
+Attacker requires the capability to create new user and network namespace
+in order to trigger the bug.
+See my additional commentary at the end of the analysis.
+
+Analysis:
+
+static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+                          struct netlink_ext_ack *extack)
+{
+...
+
+      // (1) this lock is preventing .change handler (`ets_qdisc_change`)
+      //to race with .dequeue handler (`ets_qdisc_dequeue`)
+      sch_tree_lock(sch);
+
+      for (i = nbands; i < oldbands; i++) {
+              if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
+                      list_del_init(&q->classes[i].alist);
+              qdisc_purge_queue(q->classes[i].qdisc);
+      }
+
+      WRITE_ONCE(q->nbands, nbands);
+      for (i = nstrict; i < q->nstrict; i++) {
+              if (q->classes[i].qdisc->q.qlen) {
+                     // (2) the class is added to the q->active
+                      list_add_tail(&q->classes[i].alist, &q->active);
+                      q->classes[i].deficit = quanta[i];
+              }
+      }
+      WRITE_ONCE(q->nstrict, nstrict);
+      memcpy(q->prio2band, priomap, sizeof(priomap));
+
+      for (i = 0; i < q->nbands; i++)
+              WRITE_ONCE(q->classes[i].quantum, quanta[i]);
+
+      for (i = oldbands; i < q->nbands; i++) {
+              q->classes[i].qdisc = queues[i];
+              if (q->classes[i].qdisc != &noop_qdisc)
+                      qdisc_hash_add(q->classes[i].qdisc, true);
+      }
+
+      // (3) the qdisc is unlocked, now dequeue can be called in parallel
+      // to the rest of .change handler
+      sch_tree_unlock(sch);
+
+      ets_offload_change(sch);
+      for (i = q->nbands; i < oldbands; i++) {
+             // (4) we're reducing the refcount for our class's qdisc and
+             //  freeing it
+              qdisc_put(q->classes[i].qdisc);
+             // (5) If we call .dequeue between (4) and (5), we will have
+             // a strong UAF and we can control RIP
+              q->classes[i].qdisc = NULL;
+              WRITE_ONCE(q->classes[i].quantum, 0);
+              q->classes[i].deficit = 0;
+              gnet_stats_basic_sync_init(&q->classes[i].bstats);
+              memset(&q->classes[i].qstats, 0, sizeof(q->classes[i].qstats));
+      }
+      return 0;
+}
+
+Comment:
+This happens because some of the classes have their qdiscs assigned to
+NULL, but remain in the active list. This commit fixes this issue by always
+removing the class from the active list before deleting and freeing its
+associated qdisc
+
+Reproducer Steps
+(trimmed version of what was sent by zdi-disclosures@trendmicro.com)
+
+```
+DEV="${DEV:-lo}"
+ROOT_HANDLE="${ROOT_HANDLE:-1:}"
+BAND2_HANDLE="${BAND2_HANDLE:-20:}"   # child under 1:2
+PING_BYTES="${PING_BYTES:-48}"
+PING_COUNT="${PING_COUNT:-200000}"
+PING_DST="${PING_DST:-127.0.0.1}"
+
+SLOW_TBF_RATE="${SLOW_TBF_RATE:-8bit}"
+SLOW_TBF_BURST="${SLOW_TBF_BURST:-100b}"
+SLOW_TBF_LAT="${SLOW_TBF_LAT:-1s}"
+
+cleanup() {
+  tc qdisc del dev "$DEV" root 2>/dev/null
+}
+trap cleanup EXIT
+
+ip link set "$DEV" up
+
+tc qdisc del dev "$DEV" root 2>/dev/null || true
+
+tc qdisc add dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
+
+tc qdisc add dev "$DEV" parent 1:2 handle "$BAND2_HANDLE" \
+  tbf rate "$SLOW_TBF_RATE" burst "$SLOW_TBF_BURST" latency "$SLOW_TBF_LAT"
+
+tc filter add dev "$DEV" parent 1: protocol all prio 1 u32 match u32 0 0 flowid 1:2
+tc -s qdisc ls dev $DEV
+
+ping -I "$DEV" -f -c "$PING_COUNT" -s "$PING_BYTES" -W 0.001 "$PING_DST" \
+  >/dev/null 2>&1 &
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 0
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
+tc -s qdisc ls dev $DEV
+tc qdisc del dev "$DEV" parent 1:2 || true
+tc -s qdisc ls dev $DEV
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 1 strict 1
+```
+
+KASAN report
+```
+==================================================================
+BUG: KASAN: slab-use-after-free in ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
+Read of size 8 at addr ffff8880502fc018 by task ping/12308
+>
+CPU: 0 UID: 0 PID: 12308 Comm: ping Not tainted 6.18.0-rc4-dirty #1 PREEMPT(full)
+Hardware name: QEMU Ubuntu 25.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <IRQ>
+ __dump_stack kernel/lib/dump_stack.c:94
+ dump_stack_lvl+0x100/0x190 kernel/lib/dump_stack.c:120
+ print_address_description kernel/mm/kasan/report.c:378
+ print_report+0x156/0x4c9 kernel/mm/kasan/report.c:482
+ kasan_report+0xdf/0x110 kernel/mm/kasan/report.c:595
+ ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
+ dequeue_skb kernel/net/sched/sch_generic.c:294
+ qdisc_restart kernel/net/sched/sch_generic.c:399
+ __qdisc_run+0x1c9/0x1b00 kernel/net/sched/sch_generic.c:417
+ __dev_xmit_skb kernel/net/core/dev.c:4221
+ __dev_queue_xmit+0x2848/0x4410 kernel/net/core/dev.c:4729
+ dev_queue_xmit kernel/./include/linux/netdevice.h:3365
+[...]
+
+Allocated by task 17115:
+ kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
+ kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
+ poison_kmalloc_redzone kernel/mm/kasan/common.c:400
+ __kasan_kmalloc+0xaa/0xb0 kernel/mm/kasan/common.c:417
+ kasan_kmalloc kernel/./include/linux/kasan.h:262
+ __do_kmalloc_node kernel/mm/slub.c:5642
+ __kmalloc_node_noprof+0x34e/0x990 kernel/mm/slub.c:5648
+ kmalloc_node_noprof kernel/./include/linux/slab.h:987
+ qdisc_alloc+0xb8/0xc30 kernel/net/sched/sch_generic.c:950
+ qdisc_create_dflt+0x93/0x490 kernel/net/sched/sch_generic.c:1012
+ ets_class_graft+0x4fd/0x800 kernel/net/sched/sch_ets.c:261
+ qdisc_graft+0x3e4/0x1780 kernel/net/sched/sch_api.c:1196
+[...]
+
+Freed by task 9905:
+ kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
+ kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
+ __kasan_save_free_info+0x3b/0x70 kernel/mm/kasan/generic.c:587
+ kasan_save_free_info kernel/mm/kasan/kasan.h:406
+ poison_slab_object kernel/mm/kasan/common.c:252
+ __kasan_slab_free+0x5f/0x80 kernel/mm/kasan/common.c:284
+ kasan_slab_free kernel/./include/linux/kasan.h:234
+ slab_free_hook kernel/mm/slub.c:2539
+ slab_free kernel/mm/slub.c:6630
+ kfree+0x144/0x700 kernel/mm/slub.c:6837
+ rcu_do_batch kernel/kernel/rcu/tree.c:2605
+ rcu_core+0x7c0/0x1500 kernel/kernel/rcu/tree.c:2861
+ handle_softirqs+0x1ea/0x8a0 kernel/kernel/softirq.c:622
+ __do_softirq kernel/kernel/softirq.c:656
+[...]
+
+Commentary:
+
+1. Maher Azzouzi working with Trend Micro Zero Day Initiative was reported as
+the person who found the issue. I requested to get a proper email to add to the
+reported-by tag but got no response. For this reason i will credit the person
+i exchanged emails with i.e zdi-disclosures@trendmicro.com
+
+2. Neither i nor Victor who did a much more thorough testing was able to
+reproduce a UAF with the PoC or other approaches we tried. We were both able to
+reproduce a null ptr deref. After exchange with zdi-disclosures@trendmicro.com
+they sent a small change to be made to the code to add an extra delay which
+was able to simulate the UAF. i.e, this:
+   qdisc_put(q->classes[i].qdisc);
+   mdelay(90);
+   q->classes[i].qdisc = NULL;
+
+I was informed by Thomas Gleixner(tglx@linutronix.de) that adding delays was
+acceptable approach for demonstrating the bug, quote:
+"Adding such delays is common exploit validation practice"
+The equivalent delay could happen "by virt scheduling the vCPU out, SMIs,
+NMIs, PREEMPT_RT enabled kernel"
+
+3. I asked the OP to test and report back but got no response and after a
+few days gave up and proceeded to submit this fix.
+
+Fixes: de6d25924c2a ("net/sched: sch_ets: don't peek at classes beyond 'nbands'")
+Reported-by: zdi-disclosures@trendmicro.com
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20251128151919.576920-1-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_ets.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index d95d127975254..bcd91ffe9bc6a 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -665,7 +665,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+       sch_tree_lock(sch);
+       for (i = nbands; i < oldbands; i++) {
+-              if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
++              if (cl_is_active(&q->classes[i]))
+                       list_del_init(&q->classes[i].alist);
+               qdisc_purge_queue(q->classes[i].qdisc);
+       }
+-- 
+2.51.0
+
diff --git a/queue-5.15/net-sched-ets-remove-drr-class-from-the-active-list-.patch b/queue-5.15/net-sched-ets-remove-drr-class-from-the-active-list-.patch
new file mode 100644 (file)
index 0000000..dade0c4
--- /dev/null
@@ -0,0 +1,88 @@
+From 69192aab06414b1c096310bb5038b3493e4f20c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 16:01:24 -0300
+Subject: net/sched: ets: Remove drr class from the active list if it changes
+ to strict
+
+From: Victor Nogueira <victor@mojatatu.com>
+
+[ Upstream commit b1e125ae425aba9b45252e933ca8df52a843ec70 ]
+
+Whenever a user issues an ets qdisc change command, transforming a
+drr class into a strict one, the ets code isn't checking whether that
+class was in the active list and removing it. This means that, if a
+user changes a strict class (which was in the active list) back to a drr
+one, that class will be added twice to the active list [1].
+
+Doing so with the following commands:
+
+tc qdisc add dev lo root handle 1: ets bands 2 strict 1
+tc qdisc add dev lo parent 1:2 handle 20: \
+    tbf rate 8bit burst 100b latency 1s
+tc filter add dev lo parent 1: basic classid 1:2
+ping -c1 -W0.01 -s 56 127.0.0.1
+tc qdisc change dev lo root handle 1: ets bands 2 strict 2
+tc qdisc change dev lo root handle 1: ets bands 2 strict 1
+ping -c1 -W0.01 -s 56 127.0.0.1
+
+Will trigger the following splat with list debug turned on:
+
+[   59.279014][  T365] ------------[ cut here ]------------
+[   59.279452][  T365] list_add double add: new=ffff88801d60e350, prev=ffff88801d60e350, next=ffff88801d60e2c0.
+[   59.280153][  T365] WARNING: CPU: 3 PID: 365 at lib/list_debug.c:35 __list_add_valid_or_report+0x17f/0x220
+[   59.280860][  T365] Modules linked in:
+[   59.281165][  T365] CPU: 3 UID: 0 PID: 365 Comm: tc Not tainted 6.18.0-rc7-00105-g7e9f13163c13-dirty #239 PREEMPT(voluntary)
+[   59.281977][  T365] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+[   59.282391][  T365] RIP: 0010:__list_add_valid_or_report+0x17f/0x220
+[   59.282842][  T365] Code: 89 c6 e8 d4 b7 0d ff 90 0f 0b 90 90 31 c0 e9 31 ff ff ff 90 48 c7 c7 e0 a0 22 9f 48 89 f2 48 89 c1 4c 89 c6 e8 b2 b7 0d ff 90 <0f> 0b 90 90 31 c0 e9 0f ff ff ff 48 89 f7 48 89 44 24 10 4c 89 44
+...
+[   59.288812][  T365] Call Trace:
+[   59.289056][  T365]  <TASK>
+[   59.289224][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.289546][  T365]  ets_qdisc_change+0xd2b/0x1e80
+[   59.289891][  T365]  ? __lock_acquire+0x7e7/0x1be0
+[   59.290223][  T365]  ? __pfx_ets_qdisc_change+0x10/0x10
+[   59.290546][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.290898][  T365]  ? __mutex_trylock_common+0xda/0x240
+[   59.291228][  T365]  ? __pfx___mutex_trylock_common+0x10/0x10
+[   59.291655][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.291993][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.292313][  T365]  ? trace_contention_end+0xc8/0x110
+[   59.292656][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.293022][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.293351][  T365]  tc_modify_qdisc+0x63a/0x1cf0
+
+Fix this by always checking and removing an ets class from the active list
+when changing it to strict.
+
+[1] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/tree/net/sched/sch_ets.c?id=ce052b9402e461a9aded599f5b47e76bc727f7de#n663
+
+Fixes: cd9b50adc6bb9 ("net/sched: ets: fix crash when flipping from 'strict' to 'quantum'")
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/20251208190125.1868423-1-victor@mojatatu.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_ets.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index bcd91ffe9bc6a..ce3d41a4d4f6a 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -677,6 +677,10 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+                       q->classes[i].deficit = quanta[i];
+               }
+       }
++      for (i = q->nstrict; i < nstrict; i++) {
++              if (cl_is_active(&q->classes[i]))
++                      list_del_init(&q->classes[i].alist);
++      }
+       WRITE_ONCE(q->nstrict, nstrict);
+       memcpy(q->prio2band, priomap, sizeof(priomap));
+-- 
+2.51.0
+
diff --git a/queue-5.15/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch b/queue-5.15/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch
new file mode 100644 (file)
index 0000000..86c43ea
--- /dev/null
@@ -0,0 +1,90 @@
+From ec370ef854c0e4e8d5f611613e3ffbd3c3301405 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 12:58:01 +0100
+Subject: netfilter: nf_conncount: fix leaked ct in error paths
+
+From: Fernando Fernandez Mancera <fmancera@suse.de>
+
+[ Upstream commit 2e2a720766886190a6d35c116794693aabd332b6 ]
+
+There are some situations where ct might be leaked as error paths are
+skipping the refcounted check and return immediately. In order to solve
+it make sure that the check is always called.
+
+Fixes: be102eb6a0e7 ("netfilter: nf_conncount: rework API to use sk_buff directly")
+Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conncount.c | 25 ++++++++++++++-----------
+ 1 file changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
+index 97b631a81484d..c00b8e522c5a7 100644
+--- a/net/netfilter/nf_conncount.c
++++ b/net/netfilter/nf_conncount.c
+@@ -172,14 +172,14 @@ static int __nf_conncount_add(struct net *net,
+       struct nf_conn *found_ct;
+       unsigned int collect = 0;
+       bool refcounted = false;
++      int err = 0;
+       if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted))
+               return -ENOENT;
+       if (ct && nf_ct_is_confirmed(ct)) {
+-              if (refcounted)
+-                      nf_ct_put(ct);
+-              return -EEXIST;
++              err = -EEXIST;
++              goto out_put;
+       }
+       if ((u32)jiffies == list->last_gc)
+@@ -231,12 +231,16 @@ static int __nf_conncount_add(struct net *net,
+       }
+ add_new_node:
+-      if (WARN_ON_ONCE(list->count > INT_MAX))
+-              return -EOVERFLOW;
++      if (WARN_ON_ONCE(list->count > INT_MAX)) {
++              err = -EOVERFLOW;
++              goto out_put;
++      }
+       conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC);
+-      if (conn == NULL)
+-              return -ENOMEM;
++      if (conn == NULL) {
++              err = -ENOMEM;
++              goto out_put;
++      }
+       conn->tuple = tuple;
+       conn->zone = *zone;
+@@ -249,7 +253,7 @@ static int __nf_conncount_add(struct net *net,
+ out_put:
+       if (refcounted)
+               nf_ct_put(ct);
+-      return 0;
++      return err;
+ }
+ int nf_conncount_add_skb(struct net *net,
+@@ -446,11 +450,10 @@ insert_tree(struct net *net,
+               rb_link_node_rcu(&rbconn->node, parent, rbnode);
+               rb_insert_color(&rbconn->node, root);
+-
+-              if (refcounted)
+-                      nf_ct_put(ct);
+       }
+ out_unlock:
++      if (refcounted)
++              nf_ct_put(ct);
+       spin_unlock_bh(&nf_conncount_locks[hash]);
+       return count;
+ }
+-- 
+2.51.0
+
diff --git a/queue-5.15/netrom-fix-memory-leak-in-nr_sendmsg.patch b/queue-5.15/netrom-fix-memory-leak-in-nr_sendmsg.patch
new file mode 100644 (file)
index 0000000..171f779
--- /dev/null
@@ -0,0 +1,74 @@
+From af72b1c3f0379695d49363d764ddaaf557935e40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Nov 2025 12:13:15 +0800
+Subject: netrom: Fix memory leak in nr_sendmsg()
+
+From: Wang Liang <wangliang74@huawei.com>
+
+[ Upstream commit 613d12dd794e078be8ff3cf6b62a6b9acf7f4619 ]
+
+syzbot reported a memory leak [1].
+
+When function sock_alloc_send_skb() return NULL in nr_output(), the
+original skb is not freed, which was allocated in nr_sendmsg(). Fix this
+by freeing it before return.
+
+[1]
+BUG: memory leak
+unreferenced object 0xffff888129f35500 (size 240):
+  comm "syz.0.17", pid 6119, jiffies 4294944652
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+    00 00 00 00 00 00 00 00 00 10 52 28 81 88 ff ff  ..........R(....
+  backtrace (crc 1456a3e4):
+    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
+    slab_post_alloc_hook mm/slub.c:4983 [inline]
+    slab_alloc_node mm/slub.c:5288 [inline]
+    kmem_cache_alloc_node_noprof+0x36f/0x5e0 mm/slub.c:5340
+    __alloc_skb+0x203/0x240 net/core/skbuff.c:660
+    alloc_skb include/linux/skbuff.h:1383 [inline]
+    alloc_skb_with_frags+0x69/0x3f0 net/core/skbuff.c:6671
+    sock_alloc_send_pskb+0x379/0x3e0 net/core/sock.c:2965
+    sock_alloc_send_skb include/net/sock.h:1859 [inline]
+    nr_sendmsg+0x287/0x450 net/netrom/af_netrom.c:1105
+    sock_sendmsg_nosec net/socket.c:727 [inline]
+    __sock_sendmsg net/socket.c:742 [inline]
+    sock_write_iter+0x293/0x2a0 net/socket.c:1195
+    new_sync_write fs/read_write.c:593 [inline]
+    vfs_write+0x45d/0x710 fs/read_write.c:686
+    ksys_write+0x143/0x170 fs/read_write.c:738
+    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+    do_syscall_64+0xa4/0xfa0 arch/x86/entry/syscall_64.c:94
+    entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Reported-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=d7abc36bbbb6d7d40b58
+Tested-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Wang Liang <wangliang74@huawei.com>
+Link: https://patch.msgid.link/20251129041315.1550766-1-wangliang74@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netrom/nr_out.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/netrom/nr_out.c b/net/netrom/nr_out.c
+index 5e531394a724b..2b3cbceb0b52d 100644
+--- a/net/netrom/nr_out.c
++++ b/net/netrom/nr_out.c
+@@ -43,8 +43,10 @@ void nr_output(struct sock *sk, struct sk_buff *skb)
+               frontlen = skb_headroom(skb);
+               while (skb->len > 0) {
+-                      if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL)
++                      if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL) {
++                              kfree_skb(skb);
+                               return;
++                      }
+                       skb_reserve(skbn, frontlen);
+-- 
+2.51.0
+
diff --git a/queue-5.15/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch b/queue-5.15/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch
new file mode 100644 (file)
index 0000000..17671f6
--- /dev/null
@@ -0,0 +1,37 @@
+From a9efa6b146a810c6de7d68c69defa2783cad7c8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 09:56:39 +0300
+Subject: nfc: pn533: Fix error code in pn533_acr122_poweron_rdr()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 885bebac9909994050bbbeed0829c727e42bd1b7 ]
+
+Set the error code if "transferred != sizeof(cmd)" instead of
+returning success.
+
+Fixes: dbafc28955fa ("NFC: pn533: don't send USB data off of the stack")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/aTfIJ9tZPmeUF4W1@stanley.mountain
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/pn533/usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c
+index 47d423cc26081..11d3c4045c1e1 100644
+--- a/drivers/nfc/pn533/usb.c
++++ b/drivers/nfc/pn533/usb.c
+@@ -407,7 +407,7 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy)
+       if (rc || (transferred != sizeof(cmd))) {
+               nfc_err(&phy->udev->dev,
+                       "Reader power on cmd error %d\n", rc);
+-              return rc;
++              return rc ?: -EINVAL;
+       }
+       rc =  usb_submit_urb(phy->in_urb, GFP_KERNEL);
+-- 
+2.51.0
+
index 2792f2f5e66ede3f7a3762b3382e1443bdce1599..46bed951bb6a13823f6f90b67081bc4dd89e22b3 100644 (file)
@@ -220,3 +220,26 @@ hfsplus-verify-inode-mode-when-loading-from-disk.patch
 hfsplus-fix-volume-corruption-issue-for-generic-073.patch
 btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch
 bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch
 hfsplus-fix-volume-corruption-issue-for-generic-073.patch
 btrfs-scrub-always-update-btrfs_scrub_progress-last_.patch
 bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch
+netrom-fix-memory-leak-in-nr_sendmsg.patch
+net-sched-ets-always-remove-class-from-active-list-b.patch
+ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch
+mlxsw-spectrum_router-fix-neighbour-use-after-free.patch
+mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch
+net-openvswitch-fix-middle-attribute-validation-in-p.patch
+broadcom-b44-prevent-uninitialized-value-usage.patch
+netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch
+ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch
+caif-fix-integer-underflow-in-cffrml_receive.patch
+net-sched-ets-remove-drr-class-from-the-active-list-.patch
+nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch
+ethtool-use-phydev-variable.patch
+net-ethtool-ioctl-remove-if-n_stats-checks-from-etht.patch
+net-ethtool-ioctl-split-ethtool_get_phy_stats-into-m.patch
+ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch
+net-mlx5-fw_tracer-add-support-for-unrecognized-stri.patch
+net-mlx5-fw_tracer-validate-format-string-parameters.patch
+net-mlx5-fw_tracer-handle-escaped-percent-properly.patch
+net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch
+net-hns3-align-type-of-some-variables-with-their-pri.patch
+net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch
+net-hns3-add-vlan-id-validation-before-using.patch
diff --git a/queue-6.1/broadcom-b44-prevent-uninitialized-value-usage.patch b/queue-6.1/broadcom-b44-prevent-uninitialized-value-usage.patch
new file mode 100644 (file)
index 0000000..d451181
--- /dev/null
@@ -0,0 +1,45 @@
+From 99233debd4425b71f2e284d2c7f77ed41cd870d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 18:58:16 +0300
+Subject: broadcom: b44: prevent uninitialized value usage
+
+From: Alexey Simakov <bigalex934@gmail.com>
+
+[ Upstream commit 50b3db3e11864cb4e18ff099cfb38e11e7f87a68 ]
+
+On execution path with raised B44_FLAG_EXTERNAL_PHY, b44_readphy()
+leaves bmcr value uninitialized and it is used later in the code.
+
+Add check of this flag at the beginning of the b44_nway_reset() and
+exit early of the function with restarting autonegotiation if an
+external PHY is used.
+
+Fixes: 753f492093da ("[B44]: port to native ssb support")
+Reviewed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Alexey Simakov <bigalex934@gmail.com>
+Reviewed-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20251205155815.4348-1-bigalex934@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/b44.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
+index 5b6209f5a8017..b3e3e869c4379 100644
+--- a/drivers/net/ethernet/broadcom/b44.c
++++ b/drivers/net/ethernet/broadcom/b44.c
+@@ -1811,6 +1811,9 @@ static int b44_nway_reset(struct net_device *dev)
+       u32 bmcr;
+       int r;
++      if (bp->flags & B44_FLAG_EXTERNAL_PHY)
++              return phy_ethtool_nway_reset(dev);
++
+       spin_lock_irq(&bp->lock);
+       b44_readphy(bp, MII_BMCR, &bmcr);
+       b44_readphy(bp, MII_BMCR, &bmcr);
+-- 
+2.51.0
+
diff --git a/queue-6.1/caif-fix-integer-underflow-in-cffrml_receive.patch b/queue-6.1/caif-fix-integer-underflow-in-cffrml_receive.patch
new file mode 100644 (file)
index 0000000..be50c71
--- /dev/null
@@ -0,0 +1,58 @@
+From d610ea84c5db5a8fa9c95770d41e328c37a381c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Dec 2025 21:30:47 +0800
+Subject: caif: fix integer underflow in cffrml_receive()
+
+From: Junrui Luo <moonafterrain@outlook.com>
+
+[ Upstream commit 8a11ff0948b5ad09b71896b7ccc850625f9878d1 ]
+
+The cffrml_receive() function extracts a length field from the packet
+header and, when FCS is disabled, subtracts 2 from this length without
+validating that len >= 2.
+
+If an attacker sends a malicious packet with a length field of 0 or 1
+to an interface with FCS disabled, the subtraction causes an integer
+underflow.
+
+This can lead to memory exhaustion and kernel instability, potential
+information disclosure if padding contains uninitialized kernel memory.
+
+Fix this by validating that len >= 2 before performing the subtraction.
+
+Reported-by: Yuhao Jiang <danisjiang@gmail.com>
+Reported-by: Junrui Luo <moonafterrain@outlook.com>
+Fixes: b482cd2053e3 ("net-caif: add CAIF core protocol stack")
+Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/SYBPR01MB7881511122BAFEA8212A1608AFA6A@SYBPR01MB7881.ausprd01.prod.outlook.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/caif/cffrml.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c
+index 6651a8dc62e04..d4d63586053ad 100644
+--- a/net/caif/cffrml.c
++++ b/net/caif/cffrml.c
+@@ -92,8 +92,15 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
+       len = le16_to_cpu(tmp);
+       /* Subtract for FCS on length if FCS is not used. */
+-      if (!this->dofcs)
++      if (!this->dofcs) {
++              if (len < 2) {
++                      ++cffrml_rcv_error;
++                      pr_err("Invalid frame length (%d)\n", len);
++                      cfpkt_destroy(pkt);
++                      return -EPROTO;
++              }
+               len -= 2;
++      }
+       if (cfpkt_setlen(pkt, len) < 0) {
+               ++cffrml_rcv_error;
+-- 
+2.51.0
+
diff --git a/queue-6.1/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch b/queue-6.1/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch
new file mode 100644 (file)
index 0000000..213e662
--- /dev/null
@@ -0,0 +1,159 @@
+From 887aaaabe2fbab1d5e0d5ac6b201af539510975b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 14:19:01 +0200
+Subject: ethtool: Avoid overflowing userspace buffer on stats query
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 7b07be1ff1cb6c49869910518650e8d0abc7d25f ]
+
+The ethtool -S command operates across three ioctl calls:
+ETHTOOL_GSSET_INFO for the size, ETHTOOL_GSTRINGS for the names, and
+ETHTOOL_GSTATS for the values.
+
+If the number of stats changes between these calls (e.g., due to device
+reconfiguration), userspace's buffer allocation will be incorrect,
+potentially leading to buffer overflow.
+
+Drivers are generally expected to maintain stable stat counts, but some
+drivers (e.g., mlx5, bnx2x, bna, ksz884x) use dynamic counters, making
+this scenario possible.
+
+Some drivers try to handle this internally:
+- bnad_get_ethtool_stats() returns early in case stats.n_stats is not
+  equal to the driver's stats count.
+- micrel/ksz884x also makes sure not to write anything beyond
+  stats.n_stats and overflow the buffer.
+
+However, both use stats.n_stats which is already assigned with the value
+returned from get_sset_count(), hence won't solve the issue described
+here.
+
+Change ethtool_get_strings(), ethtool_get_stats(),
+ethtool_get_phy_stats() to not return anything in case of a mismatch
+between userspace's size and get_sset_size(), to prevent buffer
+overflow.
+The returned n_stats value will be equal to zero, to reflect that
+nothing has been returned.
+
+This could result in one of two cases when using upstream ethtool,
+depending on when the size change is detected:
+1. When detected in ethtool_get_strings():
+    # ethtool -S eth2
+    no stats available
+
+2. When detected in get stats, all stats will be reported as zero.
+
+Both cases are presumably transient, and a subsequent ethtool call
+should succeed.
+
+Other than the overflow avoidance, these two cases are very evident (no
+output/cleared stats), which is arguably better than presenting
+incorrect/shifted stats.
+I also considered returning an error instead of a "silent" response, but
+that seems more destructive towards userspace apps.
+
+Notes:
+- This patch does not claim to fix the inherent race, it only makes sure
+  that we do not overflow the userspace buffer, and makes for a more
+  predictable behavior.
+
+- RTNL lock is held during each ioctl, the race window exists between
+  the separate ioctl calls when the lock is released.
+
+- Userspace ethtool always fills stats.n_stats, but it is likely that
+  these stats ioctls are implemented in other userspace applications
+  which might not fill it. The added code checks that it's not zero,
+  to prevent any regressions.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Link: https://patch.msgid.link/20251208121901.3203692-1-gal@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 30 ++++++++++++++++++++++++------
+ 1 file changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 208a40ae4ccbb..0e45e7fd68bf2 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -1938,7 +1938,10 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
+               return -ENOMEM;
+       WARN_ON_ONCE(!ret);
+-      gstrings.len = ret;
++      if (gstrings.len && gstrings.len != ret)
++              gstrings.len = 0;
++      else
++              gstrings.len = ret;
+       if (gstrings.len) {
+               data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
+@@ -2053,10 +2056,13 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       if (copy_from_user(&stats, useraddr, sizeof(stats)))
+               return -EFAULT;
+-      stats.n_stats = n_stats;
++      if (stats.n_stats && stats.n_stats != n_stats)
++              stats.n_stats = 0;
++      else
++              stats.n_stats = n_stats;
+-      if (n_stats) {
+-              data = vzalloc(array_size(n_stats, sizeof(u64)));
++      if (stats.n_stats) {
++              data = vzalloc(array_size(stats.n_stats, sizeof(u64)));
+               if (!data)
+                       return -ENOMEM;
+               ops->get_ethtool_stats(dev, &stats, data);
+@@ -2068,7 +2074,9 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       if (copy_to_user(useraddr, &stats, sizeof(stats)))
+               goto out;
+       useraddr += sizeof(stats);
+-      if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
++      if (stats.n_stats &&
++          copy_to_user(useraddr, data,
++                       array_size(stats.n_stats, sizeof(u64))))
+               goto out;
+       ret = 0;
+@@ -2104,6 +2112,10 @@ static int ethtool_get_phy_stats_phydev(struct phy_device *phydev,
+               return -EOPNOTSUPP;
+       n_stats = phy_ops->get_sset_count(phydev);
++      if (stats->n_stats && stats->n_stats != n_stats) {
++              stats->n_stats = 0;
++              return 0;
++      }
+       ret = ethtool_vzalloc_stats_array(n_stats, data);
+       if (ret)
+@@ -2124,6 +2136,10 @@ static int ethtool_get_phy_stats_ethtool(struct net_device *dev,
+               return -EOPNOTSUPP;
+       n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
++      if (stats->n_stats && stats->n_stats != n_stats) {
++              stats->n_stats = 0;
++              return 0;
++      }
+       ret = ethtool_vzalloc_stats_array(n_stats, data);
+       if (ret)
+@@ -2160,7 +2176,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       }
+       useraddr += sizeof(stats);
+-      if (copy_to_user(useraddr, data, array_size(stats.n_stats, sizeof(u64))))
++      if (stats.n_stats &&
++          copy_to_user(useraddr, data,
++                       array_size(stats.n_stats, sizeof(u64))))
+               ret = -EFAULT;
+  out:
+-- 
+2.51.0
+
diff --git a/queue-6.1/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch b/queue-6.1/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch
new file mode 100644 (file)
index 0000000..26a4c4d
--- /dev/null
@@ -0,0 +1,48 @@
+From 8592d19a7794a27cf1ec702fea179f21c6632071 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 13:39:03 +0300
+Subject: ipvlan: Ignore PACKET_LOOPBACK in handle_mode_l2()
+
+From: Dmitry Skorodumov <skorodumov.dmitry@huawei.com>
+
+[ Upstream commit 0c57ff008a11f24f7f05fa760222692a00465fec ]
+
+Packets with pkt_type == PACKET_LOOPBACK are captured by
+handle_frame() function, but they don't have L2 header.
+We should not process them in handle_mode_l2().
+
+This doesn't affect old L2 functionality, since handling
+was anyway incorrect.
+
+Handle them the same way as in br_handle_frame():
+just pass the skb.
+
+To observe invalid behaviour, just start "ping -b" on bcast address
+of port-interface.
+
+Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
+Signed-off-by: Dmitry Skorodumov <skorodumov.dmitry@huawei.com>
+Link: https://patch.msgid.link/20251202103906.4087675-1-skorodumov.dmitry@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ipvlan/ipvlan_core.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
+index eea81a7334052..a8017424ab538 100644
+--- a/drivers/net/ipvlan/ipvlan_core.c
++++ b/drivers/net/ipvlan/ipvlan_core.c
+@@ -738,6 +738,9 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,
+       struct ethhdr *eth = eth_hdr(skb);
+       rx_handler_result_t ret = RX_HANDLER_PASS;
++      if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
++              return RX_HANDLER_PASS;
++
+       if (is_multicast_ether_addr(eth->h_dest)) {
+               if (ipvlan_external_frame(skb, port)) {
+                       struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
+-- 
+2.51.0
+
diff --git a/queue-6.1/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch b/queue-6.1/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch
new file mode 100644 (file)
index 0000000..3249eb6
--- /dev/null
@@ -0,0 +1,80 @@
+From 52ecb9bf59aabd290843dc6279f964c7fc210b8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 16:52:13 +0800
+Subject: ipvs: fix ipv4 null-ptr-deref in route error path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Slavin Liu <slavin452@gmail.com>
+
+[ Upstream commit ad891bb3d079a46a821bf2b8867854645191bab0 ]
+
+The IPv4 code path in __ip_vs_get_out_rt() calls dst_link_failure()
+without ensuring skb->dev is set, leading to a NULL pointer dereference
+in fib_compute_spec_dst() when ipv4_link_failure() attempts to send
+ICMP destination unreachable messages.
+
+The issue emerged after commit ed0de45a1008 ("ipv4: recompile ip options
+in ipv4_link_failure") started calling __ip_options_compile() from
+ipv4_link_failure(). This code path eventually calls fib_compute_spec_dst()
+which dereferences skb->dev. An attempt was made to fix the NULL skb->dev
+dereference in commit 0113d9c9d1cc ("ipv4: fix null-deref in
+ipv4_link_failure"), but it only addressed the immediate dev_net(skb->dev)
+dereference by using a fallback device. The fix was incomplete because
+fib_compute_spec_dst() later in the call chain still accesses skb->dev
+directly, which remains NULL when IPVS calls dst_link_failure().
+
+The crash occurs when:
+1. IPVS processes a packet in NAT mode with a misconfigured destination
+2. Route lookup fails in __ip_vs_get_out_rt() before establishing a route
+3. The error path calls dst_link_failure(skb) with skb->dev == NULL
+4. ipv4_link_failure() â†’ ipv4_send_dest_unreach() â†’
+   __ip_options_compile() â†’ fib_compute_spec_dst()
+5. fib_compute_spec_dst() dereferences NULL skb->dev
+
+Apply the same fix used for IPv6 in commit 326bf17ea5d4 ("ipvs: fix
+ipv6 route unreach panic"): set skb->dev from skb_dst(skb)->dev before
+calling dst_link_failure().
+
+KASAN: null-ptr-deref in range [0x0000000000000328-0x000000000000032f]
+CPU: 1 PID: 12732 Comm: syz.1.3469 Not tainted 6.6.114 #2
+RIP: 0010:__in_dev_get_rcu include/linux/inetdevice.h:233
+RIP: 0010:fib_compute_spec_dst+0x17a/0x9f0 net/ipv4/fib_frontend.c:285
+Call Trace:
+  <TASK>
+  spec_dst_fill net/ipv4/ip_options.c:232
+  spec_dst_fill net/ipv4/ip_options.c:229
+  __ip_options_compile+0x13a1/0x17d0 net/ipv4/ip_options.c:330
+  ipv4_send_dest_unreach net/ipv4/route.c:1252
+  ipv4_link_failure+0x702/0xb80 net/ipv4/route.c:1265
+  dst_link_failure include/net/dst.h:437
+  __ip_vs_get_out_rt+0x15fd/0x19e0 net/netfilter/ipvs/ip_vs_xmit.c:412
+  ip_vs_nat_xmit+0x1d8/0xc80 net/netfilter/ipvs/ip_vs_xmit.c:764
+
+Fixes: ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure")
+Signed-off-by: Slavin Liu <slavin452@gmail.com>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
+index e1437c72ca6e6..038f0bbbc9f6d 100644
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -409,6 +409,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+       return -1;
+ err_unreach:
++      if (!skb->dev)
++              skb->dev = skb_dst(skb)->dev;
++
+       dst_link_failure(skb);
+       return -1;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.1/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch b/queue-6.1/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch
new file mode 100644 (file)
index 0000000..7b8310e
--- /dev/null
@@ -0,0 +1,96 @@
+From b2c769344c43bcbe867197ea7ec0c0f052ad5b85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:13 +0100
+Subject: mlxsw: spectrum_mr: Fix use-after-free when updating multicast route
+ stats
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 8ac1dacec458f55f871f7153242ed6ab60373b90 ]
+
+Cited commit added a dedicated mutex (instead of RTNL) to protect the
+multicast route list, so that it will not change while the driver
+periodically traverses it in order to update the kernel about multicast
+route stats that were queried from the device.
+
+One instance of list entry deletion (during route replace) was missed
+and it can result in a use-after-free [1].
+
+Fix by acquiring the mutex before deleting the entry from the list and
+releasing it afterwards.
+
+[1]
+BUG: KASAN: slab-use-after-free in mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum]
+Read of size 8 at addr ffff8881523c2fa8 by task kworker/2:5/22043
+
+CPU: 2 UID: 0 PID: 22043 Comm: kworker/2:5 Not tainted 6.18.0-rc1-custom-g1a3d6d7cd014 #1 PREEMPT(full)
+Hardware name: Mellanox Technologies Ltd. MSN2010/SA002610, BIOS 5.6.5 08/24/2017
+Workqueue: mlxsw_core mlxsw_sp_mr_stats_update [mlxsw_spectrum]
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xba/0x110
+ print_report+0x174/0x4f5
+ kasan_report+0xdf/0x110
+ mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+Allocated by task 29933:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0x8f/0xa0
+ mlxsw_sp_mr_route_add+0xd8/0x4770 [mlxsw_spectrum]
+ mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+
+Freed by task 29933:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3b/0x70
+ __kasan_slab_free+0x43/0x70
+ kfree+0x14e/0x700
+ mlxsw_sp_mr_route_add+0x2dea/0x4770 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:444 [mlxsw_spectrum]
+ mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+
+Fixes: f38656d06725 ("mlxsw: spectrum_mr: Protect multicast route list with a lock")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/f996feecfd59fde297964bfc85040b6d83ec6089.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+index 1f6bc0c7e91dd..c39aca54a0d6b 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+@@ -440,7 +440,9 @@ int mlxsw_sp_mr_route_add(struct mlxsw_sp_mr_table *mr_table,
+               rhashtable_remove_fast(&mr_table->route_ht,
+                                      &mr_orig_route->ht_node,
+                                      mlxsw_sp_mr_route_ht_params);
++              mutex_lock(&mr_table->route_list_lock);
+               list_del(&mr_orig_route->node);
++              mutex_unlock(&mr_table->route_list_lock);
+               mlxsw_sp_mr_route_destroy(mr_table, mr_orig_route);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.1/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch b/queue-6.1/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch
new file mode 100644 (file)
index 0000000..a3da38e
--- /dev/null
@@ -0,0 +1,199 @@
+From df2e2f852c60cefbddb3e744e0c4f45c851f461f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:12 +0100
+Subject: mlxsw: spectrum_router: Fix neighbour use-after-free
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 8b0e69763ef948fb872a7767df4be665d18f5fd4 ]
+
+We sometimes observe use-after-free when dereferencing a neighbour [1].
+The problem seems to be that the driver stores a pointer to the
+neighbour, but without holding a reference on it. A reference is only
+taken when the neighbour is used by a nexthop.
+
+Fix by simplifying the reference counting scheme. Always take a
+reference when storing a neighbour pointer in a neighbour entry. Avoid
+taking a referencing when the neighbour is used by a nexthop as the
+neighbour entry associated with the nexthop already holds a reference.
+
+Tested by running the test that uncovered the problem over 300 times.
+Without this patch the problem was reproduced after a handful of
+iterations.
+
+[1]
+BUG: KASAN: slab-use-after-free in mlxsw_sp_neigh_entry_update+0x2d4/0x310
+Read of size 8 at addr ffff88817f8e3420 by task ip/3929
+
+CPU: 3 UID: 0 PID: 3929 Comm: ip Not tainted 6.18.0-rc4-virtme-g36b21a067510 #3 PREEMPT(full)
+Hardware name: Nvidia SN5600/VMOD0013, BIOS 5.13 05/31/2023
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x6f/0xa0
+ print_address_description.constprop.0+0x6e/0x300
+ print_report+0xfc/0x1fb
+ kasan_report+0xe4/0x110
+ mlxsw_sp_neigh_entry_update+0x2d4/0x310
+ mlxsw_sp_router_rif_gone_sync+0x35f/0x510
+ mlxsw_sp_rif_destroy+0x1ea/0x730
+ mlxsw_sp_inetaddr_port_vlan_event+0xa1/0x1b0
+ __mlxsw_sp_inetaddr_lag_event+0xcc/0x130
+ __mlxsw_sp_inetaddr_event+0xf5/0x3c0
+ mlxsw_sp_router_netdevice_event+0x1015/0x1580
+ notifier_call_chain+0xcc/0x150
+ call_netdevice_notifiers_info+0x7e/0x100
+ __netdev_upper_dev_unlink+0x10b/0x210
+ netdev_upper_dev_unlink+0x79/0xa0
+ vrf_del_slave+0x18/0x50
+ do_set_master+0x146/0x7d0
+ do_setlink.isra.0+0x9a0/0x2880
+ rtnl_newlink+0x637/0xb20
+ rtnetlink_rcv_msg+0x6fe/0xb90
+ netlink_rcv_skb+0x123/0x380
+ netlink_unicast+0x4a3/0x770
+ netlink_sendmsg+0x75b/0xc90
+ __sock_sendmsg+0xbe/0x160
+ ____sys_sendmsg+0x5b2/0x7d0
+ ___sys_sendmsg+0xfd/0x180
+ __sys_sendmsg+0x124/0x1c0
+ do_syscall_64+0xbb/0xfd0
+ entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[...]
+
+Allocated by task 109:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0x7b/0x90
+ __kmalloc_noprof+0x2c1/0x790
+ neigh_alloc+0x6af/0x8f0
+ ___neigh_create+0x63/0xe90
+ mlxsw_sp_nexthop_neigh_init+0x430/0x7e0
+ mlxsw_sp_nexthop_type_init+0x212/0x960
+ mlxsw_sp_nexthop6_group_info_init.constprop.0+0x81f/0x1280
+ mlxsw_sp_nexthop6_group_get+0x392/0x6a0
+ mlxsw_sp_fib6_entry_create+0x46a/0xfd0
+ mlxsw_sp_router_fib6_replace+0x1ed/0x5f0
+ mlxsw_sp_router_fib6_event_work+0x10a/0x2a0
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Freed by task 154:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3b/0x60
+ __kasan_slab_free+0x43/0x70
+ kmem_cache_free_bulk.part.0+0x1eb/0x5e0
+ kvfree_rcu_bulk+0x1f2/0x260
+ kfree_rcu_work+0x130/0x1b0
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Last potentially related work creation:
+ kasan_save_stack+0x30/0x50
+ kasan_record_aux_stack+0x8c/0xa0
+ kvfree_call_rcu+0x93/0x5b0
+ mlxsw_sp_router_neigh_event_work+0x67d/0x860
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Fixes: 6cf3c971dc84 ("mlxsw: spectrum_router: Add private neigh table")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/92d75e21d95d163a41b5cea67a15cd33f547cba6.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlxsw/spectrum_router.c   | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index a00dd0ee524e1..3fa790c5ef747 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -2163,6 +2163,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
+       if (!neigh_entry)
+               return NULL;
++      neigh_hold(n);
+       neigh_entry->key.n = n;
+       neigh_entry->rif = rif;
+       INIT_LIST_HEAD(&neigh_entry->nexthop_list);
+@@ -2172,6 +2173,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
+ static void mlxsw_sp_neigh_entry_free(struct mlxsw_sp_neigh_entry *neigh_entry)
+ {
++      neigh_release(neigh_entry->key.n);
+       kfree(neigh_entry);
+ }
+@@ -4027,6 +4029,8 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
+       if (err)
+               goto err_neigh_entry_insert;
++      neigh_release(old_n);
++
+       read_lock_bh(&n->lock);
+       nud_state = n->nud_state;
+       dead = n->dead;
+@@ -4035,14 +4039,10 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
+       list_for_each_entry(nh, &neigh_entry->nexthop_list,
+                           neigh_list_node) {
+-              neigh_release(old_n);
+-              neigh_clone(n);
+               __mlxsw_sp_nexthop_neigh_update(nh, !entry_connected);
+               mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp);
+       }
+-      neigh_release(n);
+-
+       return 0;
+ err_neigh_entry_insert:
+@@ -4130,6 +4130,11 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
+               }
+       }
++      /* Release the reference taken by neigh_lookup() / neigh_create() since
++       * neigh_entry already holds one.
++       */
++      neigh_release(n);
++
+       /* If that is the first nexthop connected to that neigh, add to
+        * nexthop_neighs_list
+        */
+@@ -4156,11 +4161,9 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
+                                       struct mlxsw_sp_nexthop *nh)
+ {
+       struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
+-      struct neighbour *n;
+       if (!neigh_entry)
+               return;
+-      n = neigh_entry->key.n;
+       __mlxsw_sp_nexthop_neigh_update(nh, true);
+       list_del(&nh->neigh_list_node);
+@@ -4174,8 +4177,6 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
+       if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list))
+               mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
+-
+-      neigh_release(n);
+ }
+ static bool mlxsw_sp_ipip_netdev_ul_up(struct net_device *ol_dev)
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-ethtool-ioctl-remove-if-n_stats-checks-from-etht.patch b/queue-6.1/net-ethtool-ioctl-remove-if-n_stats-checks-from-etht.patch
new file mode 100644 (file)
index 0000000..8793b29
--- /dev/null
@@ -0,0 +1,68 @@
+From 6cdfffe30ec820ef348cddf2d72adc79c237fc52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Dec 2022 14:48:24 +0300
+Subject: net/ethtool/ioctl: remove if n_stats checks from
+ ethtool_get_phy_stats
+
+From: Daniil Tatianin <d-tatianin@yandex-team.ru>
+
+[ Upstream commit fd4778581d61d8848b532f8cdc9b325138748437 ]
+
+Now that we always early return if we don't have any stats we can remove
+these checks as they're no longer necessary.
+
+Signed-off-by: Daniil Tatianin <d-tatianin@yandex-team.ru>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 7b07be1ff1cb ("ethtool: Avoid overflowing userspace buffer on stats query")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 24 ++++++++++--------------
+ 1 file changed, 10 insertions(+), 14 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 442c4c343e155..b85f055767035 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -2106,28 +2106,24 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       stats.n_stats = n_stats;
+-      if (n_stats) {
+-              data = vzalloc(array_size(n_stats, sizeof(u64)));
+-              if (!data)
+-                      return -ENOMEM;
++      data = vzalloc(array_size(n_stats, sizeof(u64)));
++      if (!data)
++              return -ENOMEM;
+-              if (phydev && !ops->get_ethtool_phy_stats &&
+-                  phy_ops && phy_ops->get_stats) {
+-                      ret = phy_ops->get_stats(phydev, &stats, data);
+-                      if (ret < 0)
+-                              goto out;
+-              } else {
+-                      ops->get_ethtool_phy_stats(dev, &stats, data);
+-              }
++      if (phydev && !ops->get_ethtool_phy_stats &&
++              phy_ops && phy_ops->get_stats) {
++              ret = phy_ops->get_stats(phydev, &stats, data);
++              if (ret < 0)
++                      goto out;
+       } else {
+-              data = NULL;
++              ops->get_ethtool_phy_stats(dev, &stats, data);
+       }
+       ret = -EFAULT;
+       if (copy_to_user(useraddr, &stats, sizeof(stats)))
+               goto out;
+       useraddr += sizeof(stats);
+-      if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
++      if (copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
+               goto out;
+       ret = 0;
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-ethtool-ioctl-split-ethtool_get_phy_stats-into-m.patch b/queue-6.1/net-ethtool-ioctl-split-ethtool_get_phy_stats-into-m.patch
new file mode 100644 (file)
index 0000000..7f558ac
--- /dev/null
@@ -0,0 +1,168 @@
+From a2398aab1f3390a622df57828ac58bcd8b173d2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Dec 2022 14:48:25 +0300
+Subject: net/ethtool/ioctl: split ethtool_get_phy_stats into multiple helpers
+
+From: Daniil Tatianin <d-tatianin@yandex-team.ru>
+
+[ Upstream commit 201ed315f9676809cd5b20a39206e964106d4f27 ]
+
+So that it's easier to follow and make sense of the branching and
+various conditions.
+
+Stats retrieval has been split into two separate functions
+ethtool_get_phy_stats_phydev & ethtool_get_phy_stats_ethtool.
+The former attempts to retrieve the stats using phydev & phy_ops, while
+the latter uses ethtool_ops.
+
+Actual n_stats validation & array allocation has been moved into a new
+ethtool_vzalloc_stats_array helper.
+
+This also fixes a potential NULL dereference of
+ops->get_ethtool_phy_stats where it was getting called in an else branch
+unconditionally without making sure it was actually present.
+
+Found by Linux Verification Center (linuxtesting.org) with the SVACE
+static analysis tool.
+
+Signed-off-by: Daniil Tatianin <d-tatianin@yandex-team.ru>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 7b07be1ff1cb ("ethtool: Avoid overflowing userspace buffer on stats query")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 102 ++++++++++++++++++++++++++++++--------------
+ 1 file changed, 69 insertions(+), 33 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index b85f055767035..208a40ae4ccbb 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -2077,23 +2077,8 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       return ret;
+ }
+-static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
++static int ethtool_vzalloc_stats_array(int n_stats, u64 **data)
+ {
+-      const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
+-      const struct ethtool_ops *ops = dev->ethtool_ops;
+-      struct phy_device *phydev = dev->phydev;
+-      struct ethtool_stats stats;
+-      u64 *data;
+-      int ret, n_stats;
+-
+-      if (!phydev && (!ops->get_ethtool_phy_stats || !ops->get_sset_count))
+-              return -EOPNOTSUPP;
+-
+-      if (phydev && !ops->get_ethtool_phy_stats &&
+-          phy_ops && phy_ops->get_sset_count)
+-              n_stats = phy_ops->get_sset_count(phydev);
+-      else
+-              n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
+       if (n_stats < 0)
+               return n_stats;
+       if (n_stats > S32_MAX / sizeof(u64))
+@@ -2101,31 +2086,82 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       if (WARN_ON_ONCE(!n_stats))
+               return -EOPNOTSUPP;
++      *data = vzalloc(array_size(n_stats, sizeof(u64)));
++      if (!*data)
++              return -ENOMEM;
++
++      return 0;
++}
++
++static int ethtool_get_phy_stats_phydev(struct phy_device *phydev,
++                                       struct ethtool_stats *stats,
++                                       u64 **data)
++ {
++      const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
++      int n_stats, ret;
++
++      if (!phy_ops || !phy_ops->get_sset_count || !phy_ops->get_stats)
++              return -EOPNOTSUPP;
++
++      n_stats = phy_ops->get_sset_count(phydev);
++
++      ret = ethtool_vzalloc_stats_array(n_stats, data);
++      if (ret)
++              return ret;
++
++      stats->n_stats = n_stats;
++      return phy_ops->get_stats(phydev, stats, *data);
++}
++
++static int ethtool_get_phy_stats_ethtool(struct net_device *dev,
++                                        struct ethtool_stats *stats,
++                                        u64 **data)
++{
++      const struct ethtool_ops *ops = dev->ethtool_ops;
++      int n_stats, ret;
++
++      if (!ops || !ops->get_sset_count || ops->get_ethtool_phy_stats)
++              return -EOPNOTSUPP;
++
++      n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
++
++      ret = ethtool_vzalloc_stats_array(n_stats, data);
++      if (ret)
++              return ret;
++
++      stats->n_stats = n_stats;
++      ops->get_ethtool_phy_stats(dev, stats, *data);
++
++      return 0;
++}
++
++static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
++{
++      struct phy_device *phydev = dev->phydev;
++      struct ethtool_stats stats;
++      u64 *data = NULL;
++      int ret = -EOPNOTSUPP;
++
+       if (copy_from_user(&stats, useraddr, sizeof(stats)))
+               return -EFAULT;
+-      stats.n_stats = n_stats;
++      if (phydev)
++              ret = ethtool_get_phy_stats_phydev(phydev, &stats, &data);
+-      data = vzalloc(array_size(n_stats, sizeof(u64)));
+-      if (!data)
+-              return -ENOMEM;
++      if (ret == -EOPNOTSUPP)
++              ret = ethtool_get_phy_stats_ethtool(dev, &stats, &data);
+-      if (phydev && !ops->get_ethtool_phy_stats &&
+-              phy_ops && phy_ops->get_stats) {
+-              ret = phy_ops->get_stats(phydev, &stats, data);
+-              if (ret < 0)
+-                      goto out;
+-      } else {
+-              ops->get_ethtool_phy_stats(dev, &stats, data);
+-      }
++      if (ret)
++              goto out;
+-      ret = -EFAULT;
+-      if (copy_to_user(useraddr, &stats, sizeof(stats)))
++      if (copy_to_user(useraddr, &stats, sizeof(stats))) {
++              ret = -EFAULT;
+               goto out;
++      }
++
+       useraddr += sizeof(stats);
+-      if (copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
+-              goto out;
+-      ret = 0;
++      if (copy_to_user(useraddr, data, array_size(stats.n_stats, sizeof(u64))))
++              ret = -EFAULT;
+  out:
+       vfree(data);
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-hns3-add-vlan-id-validation-before-using.patch b/queue-6.1/net-hns3-add-vlan-id-validation-before-using.patch
new file mode 100644 (file)
index 0000000..536a6bb
--- /dev/null
@@ -0,0 +1,46 @@
+From ded03f8d30ca55eced75d8a4620e61897e7fe04c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:37 +0800
+Subject: net: hns3: add VLAN id validation before using
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit 6ef935e65902bfed53980ad2754b06a284ea8ac1 ]
+
+Currently, the VLAN id may be used without validation when
+receive a VLAN configuration mailbox from VF. The length of
+vlan_del_fail_bmap is BITS_TO_LONGS(VLAN_N_VID). It may cause
+out-of-bounds memory access once the VLAN id is bigger than
+or equal to VLAN_N_VID.
+
+Therefore, VLAN id needs to be checked to ensure it is within
+the range of VLAN_N_VID.
+
+Fixes: fe4144d47eef ("net: hns3: sync VLAN filter entries when kill VLAN ID failed")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-4-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index c45340f26ee49..a92f056b25613 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -10585,6 +10585,9 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
+       bool writen_to_tbl = false;
+       int ret = 0;
++      if (vlan_id >= VLAN_N_VID)
++              return -EINVAL;
++
+       /* When device is resetting or reset failed, firmware is unable to
+        * handle mailbox. Just record the vlan id, and remove it after
+        * reset finished.
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch b/queue-6.1/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch
new file mode 100644 (file)
index 0000000..770e165
--- /dev/null
@@ -0,0 +1,52 @@
+From 05660ecdaa98937f68256461ea77001c91c347be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:35 +0800
+Subject: net: hns3: using the num_tqps in the vf driver to apply for resources
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit c2a16269742e176fccdd0ef9c016a233491a49ad ]
+
+Currently, hdev->htqp is allocated using hdev->num_tqps, and kinfo->tqp
+is allocated using kinfo->num_tqps. However, kinfo->num_tqps is set to
+min(new_tqps, hdev->num_tqps);  Therefore, kinfo->num_tqps may be smaller
+than hdev->num_tqps, which causes some hdev->htqp[i] to remain
+uninitialized in hclgevf_knic_setup().
+
+Thus, this patch allocates hdev->htqp and kinfo->tqp using hdev->num_tqps,
+ensuring that the lengths of hdev->htqp and kinfo->tqp are consistent
+and that all elements are properly initialized.
+
+Fixes: e2cb1dec9779 ("net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-2-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+index cff8654354e6d..1c434a19ddc34 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -385,12 +385,12 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev)
+       new_tqps = kinfo->rss_size * num_tc;
+       kinfo->num_tqps = min(new_tqps, hdev->num_tqps);
+-      kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps,
++      kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps,
+                                 sizeof(struct hnae3_queue *), GFP_KERNEL);
+       if (!kinfo->tqp)
+               return -ENOMEM;
+-      for (i = 0; i < kinfo->num_tqps; i++) {
++      for (i = 0; i < hdev->num_tqps; i++) {
+               hdev->htqp[i].q.handle = &hdev->nic;
+               hdev->htqp[i].q.tqp_index = i;
+               kinfo->tqp[i] = &hdev->htqp[i].q;
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch b/queue-6.1/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch
new file mode 100644 (file)
index 0000000..af8a54d
--- /dev/null
@@ -0,0 +1,49 @@
+From e038afc703494b3d52792c6fce73be102e073ed7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:36 +0800
+Subject: net: hns3: using the num_tqps to check whether tqp_index is out of
+ range when vf get ring info from mbx
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit d180c11aa8a6fa735f9ac2c72c61364a9afc2ba7 ]
+
+Currently, rss_size = num_tqps / tc_num. If tc_num is 1, then num_tqps
+equals rss_size. However, if the tc_num is greater than 1, then rss_size
+will be less than num_tqps, causing the tqp_index check for subsequent TCs
+using rss_size to always fail.
+
+This patch uses the num_tqps to check whether tqp_index is out of range,
+instead of rss_size.
+
+Fixes: 326334aad024 ("net: hns3: add a check for tqp_index in hclge_get_ring_chain_from_mbx()")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-3-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+index 61e155c4d441e..a961e90a85a67 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+@@ -193,10 +193,10 @@ static int hclge_get_ring_chain_from_mbx(
+               return -EINVAL;
+       for (i = 0; i < ring_num; i++) {
+-              if (req->msg.param[i].tqp_index >= vport->nic.kinfo.rss_size) {
++              if (req->msg.param[i].tqp_index >= vport->nic.kinfo.num_tqps) {
+                       dev_err(&hdev->pdev->dev, "tqp index(%u) is out of range(0-%u)\n",
+                               req->msg.param[i].tqp_index,
+-                              vport->nic.kinfo.rss_size - 1U);
++                              vport->nic.kinfo.num_tqps - 1U);
+                       return -EINVAL;
+               }
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5-create-a-new-profile-for-sfs.patch b/queue-6.1/net-mlx5-create-a-new-profile-for-sfs.patch
new file mode 100644 (file)
index 0000000..d04eeec
--- /dev/null
@@ -0,0 +1,139 @@
+From 0cac9a5525c6ec516486244128d86f5835a81828 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Apr 2020 08:27:59 -0500
+Subject: net/mlx5: Create a new profile for SFs
+
+From: Parav Pandit <parav@mellanox.com>
+
+[ Upstream commit 9df839a711aee437390b16ee39cf0b5c1620be6a ]
+
+Create a new profile for SFs in order to disable the command cache.
+Each function command cache consumes ~500KB of memory, when using a
+large number of SFs this savings is notable on memory constarined
+systems.
+
+Use a new profile to provide for future differences between SFs and PFs.
+
+The mr_cache not used for non-PF functions, so it is excluded from the
+new profile.
+
+Signed-off-by: Parav Pandit <parav@mellanox.com>
+Reviewed-by: Bodong Wang <bodong@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: 5846a365fc64 ("net/mlx5: Drain firmware reset in shutdown callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/cmd.c           | 6 +++---
+ drivers/net/ethernet/mellanox/mlx5/core/main.c          | 9 +++++++++
+ drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h     | 1 +
+ drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c | 2 +-
+ include/linux/mlx5/driver.h                             | 1 +
+ 5 files changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 4c614a256ee05..ff45b7b5e1c21 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -1833,7 +1833,7 @@ static struct mlx5_cmd_msg *alloc_msg(struct mlx5_core_dev *dev, int in_size,
+       if (in_size <= 16)
+               goto cache_miss;
+-      for (i = 0; i < MLX5_NUM_COMMAND_CACHES; i++) {
++      for (i = 0; i < dev->profile.num_cmd_caches; i++) {
+               ch = &cmd->cache[i];
+               if (in_size > ch->max_inbox_size)
+                       continue;
+@@ -2129,7 +2129,7 @@ static void destroy_msg_cache(struct mlx5_core_dev *dev)
+       struct mlx5_cmd_msg *n;
+       int i;
+-      for (i = 0; i < MLX5_NUM_COMMAND_CACHES; i++) {
++      for (i = 0; i < dev->profile.num_cmd_caches; i++) {
+               ch = &dev->cmd.cache[i];
+               list_for_each_entry_safe(msg, n, &ch->head, list) {
+                       list_del(&msg->list);
+@@ -2159,7 +2159,7 @@ static void create_msg_cache(struct mlx5_core_dev *dev)
+       int k;
+       /* Initialize and fill the caches with initial entries */
+-      for (k = 0; k < MLX5_NUM_COMMAND_CACHES; k++) {
++      for (k = 0; k < dev->profile.num_cmd_caches; k++) {
+               ch = &cmd->cache[k];
+               spin_lock_init(&ch->lock);
+               INIT_LIST_HEAD(&ch->head);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index a53f222e3feed..891b625a6dc71 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -103,15 +103,19 @@ enum {
+ static struct mlx5_profile profile[] = {
+       [0] = {
+               .mask           = 0,
++              .num_cmd_caches = MLX5_NUM_COMMAND_CACHES,
+       },
+       [1] = {
+               .mask           = MLX5_PROF_MASK_QP_SIZE,
+               .log_max_qp     = 12,
++              .num_cmd_caches = MLX5_NUM_COMMAND_CACHES,
++
+       },
+       [2] = {
+               .mask           = MLX5_PROF_MASK_QP_SIZE |
+                                 MLX5_PROF_MASK_MR_CACHE,
+               .log_max_qp     = LOG_MAX_SUPPORTED_QPS,
++              .num_cmd_caches = MLX5_NUM_COMMAND_CACHES,
+               .mr_cache[0]    = {
+                       .size   = 500,
+                       .limit  = 250
+@@ -177,6 +181,11 @@ static struct mlx5_profile profile[] = {
+                       .limit  = 4
+               },
+       },
++      [3] = {
++              .mask           = MLX5_PROF_MASK_QP_SIZE,
++              .log_max_qp     = LOG_MAX_SUPPORTED_QPS,
++              .num_cmd_caches = 0,
++      },
+ };
+ static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+index 7d90f311b8560..07b5c86fc26a4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+@@ -142,6 +142,7 @@ enum mlx5_semaphore_space_address {
+ };
+ #define MLX5_DEFAULT_PROF       2
++#define MLX5_SF_PROF          3
+ static inline int mlx5_flexible_inlen(struct mlx5_core_dev *dev, size_t fixed,
+                                     size_t item_size, size_t num_items,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c
+index d6850eb0ed7f4..f314ad1e8c312 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c
+@@ -28,7 +28,7 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia
+       mdev->priv.adev_idx = adev->id;
+       sf_dev->mdev = mdev;
+-      err = mlx5_mdev_init(mdev, MLX5_DEFAULT_PROF);
++      err = mlx5_mdev_init(mdev, MLX5_SF_PROF);
+       if (err) {
+               mlx5_core_warn(mdev, "mlx5_mdev_init on err=%d\n", err);
+               goto mdev_err;
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index 9af7180eac9e3..0e8705c3a460d 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -755,6 +755,7 @@ enum {
+ struct mlx5_profile {
+       u64     mask;
+       u8      log_max_qp;
++      u8      num_cmd_caches;
+       struct {
+               int     size;
+               int     limit;
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5-drain-firmware-reset-in-shutdown-callback.patch b/queue-6.1/net-mlx5-drain-firmware-reset-in-shutdown-callback.patch
new file mode 100644 (file)
index 0000000..2624fbc
--- /dev/null
@@ -0,0 +1,38 @@
+From 1404950d6768fc05fe21bdd2b2ab0af0e341958b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:10 +0200
+Subject: net/mlx5: Drain firmware reset in shutdown callback
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 5846a365fc6476b02d6766963cf0985520f0385f ]
+
+Invoke drain_fw_reset() in the shutdown callback to ensure all
+firmware reset handling is completed before shutdown proceeds.
+
+Fixes: 16d42d313350 ("net/mlx5: Drain fw_reset when removing device")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Shay Drori <shayd@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-3-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 891b625a6dc71..2b89bbd95f9af 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1999,6 +1999,7 @@ static void shutdown(struct pci_dev *pdev)
+       mlx5_core_info(dev, "Shutdown was called\n");
+       set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state);
++      mlx5_drain_fw_reset(dev);
+       mlx5_drain_health_wq(dev);
+       err = mlx5_try_fast_unload(dev);
+       if (err)
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch b/queue-6.1/net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch
new file mode 100644 (file)
index 0000000..06f664b
--- /dev/null
@@ -0,0 +1,45 @@
+From 840bc999354a300f3695d2522e031230b6898e6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:09 +0200
+Subject: net/mlx5: fw reset, clear reset requested on drain_fw_reset
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 89a898d63f6f588acf5c104c65c94a38b68c69a6 ]
+
+drain_fw_reset() waits for ongoing firmware reset events and blocks new
+event handling, but does not clear the reset requested flag, and may
+keep sync reset polling.
+
+To fix it, call mlx5_sync_reset_clear_reset_requested() to clear the
+flag, stop sync reset polling, and resume health polling, ensuring
+health issues are still detected after the firmware reset drain.
+
+Fixes: 16d42d313350 ("net/mlx5: Drain fw_reset when removing device")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Shay Drori <shayd@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-2-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index de130c75de64e..bb62dad48b306 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -534,7 +534,8 @@ void mlx5_drain_fw_reset(struct mlx5_core_dev *dev)
+       cancel_work_sync(&fw_reset->reset_reload_work);
+       cancel_work_sync(&fw_reset->reset_now_work);
+       cancel_work_sync(&fw_reset->reset_abort_work);
+-      cancel_delayed_work(&fw_reset->reset_timeout_work);
++      if (test_bit(MLX5_FW_RESET_FLAGS_RESET_REQUESTED, &fw_reset->reset_flags))
++              mlx5_sync_reset_clear_reset_requested(dev, true);
+ }
+ int mlx5_fw_reset_init(struct mlx5_core_dev *dev)
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5-fw_tracer-add-support-for-unrecognized-stri.patch b/queue-6.1/net-mlx5-fw_tracer-add-support-for-unrecognized-stri.patch
new file mode 100644 (file)
index 0000000..a19f14e
--- /dev/null
@@ -0,0 +1,94 @@
+From e242617173f3667f88ad4df389dba2f685f98338 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 15:24:19 +0200
+Subject: net/mlx5: fw_tracer, Add support for unrecognized string
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit f7133135235dbd11e7cb5fe62fe5d05ce5e82eeb ]
+
+In case FW is publishing a string which isn't found in the driver's
+string DBs, keep the string as raw data.
+
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: b35966042d20 ("net/mlx5: fw_tracer, Validate format string parameters")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 25 +++++++++++++++++--
+ .../mellanox/mlx5/core/diag/fw_tracer.h       |  1 +
+ 2 files changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 3ba54ffa54bfe..83a3074a725b1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -460,6 +460,7 @@ static void poll_trace(struct mlx5_fw_tracer *tracer,
+       tracer_event->event_id = MLX5_GET(tracer_event, trace, event_id);
+       tracer_event->lost_event = MLX5_GET(tracer_event, trace, lost);
++      tracer_event->out = trace;
+       switch (tracer_event->event_id) {
+       case TRACER_EVENT_TYPE_TIMESTAMP:
+@@ -582,6 +583,26 @@ void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt,
+       mlx5_tracer_clean_message(str_frmt);
+ }
++static int mlx5_tracer_handle_raw_string(struct mlx5_fw_tracer *tracer,
++                                       struct tracer_event *tracer_event)
++{
++      struct tracer_string_format *cur_string;
++
++      cur_string = mlx5_tracer_message_insert(tracer, tracer_event);
++      if (!cur_string)
++              return -1;
++
++      cur_string->event_id = tracer_event->event_id;
++      cur_string->timestamp = tracer_event->string_event.timestamp;
++      cur_string->lost = tracer_event->lost_event;
++      cur_string->string = "0x%08x%08x";
++      cur_string->num_of_params = 2;
++      cur_string->params[0] = upper_32_bits(*tracer_event->out);
++      cur_string->params[1] = lower_32_bits(*tracer_event->out);
++      list_add_tail(&cur_string->list, &tracer->ready_strings_list);
++      return 0;
++}
++
+ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                          struct tracer_event *tracer_event)
+ {
+@@ -590,7 +611,7 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+       if (tracer_event->string_event.tdsn == 0) {
+               cur_string = mlx5_tracer_get_string(tracer, tracer_event);
+               if (!cur_string)
+-                      return -1;
++                      return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+               cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
+               cur_string->last_param_num = 0;
+@@ -605,7 +626,7 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+               if (!cur_string) {
+                       pr_debug("%s Got string event for unknown string tmsn: %d\n",
+                                __func__, tracer_event->string_event.tmsn);
+-                      return -1;
++                      return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+               }
+               cur_string->last_param_num += 1;
+               if (cur_string->last_param_num > TRACER_MAX_PARAMS) {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+index 4762b55b0b0ee..3ff412999a3e2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+@@ -158,6 +158,7 @@ struct tracer_event {
+               struct tracer_string_event string_event;
+               struct tracer_timestamp_event timestamp_event;
+       };
++      u64 *out;
+ };
+ struct mlx5_ifc_tracer_event_bits {
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch b/queue-6.1/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch
new file mode 100644 (file)
index 0000000..076f549
--- /dev/null
@@ -0,0 +1,84 @@
+From 4ae9860ffa1cf8e0b8b8304ddd7afb0eb7880d80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:12 +0200
+Subject: net/mlx5: fw_tracer, Handle escaped percent properly
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit c0289f67f7d6a0dfba0e92cfe661a5c70c8c6e92 ]
+
+The firmware tracer's format string validation and parameter counting
+did not properly handle escaped percent signs (%%). This caused
+fw_tracer to count more parameters when trace format strings contained
+literal percent characters.
+
+To fix it, allow %% to pass string validation and skip %% sequences when
+counting parameters since they represent literal percent signs rather
+than format specifiers.
+
+Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reported-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 20 +++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 2ce900b18f705..c216634c8919e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -364,11 +364,11 @@ static bool mlx5_is_valid_spec(const char *str)
+       while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l')
+               str++;
+-      /* Check if it's a valid integer/hex specifier:
++      /* Check if it's a valid integer/hex specifier or %%:
+        * Valid formats: %x, %d, %i, %u, etc.
+        */
+       if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' &&
+-          *str != 'u' && *str != 'c')
++          *str != 'u' && *str != 'c' && *str != '%')
+               return false;
+       return true;
+@@ -386,7 +386,11 @@ static bool mlx5_tracer_validate_params(const char *str)
+               if (!mlx5_is_valid_spec(substr + 1))
+                       return false;
+-              substr = strstr(substr + 1, PARAM_CHAR);
++              if (*(substr + 1) == '%')
++                      substr = strstr(substr + 2, PARAM_CHAR);
++              else
++                      substr = strstr(substr + 1, PARAM_CHAR);
++
+       }
+       return true;
+@@ -463,11 +467,15 @@ static int mlx5_tracer_get_num_of_params(char *str)
+               substr = strstr(pstr, VAL_PARM);
+       }
+-      /* count all the % characters */
++      /* count all the % characters, but skip %% (escaped percent) */
+       substr = strstr(str, PARAM_CHAR);
+       while (substr) {
+-              num_of_params += 1;
+-              str = substr + 1;
++              if (*(substr + 1) != '%') {
++                      num_of_params += 1;
++                      str = substr + 1;
++              } else {
++                      str = substr + 2;
++              }
+               substr = strstr(str, PARAM_CHAR);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-mlx5-fw_tracer-validate-format-string-parameters.patch b/queue-6.1/net-mlx5-fw_tracer-validate-format-string-parameters.patch
new file mode 100644 (file)
index 0000000..1bae50d
--- /dev/null
@@ -0,0 +1,195 @@
+From da942431ad05c382ae02cb9382bfa032c856ef71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:11 +0200
+Subject: net/mlx5: fw_tracer, Validate format string parameters
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit b35966042d20b14e2d83330049f77deec5229749 ]
+
+Add validation for format string parameters in the firmware tracer to
+prevent potential security vulnerabilities and crashes from malformed
+format strings received from firmware.
+
+The firmware tracer receives format strings from the device firmware and
+uses them to format trace messages. Without proper validation, bad
+firmware could provide format strings with invalid format specifiers
+(e.g., %s, %p, %n) that could lead to crashes, or other undefined
+behavior.
+
+Add mlx5_tracer_validate_params() to validate that all format specifiers
+in trace strings are limited to safe integer/hex formats (%x, %d, %i,
+%u, %llx, %lx, etc.). Reject strings containing other format types that
+could be used to access arbitrary memory or cause crashes.
+Invalid format strings are added to the trace output for visibility with
+"BAD_FORMAT: " prefix.
+
+Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Reported-by: Breno Leitao <leitao@debian.org>
+Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-4-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 83 ++++++++++++++++---
+ .../mellanox/mlx5/core/diag/fw_tracer.h       |  1 +
+ 2 files changed, 74 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 83a3074a725b1..2ce900b18f705 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -33,6 +33,7 @@
+ #include "lib/eq.h"
+ #include "fw_tracer.h"
+ #include "fw_tracer_tracepoint.h"
++#include <linux/ctype.h>
+ static int mlx5_query_mtrc_caps(struct mlx5_fw_tracer *tracer)
+ {
+@@ -354,6 +355,43 @@ static const char *VAL_PARM               = "%llx";
+ static const char *REPLACE_64_VAL_PARM        = "%x%x";
+ static const char *PARAM_CHAR         = "%";
++static bool mlx5_is_valid_spec(const char *str)
++{
++      /* Parse format specifiers to find the actual type.
++       * Structure: %[flags][width][.precision][length]type
++       * Skip flags, width, precision & length.
++       */
++      while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l')
++              str++;
++
++      /* Check if it's a valid integer/hex specifier:
++       * Valid formats: %x, %d, %i, %u, etc.
++       */
++      if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' &&
++          *str != 'u' && *str != 'c')
++              return false;
++
++      return true;
++}
++
++static bool mlx5_tracer_validate_params(const char *str)
++{
++      const char *substr = str;
++
++      if (!str)
++              return false;
++
++      substr = strstr(substr, PARAM_CHAR);
++      while (substr) {
++              if (!mlx5_is_valid_spec(substr + 1))
++                      return false;
++
++              substr = strstr(substr + 1, PARAM_CHAR);
++      }
++
++      return true;
++}
++
+ static int mlx5_tracer_message_hash(u32 message_id)
+ {
+       return jhash_1word(message_id, 0) & (MESSAGE_HASH_SIZE - 1);
+@@ -413,6 +451,10 @@ static int mlx5_tracer_get_num_of_params(char *str)
+       char *substr, *pstr = str;
+       int num_of_params = 0;
++      /* Validate that all parameters are valid before processing */
++      if (!mlx5_tracer_validate_params(str))
++              return -EINVAL;
++
+       /* replace %llx with %x%x */
+       substr = strstr(pstr, VAL_PARM);
+       while (substr) {
+@@ -564,14 +606,17 @@ void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt,
+ {
+       char    tmp[512];
+-      snprintf(tmp, sizeof(tmp), str_frmt->string,
+-               str_frmt->params[0],
+-               str_frmt->params[1],
+-               str_frmt->params[2],
+-               str_frmt->params[3],
+-               str_frmt->params[4],
+-               str_frmt->params[5],
+-               str_frmt->params[6]);
++      if (str_frmt->invalid_string)
++              snprintf(tmp, sizeof(tmp), "BAD_FORMAT: %s", str_frmt->string);
++      else
++              snprintf(tmp, sizeof(tmp), str_frmt->string,
++                       str_frmt->params[0],
++                       str_frmt->params[1],
++                       str_frmt->params[2],
++                       str_frmt->params[3],
++                       str_frmt->params[4],
++                       str_frmt->params[5],
++                       str_frmt->params[6]);
+       trace_mlx5_fw(dev->tracer, trace_timestamp, str_frmt->lost,
+                     str_frmt->event_id, tmp);
+@@ -603,6 +648,13 @@ static int mlx5_tracer_handle_raw_string(struct mlx5_fw_tracer *tracer,
+       return 0;
+ }
++static void mlx5_tracer_handle_bad_format_string(struct mlx5_fw_tracer *tracer,
++                                               struct tracer_string_format *cur_string)
++{
++      cur_string->invalid_string = true;
++      list_add_tail(&cur_string->list, &tracer->ready_strings_list);
++}
++
+ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                          struct tracer_event *tracer_event)
+ {
+@@ -613,12 +665,18 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+               if (!cur_string)
+                       return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+-              cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
+-              cur_string->last_param_num = 0;
+               cur_string->event_id = tracer_event->event_id;
+               cur_string->tmsn = tracer_event->string_event.tmsn;
+               cur_string->timestamp = tracer_event->string_event.timestamp;
+               cur_string->lost = tracer_event->lost_event;
++              cur_string->last_param_num = 0;
++              cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
++              if (cur_string->num_of_params < 0) {
++                      pr_debug("%s Invalid format string parameters\n",
++                               __func__);
++                      mlx5_tracer_handle_bad_format_string(tracer, cur_string);
++                      return 0;
++              }
+               if (cur_string->num_of_params == 0) /* trace with no params */
+                       list_add_tail(&cur_string->list, &tracer->ready_strings_list);
+       } else {
+@@ -628,6 +686,11 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                __func__, tracer_event->string_event.tmsn);
+                       return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+               }
++              if (cur_string->num_of_params < 0) {
++                      pr_debug("%s string parameter of invalid string, dumping\n",
++                               __func__);
++                      return 0;
++              }
+               cur_string->last_param_num += 1;
+               if (cur_string->last_param_num > TRACER_MAX_PARAMS) {
+                       pr_debug("%s Number of params exceeds the max (%d)\n",
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+index 3ff412999a3e2..c57c4f434c36a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+@@ -117,6 +117,7 @@ struct tracer_string_format {
+       struct list_head list;
+       u32 timestamp;
+       bool lost;
++      bool invalid_string;
+ };
+ enum mlx5_fw_tracer_ownership_state {
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-openvswitch-fix-middle-attribute-validation-in-p.patch b/queue-6.1/net-openvswitch-fix-middle-attribute-validation-in-p.patch
new file mode 100644 (file)
index 0000000..ff56d64
--- /dev/null
@@ -0,0 +1,112 @@
+From 69a69ac03dfe96423c03acdfd012466cce80e025 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Dec 2025 11:53:32 +0100
+Subject: net: openvswitch: fix middle attribute validation in push_nsh()
+ action
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 5ace7ef87f059d68b5f50837ef3e8a1a4870c36e ]
+
+The push_nsh() action structure looks like this:
+
+ OVS_ACTION_ATTR_PUSH_NSH(OVS_KEY_ATTR_NSH(OVS_NSH_KEY_ATTR_BASE,...))
+
+The outermost OVS_ACTION_ATTR_PUSH_NSH attribute is OK'ed by the
+nla_for_each_nested() inside __ovs_nla_copy_actions().  The innermost
+OVS_NSH_KEY_ATTR_BASE/MD1/MD2 are OK'ed by the nla_for_each_nested()
+inside nsh_key_put_from_nlattr().  But nothing checks if the attribute
+in the middle is OK.  We don't even check that this attribute is the
+OVS_KEY_ATTR_NSH.  We just do a double unwrap with a pair of nla_data()
+calls - first time directly while calling validate_push_nsh() and the
+second time as part of the nla_for_each_nested() macro, which isn't
+safe, potentially causing invalid memory access if the size of this
+attribute is incorrect.  The failure may not be noticed during
+validation due to larger netlink buffer, but cause trouble later during
+action execution where the buffer is allocated exactly to the size:
+
+ BUG: KASAN: slab-out-of-bounds in nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch]
+ Read of size 184 at addr ffff88816459a634 by task a.out/22624
+
+ CPU: 8 UID: 0 PID: 22624 6.18.0-rc7+ #115 PREEMPT(voluntary)
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x51/0x70
+  print_address_description.constprop.0+0x2c/0x390
+  kasan_report+0xdd/0x110
+  kasan_check_range+0x35/0x1b0
+  __asan_memcpy+0x20/0x60
+  nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch]
+  push_nsh+0x82/0x120 [openvswitch]
+  do_execute_actions+0x1405/0x2840 [openvswitch]
+  ovs_execute_actions+0xd5/0x3b0 [openvswitch]
+  ovs_packet_cmd_execute+0x949/0xdb0 [openvswitch]
+  genl_family_rcv_msg_doit+0x1d6/0x2b0
+  genl_family_rcv_msg+0x336/0x580
+  genl_rcv_msg+0x9f/0x130
+  netlink_rcv_skb+0x11f/0x370
+  genl_rcv+0x24/0x40
+  netlink_unicast+0x73e/0xaa0
+  netlink_sendmsg+0x744/0xbf0
+  __sys_sendto+0x3d6/0x450
+  do_syscall_64+0x79/0x2c0
+  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+  </TASK>
+
+Let's add some checks that the attribute is properly sized and it's
+the only one attribute inside the action.  Technically, there is no
+real reason for OVS_KEY_ATTR_NSH to be there, as we know that we're
+pushing an NSH header already, it just creates extra nesting, but
+that's how uAPI works today.  So, keeping as it is.
+
+Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support")
+Reported-by: Junvy Yang <zhuque@tencent.com>
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Eelco Chaudron echaudro@redhat.com
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Link: https://patch.msgid.link/20251204105334.900379-1-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/flow_netlink.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
+index d0b6e58720816..d4c8b4aa98b19 100644
+--- a/net/openvswitch/flow_netlink.c
++++ b/net/openvswitch/flow_netlink.c
+@@ -2786,13 +2786,20 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
+       return err;
+ }
+-static bool validate_push_nsh(const struct nlattr *attr, bool log)
++static bool validate_push_nsh(const struct nlattr *a, bool log)
+ {
++      struct nlattr *nsh_key = nla_data(a);
+       struct sw_flow_match match;
+       struct sw_flow_key key;
++      /* There must be one and only one NSH header. */
++      if (!nla_ok(nsh_key, nla_len(a)) ||
++          nla_total_size(nla_len(nsh_key)) != nla_len(a) ||
++          nla_type(nsh_key) != OVS_KEY_ATTR_NSH)
++              return false;
++
+       ovs_match_init(&match, &key, true, NULL);
+-      return !nsh_key_put_from_nlattr(attr, &match, false, true, log);
++      return !nsh_key_put_from_nlattr(nsh_key, &match, false, true, log);
+ }
+ /* Return false if there are any non-masked bits set.
+@@ -3346,7 +3353,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
+                                       return -EINVAL;
+                       }
+                       mac_proto = MAC_PROTO_NONE;
+-                      if (!validate_push_nsh(nla_data(a), log))
++                      if (!validate_push_nsh(a, log))
+                               return -EINVAL;
+                       break;
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-sched-ets-always-remove-class-from-active-list-b.patch b/queue-6.1/net-sched-ets-always-remove-class-from-active-list-b.patch
new file mode 100644 (file)
index 0000000..f2f39e1
--- /dev/null
@@ -0,0 +1,232 @@
+From 524ee2b989d793bde7fa2116e774a29618b4b1bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Nov 2025 10:19:19 -0500
+Subject: net/sched: ets: Always remove class from active list before deleting
+ in ets_qdisc_change
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit ce052b9402e461a9aded599f5b47e76bc727f7de ]
+
+zdi-disclosures@trendmicro.com says:
+
+The vulnerability is a race condition between `ets_qdisc_dequeue` and
+`ets_qdisc_change`.  It leads to UAF on `struct Qdisc` object.
+Attacker requires the capability to create new user and network namespace
+in order to trigger the bug.
+See my additional commentary at the end of the analysis.
+
+Analysis:
+
+static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+                          struct netlink_ext_ack *extack)
+{
+...
+
+      // (1) this lock is preventing .change handler (`ets_qdisc_change`)
+      //to race with .dequeue handler (`ets_qdisc_dequeue`)
+      sch_tree_lock(sch);
+
+      for (i = nbands; i < oldbands; i++) {
+              if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
+                      list_del_init(&q->classes[i].alist);
+              qdisc_purge_queue(q->classes[i].qdisc);
+      }
+
+      WRITE_ONCE(q->nbands, nbands);
+      for (i = nstrict; i < q->nstrict; i++) {
+              if (q->classes[i].qdisc->q.qlen) {
+                     // (2) the class is added to the q->active
+                      list_add_tail(&q->classes[i].alist, &q->active);
+                      q->classes[i].deficit = quanta[i];
+              }
+      }
+      WRITE_ONCE(q->nstrict, nstrict);
+      memcpy(q->prio2band, priomap, sizeof(priomap));
+
+      for (i = 0; i < q->nbands; i++)
+              WRITE_ONCE(q->classes[i].quantum, quanta[i]);
+
+      for (i = oldbands; i < q->nbands; i++) {
+              q->classes[i].qdisc = queues[i];
+              if (q->classes[i].qdisc != &noop_qdisc)
+                      qdisc_hash_add(q->classes[i].qdisc, true);
+      }
+
+      // (3) the qdisc is unlocked, now dequeue can be called in parallel
+      // to the rest of .change handler
+      sch_tree_unlock(sch);
+
+      ets_offload_change(sch);
+      for (i = q->nbands; i < oldbands; i++) {
+             // (4) we're reducing the refcount for our class's qdisc and
+             //  freeing it
+              qdisc_put(q->classes[i].qdisc);
+             // (5) If we call .dequeue between (4) and (5), we will have
+             // a strong UAF and we can control RIP
+              q->classes[i].qdisc = NULL;
+              WRITE_ONCE(q->classes[i].quantum, 0);
+              q->classes[i].deficit = 0;
+              gnet_stats_basic_sync_init(&q->classes[i].bstats);
+              memset(&q->classes[i].qstats, 0, sizeof(q->classes[i].qstats));
+      }
+      return 0;
+}
+
+Comment:
+This happens because some of the classes have their qdiscs assigned to
+NULL, but remain in the active list. This commit fixes this issue by always
+removing the class from the active list before deleting and freeing its
+associated qdisc
+
+Reproducer Steps
+(trimmed version of what was sent by zdi-disclosures@trendmicro.com)
+
+```
+DEV="${DEV:-lo}"
+ROOT_HANDLE="${ROOT_HANDLE:-1:}"
+BAND2_HANDLE="${BAND2_HANDLE:-20:}"   # child under 1:2
+PING_BYTES="${PING_BYTES:-48}"
+PING_COUNT="${PING_COUNT:-200000}"
+PING_DST="${PING_DST:-127.0.0.1}"
+
+SLOW_TBF_RATE="${SLOW_TBF_RATE:-8bit}"
+SLOW_TBF_BURST="${SLOW_TBF_BURST:-100b}"
+SLOW_TBF_LAT="${SLOW_TBF_LAT:-1s}"
+
+cleanup() {
+  tc qdisc del dev "$DEV" root 2>/dev/null
+}
+trap cleanup EXIT
+
+ip link set "$DEV" up
+
+tc qdisc del dev "$DEV" root 2>/dev/null || true
+
+tc qdisc add dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
+
+tc qdisc add dev "$DEV" parent 1:2 handle "$BAND2_HANDLE" \
+  tbf rate "$SLOW_TBF_RATE" burst "$SLOW_TBF_BURST" latency "$SLOW_TBF_LAT"
+
+tc filter add dev "$DEV" parent 1: protocol all prio 1 u32 match u32 0 0 flowid 1:2
+tc -s qdisc ls dev $DEV
+
+ping -I "$DEV" -f -c "$PING_COUNT" -s "$PING_BYTES" -W 0.001 "$PING_DST" \
+  >/dev/null 2>&1 &
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 0
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
+tc -s qdisc ls dev $DEV
+tc qdisc del dev "$DEV" parent 1:2 || true
+tc -s qdisc ls dev $DEV
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 1 strict 1
+```
+
+KASAN report
+```
+==================================================================
+BUG: KASAN: slab-use-after-free in ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
+Read of size 8 at addr ffff8880502fc018 by task ping/12308
+>
+CPU: 0 UID: 0 PID: 12308 Comm: ping Not tainted 6.18.0-rc4-dirty #1 PREEMPT(full)
+Hardware name: QEMU Ubuntu 25.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <IRQ>
+ __dump_stack kernel/lib/dump_stack.c:94
+ dump_stack_lvl+0x100/0x190 kernel/lib/dump_stack.c:120
+ print_address_description kernel/mm/kasan/report.c:378
+ print_report+0x156/0x4c9 kernel/mm/kasan/report.c:482
+ kasan_report+0xdf/0x110 kernel/mm/kasan/report.c:595
+ ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
+ dequeue_skb kernel/net/sched/sch_generic.c:294
+ qdisc_restart kernel/net/sched/sch_generic.c:399
+ __qdisc_run+0x1c9/0x1b00 kernel/net/sched/sch_generic.c:417
+ __dev_xmit_skb kernel/net/core/dev.c:4221
+ __dev_queue_xmit+0x2848/0x4410 kernel/net/core/dev.c:4729
+ dev_queue_xmit kernel/./include/linux/netdevice.h:3365
+[...]
+
+Allocated by task 17115:
+ kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
+ kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
+ poison_kmalloc_redzone kernel/mm/kasan/common.c:400
+ __kasan_kmalloc+0xaa/0xb0 kernel/mm/kasan/common.c:417
+ kasan_kmalloc kernel/./include/linux/kasan.h:262
+ __do_kmalloc_node kernel/mm/slub.c:5642
+ __kmalloc_node_noprof+0x34e/0x990 kernel/mm/slub.c:5648
+ kmalloc_node_noprof kernel/./include/linux/slab.h:987
+ qdisc_alloc+0xb8/0xc30 kernel/net/sched/sch_generic.c:950
+ qdisc_create_dflt+0x93/0x490 kernel/net/sched/sch_generic.c:1012
+ ets_class_graft+0x4fd/0x800 kernel/net/sched/sch_ets.c:261
+ qdisc_graft+0x3e4/0x1780 kernel/net/sched/sch_api.c:1196
+[...]
+
+Freed by task 9905:
+ kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
+ kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
+ __kasan_save_free_info+0x3b/0x70 kernel/mm/kasan/generic.c:587
+ kasan_save_free_info kernel/mm/kasan/kasan.h:406
+ poison_slab_object kernel/mm/kasan/common.c:252
+ __kasan_slab_free+0x5f/0x80 kernel/mm/kasan/common.c:284
+ kasan_slab_free kernel/./include/linux/kasan.h:234
+ slab_free_hook kernel/mm/slub.c:2539
+ slab_free kernel/mm/slub.c:6630
+ kfree+0x144/0x700 kernel/mm/slub.c:6837
+ rcu_do_batch kernel/kernel/rcu/tree.c:2605
+ rcu_core+0x7c0/0x1500 kernel/kernel/rcu/tree.c:2861
+ handle_softirqs+0x1ea/0x8a0 kernel/kernel/softirq.c:622
+ __do_softirq kernel/kernel/softirq.c:656
+[...]
+
+Commentary:
+
+1. Maher Azzouzi working with Trend Micro Zero Day Initiative was reported as
+the person who found the issue. I requested to get a proper email to add to the
+reported-by tag but got no response. For this reason i will credit the person
+i exchanged emails with i.e zdi-disclosures@trendmicro.com
+
+2. Neither i nor Victor who did a much more thorough testing was able to
+reproduce a UAF with the PoC or other approaches we tried. We were both able to
+reproduce a null ptr deref. After exchange with zdi-disclosures@trendmicro.com
+they sent a small change to be made to the code to add an extra delay which
+was able to simulate the UAF. i.e, this:
+   qdisc_put(q->classes[i].qdisc);
+   mdelay(90);
+   q->classes[i].qdisc = NULL;
+
+I was informed by Thomas Gleixner(tglx@linutronix.de) that adding delays was
+acceptable approach for demonstrating the bug, quote:
+"Adding such delays is common exploit validation practice"
+The equivalent delay could happen "by virt scheduling the vCPU out, SMIs,
+NMIs, PREEMPT_RT enabled kernel"
+
+3. I asked the OP to test and report back but got no response and after a
+few days gave up and proceeded to submit this fix.
+
+Fixes: de6d25924c2a ("net/sched: sch_ets: don't peek at classes beyond 'nbands'")
+Reported-by: zdi-disclosures@trendmicro.com
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20251128151919.576920-1-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_ets.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index 9873f4ae90c3a..b732d09ede99a 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -652,7 +652,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+       sch_tree_lock(sch);
+       for (i = nbands; i < oldbands; i++) {
+-              if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
++              if (cl_is_active(&q->classes[i]))
+                       list_del_init(&q->classes[i].alist);
+               qdisc_purge_queue(q->classes[i].qdisc);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.1/net-sched-ets-remove-drr-class-from-the-active-list-.patch b/queue-6.1/net-sched-ets-remove-drr-class-from-the-active-list-.patch
new file mode 100644 (file)
index 0000000..30faa7d
--- /dev/null
@@ -0,0 +1,88 @@
+From e1e032ab5b9a273c478cf8b203798e23cea96831 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 16:01:24 -0300
+Subject: net/sched: ets: Remove drr class from the active list if it changes
+ to strict
+
+From: Victor Nogueira <victor@mojatatu.com>
+
+[ Upstream commit b1e125ae425aba9b45252e933ca8df52a843ec70 ]
+
+Whenever a user issues an ets qdisc change command, transforming a
+drr class into a strict one, the ets code isn't checking whether that
+class was in the active list and removing it. This means that, if a
+user changes a strict class (which was in the active list) back to a drr
+one, that class will be added twice to the active list [1].
+
+Doing so with the following commands:
+
+tc qdisc add dev lo root handle 1: ets bands 2 strict 1
+tc qdisc add dev lo parent 1:2 handle 20: \
+    tbf rate 8bit burst 100b latency 1s
+tc filter add dev lo parent 1: basic classid 1:2
+ping -c1 -W0.01 -s 56 127.0.0.1
+tc qdisc change dev lo root handle 1: ets bands 2 strict 2
+tc qdisc change dev lo root handle 1: ets bands 2 strict 1
+ping -c1 -W0.01 -s 56 127.0.0.1
+
+Will trigger the following splat with list debug turned on:
+
+[   59.279014][  T365] ------------[ cut here ]------------
+[   59.279452][  T365] list_add double add: new=ffff88801d60e350, prev=ffff88801d60e350, next=ffff88801d60e2c0.
+[   59.280153][  T365] WARNING: CPU: 3 PID: 365 at lib/list_debug.c:35 __list_add_valid_or_report+0x17f/0x220
+[   59.280860][  T365] Modules linked in:
+[   59.281165][  T365] CPU: 3 UID: 0 PID: 365 Comm: tc Not tainted 6.18.0-rc7-00105-g7e9f13163c13-dirty #239 PREEMPT(voluntary)
+[   59.281977][  T365] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+[   59.282391][  T365] RIP: 0010:__list_add_valid_or_report+0x17f/0x220
+[   59.282842][  T365] Code: 89 c6 e8 d4 b7 0d ff 90 0f 0b 90 90 31 c0 e9 31 ff ff ff 90 48 c7 c7 e0 a0 22 9f 48 89 f2 48 89 c1 4c 89 c6 e8 b2 b7 0d ff 90 <0f> 0b 90 90 31 c0 e9 0f ff ff ff 48 89 f7 48 89 44 24 10 4c 89 44
+...
+[   59.288812][  T365] Call Trace:
+[   59.289056][  T365]  <TASK>
+[   59.289224][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.289546][  T365]  ets_qdisc_change+0xd2b/0x1e80
+[   59.289891][  T365]  ? __lock_acquire+0x7e7/0x1be0
+[   59.290223][  T365]  ? __pfx_ets_qdisc_change+0x10/0x10
+[   59.290546][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.290898][  T365]  ? __mutex_trylock_common+0xda/0x240
+[   59.291228][  T365]  ? __pfx___mutex_trylock_common+0x10/0x10
+[   59.291655][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.291993][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.292313][  T365]  ? trace_contention_end+0xc8/0x110
+[   59.292656][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.293022][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.293351][  T365]  tc_modify_qdisc+0x63a/0x1cf0
+
+Fix this by always checking and removing an ets class from the active list
+when changing it to strict.
+
+[1] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/tree/net/sched/sch_ets.c?id=ce052b9402e461a9aded599f5b47e76bc727f7de#n663
+
+Fixes: cd9b50adc6bb9 ("net/sched: ets: fix crash when flipping from 'strict' to 'quantum'")
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/20251208190125.1868423-1-victor@mojatatu.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_ets.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index b732d09ede99a..6ff619277ffd9 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -664,6 +664,10 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+                       q->classes[i].deficit = quanta[i];
+               }
+       }
++      for (i = q->nstrict; i < nstrict; i++) {
++              if (cl_is_active(&q->classes[i]))
++                      list_del_init(&q->classes[i].alist);
++      }
+       WRITE_ONCE(q->nstrict, nstrict);
+       memcpy(q->prio2band, priomap, sizeof(priomap));
+-- 
+2.51.0
+
diff --git a/queue-6.1/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch b/queue-6.1/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch
new file mode 100644 (file)
index 0000000..7fb0a38
--- /dev/null
@@ -0,0 +1,90 @@
+From a3a4e4576deabf2366a38931c1b22a019802fc4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 12:58:01 +0100
+Subject: netfilter: nf_conncount: fix leaked ct in error paths
+
+From: Fernando Fernandez Mancera <fmancera@suse.de>
+
+[ Upstream commit 2e2a720766886190a6d35c116794693aabd332b6 ]
+
+There are some situations where ct might be leaked as error paths are
+skipping the refcounted check and return immediately. In order to solve
+it make sure that the check is always called.
+
+Fixes: be102eb6a0e7 ("netfilter: nf_conncount: rework API to use sk_buff directly")
+Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conncount.c | 25 ++++++++++++++-----------
+ 1 file changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
+index 97b631a81484d..c00b8e522c5a7 100644
+--- a/net/netfilter/nf_conncount.c
++++ b/net/netfilter/nf_conncount.c
+@@ -172,14 +172,14 @@ static int __nf_conncount_add(struct net *net,
+       struct nf_conn *found_ct;
+       unsigned int collect = 0;
+       bool refcounted = false;
++      int err = 0;
+       if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted))
+               return -ENOENT;
+       if (ct && nf_ct_is_confirmed(ct)) {
+-              if (refcounted)
+-                      nf_ct_put(ct);
+-              return -EEXIST;
++              err = -EEXIST;
++              goto out_put;
+       }
+       if ((u32)jiffies == list->last_gc)
+@@ -231,12 +231,16 @@ static int __nf_conncount_add(struct net *net,
+       }
+ add_new_node:
+-      if (WARN_ON_ONCE(list->count > INT_MAX))
+-              return -EOVERFLOW;
++      if (WARN_ON_ONCE(list->count > INT_MAX)) {
++              err = -EOVERFLOW;
++              goto out_put;
++      }
+       conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC);
+-      if (conn == NULL)
+-              return -ENOMEM;
++      if (conn == NULL) {
++              err = -ENOMEM;
++              goto out_put;
++      }
+       conn->tuple = tuple;
+       conn->zone = *zone;
+@@ -249,7 +253,7 @@ static int __nf_conncount_add(struct net *net,
+ out_put:
+       if (refcounted)
+               nf_ct_put(ct);
+-      return 0;
++      return err;
+ }
+ int nf_conncount_add_skb(struct net *net,
+@@ -446,11 +450,10 @@ insert_tree(struct net *net,
+               rb_link_node_rcu(&rbconn->node, parent, rbnode);
+               rb_insert_color(&rbconn->node, root);
+-
+-              if (refcounted)
+-                      nf_ct_put(ct);
+       }
+ out_unlock:
++      if (refcounted)
++              nf_ct_put(ct);
+       spin_unlock_bh(&nf_conncount_locks[hash]);
+       return count;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.1/netrom-fix-memory-leak-in-nr_sendmsg.patch b/queue-6.1/netrom-fix-memory-leak-in-nr_sendmsg.patch
new file mode 100644 (file)
index 0000000..5de6443
--- /dev/null
@@ -0,0 +1,74 @@
+From 22bf9575987cf8ff72992b14f4bafa69f592f6da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Nov 2025 12:13:15 +0800
+Subject: netrom: Fix memory leak in nr_sendmsg()
+
+From: Wang Liang <wangliang74@huawei.com>
+
+[ Upstream commit 613d12dd794e078be8ff3cf6b62a6b9acf7f4619 ]
+
+syzbot reported a memory leak [1].
+
+When function sock_alloc_send_skb() return NULL in nr_output(), the
+original skb is not freed, which was allocated in nr_sendmsg(). Fix this
+by freeing it before return.
+
+[1]
+BUG: memory leak
+unreferenced object 0xffff888129f35500 (size 240):
+  comm "syz.0.17", pid 6119, jiffies 4294944652
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+    00 00 00 00 00 00 00 00 00 10 52 28 81 88 ff ff  ..........R(....
+  backtrace (crc 1456a3e4):
+    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
+    slab_post_alloc_hook mm/slub.c:4983 [inline]
+    slab_alloc_node mm/slub.c:5288 [inline]
+    kmem_cache_alloc_node_noprof+0x36f/0x5e0 mm/slub.c:5340
+    __alloc_skb+0x203/0x240 net/core/skbuff.c:660
+    alloc_skb include/linux/skbuff.h:1383 [inline]
+    alloc_skb_with_frags+0x69/0x3f0 net/core/skbuff.c:6671
+    sock_alloc_send_pskb+0x379/0x3e0 net/core/sock.c:2965
+    sock_alloc_send_skb include/net/sock.h:1859 [inline]
+    nr_sendmsg+0x287/0x450 net/netrom/af_netrom.c:1105
+    sock_sendmsg_nosec net/socket.c:727 [inline]
+    __sock_sendmsg net/socket.c:742 [inline]
+    sock_write_iter+0x293/0x2a0 net/socket.c:1195
+    new_sync_write fs/read_write.c:593 [inline]
+    vfs_write+0x45d/0x710 fs/read_write.c:686
+    ksys_write+0x143/0x170 fs/read_write.c:738
+    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+    do_syscall_64+0xa4/0xfa0 arch/x86/entry/syscall_64.c:94
+    entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Reported-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=d7abc36bbbb6d7d40b58
+Tested-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Wang Liang <wangliang74@huawei.com>
+Link: https://patch.msgid.link/20251129041315.1550766-1-wangliang74@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netrom/nr_out.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/netrom/nr_out.c b/net/netrom/nr_out.c
+index 5e531394a724b..2b3cbceb0b52d 100644
+--- a/net/netrom/nr_out.c
++++ b/net/netrom/nr_out.c
+@@ -43,8 +43,10 @@ void nr_output(struct sock *sk, struct sk_buff *skb)
+               frontlen = skb_headroom(skb);
+               while (skb->len > 0) {
+-                      if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL)
++                      if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL) {
++                              kfree_skb(skb);
+                               return;
++                      }
+                       skb_reserve(skbn, frontlen);
+-- 
+2.51.0
+
diff --git a/queue-6.1/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch b/queue-6.1/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch
new file mode 100644 (file)
index 0000000..e087930
--- /dev/null
@@ -0,0 +1,37 @@
+From 20e038b89ffdf75033031de4a9e483bc363bbcb1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 09:56:39 +0300
+Subject: nfc: pn533: Fix error code in pn533_acr122_poweron_rdr()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 885bebac9909994050bbbeed0829c727e42bd1b7 ]
+
+Set the error code if "transferred != sizeof(cmd)" instead of
+returning success.
+
+Fixes: dbafc28955fa ("NFC: pn533: don't send USB data off of the stack")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/aTfIJ9tZPmeUF4W1@stanley.mountain
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/pn533/usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c
+index a187f0e0b0f7d..9e079be43583e 100644
+--- a/drivers/nfc/pn533/usb.c
++++ b/drivers/nfc/pn533/usb.c
+@@ -407,7 +407,7 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy)
+       if (rc || (transferred != sizeof(cmd))) {
+               nfc_err(&phy->udev->dev,
+                       "Reader power on cmd error %d\n", rc);
+-              return rc;
++              return rc ?: -EINVAL;
+       }
+       rc =  usb_submit_urb(phy->in_urb, GFP_KERNEL);
+-- 
+2.51.0
+
index 5465e73a07328b75fdb9ba99c60ff11f9b381b61..742c94f02e2909c71095dcd4bc15887649687acd 100644 (file)
@@ -245,3 +245,27 @@ smb-server-fix-return-value-of-smb2_ioctl.patch
 ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch
 bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch
 gfs2-fix-use-of-bio_chain.patch
 ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-u.patch
 bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch
 gfs2-fix-use-of-bio_chain.patch
+netrom-fix-memory-leak-in-nr_sendmsg.patch
+net-sched-ets-always-remove-class-from-active-list-b.patch
+ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch
+mlxsw-spectrum_router-fix-neighbour-use-after-free.patch
+mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch
+net-openvswitch-fix-middle-attribute-validation-in-p.patch
+broadcom-b44-prevent-uninitialized-value-usage.patch
+netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch
+ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch
+caif-fix-integer-underflow-in-cffrml_receive.patch
+net-sched-ets-remove-drr-class-from-the-active-list-.patch
+nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch
+net-ethtool-ioctl-remove-if-n_stats-checks-from-etht.patch
+net-ethtool-ioctl-split-ethtool_get_phy_stats-into-m.patch
+ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch
+net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch
+net-mlx5-create-a-new-profile-for-sfs.patch
+net-mlx5-drain-firmware-reset-in-shutdown-callback.patch
+net-mlx5-fw_tracer-add-support-for-unrecognized-stri.patch
+net-mlx5-fw_tracer-validate-format-string-parameters.patch
+net-mlx5-fw_tracer-handle-escaped-percent-properly.patch
+net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch
+net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch
+net-hns3-add-vlan-id-validation-before-using.patch
diff --git a/queue-6.12/bnxt_en-fix-xdp_tx-path.patch b/queue-6.12/bnxt_en-fix-xdp_tx-path.patch
new file mode 100644 (file)
index 0000000..3b74fed
--- /dev/null
@@ -0,0 +1,74 @@
+From cd9c6fc2ac9e6ac2af40f7db86a994d8241d72eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 16:30:24 -0800
+Subject: bnxt_en: Fix XDP_TX path
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit 0373d5c387f24de749cc22e694a14b3a7c7eb515 ]
+
+For XDP_TX action in bnxt_rx_xdp(), clearing of the event flags is not
+correct.  __bnxt_poll_work() -> bnxt_rx_pkt() -> bnxt_rx_xdp() may be
+looping within NAPI and some event flags may be set in earlier
+iterations.  In particular, if BNXT_TX_EVENT is set earlier indicating
+some XDP_TX packets are ready and pending, it will be cleared if it is
+XDP_TX action again.  Normally, we will set BNXT_TX_EVENT again when we
+successfully call __bnxt_xmit_xdp().  But if the TX ring has no more
+room, the flag will not be set.  This will cause the TX producer to be
+ahead but the driver will not hit the TX doorbell.
+
+For multi-buf XDP_TX, there is no need to clear the event flags and set
+BNXT_AGG_EVENT.  The BNXT_AGG_EVENT flag should have been set earlier in
+bnxt_rx_pkt().
+
+The visible symptom of this is that the RX ring associated with the
+TX XDP ring will eventually become empty and all packets will be dropped.
+Because this condition will cause the driver to not refill the RX ring
+seeing that the TX ring has forever pending XDP_TX packets.
+
+The fix is to only clear BNXT_RX_EVENT when we have successfully
+called __bnxt_xmit_xdp().
+
+Fixes: 7f0a168b0441 ("bnxt_en: Add completion ring pointer in TX and RX ring structures")
+Reported-by: Pavel Dubovitsky <pdubovitsky@meta.com>
+Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
+Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20251203003024.2246699-1-michael.chan@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+index 844812bd65363..fa3c6515cc4d6 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+@@ -268,13 +268,11 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
+       case XDP_TX:
+               rx_buf = &rxr->rx_buf_ring[cons];
+               mapping = rx_buf->mapping - bp->rx_dma_offset;
+-              *event &= BNXT_TX_CMP_EVENT;
+               if (unlikely(xdp_buff_has_frags(xdp))) {
+                       struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);
+                       tx_needed += sinfo->nr_frags;
+-                      *event = BNXT_AGG_EVENT;
+               }
+               if (tx_avail < tx_needed) {
+@@ -287,6 +285,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
+               dma_sync_single_for_device(&pdev->dev, mapping + offset, *len,
+                                          bp->rx_dir);
++              *event &= ~BNXT_RX_EVENT;
+               *event |= BNXT_TX_EVENT;
+               __bnxt_xmit_xdp(bp, txr, mapping + offset, *len,
+                               NEXT_RX(rxr->rx_prod), xdp);
+-- 
+2.51.0
+
diff --git a/queue-6.12/broadcom-b44-prevent-uninitialized-value-usage.patch b/queue-6.12/broadcom-b44-prevent-uninitialized-value-usage.patch
new file mode 100644 (file)
index 0000000..ac9d7eb
--- /dev/null
@@ -0,0 +1,45 @@
+From 8b63725595f550cbf34418aab9f77b155c88fb46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 18:58:16 +0300
+Subject: broadcom: b44: prevent uninitialized value usage
+
+From: Alexey Simakov <bigalex934@gmail.com>
+
+[ Upstream commit 50b3db3e11864cb4e18ff099cfb38e11e7f87a68 ]
+
+On execution path with raised B44_FLAG_EXTERNAL_PHY, b44_readphy()
+leaves bmcr value uninitialized and it is used later in the code.
+
+Add check of this flag at the beginning of the b44_nway_reset() and
+exit early of the function with restarting autonegotiation if an
+external PHY is used.
+
+Fixes: 753f492093da ("[B44]: port to native ssb support")
+Reviewed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Alexey Simakov <bigalex934@gmail.com>
+Reviewed-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20251205155815.4348-1-bigalex934@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/b44.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
+index e5809ad5eb827..29f0de9e31545 100644
+--- a/drivers/net/ethernet/broadcom/b44.c
++++ b/drivers/net/ethernet/broadcom/b44.c
+@@ -1789,6 +1789,9 @@ static int b44_nway_reset(struct net_device *dev)
+       u32 bmcr;
+       int r;
++      if (bp->flags & B44_FLAG_EXTERNAL_PHY)
++              return phy_ethtool_nway_reset(dev);
++
+       spin_lock_irq(&bp->lock);
+       b44_readphy(bp, MII_BMCR, &bmcr);
+       b44_readphy(bp, MII_BMCR, &bmcr);
+-- 
+2.51.0
+
diff --git a/queue-6.12/caif-fix-integer-underflow-in-cffrml_receive.patch b/queue-6.12/caif-fix-integer-underflow-in-cffrml_receive.patch
new file mode 100644 (file)
index 0000000..37cfa07
--- /dev/null
@@ -0,0 +1,58 @@
+From 412acda7a1994d5217023c1330cf182c056a02c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Dec 2025 21:30:47 +0800
+Subject: caif: fix integer underflow in cffrml_receive()
+
+From: Junrui Luo <moonafterrain@outlook.com>
+
+[ Upstream commit 8a11ff0948b5ad09b71896b7ccc850625f9878d1 ]
+
+The cffrml_receive() function extracts a length field from the packet
+header and, when FCS is disabled, subtracts 2 from this length without
+validating that len >= 2.
+
+If an attacker sends a malicious packet with a length field of 0 or 1
+to an interface with FCS disabled, the subtraction causes an integer
+underflow.
+
+This can lead to memory exhaustion and kernel instability, potential
+information disclosure if padding contains uninitialized kernel memory.
+
+Fix this by validating that len >= 2 before performing the subtraction.
+
+Reported-by: Yuhao Jiang <danisjiang@gmail.com>
+Reported-by: Junrui Luo <moonafterrain@outlook.com>
+Fixes: b482cd2053e3 ("net-caif: add CAIF core protocol stack")
+Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/SYBPR01MB7881511122BAFEA8212A1608AFA6A@SYBPR01MB7881.ausprd01.prod.outlook.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/caif/cffrml.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c
+index 6651a8dc62e04..d4d63586053ad 100644
+--- a/net/caif/cffrml.c
++++ b/net/caif/cffrml.c
+@@ -92,8 +92,15 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
+       len = le16_to_cpu(tmp);
+       /* Subtract for FCS on length if FCS is not used. */
+-      if (!this->dofcs)
++      if (!this->dofcs) {
++              if (len < 2) {
++                      ++cffrml_rcv_error;
++                      pr_err("Invalid frame length (%d)\n", len);
++                      cfpkt_destroy(pkt);
++                      return -EPROTO;
++              }
+               len -= 2;
++      }
+       if (cfpkt_setlen(pkt, len) < 0) {
+               ++cffrml_rcv_error;
+-- 
+2.51.0
+
diff --git a/queue-6.12/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch b/queue-6.12/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch
new file mode 100644 (file)
index 0000000..0662132
--- /dev/null
@@ -0,0 +1,159 @@
+From e525981fac6bfe534128bfc18a6e5f08d289dd53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 14:19:01 +0200
+Subject: ethtool: Avoid overflowing userspace buffer on stats query
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 7b07be1ff1cb6c49869910518650e8d0abc7d25f ]
+
+The ethtool -S command operates across three ioctl calls:
+ETHTOOL_GSSET_INFO for the size, ETHTOOL_GSTRINGS for the names, and
+ETHTOOL_GSTATS for the values.
+
+If the number of stats changes between these calls (e.g., due to device
+reconfiguration), userspace's buffer allocation will be incorrect,
+potentially leading to buffer overflow.
+
+Drivers are generally expected to maintain stable stat counts, but some
+drivers (e.g., mlx5, bnx2x, bna, ksz884x) use dynamic counters, making
+this scenario possible.
+
+Some drivers try to handle this internally:
+- bnad_get_ethtool_stats() returns early in case stats.n_stats is not
+  equal to the driver's stats count.
+- micrel/ksz884x also makes sure not to write anything beyond
+  stats.n_stats and overflow the buffer.
+
+However, both use stats.n_stats which is already assigned with the value
+returned from get_sset_count(), hence won't solve the issue described
+here.
+
+Change ethtool_get_strings(), ethtool_get_stats(),
+ethtool_get_phy_stats() to not return anything in case of a mismatch
+between userspace's size and get_sset_size(), to prevent buffer
+overflow.
+The returned n_stats value will be equal to zero, to reflect that
+nothing has been returned.
+
+This could result in one of two cases when using upstream ethtool,
+depending on when the size change is detected:
+1. When detected in ethtool_get_strings():
+    # ethtool -S eth2
+    no stats available
+
+2. When detected in get stats, all stats will be reported as zero.
+
+Both cases are presumably transient, and a subsequent ethtool call
+should succeed.
+
+Other than the overflow avoidance, these two cases are very evident (no
+output/cleared stats), which is arguably better than presenting
+incorrect/shifted stats.
+I also considered returning an error instead of a "silent" response, but
+that seems more destructive towards userspace apps.
+
+Notes:
+- This patch does not claim to fix the inherent race, it only makes sure
+  that we do not overflow the userspace buffer, and makes for a more
+  predictable behavior.
+
+- RTNL lock is held during each ioctl, the race window exists between
+  the separate ioctl calls when the lock is released.
+
+- Userspace ethtool always fills stats.n_stats, but it is likely that
+  these stats ioctls are implemented in other userspace applications
+  which might not fill it. The added code checks that it's not zero,
+  to prevent any regressions.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Link: https://patch.msgid.link/20251208121901.3203692-1-gal@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 30 ++++++++++++++++++++++++------
+ 1 file changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 8b9692c35e706..67fba88f60984 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -2231,7 +2231,10 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
+               return -ENOMEM;
+       WARN_ON_ONCE(!ret);
+-      gstrings.len = ret;
++      if (gstrings.len && gstrings.len != ret)
++              gstrings.len = 0;
++      else
++              gstrings.len = ret;
+       if (gstrings.len) {
+               data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
+@@ -2353,10 +2356,13 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       if (copy_from_user(&stats, useraddr, sizeof(stats)))
+               return -EFAULT;
+-      stats.n_stats = n_stats;
++      if (stats.n_stats && stats.n_stats != n_stats)
++              stats.n_stats = 0;
++      else
++              stats.n_stats = n_stats;
+-      if (n_stats) {
+-              data = vzalloc(array_size(n_stats, sizeof(u64)));
++      if (stats.n_stats) {
++              data = vzalloc(array_size(stats.n_stats, sizeof(u64)));
+               if (!data)
+                       return -ENOMEM;
+               ops->get_ethtool_stats(dev, &stats, data);
+@@ -2368,7 +2374,9 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       if (copy_to_user(useraddr, &stats, sizeof(stats)))
+               goto out;
+       useraddr += sizeof(stats);
+-      if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
++      if (stats.n_stats &&
++          copy_to_user(useraddr, data,
++                       array_size(stats.n_stats, sizeof(u64))))
+               goto out;
+       ret = 0;
+@@ -2404,6 +2412,10 @@ static int ethtool_get_phy_stats_phydev(struct phy_device *phydev,
+               return -EOPNOTSUPP;
+       n_stats = phy_ops->get_sset_count(phydev);
++      if (stats->n_stats && stats->n_stats != n_stats) {
++              stats->n_stats = 0;
++              return 0;
++      }
+       ret = ethtool_vzalloc_stats_array(n_stats, data);
+       if (ret)
+@@ -2424,6 +2436,10 @@ static int ethtool_get_phy_stats_ethtool(struct net_device *dev,
+               return -EOPNOTSUPP;
+       n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
++      if (stats->n_stats && stats->n_stats != n_stats) {
++              stats->n_stats = 0;
++              return 0;
++      }
+       ret = ethtool_vzalloc_stats_array(n_stats, data);
+       if (ret)
+@@ -2460,7 +2476,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       }
+       useraddr += sizeof(stats);
+-      if (copy_to_user(useraddr, data, array_size(stats.n_stats, sizeof(u64))))
++      if (stats.n_stats &&
++          copy_to_user(useraddr, data,
++                       array_size(stats.n_stats, sizeof(u64))))
+               ret = -EFAULT;
+  out:
+-- 
+2.51.0
+
diff --git a/queue-6.12/iommufd-selftest-add-coverage-for-reporting-max_pasi.patch b/queue-6.12/iommufd-selftest-add-coverage-for-reporting-max_pasi.patch
new file mode 100644 (file)
index 0000000..c638b43
--- /dev/null
@@ -0,0 +1,153 @@
+From 383b6ebedeaa085892b94ce2a66d1550321d093f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 11:01:43 -0700
+Subject: iommufd/selftest: Add coverage for reporting max_pasid_log2 via
+ IOMMU_HW_INFO
+
+From: Yi Liu <yi.l.liu@intel.com>
+
+[ Upstream commit 6d9500bb1ff8c7f9c3ce199521c41aa41e8fd994 ]
+
+IOMMU_HW_INFO is extended to report max_pasid_log2, hence add coverage
+for it.
+
+Link: https://patch.msgid.link/r/20250321180143.8468-6-yi.l.liu@intel.com
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Signed-off-by: Yi Liu <yi.l.liu@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Stable-dep-of: 5b244b077c0b ("iommufd/selftest: Make it clearer to gcc that the access is not out of bounds")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/iommu/iommufd.c        | 18 ++++++++++++++++++
+ .../testing/selftests/iommu/iommufd_fail_nth.c |  3 ++-
+ tools/testing/selftests/iommu/iommufd_utils.h  | 17 +++++++++++++----
+ 3 files changed, 33 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
+index 7a535c590245f..92c6020c15fa1 100644
+--- a/tools/testing/selftests/iommu/iommufd.c
++++ b/tools/testing/selftests/iommu/iommufd.c
+@@ -194,12 +194,14 @@ FIXTURE(iommufd_ioas)
+       uint32_t hwpt_id;
+       uint32_t device_id;
+       uint64_t base_iova;
++      uint32_t device_pasid_id;
+ };
+ FIXTURE_VARIANT(iommufd_ioas)
+ {
+       unsigned int mock_domains;
+       unsigned int memory_limit;
++      bool pasid_capable;
+ };
+ FIXTURE_SETUP(iommufd_ioas)
+@@ -222,6 +224,12 @@ FIXTURE_SETUP(iommufd_ioas)
+                                    &self->hwpt_id, &self->device_id);
+               self->base_iova = MOCK_APERTURE_START;
+       }
++
++      if (variant->pasid_capable)
++              test_cmd_mock_domain_flags(self->ioas_id,
++                                         MOCK_FLAGS_DEVICE_PASID,
++                                         NULL, NULL,
++                                         &self->device_pasid_id);
+ }
+ FIXTURE_TEARDOWN(iommufd_ioas)
+@@ -237,6 +245,7 @@ FIXTURE_VARIANT_ADD(iommufd_ioas, no_domain)
+ FIXTURE_VARIANT_ADD(iommufd_ioas, mock_domain)
+ {
+       .mock_domains = 1,
++      .pasid_capable = true,
+ };
+ FIXTURE_VARIANT_ADD(iommufd_ioas, two_mock_domain)
+@@ -602,6 +611,8 @@ TEST_F(iommufd_ioas, get_hw_info)
+       } buffer_smaller;
+       if (self->device_id) {
++              uint8_t max_pasid = 0;
++
+               /* Provide a zero-size user_buffer */
+               test_cmd_get_hw_info(self->device_id, NULL, 0);
+               /* Provide a user_buffer with exact size */
+@@ -616,6 +627,13 @@ TEST_F(iommufd_ioas, get_hw_info)
+                * the fields within the size range still gets updated.
+                */
+               test_cmd_get_hw_info(self->device_id, &buffer_smaller, sizeof(buffer_smaller));
++              test_cmd_get_hw_info_pasid(self->device_id, &max_pasid);
++              ASSERT_EQ(0, max_pasid);
++              if (variant->pasid_capable) {
++                      test_cmd_get_hw_info_pasid(self->device_pasid_id,
++                                                 &max_pasid);
++                      ASSERT_EQ(MOCK_PASID_WIDTH, max_pasid);
++              }
+       } else {
+               test_err_get_hw_info(ENOENT, self->device_id,
+                                    &buffer_exact, sizeof(buffer_exact));
+diff --git a/tools/testing/selftests/iommu/iommufd_fail_nth.c b/tools/testing/selftests/iommu/iommufd_fail_nth.c
+index c5d5e69452b01..62d02556b34cc 100644
+--- a/tools/testing/selftests/iommu/iommufd_fail_nth.c
++++ b/tools/testing/selftests/iommu/iommufd_fail_nth.c
+@@ -612,7 +612,8 @@ TEST_FAIL_NTH(basic_fail_nth, device)
+                                 &idev_id))
+               return -1;
+-      if (_test_cmd_get_hw_info(self->fd, idev_id, &info, sizeof(info), NULL))
++      if (_test_cmd_get_hw_info(self->fd, idev_id, &info,
++                                sizeof(info), NULL, NULL))
+               return -1;
+       if (_test_cmd_hwpt_alloc(self->fd, idev_id, ioas_id, 0, 0, &hwpt_id,
+diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h
+index 40f6f14ce136f..8994b43e86f89 100644
+--- a/tools/testing/selftests/iommu/iommufd_utils.h
++++ b/tools/testing/selftests/iommu/iommufd_utils.h
+@@ -638,7 +638,8 @@ static void teardown_iommufd(int fd, struct __test_metadata *_metadata)
+ /* @data can be NULL */
+ static int _test_cmd_get_hw_info(int fd, __u32 device_id, void *data,
+-                               size_t data_len, uint32_t *capabilities)
++                               size_t data_len, uint32_t *capabilities,
++                               uint8_t *max_pasid)
+ {
+       struct iommu_test_hw_info *info = (struct iommu_test_hw_info *)data;
+       struct iommu_hw_info cmd = {
+@@ -683,6 +684,9 @@ static int _test_cmd_get_hw_info(int fd, __u32 device_id, void *data,
+                       assert(!info->flags);
+       }
++      if (max_pasid)
++              *max_pasid = cmd.out_max_pasid_log2;
++
+       if (capabilities)
+               *capabilities = cmd.out_capabilities;
+@@ -691,14 +695,19 @@ static int _test_cmd_get_hw_info(int fd, __u32 device_id, void *data,
+ #define test_cmd_get_hw_info(device_id, data, data_len)               \
+       ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, data, \
+-                                         data_len, NULL))
++                                         data_len, NULL, NULL))
+ #define test_err_get_hw_info(_errno, device_id, data, data_len)               \
+       EXPECT_ERRNO(_errno, _test_cmd_get_hw_info(self->fd, device_id, data, \
+-                                                 data_len, NULL))
++                                                 data_len, NULL, NULL))
+ #define test_cmd_get_hw_capabilities(device_id, caps, mask) \
+-      ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, NULL, 0, &caps))
++      ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, NULL, \
++                                         0, &caps, NULL))
++
++#define test_cmd_get_hw_info_pasid(device_id, max_pasid)              \
++      ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, NULL, \
++                                         0, NULL, max_pasid))
+ static int _test_ioctl_fault_alloc(int fd, __u32 *fault_id, __u32 *fault_fd)
+ {
+-- 
+2.51.0
+
diff --git a/queue-6.12/iommufd-selftest-check-for-overflow-in-iommu_test_op.patch b/queue-6.12/iommufd-selftest-check-for-overflow-in-iommu_test_op.patch
new file mode 100644 (file)
index 0000000..793c85e
--- /dev/null
@@ -0,0 +1,57 @@
+From 8636abbbf8eb295e774b51690bf38718de203e61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Dec 2025 11:53:40 -0400
+Subject: iommufd/selftest: Check for overflow in IOMMU_TEST_OP_ADD_RESERVED
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit e6a973af11135439de32ece3b9cbe3bfc043bea8 ]
+
+syzkaller found it could overflow math in the test infrastructure and
+cause a WARN_ON by corrupting the reserved interval tree. This only
+effects test kernels with CONFIG_IOMMUFD_TEST.
+
+Validate the user input length in the test ioctl.
+
+Fixes: f4b20bb34c83 ("iommufd: Add kernel support for testing iommufd")
+Link: https://patch.msgid.link/r/0-v1-cd99f6049ba5+51-iommufd_syz_add_resv_jgg@nvidia.com
+Reviewed-by: Samiullah Khawaja <skhawaja@google.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Tested-by: Yi Liu <yi.l.liu@intel.com>
+Reported-by: syzbot+57fdb0cf6a0c5d1f15a2@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/69368129.a70a0220.38f243.008f.GAE@google.com
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/iommufd/selftest.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
+index 540437be168a0..aed260d4a93cc 100644
+--- a/drivers/iommu/iommufd/selftest.c
++++ b/drivers/iommu/iommufd/selftest.c
+@@ -836,14 +836,20 @@ static int iommufd_test_add_reserved(struct iommufd_ucmd *ucmd,
+                                    unsigned int mockpt_id,
+                                    unsigned long start, size_t length)
+ {
++      unsigned long last;
+       struct iommufd_ioas *ioas;
+       int rc;
++      if (!length)
++              return -EINVAL;
++      if (check_add_overflow(start, length - 1, &last))
++              return -EOVERFLOW;
++
+       ioas = iommufd_get_ioas(ucmd->ictx, mockpt_id);
+       if (IS_ERR(ioas))
+               return PTR_ERR(ioas);
+       down_write(&ioas->iopt.iova_rwsem);
+-      rc = iopt_reserve_iova(&ioas->iopt, start, start + length - 1, NULL);
++      rc = iopt_reserve_iova(&ioas->iopt, start, last, NULL);
+       up_write(&ioas->iopt.iova_rwsem);
+       iommufd_put_object(ucmd->ictx, &ioas->obj);
+       return rc;
+-- 
+2.51.0
+
diff --git a/queue-6.12/iommufd-selftest-make-it-clearer-to-gcc-that-the-acc.patch b/queue-6.12/iommufd-selftest-make-it-clearer-to-gcc-that-the-acc.patch
new file mode 100644 (file)
index 0000000..355e4ed
--- /dev/null
@@ -0,0 +1,71 @@
+From 0f45c64ae033edbe6672097a864f3f22cf725ee7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 14:56:12 -0400
+Subject: iommufd/selftest: Make it clearer to gcc that the access is not out
+ of bounds
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit 5b244b077c0b0e76573fbb9542cf038e42368901 ]
+
+GCC gets a bit confused and reports:
+
+   In function '_test_cmd_get_hw_info',
+       inlined from 'iommufd_ioas_get_hw_info' at iommufd.c:779:3,
+       inlined from 'wrapper_iommufd_ioas_get_hw_info' at iommufd.c:752:1:
+>> iommufd_utils.h:804:37: warning: array subscript 'struct iommu_test_hw_info[0]' is partly outside array bounds of 'struct iommu_test_hw_info_buffer_smaller[1]' [-Warray-bounds=]
+     804 |                         assert(!info->flags);
+         |                                 ~~~~^~~~~~~
+   iommufd.c: In function 'wrapper_iommufd_ioas_get_hw_info':
+   iommufd.c:761:11: note: object 'buffer_smaller' of size 4
+     761 |         } buffer_smaller;
+         |           ^~~~~~~~~~~~~~
+
+While it is true that "struct iommu_test_hw_info[0]" is partly out of
+bounds of the input pointer, it is not true that info->flags is out of
+bounds. Unclear why it warns on this.
+
+Reuse an existing properly sized stack buffer and pass a truncated length
+instead to test the same thing.
+
+Fixes: af4fde93c319 ("iommufd/selftest: Add coverage for IOMMU_GET_HW_INFO ioctl")
+Link: https://patch.msgid.link/r/0-v1-63a2cffb09da+4486-iommufd_gcc_bounds_jgg@nvidia.com
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202512032344.kaAcKFIM-lkp@intel.com/
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/iommu/iommufd.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
+index b678b24f5a142..6f99268365338 100644
+--- a/tools/testing/selftests/iommu/iommufd.c
++++ b/tools/testing/selftests/iommu/iommufd.c
+@@ -606,9 +606,6 @@ TEST_F(iommufd_ioas, get_hw_info)
+               struct iommu_test_hw_info info;
+               uint64_t trailing_bytes;
+       } buffer_larger;
+-      struct iommu_test_hw_info_buffer_smaller {
+-              __u32 flags;
+-      } buffer_smaller;
+       if (self->device_id) {
+               uint8_t max_pasid = 0;
+@@ -640,8 +637,9 @@ TEST_F(iommufd_ioas, get_hw_info)
+                * the fields within the size range still gets updated.
+                */
+               test_cmd_get_hw_info(self->device_id,
+-                                   IOMMU_HW_INFO_TYPE_DEFAULT,
+-                                   &buffer_smaller, sizeof(buffer_smaller));
++                                   IOMMU_HW_INFO_TYPE_DEFAULT, &buffer_exact,
++                                   offsetofend(struct iommu_test_hw_info,
++                                               flags));
+               test_cmd_get_hw_info_pasid(self->device_id, &max_pasid);
+               ASSERT_EQ(0, max_pasid);
+               if (variant->pasid_capable) {
+-- 
+2.51.0
+
diff --git a/queue-6.12/iommufd-selftest-update-hw_info-coverage-for-an-inpu.patch b/queue-6.12/iommufd-selftest-update-hw_info-coverage-for-an-inpu.patch
new file mode 100644 (file)
index 0000000..03ae3a5
--- /dev/null
@@ -0,0 +1,178 @@
+From de34aee69f711f64029e423284bf055c7aa6100f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jul 2025 22:59:14 -0700
+Subject: iommufd/selftest: Update hw_info coverage for an input data_type
+
+From: Nicolin Chen <nicolinc@nvidia.com>
+
+[ Upstream commit 3a35f7d4a4673edf6f02422bb2d78b17c667e167 ]
+
+Test both IOMMU_HW_INFO_TYPE_DEFAULT and IOMMU_HW_INFO_TYPE_SELFTEST, and
+add a negative test for an unsupported type.
+
+Also drop the unused mask in test_cmd_get_hw_capabilities() as checkpatch
+is complaining.
+
+Link: https://patch.msgid.link/r/f01a1e50cd7366f217cbf192ad0b2b79e0eb89f0.1752126748.git.nicolinc@nvidia.com
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Pranjal Shrivastava <praan@google.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Stable-dep-of: 5b244b077c0b ("iommufd/selftest: Make it clearer to gcc that the access is not out of bounds")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/iommu/iommufd.c       | 32 +++++++++++++-----
+ .../selftests/iommu/iommufd_fail_nth.c        |  4 +--
+ tools/testing/selftests/iommu/iommufd_utils.h | 33 +++++++++++--------
+ 3 files changed, 46 insertions(+), 23 deletions(-)
+
+diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
+index 92c6020c15fa1..b678b24f5a142 100644
+--- a/tools/testing/selftests/iommu/iommufd.c
++++ b/tools/testing/selftests/iommu/iommufd.c
+@@ -614,19 +614,34 @@ TEST_F(iommufd_ioas, get_hw_info)
+               uint8_t max_pasid = 0;
+               /* Provide a zero-size user_buffer */
+-              test_cmd_get_hw_info(self->device_id, NULL, 0);
++              test_cmd_get_hw_info(self->device_id,
++                                   IOMMU_HW_INFO_TYPE_DEFAULT, NULL, 0);
+               /* Provide a user_buffer with exact size */
+-              test_cmd_get_hw_info(self->device_id, &buffer_exact, sizeof(buffer_exact));
++              test_cmd_get_hw_info(self->device_id,
++                                   IOMMU_HW_INFO_TYPE_DEFAULT, &buffer_exact,
++                                   sizeof(buffer_exact));
++
++              /* Request for a wrong data_type, and a correct one */
++              test_err_get_hw_info(EOPNOTSUPP, self->device_id,
++                                   IOMMU_HW_INFO_TYPE_SELFTEST + 1,
++                                   &buffer_exact, sizeof(buffer_exact));
++              test_cmd_get_hw_info(self->device_id,
++                                   IOMMU_HW_INFO_TYPE_SELFTEST, &buffer_exact,
++                                   sizeof(buffer_exact));
+               /*
+                * Provide a user_buffer with size larger than the exact size to check if
+                * kernel zero the trailing bytes.
+                */
+-              test_cmd_get_hw_info(self->device_id, &buffer_larger, sizeof(buffer_larger));
++              test_cmd_get_hw_info(self->device_id,
++                                   IOMMU_HW_INFO_TYPE_DEFAULT, &buffer_larger,
++                                   sizeof(buffer_larger));
+               /*
+                * Provide a user_buffer with size smaller than the exact size to check if
+                * the fields within the size range still gets updated.
+                */
+-              test_cmd_get_hw_info(self->device_id, &buffer_smaller, sizeof(buffer_smaller));
++              test_cmd_get_hw_info(self->device_id,
++                                   IOMMU_HW_INFO_TYPE_DEFAULT,
++                                   &buffer_smaller, sizeof(buffer_smaller));
+               test_cmd_get_hw_info_pasid(self->device_id, &max_pasid);
+               ASSERT_EQ(0, max_pasid);
+               if (variant->pasid_capable) {
+@@ -636,9 +651,11 @@ TEST_F(iommufd_ioas, get_hw_info)
+               }
+       } else {
+               test_err_get_hw_info(ENOENT, self->device_id,
+-                                   &buffer_exact, sizeof(buffer_exact));
++                                   IOMMU_HW_INFO_TYPE_DEFAULT, &buffer_exact,
++                                   sizeof(buffer_exact));
+               test_err_get_hw_info(ENOENT, self->device_id,
+-                                   &buffer_larger, sizeof(buffer_larger));
++                                   IOMMU_HW_INFO_TYPE_DEFAULT, &buffer_larger,
++                                   sizeof(buffer_larger));
+       }
+ }
+@@ -1945,8 +1962,7 @@ TEST_F(iommufd_dirty_tracking, device_dirty_capability)
+       test_cmd_hwpt_alloc(self->idev_id, self->ioas_id, 0, &hwpt_id);
+       test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);
+-      test_cmd_get_hw_capabilities(self->idev_id, caps,
+-                                   IOMMU_HW_CAP_DIRTY_TRACKING);
++      test_cmd_get_hw_capabilities(self->idev_id, caps);
+       ASSERT_EQ(IOMMU_HW_CAP_DIRTY_TRACKING,
+                 caps & IOMMU_HW_CAP_DIRTY_TRACKING);
+diff --git a/tools/testing/selftests/iommu/iommufd_fail_nth.c b/tools/testing/selftests/iommu/iommufd_fail_nth.c
+index 62d02556b34cc..e2012d128e11b 100644
+--- a/tools/testing/selftests/iommu/iommufd_fail_nth.c
++++ b/tools/testing/selftests/iommu/iommufd_fail_nth.c
+@@ -612,8 +612,8 @@ TEST_FAIL_NTH(basic_fail_nth, device)
+                                 &idev_id))
+               return -1;
+-      if (_test_cmd_get_hw_info(self->fd, idev_id, &info,
+-                                sizeof(info), NULL, NULL))
++      if (_test_cmd_get_hw_info(self->fd, idev_id, IOMMU_HW_INFO_TYPE_DEFAULT,
++                                &info, sizeof(info), NULL, NULL))
+               return -1;
+       if (_test_cmd_hwpt_alloc(self->fd, idev_id, ioas_id, 0, 0, &hwpt_id,
+diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h
+index 8994b43e86f89..9668f2268bd9b 100644
+--- a/tools/testing/selftests/iommu/iommufd_utils.h
++++ b/tools/testing/selftests/iommu/iommufd_utils.h
+@@ -637,20 +637,24 @@ static void teardown_iommufd(int fd, struct __test_metadata *_metadata)
+ #endif
+ /* @data can be NULL */
+-static int _test_cmd_get_hw_info(int fd, __u32 device_id, void *data,
+-                               size_t data_len, uint32_t *capabilities,
+-                               uint8_t *max_pasid)
++static int _test_cmd_get_hw_info(int fd, __u32 device_id, __u32 data_type,
++                               void *data, size_t data_len,
++                               uint32_t *capabilities, uint8_t *max_pasid)
+ {
+       struct iommu_test_hw_info *info = (struct iommu_test_hw_info *)data;
+       struct iommu_hw_info cmd = {
+               .size = sizeof(cmd),
+               .dev_id = device_id,
+               .data_len = data_len,
++              .in_data_type = data_type,
+               .data_uptr = (uint64_t)data,
+               .out_capabilities = 0,
+       };
+       int ret;
++      if (data_type != IOMMU_HW_INFO_TYPE_DEFAULT)
++              cmd.flags |= IOMMU_HW_INFO_FLAG_INPUT_TYPE;
++
+       ret = ioctl(fd, IOMMU_GET_HW_INFO, &cmd);
+       if (ret)
+               return ret;
+@@ -693,20 +697,23 @@ static int _test_cmd_get_hw_info(int fd, __u32 device_id, void *data,
+       return 0;
+ }
+-#define test_cmd_get_hw_info(device_id, data, data_len)               \
+-      ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, data, \
+-                                         data_len, NULL, NULL))
++#define test_cmd_get_hw_info(device_id, data_type, data, data_len)         \
++      ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, data_type, \
++                                         data, data_len, NULL, NULL))
+-#define test_err_get_hw_info(_errno, device_id, data, data_len)               \
+-      EXPECT_ERRNO(_errno, _test_cmd_get_hw_info(self->fd, device_id, data, \
+-                                                 data_len, NULL, NULL))
++#define test_err_get_hw_info(_errno, device_id, data_type, data, data_len) \
++      EXPECT_ERRNO(_errno,                                               \
++                   _test_cmd_get_hw_info(self->fd, device_id, data_type, \
++                                         data, data_len, NULL, NULL))
+-#define test_cmd_get_hw_capabilities(device_id, caps, mask) \
+-      ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, NULL, \
++#define test_cmd_get_hw_capabilities(device_id, caps)                        \
++      ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id,              \
++                                         IOMMU_HW_INFO_TYPE_DEFAULT, NULL, \
+                                          0, &caps, NULL))
+-#define test_cmd_get_hw_info_pasid(device_id, max_pasid)              \
+-      ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, NULL, \
++#define test_cmd_get_hw_info_pasid(device_id, max_pasid)                     \
++      ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id,              \
++                                         IOMMU_HW_INFO_TYPE_DEFAULT, NULL, \
+                                          0, NULL, max_pasid))
+ static int _test_ioctl_fault_alloc(int fd, __u32 *fault_id, __u32 *fault_fd)
+-- 
+2.51.0
+
diff --git a/queue-6.12/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch b/queue-6.12/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch
new file mode 100644 (file)
index 0000000..d4516a9
--- /dev/null
@@ -0,0 +1,48 @@
+From 40be980713835badc2675f8c83f8828f5c4c57a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 13:39:03 +0300
+Subject: ipvlan: Ignore PACKET_LOOPBACK in handle_mode_l2()
+
+From: Dmitry Skorodumov <skorodumov.dmitry@huawei.com>
+
+[ Upstream commit 0c57ff008a11f24f7f05fa760222692a00465fec ]
+
+Packets with pkt_type == PACKET_LOOPBACK are captured by
+handle_frame() function, but they don't have L2 header.
+We should not process them in handle_mode_l2().
+
+This doesn't affect old L2 functionality, since handling
+was anyway incorrect.
+
+Handle them the same way as in br_handle_frame():
+just pass the skb.
+
+To observe invalid behaviour, just start "ping -b" on bcast address
+of port-interface.
+
+Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
+Signed-off-by: Dmitry Skorodumov <skorodumov.dmitry@huawei.com>
+Link: https://patch.msgid.link/20251202103906.4087675-1-skorodumov.dmitry@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ipvlan/ipvlan_core.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
+index ca62188a317ad..83bd65a227709 100644
+--- a/drivers/net/ipvlan/ipvlan_core.c
++++ b/drivers/net/ipvlan/ipvlan_core.c
+@@ -737,6 +737,9 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,
+       struct ethhdr *eth = eth_hdr(skb);
+       rx_handler_result_t ret = RX_HANDLER_PASS;
++      if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
++              return RX_HANDLER_PASS;
++
+       if (is_multicast_ether_addr(eth->h_dest)) {
+               if (ipvlan_external_frame(skb, port)) {
+                       struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
+-- 
+2.51.0
+
diff --git a/queue-6.12/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch b/queue-6.12/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch
new file mode 100644 (file)
index 0000000..3c4cb61
--- /dev/null
@@ -0,0 +1,80 @@
+From a9d09bd70996685b921ee05347c8d118e5db8e89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 16:52:13 +0800
+Subject: ipvs: fix ipv4 null-ptr-deref in route error path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Slavin Liu <slavin452@gmail.com>
+
+[ Upstream commit ad891bb3d079a46a821bf2b8867854645191bab0 ]
+
+The IPv4 code path in __ip_vs_get_out_rt() calls dst_link_failure()
+without ensuring skb->dev is set, leading to a NULL pointer dereference
+in fib_compute_spec_dst() when ipv4_link_failure() attempts to send
+ICMP destination unreachable messages.
+
+The issue emerged after commit ed0de45a1008 ("ipv4: recompile ip options
+in ipv4_link_failure") started calling __ip_options_compile() from
+ipv4_link_failure(). This code path eventually calls fib_compute_spec_dst()
+which dereferences skb->dev. An attempt was made to fix the NULL skb->dev
+dereference in commit 0113d9c9d1cc ("ipv4: fix null-deref in
+ipv4_link_failure"), but it only addressed the immediate dev_net(skb->dev)
+dereference by using a fallback device. The fix was incomplete because
+fib_compute_spec_dst() later in the call chain still accesses skb->dev
+directly, which remains NULL when IPVS calls dst_link_failure().
+
+The crash occurs when:
+1. IPVS processes a packet in NAT mode with a misconfigured destination
+2. Route lookup fails in __ip_vs_get_out_rt() before establishing a route
+3. The error path calls dst_link_failure(skb) with skb->dev == NULL
+4. ipv4_link_failure() â†’ ipv4_send_dest_unreach() â†’
+   __ip_options_compile() â†’ fib_compute_spec_dst()
+5. fib_compute_spec_dst() dereferences NULL skb->dev
+
+Apply the same fix used for IPv6 in commit 326bf17ea5d4 ("ipvs: fix
+ipv6 route unreach panic"): set skb->dev from skb_dst(skb)->dev before
+calling dst_link_failure().
+
+KASAN: null-ptr-deref in range [0x0000000000000328-0x000000000000032f]
+CPU: 1 PID: 12732 Comm: syz.1.3469 Not tainted 6.6.114 #2
+RIP: 0010:__in_dev_get_rcu include/linux/inetdevice.h:233
+RIP: 0010:fib_compute_spec_dst+0x17a/0x9f0 net/ipv4/fib_frontend.c:285
+Call Trace:
+  <TASK>
+  spec_dst_fill net/ipv4/ip_options.c:232
+  spec_dst_fill net/ipv4/ip_options.c:229
+  __ip_options_compile+0x13a1/0x17d0 net/ipv4/ip_options.c:330
+  ipv4_send_dest_unreach net/ipv4/route.c:1252
+  ipv4_link_failure+0x702/0xb80 net/ipv4/route.c:1265
+  dst_link_failure include/net/dst.h:437
+  __ip_vs_get_out_rt+0x15fd/0x19e0 net/netfilter/ipvs/ip_vs_xmit.c:412
+  ip_vs_nat_xmit+0x1d8/0xc80 net/netfilter/ipvs/ip_vs_xmit.c:764
+
+Fixes: ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure")
+Signed-off-by: Slavin Liu <slavin452@gmail.com>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
+index 014f077403695..fa2db17f6298b 100644
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -409,6 +409,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+       return -1;
+ err_unreach:
++      if (!skb->dev)
++              skb->dev = skb_dst(skb)->dev;
++
+       dst_link_failure(skb);
+       return -1;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch b/queue-6.12/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch
new file mode 100644 (file)
index 0000000..73b3674
--- /dev/null
@@ -0,0 +1,96 @@
+From ce1810f4776af91f8b7063538c62d701fb2a25e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:13 +0100
+Subject: mlxsw: spectrum_mr: Fix use-after-free when updating multicast route
+ stats
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 8ac1dacec458f55f871f7153242ed6ab60373b90 ]
+
+Cited commit added a dedicated mutex (instead of RTNL) to protect the
+multicast route list, so that it will not change while the driver
+periodically traverses it in order to update the kernel about multicast
+route stats that were queried from the device.
+
+One instance of list entry deletion (during route replace) was missed
+and it can result in a use-after-free [1].
+
+Fix by acquiring the mutex before deleting the entry from the list and
+releasing it afterwards.
+
+[1]
+BUG: KASAN: slab-use-after-free in mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum]
+Read of size 8 at addr ffff8881523c2fa8 by task kworker/2:5/22043
+
+CPU: 2 UID: 0 PID: 22043 Comm: kworker/2:5 Not tainted 6.18.0-rc1-custom-g1a3d6d7cd014 #1 PREEMPT(full)
+Hardware name: Mellanox Technologies Ltd. MSN2010/SA002610, BIOS 5.6.5 08/24/2017
+Workqueue: mlxsw_core mlxsw_sp_mr_stats_update [mlxsw_spectrum]
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xba/0x110
+ print_report+0x174/0x4f5
+ kasan_report+0xdf/0x110
+ mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+Allocated by task 29933:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0x8f/0xa0
+ mlxsw_sp_mr_route_add+0xd8/0x4770 [mlxsw_spectrum]
+ mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+
+Freed by task 29933:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3b/0x70
+ __kasan_slab_free+0x43/0x70
+ kfree+0x14e/0x700
+ mlxsw_sp_mr_route_add+0x2dea/0x4770 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:444 [mlxsw_spectrum]
+ mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+
+Fixes: f38656d06725 ("mlxsw: spectrum_mr: Protect multicast route list with a lock")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/f996feecfd59fde297964bfc85040b6d83ec6089.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+index 5afe6b155ef0d..81935f87bfcd7 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+@@ -440,7 +440,9 @@ int mlxsw_sp_mr_route_add(struct mlxsw_sp_mr_table *mr_table,
+               rhashtable_remove_fast(&mr_table->route_ht,
+                                      &mr_orig_route->ht_node,
+                                      mlxsw_sp_mr_route_ht_params);
++              mutex_lock(&mr_table->route_list_lock);
+               list_del(&mr_orig_route->node);
++              mutex_unlock(&mr_table->route_list_lock);
+               mlxsw_sp_mr_route_destroy(mr_table, mr_orig_route);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.12/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch b/queue-6.12/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch
new file mode 100644 (file)
index 0000000..ee53ac0
--- /dev/null
@@ -0,0 +1,199 @@
+From a8f8fa19957625e4c93787b8126a2f159259ce03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:12 +0100
+Subject: mlxsw: spectrum_router: Fix neighbour use-after-free
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 8b0e69763ef948fb872a7767df4be665d18f5fd4 ]
+
+We sometimes observe use-after-free when dereferencing a neighbour [1].
+The problem seems to be that the driver stores a pointer to the
+neighbour, but without holding a reference on it. A reference is only
+taken when the neighbour is used by a nexthop.
+
+Fix by simplifying the reference counting scheme. Always take a
+reference when storing a neighbour pointer in a neighbour entry. Avoid
+taking a referencing when the neighbour is used by a nexthop as the
+neighbour entry associated with the nexthop already holds a reference.
+
+Tested by running the test that uncovered the problem over 300 times.
+Without this patch the problem was reproduced after a handful of
+iterations.
+
+[1]
+BUG: KASAN: slab-use-after-free in mlxsw_sp_neigh_entry_update+0x2d4/0x310
+Read of size 8 at addr ffff88817f8e3420 by task ip/3929
+
+CPU: 3 UID: 0 PID: 3929 Comm: ip Not tainted 6.18.0-rc4-virtme-g36b21a067510 #3 PREEMPT(full)
+Hardware name: Nvidia SN5600/VMOD0013, BIOS 5.13 05/31/2023
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x6f/0xa0
+ print_address_description.constprop.0+0x6e/0x300
+ print_report+0xfc/0x1fb
+ kasan_report+0xe4/0x110
+ mlxsw_sp_neigh_entry_update+0x2d4/0x310
+ mlxsw_sp_router_rif_gone_sync+0x35f/0x510
+ mlxsw_sp_rif_destroy+0x1ea/0x730
+ mlxsw_sp_inetaddr_port_vlan_event+0xa1/0x1b0
+ __mlxsw_sp_inetaddr_lag_event+0xcc/0x130
+ __mlxsw_sp_inetaddr_event+0xf5/0x3c0
+ mlxsw_sp_router_netdevice_event+0x1015/0x1580
+ notifier_call_chain+0xcc/0x150
+ call_netdevice_notifiers_info+0x7e/0x100
+ __netdev_upper_dev_unlink+0x10b/0x210
+ netdev_upper_dev_unlink+0x79/0xa0
+ vrf_del_slave+0x18/0x50
+ do_set_master+0x146/0x7d0
+ do_setlink.isra.0+0x9a0/0x2880
+ rtnl_newlink+0x637/0xb20
+ rtnetlink_rcv_msg+0x6fe/0xb90
+ netlink_rcv_skb+0x123/0x380
+ netlink_unicast+0x4a3/0x770
+ netlink_sendmsg+0x75b/0xc90
+ __sock_sendmsg+0xbe/0x160
+ ____sys_sendmsg+0x5b2/0x7d0
+ ___sys_sendmsg+0xfd/0x180
+ __sys_sendmsg+0x124/0x1c0
+ do_syscall_64+0xbb/0xfd0
+ entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[...]
+
+Allocated by task 109:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0x7b/0x90
+ __kmalloc_noprof+0x2c1/0x790
+ neigh_alloc+0x6af/0x8f0
+ ___neigh_create+0x63/0xe90
+ mlxsw_sp_nexthop_neigh_init+0x430/0x7e0
+ mlxsw_sp_nexthop_type_init+0x212/0x960
+ mlxsw_sp_nexthop6_group_info_init.constprop.0+0x81f/0x1280
+ mlxsw_sp_nexthop6_group_get+0x392/0x6a0
+ mlxsw_sp_fib6_entry_create+0x46a/0xfd0
+ mlxsw_sp_router_fib6_replace+0x1ed/0x5f0
+ mlxsw_sp_router_fib6_event_work+0x10a/0x2a0
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Freed by task 154:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3b/0x60
+ __kasan_slab_free+0x43/0x70
+ kmem_cache_free_bulk.part.0+0x1eb/0x5e0
+ kvfree_rcu_bulk+0x1f2/0x260
+ kfree_rcu_work+0x130/0x1b0
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Last potentially related work creation:
+ kasan_save_stack+0x30/0x50
+ kasan_record_aux_stack+0x8c/0xa0
+ kvfree_call_rcu+0x93/0x5b0
+ mlxsw_sp_router_neigh_event_work+0x67d/0x860
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Fixes: 6cf3c971dc84 ("mlxsw: spectrum_router: Add private neigh table")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/92d75e21d95d163a41b5cea67a15cd33f547cba6.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlxsw/spectrum_router.c   | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index 4ab58cb1ab7f4..7066bc5612c62 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -2265,6 +2265,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
+       if (!neigh_entry)
+               return NULL;
++      neigh_hold(n);
+       neigh_entry->key.n = n;
+       neigh_entry->rif = rif;
+       INIT_LIST_HEAD(&neigh_entry->nexthop_list);
+@@ -2274,6 +2275,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
+ static void mlxsw_sp_neigh_entry_free(struct mlxsw_sp_neigh_entry *neigh_entry)
+ {
++      neigh_release(neigh_entry->key.n);
+       kfree(neigh_entry);
+ }
+@@ -4320,6 +4322,8 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
+       if (err)
+               goto err_neigh_entry_insert;
++      neigh_release(old_n);
++
+       read_lock_bh(&n->lock);
+       nud_state = n->nud_state;
+       dead = n->dead;
+@@ -4328,14 +4332,10 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
+       list_for_each_entry(nh, &neigh_entry->nexthop_list,
+                           neigh_list_node) {
+-              neigh_release(old_n);
+-              neigh_clone(n);
+               __mlxsw_sp_nexthop_neigh_update(nh, !entry_connected);
+               mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp);
+       }
+-      neigh_release(n);
+-
+       return 0;
+ err_neigh_entry_insert:
+@@ -4428,6 +4428,11 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
+               }
+       }
++      /* Release the reference taken by neigh_lookup() / neigh_create() since
++       * neigh_entry already holds one.
++       */
++      neigh_release(n);
++
+       /* If that is the first nexthop connected to that neigh, add to
+        * nexthop_neighs_list
+        */
+@@ -4454,11 +4459,9 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
+                                       struct mlxsw_sp_nexthop *nh)
+ {
+       struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
+-      struct neighbour *n;
+       if (!neigh_entry)
+               return;
+-      n = neigh_entry->key.n;
+       __mlxsw_sp_nexthop_neigh_update(nh, true);
+       list_del(&nh->neigh_list_node);
+@@ -4472,8 +4475,6 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
+       if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list))
+               mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
+-
+-      neigh_release(n);
+ }
+ static bool mlxsw_sp_ipip_netdev_ul_up(struct net_device *ol_dev)
+-- 
+2.51.0
+
diff --git a/queue-6.12/mlxsw-spectrum_router-fix-possible-neighbour-referen.patch b/queue-6.12/mlxsw-spectrum_router-fix-possible-neighbour-referen.patch
new file mode 100644 (file)
index 0000000..e29b6da
--- /dev/null
@@ -0,0 +1,64 @@
+From f06623b857938159c3ae6c5fb717dc4553902d1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:11 +0100
+Subject: mlxsw: spectrum_router: Fix possible neighbour reference count leak
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit b6b638bda240395dff49a87403b2e32493e56d2a ]
+
+mlxsw_sp_router_schedule_work() takes a reference on a neighbour,
+expecting a work item to release it later on. However, we might fail to
+schedule the work item, in which case the neighbour reference count will
+be leaked.
+
+Fix by taking the reference just before scheduling the work item. Note
+that mlxsw_sp_router_schedule_work() can receive a NULL neighbour
+pointer, but neigh_clone() handles that correctly.
+
+Spotted during code review, did not actually observe the reference count
+leak.
+
+Fixes: 151b89f6025a ("mlxsw: spectrum_router: Reuse work neighbor initialization in work scheduler")
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/ec2934ae4aca187a8d8c9329a08ce93cca411378.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index 511cd92e0e3e7..4ab58cb1ab7f4 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -2858,6 +2858,11 @@ static int mlxsw_sp_router_schedule_work(struct net *net,
+       if (!net_work)
+               return NOTIFY_BAD;
++      /* Take a reference to ensure the neighbour won't be destructed until
++       * we drop the reference in the work item.
++       */
++      neigh_clone(n);
++
+       INIT_WORK(&net_work->work, cb);
+       net_work->mlxsw_sp = router->mlxsw_sp;
+       net_work->n = n;
+@@ -2881,11 +2886,6 @@ static int mlxsw_sp_router_schedule_neigh_work(struct mlxsw_sp_router *router,
+       struct net *net;
+       net = neigh_parms_net(n->parms);
+-
+-      /* Take a reference to ensure the neighbour won't be destructed until we
+-       * drop the reference in delayed work.
+-       */
+-      neigh_clone(n);
+       return mlxsw_sp_router_schedule_work(net, router, n,
+                                            mlxsw_sp_router_neigh_event_work);
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-enetc-do-not-transmit-redirected-xdp-frames-when.patch b/queue-6.12/net-enetc-do-not-transmit-redirected-xdp-frames-when.patch
new file mode 100644 (file)
index 0000000..f445f63
--- /dev/null
@@ -0,0 +1,66 @@
+From e84a22410907b49b35165ec3f207b7812851bbcc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:09:19 +0800
+Subject: net: enetc: do not transmit redirected XDP frames when the link is
+ down
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit 2939203ffee818f1e5ebd60bbb85a174d63aab9c ]
+
+In the current implementation, the enetc_xdp_xmit() always transmits
+redirected XDP frames even if the link is down, but the frames cannot
+be transmitted from TX BD rings when the link is down, so the frames
+are still kept in the TX BD rings. If the XDP program is uninstalled,
+users will see the following warning logs.
+
+fsl_enetc 0000:00:00.0 eno0: timeout for tx ring #6 clear
+
+More worse, the TX BD ring cannot work properly anymore, because the
+HW PIR and CIR are not equal after the re-initialization of the TX
+BD ring. At this point, the BDs between CIR and PIR are invalid,
+which will cause a hardware malfunction.
+
+Another reason is that there is internal context in the ring prefetch
+logic that will retain the state from the first incarnation of the ring
+and continue prefetching from the stale location when we re-initialize
+the ring. The internal context is only reset by an FLR. That is to say,
+for LS1028A ENETC, software cannot set the HW CIR and PIR when
+initializing the TX BD ring.
+
+It does not make sense to transmit redirected XDP frames when the link is
+down. Add a link status check to prevent transmission in this condition.
+This fixes part of the issue, but more complex cases remain. For example,
+the TX BD ring may still contain unsent frames when the link goes down.
+Those situations require additional patches, which will build on this
+one.
+
+Fixes: 9d2b68cc108d ("net: enetc: add support for XDP_REDIRECT")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Reviewed-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20251211020919.121113-1-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index 749b65aab14a9..c58e44144c2fa 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -1429,7 +1429,8 @@ int enetc_xdp_xmit(struct net_device *ndev, int num_frames,
+       int xdp_tx_bd_cnt, i, k;
+       int xdp_tx_frm_cnt = 0;
+-      if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags)))
++      if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags) ||
++                   !netif_carrier_ok(ndev)))
+               return -ENETDOWN;
+       enetc_lock_mdio();
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-fec-err007885-workaround-for-xdp-tx-path.patch b/queue-6.12/net-fec-err007885-workaround-for-xdp-tx-path.patch
new file mode 100644 (file)
index 0000000..6bbd873
--- /dev/null
@@ -0,0 +1,49 @@
+From 506822590d2945c06a0964c27cff7af163b76bc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Nov 2025 10:59:15 +0800
+Subject: net: fec: ERR007885 Workaround for XDP TX path
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit e8e032cd24dda7cceaa27bc2eb627f82843f0466 ]
+
+The ERR007885 will lead to a TDAR race condition for mutliQ when the
+driver sets TDAR and the UDMA clears TDAR simultaneously or in a small
+window (2-4 cycles). And it will cause the udma_tx and udma_tx_arbiter
+state machines to hang. Therefore, the commit 53bb20d1faba ("net: fec:
+add variable reg_desc_active to speed things up") and the commit
+a179aad12bad ("net: fec: ERR007885 Workaround for conventional TX") have
+added the workaround to fix the potential issue for the conventional TX
+path. Similarly, the XDP TX path should also have the potential hang
+issue, so add the workaround for XDP TX path.
+
+Fixes: 6d6b39f180b8 ("net: fec: add initial XDP support")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251128025915.2486943-1-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_main.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index d1800868c2e01..9018a7d3864fd 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -3934,7 +3934,12 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep,
+       txq->bd.cur = bdp;
+       /* Trigger transmission start */
+-      writel(0, txq->bd.reg_desc_active);
++      if (!(fep->quirks & FEC_QUIRK_ERR007885) ||
++          !readl(txq->bd.reg_desc_active) ||
++          !readl(txq->bd.reg_desc_active) ||
++          !readl(txq->bd.reg_desc_active) ||
++          !readl(txq->bd.reg_desc_active))
++              writel(0, txq->bd.reg_desc_active);
+       return 0;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-handshake-duplicate-handshake-cancellations-leak.patch b/queue-6.12/net-handshake-duplicate-handshake-cancellations-leak.patch
new file mode 100644 (file)
index 0000000..f5c78ca
--- /dev/null
@@ -0,0 +1,61 @@
+From ea2a1609f958d628aa9d8af8201c7d63d182b0c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:30:15 -0500
+Subject: net/handshake: duplicate handshake cancellations leak socket
+
+From: Scott Mayhew <smayhew@redhat.com>
+
+[ Upstream commit 15564bd67e2975002f2a8e9defee33e321d3183f ]
+
+When a handshake request is cancelled it is removed from the
+handshake_net->hn_requests list, but it is still present in the
+handshake_rhashtbl until it is destroyed.
+
+If a second cancellation request arrives for the same handshake request,
+then remove_pending() will return false... and assuming
+HANDSHAKE_F_REQ_COMPLETED isn't set in req->hr_flags, we'll continue
+processing through the out_true label, where we put another reference on
+the sock and a refcount underflow occurs.
+
+This can happen for example if a handshake times out - particularly if
+the SUNRPC client sends the AUTH_TLS probe to the server but doesn't
+follow it up with the ClientHello due to a problem with tlshd.  When the
+timeout is hit on the server, the server will send a FIN, which triggers
+a cancellation request via xs_reset_transport().  When the timeout is
+hit on the client, another cancellation request happens via
+xs_tls_handshake_sync().
+
+Add a test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED) in the pending cancel
+path so duplicate cancels can be detected.
+
+Fixes: 3b3009ea8abb ("net/handshake: Create a NETLINK service for handling handshake requests")
+Suggested-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Scott Mayhew <smayhew@redhat.com>
+Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
+Link: https://patch.msgid.link/20251209193015.3032058-1-smayhew@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/request.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 94d5cef3e048b..0ac126b0add60 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -325,7 +325,11 @@ bool handshake_req_cancel(struct sock *sk)
+       hn = handshake_pernet(net);
+       if (hn && remove_pending(hn, req)) {
+-              /* Request hadn't been accepted */
++              /* Request hadn't been accepted - mark cancelled */
++              if (test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) {
++                      trace_handshake_cancel_busy(net, req, sk);
++                      return false;
++              }
+               goto out_true;
+       }
+       if (test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) {
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-hns3-add-vlan-id-validation-before-using.patch b/queue-6.12/net-hns3-add-vlan-id-validation-before-using.patch
new file mode 100644 (file)
index 0000000..d60896a
--- /dev/null
@@ -0,0 +1,46 @@
+From 1a875571cb7f3402dc7b81227801e6c5d06c67f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:37 +0800
+Subject: net: hns3: add VLAN id validation before using
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit 6ef935e65902bfed53980ad2754b06a284ea8ac1 ]
+
+Currently, the VLAN id may be used without validation when
+receive a VLAN configuration mailbox from VF. The length of
+vlan_del_fail_bmap is BITS_TO_LONGS(VLAN_N_VID). It may cause
+out-of-bounds memory access once the VLAN id is bigger than
+or equal to VLAN_N_VID.
+
+Therefore, VLAN id needs to be checked to ensure it is within
+the range of VLAN_N_VID.
+
+Fixes: fe4144d47eef ("net: hns3: sync VLAN filter entries when kill VLAN ID failed")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-4-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index f5eafd1ded413..8dd970ef02ac6 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -10572,6 +10572,9 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
+       bool writen_to_tbl = false;
+       int ret = 0;
++      if (vlan_id >= VLAN_N_VID)
++              return -EINVAL;
++
+       /* When device is resetting or reset failed, firmware is unable to
+        * handle mailbox. Just record the vlan id, and remove it after
+        * reset finished.
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch b/queue-6.12/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch
new file mode 100644 (file)
index 0000000..9452c96
--- /dev/null
@@ -0,0 +1,52 @@
+From 6ecf3e5c670791dcd49fe516ebd73460a21adc9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:35 +0800
+Subject: net: hns3: using the num_tqps in the vf driver to apply for resources
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit c2a16269742e176fccdd0ef9c016a233491a49ad ]
+
+Currently, hdev->htqp is allocated using hdev->num_tqps, and kinfo->tqp
+is allocated using kinfo->num_tqps. However, kinfo->num_tqps is set to
+min(new_tqps, hdev->num_tqps);  Therefore, kinfo->num_tqps may be smaller
+than hdev->num_tqps, which causes some hdev->htqp[i] to remain
+uninitialized in hclgevf_knic_setup().
+
+Thus, this patch allocates hdev->htqp and kinfo->tqp using hdev->num_tqps,
+ensuring that the lengths of hdev->htqp and kinfo->tqp are consistent
+and that all elements are properly initialized.
+
+Fixes: e2cb1dec9779 ("net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-2-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+index e8573358309ca..0bf8fc7e6b3a8 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -370,12 +370,12 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev)
+       new_tqps = kinfo->rss_size * num_tc;
+       kinfo->num_tqps = min(new_tqps, hdev->num_tqps);
+-      kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps,
++      kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps,
+                                 sizeof(struct hnae3_queue *), GFP_KERNEL);
+       if (!kinfo->tqp)
+               return -ENOMEM;
+-      for (i = 0; i < kinfo->num_tqps; i++) {
++      for (i = 0; i < hdev->num_tqps; i++) {
+               hdev->htqp[i].q.handle = &hdev->nic;
+               hdev->htqp[i].q.tqp_index = i;
+               kinfo->tqp[i] = &hdev->htqp[i].q;
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch b/queue-6.12/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch
new file mode 100644 (file)
index 0000000..e8951a0
--- /dev/null
@@ -0,0 +1,49 @@
+From 20409cbc8c679d8e796b64b59f1b8e12354c5495 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:36 +0800
+Subject: net: hns3: using the num_tqps to check whether tqp_index is out of
+ range when vf get ring info from mbx
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit d180c11aa8a6fa735f9ac2c72c61364a9afc2ba7 ]
+
+Currently, rss_size = num_tqps / tc_num. If tc_num is 1, then num_tqps
+equals rss_size. However, if the tc_num is greater than 1, then rss_size
+will be less than num_tqps, causing the tqp_index check for subsequent TCs
+using rss_size to always fail.
+
+This patch uses the num_tqps to check whether tqp_index is out of range,
+instead of rss_size.
+
+Fixes: 326334aad024 ("net: hns3: add a check for tqp_index in hclge_get_ring_chain_from_mbx()")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-3-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+index 59c863306657f..9eab095d784bd 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+@@ -193,10 +193,10 @@ static int hclge_get_ring_chain_from_mbx(
+               return -EINVAL;
+       for (i = 0; i < ring_num; i++) {
+-              if (req->msg.param[i].tqp_index >= vport->nic.kinfo.rss_size) {
++              if (req->msg.param[i].tqp_index >= vport->nic.kinfo.num_tqps) {
+                       dev_err(&hdev->pdev->dev, "tqp index(%u) is out of range(0-%u)\n",
+                               req->msg.param[i].tqp_index,
+-                              vport->nic.kinfo.rss_size - 1U);
++                              vport->nic.kinfo.num_tqps - 1U);
+                       return -EINVAL;
+               }
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-mlx5-drain-firmware-reset-in-shutdown-callback.patch b/queue-6.12/net-mlx5-drain-firmware-reset-in-shutdown-callback.patch
new file mode 100644 (file)
index 0000000..b932f01
--- /dev/null
@@ -0,0 +1,38 @@
+From 71c42033fff70434d0d68d060cdb98337da109d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:10 +0200
+Subject: net/mlx5: Drain firmware reset in shutdown callback
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 5846a365fc6476b02d6766963cf0985520f0385f ]
+
+Invoke drain_fw_reset() in the shutdown callback to ensure all
+firmware reset handling is completed before shutdown proceeds.
+
+Fixes: 16d42d313350 ("net/mlx5: Drain fw_reset when removing device")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Shay Drori <shayd@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-3-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 11d8739b9497a..e97b3494b9161 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -2196,6 +2196,7 @@ static void shutdown(struct pci_dev *pdev)
+       mlx5_core_info(dev, "Shutdown was called\n");
+       set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state);
++      mlx5_drain_fw_reset(dev);
+       mlx5_drain_health_wq(dev);
+       err = mlx5_try_fast_unload(dev);
+       if (err)
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch b/queue-6.12/net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch
new file mode 100644 (file)
index 0000000..28a7a7e
--- /dev/null
@@ -0,0 +1,45 @@
+From c7158c6b50d6ed840fe7f40e96afe9862b9eb0bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:09 +0200
+Subject: net/mlx5: fw reset, clear reset requested on drain_fw_reset
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 89a898d63f6f588acf5c104c65c94a38b68c69a6 ]
+
+drain_fw_reset() waits for ongoing firmware reset events and blocks new
+event handling, but does not clear the reset requested flag, and may
+keep sync reset polling.
+
+To fix it, call mlx5_sync_reset_clear_reset_requested() to clear the
+flag, stop sync reset polling, and resume health polling, ensuring
+health issues are still detected after the firmware reset drain.
+
+Fixes: 16d42d313350 ("net/mlx5: Drain fw_reset when removing device")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Shay Drori <shayd@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-2-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 35d2fe08c0fb5..ad4d17a243de9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -832,7 +832,8 @@ void mlx5_drain_fw_reset(struct mlx5_core_dev *dev)
+       cancel_work_sync(&fw_reset->reset_reload_work);
+       cancel_work_sync(&fw_reset->reset_now_work);
+       cancel_work_sync(&fw_reset->reset_abort_work);
+-      cancel_delayed_work(&fw_reset->reset_timeout_work);
++      if (test_bit(MLX5_FW_RESET_FLAGS_RESET_REQUESTED, &fw_reset->reset_flags))
++              mlx5_sync_reset_clear_reset_requested(dev, true);
+ }
+ static const struct devlink_param mlx5_fw_reset_devlink_params[] = {
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch b/queue-6.12/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch
new file mode 100644 (file)
index 0000000..71168b8
--- /dev/null
@@ -0,0 +1,84 @@
+From 67e8d2d9ae70078b98bfbf912f8d1f95cbfc9145 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:12 +0200
+Subject: net/mlx5: fw_tracer, Handle escaped percent properly
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit c0289f67f7d6a0dfba0e92cfe661a5c70c8c6e92 ]
+
+The firmware tracer's format string validation and parameter counting
+did not properly handle escaped percent signs (%%). This caused
+fw_tracer to count more parameters when trace format strings contained
+literal percent characters.
+
+To fix it, allow %% to pass string validation and skip %% sequences when
+counting parameters since they represent literal percent signs rather
+than format specifiers.
+
+Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reported-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 20 +++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 9c86c8c72d049..0b82a6a133d6c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -368,11 +368,11 @@ static bool mlx5_is_valid_spec(const char *str)
+       while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l')
+               str++;
+-      /* Check if it's a valid integer/hex specifier:
++      /* Check if it's a valid integer/hex specifier or %%:
+        * Valid formats: %x, %d, %i, %u, etc.
+        */
+       if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' &&
+-          *str != 'u' && *str != 'c')
++          *str != 'u' && *str != 'c' && *str != '%')
+               return false;
+       return true;
+@@ -390,7 +390,11 @@ static bool mlx5_tracer_validate_params(const char *str)
+               if (!mlx5_is_valid_spec(substr + 1))
+                       return false;
+-              substr = strstr(substr + 1, PARAM_CHAR);
++              if (*(substr + 1) == '%')
++                      substr = strstr(substr + 2, PARAM_CHAR);
++              else
++                      substr = strstr(substr + 1, PARAM_CHAR);
++
+       }
+       return true;
+@@ -469,11 +473,15 @@ static int mlx5_tracer_get_num_of_params(char *str)
+               substr = strstr(pstr, VAL_PARM);
+       }
+-      /* count all the % characters */
++      /* count all the % characters, but skip %% (escaped percent) */
+       substr = strstr(str, PARAM_CHAR);
+       while (substr) {
+-              num_of_params += 1;
+-              str = substr + 1;
++              if (*(substr + 1) != '%') {
++                      num_of_params += 1;
++                      str = substr + 1;
++              } else {
++                      str = substr + 2;
++              }
+               substr = strstr(str, PARAM_CHAR);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-mlx5-fw_tracer-validate-format-string-parameters.patch b/queue-6.12/net-mlx5-fw_tracer-validate-format-string-parameters.patch
new file mode 100644 (file)
index 0000000..039ffda
--- /dev/null
@@ -0,0 +1,195 @@
+From bf7c13751aab5ab3d9d3f31a9e8c0d945d295177 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:11 +0200
+Subject: net/mlx5: fw_tracer, Validate format string parameters
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit b35966042d20b14e2d83330049f77deec5229749 ]
+
+Add validation for format string parameters in the firmware tracer to
+prevent potential security vulnerabilities and crashes from malformed
+format strings received from firmware.
+
+The firmware tracer receives format strings from the device firmware and
+uses them to format trace messages. Without proper validation, bad
+firmware could provide format strings with invalid format specifiers
+(e.g., %s, %p, %n) that could lead to crashes, or other undefined
+behavior.
+
+Add mlx5_tracer_validate_params() to validate that all format specifiers
+in trace strings are limited to safe integer/hex formats (%x, %d, %i,
+%u, %llx, %lx, etc.). Reject strings containing other format types that
+could be used to access arbitrary memory or cause crashes.
+Invalid format strings are added to the trace output for visibility with
+"BAD_FORMAT: " prefix.
+
+Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Reported-by: Breno Leitao <leitao@debian.org>
+Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-4-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 83 ++++++++++++++++---
+ .../mellanox/mlx5/core/diag/fw_tracer.h       |  1 +
+ 2 files changed, 74 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 080e7eab52c7e..9c86c8c72d049 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -33,6 +33,7 @@
+ #include "lib/eq.h"
+ #include "fw_tracer.h"
+ #include "fw_tracer_tracepoint.h"
++#include <linux/ctype.h>
+ static int mlx5_query_mtrc_caps(struct mlx5_fw_tracer *tracer)
+ {
+@@ -358,6 +359,43 @@ static const char *VAL_PARM               = "%llx";
+ static const char *REPLACE_64_VAL_PARM        = "%x%x";
+ static const char *PARAM_CHAR         = "%";
++static bool mlx5_is_valid_spec(const char *str)
++{
++      /* Parse format specifiers to find the actual type.
++       * Structure: %[flags][width][.precision][length]type
++       * Skip flags, width, precision & length.
++       */
++      while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l')
++              str++;
++
++      /* Check if it's a valid integer/hex specifier:
++       * Valid formats: %x, %d, %i, %u, etc.
++       */
++      if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' &&
++          *str != 'u' && *str != 'c')
++              return false;
++
++      return true;
++}
++
++static bool mlx5_tracer_validate_params(const char *str)
++{
++      const char *substr = str;
++
++      if (!str)
++              return false;
++
++      substr = strstr(substr, PARAM_CHAR);
++      while (substr) {
++              if (!mlx5_is_valid_spec(substr + 1))
++                      return false;
++
++              substr = strstr(substr + 1, PARAM_CHAR);
++      }
++
++      return true;
++}
++
+ static int mlx5_tracer_message_hash(u32 message_id)
+ {
+       return jhash_1word(message_id, 0) & (MESSAGE_HASH_SIZE - 1);
+@@ -419,6 +457,10 @@ static int mlx5_tracer_get_num_of_params(char *str)
+       char *substr, *pstr = str;
+       int num_of_params = 0;
++      /* Validate that all parameters are valid before processing */
++      if (!mlx5_tracer_validate_params(str))
++              return -EINVAL;
++
+       /* replace %llx with %x%x */
+       substr = strstr(pstr, VAL_PARM);
+       while (substr) {
+@@ -570,14 +612,17 @@ void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt,
+ {
+       char    tmp[512];
+-      snprintf(tmp, sizeof(tmp), str_frmt->string,
+-               str_frmt->params[0],
+-               str_frmt->params[1],
+-               str_frmt->params[2],
+-               str_frmt->params[3],
+-               str_frmt->params[4],
+-               str_frmt->params[5],
+-               str_frmt->params[6]);
++      if (str_frmt->invalid_string)
++              snprintf(tmp, sizeof(tmp), "BAD_FORMAT: %s", str_frmt->string);
++      else
++              snprintf(tmp, sizeof(tmp), str_frmt->string,
++                       str_frmt->params[0],
++                       str_frmt->params[1],
++                       str_frmt->params[2],
++                       str_frmt->params[3],
++                       str_frmt->params[4],
++                       str_frmt->params[5],
++                       str_frmt->params[6]);
+       trace_mlx5_fw(dev->tracer, trace_timestamp, str_frmt->lost,
+                     str_frmt->event_id, tmp);
+@@ -609,6 +654,13 @@ static int mlx5_tracer_handle_raw_string(struct mlx5_fw_tracer *tracer,
+       return 0;
+ }
++static void mlx5_tracer_handle_bad_format_string(struct mlx5_fw_tracer *tracer,
++                                               struct tracer_string_format *cur_string)
++{
++      cur_string->invalid_string = true;
++      list_add_tail(&cur_string->list, &tracer->ready_strings_list);
++}
++
+ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                          struct tracer_event *tracer_event)
+ {
+@@ -619,12 +671,18 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+               if (!cur_string)
+                       return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+-              cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
+-              cur_string->last_param_num = 0;
+               cur_string->event_id = tracer_event->event_id;
+               cur_string->tmsn = tracer_event->string_event.tmsn;
+               cur_string->timestamp = tracer_event->string_event.timestamp;
+               cur_string->lost = tracer_event->lost_event;
++              cur_string->last_param_num = 0;
++              cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
++              if (cur_string->num_of_params < 0) {
++                      pr_debug("%s Invalid format string parameters\n",
++                               __func__);
++                      mlx5_tracer_handle_bad_format_string(tracer, cur_string);
++                      return 0;
++              }
+               if (cur_string->num_of_params == 0) /* trace with no params */
+                       list_add_tail(&cur_string->list, &tracer->ready_strings_list);
+       } else {
+@@ -634,6 +692,11 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                __func__, tracer_event->string_event.tmsn);
+                       return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+               }
++              if (cur_string->num_of_params < 0) {
++                      pr_debug("%s string parameter of invalid string, dumping\n",
++                               __func__);
++                      return 0;
++              }
+               cur_string->last_param_num += 1;
+               if (cur_string->last_param_num > TRACER_MAX_PARAMS) {
+                       pr_debug("%s Number of params exceeds the max (%d)\n",
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+index 5c548bb74f07b..30d0bcba88479 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+@@ -125,6 +125,7 @@ struct tracer_string_format {
+       struct list_head list;
+       u32 timestamp;
+       bool lost;
++      bool invalid_string;
+ };
+ enum mlx5_fw_tracer_ownership_state {
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-mlx5-serialize-firmware-reset-with-devlink.patch b/queue-6.12/net-mlx5-serialize-firmware-reset-with-devlink.patch
new file mode 100644 (file)
index 0000000..532ba82
--- /dev/null
@@ -0,0 +1,209 @@
+From e56b4dc58eb05d61c510bef1146cc72b15aeb3db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:13 +0200
+Subject: net/mlx5: Serialize firmware reset with devlink
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 367e501f8b095eca08d2eb0ba4ccea5b5e82c169 ]
+
+The firmware reset mechanism can be triggered by asynchronous events,
+which may race with other devlink operations like devlink reload or
+devlink dev eswitch set, potentially leading to inconsistent states.
+
+This patch addresses the race by using the devl_lock to serialize the
+firmware reset against other devlink operations. When a reset is
+requested, the driver attempts to acquire the lock. If successful, it
+sets a flag to block devlink reload or eswitch changes, ACKs the reset
+to firmware and then releases the lock. If the lock is already held by
+another operation, the driver NACKs the firmware reset request,
+indicating that the reset cannot proceed.
+
+Firmware reset does not keep the devl_lock and instead uses an internal
+firmware reset bit. This is because firmware resets can be triggered by
+asynchronous events, and processed in different threads. It is illegal
+and unsafe to acquire a lock in one thread and attempt to release it in
+another, as lock ownership is intrinsically thread-specific.
+
+This change ensures that firmware resets and other devlink operations
+are mutually exclusive during the critical reset request phase,
+preventing race conditions.
+
+Fixes: 38b9f903f22b ("net/mlx5: Handle sync reset request event")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Mateusz Berezecki <mberezecki@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-6-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/devlink.c |  5 +++
+ .../mellanox/mlx5/core/eswitch_offloads.c     |  6 +++
+ .../ethernet/mellanox/mlx5/core/fw_reset.c    | 45 +++++++++++++++++--
+ .../ethernet/mellanox/mlx5/core/fw_reset.h    |  1 +
+ 4 files changed, 53 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 511b3ba245420..e9d49afc31db5 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -143,6 +143,11 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
+       struct pci_dev *pdev = dev->pdev;
+       int ret = 0;
++      if (mlx5_fw_reset_in_progress(dev)) {
++              NL_SET_ERR_MSG_MOD(extack, "Can't reload during firmware reset");
++              return -EBUSY;
++      }
++
+       if (mlx5_dev_is_lightweight(dev)) {
+               if (action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT)
+                       return -EOPNOTSUPP;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index 558962423521c..f4cb3e78d0651 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -52,6 +52,7 @@
+ #include "devlink.h"
+ #include "lag/lag.h"
+ #include "en/tc/post_meter.h"
++#include "fw_reset.h"
+ /* There are two match-all miss flows, one for unicast dst mac and
+  * one for multicast.
+@@ -3731,6 +3732,11 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
+       if (IS_ERR(esw))
+               return PTR_ERR(esw);
++      if (mlx5_fw_reset_in_progress(esw->dev)) {
++              NL_SET_ERR_MSG_MOD(extack, "Can't change eswitch mode during firmware reset");
++              return -EBUSY;
++      }
++
+       if (esw_mode_from_devlink(mode, &mlx5_mode))
+               return -EINVAL;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index ad4d17a243de9..1411513da66b2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -15,6 +15,7 @@ enum {
+       MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
+       MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED,
+       MLX5_FW_RESET_FLAGS_UNLOAD_EVENT,
++      MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS,
+ };
+ struct mlx5_fw_reset {
+@@ -126,6 +127,16 @@ int mlx5_fw_reset_query(struct mlx5_core_dev *dev, u8 *reset_level, u8 *reset_ty
+       return mlx5_reg_mfrl_query(dev, reset_level, reset_type, NULL, NULL);
+ }
++bool mlx5_fw_reset_in_progress(struct mlx5_core_dev *dev)
++{
++      struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
++
++      if (!fw_reset)
++              return false;
++
++      return test_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
++}
++
+ static int mlx5_fw_reset_get_reset_method(struct mlx5_core_dev *dev,
+                                         u8 *reset_method)
+ {
+@@ -241,6 +252,8 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
+                                                       BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE));
+               devl_unlock(devlink);
+       }
++
++      clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
+ }
+ static void mlx5_stop_sync_reset_poll(struct mlx5_core_dev *dev)
+@@ -456,27 +469,48 @@ static void mlx5_sync_reset_request_event(struct work_struct *work)
+       struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
+                                                     reset_request_work);
+       struct mlx5_core_dev *dev = fw_reset->dev;
++      bool nack_request = false;
++      struct devlink *devlink;
+       int err;
+       err = mlx5_fw_reset_get_reset_method(dev, &fw_reset->reset_method);
+-      if (err)
++      if (err) {
++              nack_request = true;
+               mlx5_core_warn(dev, "Failed reading MFRL, err %d\n", err);
++      } else if (!mlx5_is_reset_now_capable(dev, fw_reset->reset_method) ||
++                 test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
++                          &fw_reset->reset_flags)) {
++              nack_request = true;
++      }
+-      if (err || test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) ||
+-          !mlx5_is_reset_now_capable(dev, fw_reset->reset_method)) {
++      devlink = priv_to_devlink(dev);
++      /* For external resets, try to acquire devl_lock. Skip if devlink reset is
++       * pending (lock already held)
++       */
++      if (nack_request ||
++          (!test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP,
++                     &fw_reset->reset_flags) &&
++           !devl_trylock(devlink))) {
+               err = mlx5_fw_reset_set_reset_sync_nack(dev);
+               mlx5_core_warn(dev, "PCI Sync FW Update Reset Nack %s",
+                              err ? "Failed" : "Sent");
+               return;
+       }
++
+       if (mlx5_sync_reset_set_reset_requested(dev))
+-              return;
++              goto unlock;
++
++      set_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
+       err = mlx5_fw_reset_set_reset_sync_ack(dev);
+       if (err)
+               mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack Failed. Error code: %d\n", err);
+       else
+               mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack. Device reset is expected.\n");
++
++unlock:
++      if (!test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags))
++              devl_unlock(devlink);
+ }
+ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev, u16 dev_id)
+@@ -710,6 +744,8 @@ static void mlx5_sync_reset_abort_event(struct work_struct *work)
+       if (mlx5_sync_reset_clear_reset_requested(dev, true))
+               return;
++
++      clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
+       mlx5_core_warn(dev, "PCI Sync FW Update Reset Aborted.\n");
+ }
+@@ -746,6 +782,7 @@ static void mlx5_sync_reset_timeout_work(struct work_struct *work)
+       if (mlx5_sync_reset_clear_reset_requested(dev, true))
+               return;
++      clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
+       mlx5_core_warn(dev, "PCI Sync FW Update Reset Timeout.\n");
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+index d5b28525c960d..2d96b2adc1cdf 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+@@ -10,6 +10,7 @@ int mlx5_fw_reset_query(struct mlx5_core_dev *dev, u8 *reset_level, u8 *reset_ty
+ int mlx5_fw_reset_set_reset_sync(struct mlx5_core_dev *dev, u8 reset_type_sel,
+                                struct netlink_ext_ack *extack);
+ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev);
++bool mlx5_fw_reset_in_progress(struct mlx5_core_dev *dev);
+ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev);
+ void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked);
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-openvswitch-fix-middle-attribute-validation-in-p.patch b/queue-6.12/net-openvswitch-fix-middle-attribute-validation-in-p.patch
new file mode 100644 (file)
index 0000000..e13156e
--- /dev/null
@@ -0,0 +1,112 @@
+From ccb574c6b9f4a8cbbb1aa0805337b59220b666bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Dec 2025 11:53:32 +0100
+Subject: net: openvswitch: fix middle attribute validation in push_nsh()
+ action
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 5ace7ef87f059d68b5f50837ef3e8a1a4870c36e ]
+
+The push_nsh() action structure looks like this:
+
+ OVS_ACTION_ATTR_PUSH_NSH(OVS_KEY_ATTR_NSH(OVS_NSH_KEY_ATTR_BASE,...))
+
+The outermost OVS_ACTION_ATTR_PUSH_NSH attribute is OK'ed by the
+nla_for_each_nested() inside __ovs_nla_copy_actions().  The innermost
+OVS_NSH_KEY_ATTR_BASE/MD1/MD2 are OK'ed by the nla_for_each_nested()
+inside nsh_key_put_from_nlattr().  But nothing checks if the attribute
+in the middle is OK.  We don't even check that this attribute is the
+OVS_KEY_ATTR_NSH.  We just do a double unwrap with a pair of nla_data()
+calls - first time directly while calling validate_push_nsh() and the
+second time as part of the nla_for_each_nested() macro, which isn't
+safe, potentially causing invalid memory access if the size of this
+attribute is incorrect.  The failure may not be noticed during
+validation due to larger netlink buffer, but cause trouble later during
+action execution where the buffer is allocated exactly to the size:
+
+ BUG: KASAN: slab-out-of-bounds in nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch]
+ Read of size 184 at addr ffff88816459a634 by task a.out/22624
+
+ CPU: 8 UID: 0 PID: 22624 6.18.0-rc7+ #115 PREEMPT(voluntary)
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x51/0x70
+  print_address_description.constprop.0+0x2c/0x390
+  kasan_report+0xdd/0x110
+  kasan_check_range+0x35/0x1b0
+  __asan_memcpy+0x20/0x60
+  nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch]
+  push_nsh+0x82/0x120 [openvswitch]
+  do_execute_actions+0x1405/0x2840 [openvswitch]
+  ovs_execute_actions+0xd5/0x3b0 [openvswitch]
+  ovs_packet_cmd_execute+0x949/0xdb0 [openvswitch]
+  genl_family_rcv_msg_doit+0x1d6/0x2b0
+  genl_family_rcv_msg+0x336/0x580
+  genl_rcv_msg+0x9f/0x130
+  netlink_rcv_skb+0x11f/0x370
+  genl_rcv+0x24/0x40
+  netlink_unicast+0x73e/0xaa0
+  netlink_sendmsg+0x744/0xbf0
+  __sys_sendto+0x3d6/0x450
+  do_syscall_64+0x79/0x2c0
+  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+  </TASK>
+
+Let's add some checks that the attribute is properly sized and it's
+the only one attribute inside the action.  Technically, there is no
+real reason for OVS_KEY_ATTR_NSH to be there, as we know that we're
+pushing an NSH header already, it just creates extra nesting, but
+that's how uAPI works today.  So, keeping as it is.
+
+Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support")
+Reported-by: Junvy Yang <zhuque@tencent.com>
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Eelco Chaudron echaudro@redhat.com
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Link: https://patch.msgid.link/20251204105334.900379-1-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/flow_netlink.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
+index e3359e15aa2e4..7d5490ea23e1d 100644
+--- a/net/openvswitch/flow_netlink.c
++++ b/net/openvswitch/flow_netlink.c
+@@ -2802,13 +2802,20 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
+       return err;
+ }
+-static bool validate_push_nsh(const struct nlattr *attr, bool log)
++static bool validate_push_nsh(const struct nlattr *a, bool log)
+ {
++      struct nlattr *nsh_key = nla_data(a);
+       struct sw_flow_match match;
+       struct sw_flow_key key;
++      /* There must be one and only one NSH header. */
++      if (!nla_ok(nsh_key, nla_len(a)) ||
++          nla_total_size(nla_len(nsh_key)) != nla_len(a) ||
++          nla_type(nsh_key) != OVS_KEY_ATTR_NSH)
++              return false;
++
+       ovs_match_init(&match, &key, true, NULL);
+-      return !nsh_key_put_from_nlattr(attr, &match, false, true, log);
++      return !nsh_key_put_from_nlattr(nsh_key, &match, false, true, log);
+ }
+ /* Return false if there are any non-masked bits set.
+@@ -3388,7 +3395,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
+                                       return -EINVAL;
+                       }
+                       mac_proto = MAC_PROTO_NONE;
+-                      if (!validate_push_nsh(nla_data(a), log))
++                      if (!validate_push_nsh(a, log))
+                               return -EINVAL;
+                       break;
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-sched-ets-always-remove-class-from-active-list-b.patch b/queue-6.12/net-sched-ets-always-remove-class-from-active-list-b.patch
new file mode 100644 (file)
index 0000000..13e4526
--- /dev/null
@@ -0,0 +1,232 @@
+From a773822336c3ab6fb0511a016ccc156376ca33e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Nov 2025 10:19:19 -0500
+Subject: net/sched: ets: Always remove class from active list before deleting
+ in ets_qdisc_change
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit ce052b9402e461a9aded599f5b47e76bc727f7de ]
+
+zdi-disclosures@trendmicro.com says:
+
+The vulnerability is a race condition between `ets_qdisc_dequeue` and
+`ets_qdisc_change`.  It leads to UAF on `struct Qdisc` object.
+Attacker requires the capability to create new user and network namespace
+in order to trigger the bug.
+See my additional commentary at the end of the analysis.
+
+Analysis:
+
+static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+                          struct netlink_ext_ack *extack)
+{
+...
+
+      // (1) this lock is preventing .change handler (`ets_qdisc_change`)
+      //to race with .dequeue handler (`ets_qdisc_dequeue`)
+      sch_tree_lock(sch);
+
+      for (i = nbands; i < oldbands; i++) {
+              if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
+                      list_del_init(&q->classes[i].alist);
+              qdisc_purge_queue(q->classes[i].qdisc);
+      }
+
+      WRITE_ONCE(q->nbands, nbands);
+      for (i = nstrict; i < q->nstrict; i++) {
+              if (q->classes[i].qdisc->q.qlen) {
+                     // (2) the class is added to the q->active
+                      list_add_tail(&q->classes[i].alist, &q->active);
+                      q->classes[i].deficit = quanta[i];
+              }
+      }
+      WRITE_ONCE(q->nstrict, nstrict);
+      memcpy(q->prio2band, priomap, sizeof(priomap));
+
+      for (i = 0; i < q->nbands; i++)
+              WRITE_ONCE(q->classes[i].quantum, quanta[i]);
+
+      for (i = oldbands; i < q->nbands; i++) {
+              q->classes[i].qdisc = queues[i];
+              if (q->classes[i].qdisc != &noop_qdisc)
+                      qdisc_hash_add(q->classes[i].qdisc, true);
+      }
+
+      // (3) the qdisc is unlocked, now dequeue can be called in parallel
+      // to the rest of .change handler
+      sch_tree_unlock(sch);
+
+      ets_offload_change(sch);
+      for (i = q->nbands; i < oldbands; i++) {
+             // (4) we're reducing the refcount for our class's qdisc and
+             //  freeing it
+              qdisc_put(q->classes[i].qdisc);
+             // (5) If we call .dequeue between (4) and (5), we will have
+             // a strong UAF and we can control RIP
+              q->classes[i].qdisc = NULL;
+              WRITE_ONCE(q->classes[i].quantum, 0);
+              q->classes[i].deficit = 0;
+              gnet_stats_basic_sync_init(&q->classes[i].bstats);
+              memset(&q->classes[i].qstats, 0, sizeof(q->classes[i].qstats));
+      }
+      return 0;
+}
+
+Comment:
+This happens because some of the classes have their qdiscs assigned to
+NULL, but remain in the active list. This commit fixes this issue by always
+removing the class from the active list before deleting and freeing its
+associated qdisc
+
+Reproducer Steps
+(trimmed version of what was sent by zdi-disclosures@trendmicro.com)
+
+```
+DEV="${DEV:-lo}"
+ROOT_HANDLE="${ROOT_HANDLE:-1:}"
+BAND2_HANDLE="${BAND2_HANDLE:-20:}"   # child under 1:2
+PING_BYTES="${PING_BYTES:-48}"
+PING_COUNT="${PING_COUNT:-200000}"
+PING_DST="${PING_DST:-127.0.0.1}"
+
+SLOW_TBF_RATE="${SLOW_TBF_RATE:-8bit}"
+SLOW_TBF_BURST="${SLOW_TBF_BURST:-100b}"
+SLOW_TBF_LAT="${SLOW_TBF_LAT:-1s}"
+
+cleanup() {
+  tc qdisc del dev "$DEV" root 2>/dev/null
+}
+trap cleanup EXIT
+
+ip link set "$DEV" up
+
+tc qdisc del dev "$DEV" root 2>/dev/null || true
+
+tc qdisc add dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
+
+tc qdisc add dev "$DEV" parent 1:2 handle "$BAND2_HANDLE" \
+  tbf rate "$SLOW_TBF_RATE" burst "$SLOW_TBF_BURST" latency "$SLOW_TBF_LAT"
+
+tc filter add dev "$DEV" parent 1: protocol all prio 1 u32 match u32 0 0 flowid 1:2
+tc -s qdisc ls dev $DEV
+
+ping -I "$DEV" -f -c "$PING_COUNT" -s "$PING_BYTES" -W 0.001 "$PING_DST" \
+  >/dev/null 2>&1 &
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 0
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
+tc -s qdisc ls dev $DEV
+tc qdisc del dev "$DEV" parent 1:2 || true
+tc -s qdisc ls dev $DEV
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 1 strict 1
+```
+
+KASAN report
+```
+==================================================================
+BUG: KASAN: slab-use-after-free in ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
+Read of size 8 at addr ffff8880502fc018 by task ping/12308
+>
+CPU: 0 UID: 0 PID: 12308 Comm: ping Not tainted 6.18.0-rc4-dirty #1 PREEMPT(full)
+Hardware name: QEMU Ubuntu 25.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <IRQ>
+ __dump_stack kernel/lib/dump_stack.c:94
+ dump_stack_lvl+0x100/0x190 kernel/lib/dump_stack.c:120
+ print_address_description kernel/mm/kasan/report.c:378
+ print_report+0x156/0x4c9 kernel/mm/kasan/report.c:482
+ kasan_report+0xdf/0x110 kernel/mm/kasan/report.c:595
+ ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
+ dequeue_skb kernel/net/sched/sch_generic.c:294
+ qdisc_restart kernel/net/sched/sch_generic.c:399
+ __qdisc_run+0x1c9/0x1b00 kernel/net/sched/sch_generic.c:417
+ __dev_xmit_skb kernel/net/core/dev.c:4221
+ __dev_queue_xmit+0x2848/0x4410 kernel/net/core/dev.c:4729
+ dev_queue_xmit kernel/./include/linux/netdevice.h:3365
+[...]
+
+Allocated by task 17115:
+ kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
+ kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
+ poison_kmalloc_redzone kernel/mm/kasan/common.c:400
+ __kasan_kmalloc+0xaa/0xb0 kernel/mm/kasan/common.c:417
+ kasan_kmalloc kernel/./include/linux/kasan.h:262
+ __do_kmalloc_node kernel/mm/slub.c:5642
+ __kmalloc_node_noprof+0x34e/0x990 kernel/mm/slub.c:5648
+ kmalloc_node_noprof kernel/./include/linux/slab.h:987
+ qdisc_alloc+0xb8/0xc30 kernel/net/sched/sch_generic.c:950
+ qdisc_create_dflt+0x93/0x490 kernel/net/sched/sch_generic.c:1012
+ ets_class_graft+0x4fd/0x800 kernel/net/sched/sch_ets.c:261
+ qdisc_graft+0x3e4/0x1780 kernel/net/sched/sch_api.c:1196
+[...]
+
+Freed by task 9905:
+ kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
+ kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
+ __kasan_save_free_info+0x3b/0x70 kernel/mm/kasan/generic.c:587
+ kasan_save_free_info kernel/mm/kasan/kasan.h:406
+ poison_slab_object kernel/mm/kasan/common.c:252
+ __kasan_slab_free+0x5f/0x80 kernel/mm/kasan/common.c:284
+ kasan_slab_free kernel/./include/linux/kasan.h:234
+ slab_free_hook kernel/mm/slub.c:2539
+ slab_free kernel/mm/slub.c:6630
+ kfree+0x144/0x700 kernel/mm/slub.c:6837
+ rcu_do_batch kernel/kernel/rcu/tree.c:2605
+ rcu_core+0x7c0/0x1500 kernel/kernel/rcu/tree.c:2861
+ handle_softirqs+0x1ea/0x8a0 kernel/kernel/softirq.c:622
+ __do_softirq kernel/kernel/softirq.c:656
+[...]
+
+Commentary:
+
+1. Maher Azzouzi working with Trend Micro Zero Day Initiative was reported as
+the person who found the issue. I requested to get a proper email to add to the
+reported-by tag but got no response. For this reason i will credit the person
+i exchanged emails with i.e zdi-disclosures@trendmicro.com
+
+2. Neither i nor Victor who did a much more thorough testing was able to
+reproduce a UAF with the PoC or other approaches we tried. We were both able to
+reproduce a null ptr deref. After exchange with zdi-disclosures@trendmicro.com
+they sent a small change to be made to the code to add an extra delay which
+was able to simulate the UAF. i.e, this:
+   qdisc_put(q->classes[i].qdisc);
+   mdelay(90);
+   q->classes[i].qdisc = NULL;
+
+I was informed by Thomas Gleixner(tglx@linutronix.de) that adding delays was
+acceptable approach for demonstrating the bug, quote:
+"Adding such delays is common exploit validation practice"
+The equivalent delay could happen "by virt scheduling the vCPU out, SMIs,
+NMIs, PREEMPT_RT enabled kernel"
+
+3. I asked the OP to test and report back but got no response and after a
+few days gave up and proceeded to submit this fix.
+
+Fixes: de6d25924c2a ("net/sched: sch_ets: don't peek at classes beyond 'nbands'")
+Reported-by: zdi-disclosures@trendmicro.com
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20251128151919.576920-1-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_ets.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index 82635dd2cfa59..ae46643e596d3 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -652,7 +652,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+       sch_tree_lock(sch);
+       for (i = nbands; i < oldbands; i++) {
+-              if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
++              if (cl_is_active(&q->classes[i]))
+                       list_del_init(&q->classes[i].alist);
+               qdisc_purge_queue(q->classes[i].qdisc);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.12/net-sched-ets-remove-drr-class-from-the-active-list-.patch b/queue-6.12/net-sched-ets-remove-drr-class-from-the-active-list-.patch
new file mode 100644 (file)
index 0000000..08a04fc
--- /dev/null
@@ -0,0 +1,88 @@
+From 5657b91dc6d2b8fdf094060a9185ceead654078a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 16:01:24 -0300
+Subject: net/sched: ets: Remove drr class from the active list if it changes
+ to strict
+
+From: Victor Nogueira <victor@mojatatu.com>
+
+[ Upstream commit b1e125ae425aba9b45252e933ca8df52a843ec70 ]
+
+Whenever a user issues an ets qdisc change command, transforming a
+drr class into a strict one, the ets code isn't checking whether that
+class was in the active list and removing it. This means that, if a
+user changes a strict class (which was in the active list) back to a drr
+one, that class will be added twice to the active list [1].
+
+Doing so with the following commands:
+
+tc qdisc add dev lo root handle 1: ets bands 2 strict 1
+tc qdisc add dev lo parent 1:2 handle 20: \
+    tbf rate 8bit burst 100b latency 1s
+tc filter add dev lo parent 1: basic classid 1:2
+ping -c1 -W0.01 -s 56 127.0.0.1
+tc qdisc change dev lo root handle 1: ets bands 2 strict 2
+tc qdisc change dev lo root handle 1: ets bands 2 strict 1
+ping -c1 -W0.01 -s 56 127.0.0.1
+
+Will trigger the following splat with list debug turned on:
+
+[   59.279014][  T365] ------------[ cut here ]------------
+[   59.279452][  T365] list_add double add: new=ffff88801d60e350, prev=ffff88801d60e350, next=ffff88801d60e2c0.
+[   59.280153][  T365] WARNING: CPU: 3 PID: 365 at lib/list_debug.c:35 __list_add_valid_or_report+0x17f/0x220
+[   59.280860][  T365] Modules linked in:
+[   59.281165][  T365] CPU: 3 UID: 0 PID: 365 Comm: tc Not tainted 6.18.0-rc7-00105-g7e9f13163c13-dirty #239 PREEMPT(voluntary)
+[   59.281977][  T365] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+[   59.282391][  T365] RIP: 0010:__list_add_valid_or_report+0x17f/0x220
+[   59.282842][  T365] Code: 89 c6 e8 d4 b7 0d ff 90 0f 0b 90 90 31 c0 e9 31 ff ff ff 90 48 c7 c7 e0 a0 22 9f 48 89 f2 48 89 c1 4c 89 c6 e8 b2 b7 0d ff 90 <0f> 0b 90 90 31 c0 e9 0f ff ff ff 48 89 f7 48 89 44 24 10 4c 89 44
+...
+[   59.288812][  T365] Call Trace:
+[   59.289056][  T365]  <TASK>
+[   59.289224][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.289546][  T365]  ets_qdisc_change+0xd2b/0x1e80
+[   59.289891][  T365]  ? __lock_acquire+0x7e7/0x1be0
+[   59.290223][  T365]  ? __pfx_ets_qdisc_change+0x10/0x10
+[   59.290546][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.290898][  T365]  ? __mutex_trylock_common+0xda/0x240
+[   59.291228][  T365]  ? __pfx___mutex_trylock_common+0x10/0x10
+[   59.291655][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.291993][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.292313][  T365]  ? trace_contention_end+0xc8/0x110
+[   59.292656][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.293022][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.293351][  T365]  tc_modify_qdisc+0x63a/0x1cf0
+
+Fix this by always checking and removing an ets class from the active list
+when changing it to strict.
+
+[1] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/tree/net/sched/sch_ets.c?id=ce052b9402e461a9aded599f5b47e76bc727f7de#n663
+
+Fixes: cd9b50adc6bb9 ("net/sched: ets: fix crash when flipping from 'strict' to 'quantum'")
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/20251208190125.1868423-1-victor@mojatatu.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_ets.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index ae46643e596d3..306e046276d46 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -664,6 +664,10 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+                       q->classes[i].deficit = quanta[i];
+               }
+       }
++      for (i = q->nstrict; i < nstrict; i++) {
++              if (cl_is_active(&q->classes[i]))
++                      list_del_init(&q->classes[i].alist);
++      }
+       WRITE_ONCE(q->nstrict, nstrict);
+       memcpy(q->prio2band, priomap, sizeof(priomap));
+-- 
+2.51.0
+
diff --git a/queue-6.12/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch b/queue-6.12/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch
new file mode 100644 (file)
index 0000000..6f6c631
--- /dev/null
@@ -0,0 +1,90 @@
+From 191b042ce00604aab1491b19a9f26e88753d2239 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 12:58:01 +0100
+Subject: netfilter: nf_conncount: fix leaked ct in error paths
+
+From: Fernando Fernandez Mancera <fmancera@suse.de>
+
+[ Upstream commit 2e2a720766886190a6d35c116794693aabd332b6 ]
+
+There are some situations where ct might be leaked as error paths are
+skipping the refcounted check and return immediately. In order to solve
+it make sure that the check is always called.
+
+Fixes: be102eb6a0e7 ("netfilter: nf_conncount: rework API to use sk_buff directly")
+Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conncount.c | 25 ++++++++++++++-----------
+ 1 file changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
+index b84cfb5616df4..3c1b155f7a0ea 100644
+--- a/net/netfilter/nf_conncount.c
++++ b/net/netfilter/nf_conncount.c
+@@ -172,14 +172,14 @@ static int __nf_conncount_add(struct net *net,
+       struct nf_conn *found_ct;
+       unsigned int collect = 0;
+       bool refcounted = false;
++      int err = 0;
+       if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted))
+               return -ENOENT;
+       if (ct && nf_ct_is_confirmed(ct)) {
+-              if (refcounted)
+-                      nf_ct_put(ct);
+-              return -EEXIST;
++              err = -EEXIST;
++              goto out_put;
+       }
+       if ((u32)jiffies == list->last_gc)
+@@ -231,12 +231,16 @@ static int __nf_conncount_add(struct net *net,
+       }
+ add_new_node:
+-      if (WARN_ON_ONCE(list->count > INT_MAX))
+-              return -EOVERFLOW;
++      if (WARN_ON_ONCE(list->count > INT_MAX)) {
++              err = -EOVERFLOW;
++              goto out_put;
++      }
+       conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC);
+-      if (conn == NULL)
+-              return -ENOMEM;
++      if (conn == NULL) {
++              err = -ENOMEM;
++              goto out_put;
++      }
+       conn->tuple = tuple;
+       conn->zone = *zone;
+@@ -249,7 +253,7 @@ static int __nf_conncount_add(struct net *net,
+ out_put:
+       if (refcounted)
+               nf_ct_put(ct);
+-      return 0;
++      return err;
+ }
+ int nf_conncount_add_skb(struct net *net,
+@@ -446,11 +450,10 @@ insert_tree(struct net *net,
+               rb_link_node_rcu(&rbconn->node, parent, rbnode);
+               rb_insert_color(&rbconn->node, root);
+-
+-              if (refcounted)
+-                      nf_ct_put(ct);
+       }
+ out_unlock:
++      if (refcounted)
++              nf_ct_put(ct);
+       spin_unlock_bh(&nf_conncount_locks[hash]);
+       return count;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.12/netfilter-nf_nat-remove-bogus-direction-check.patch b/queue-6.12/netfilter-nf_nat-remove-bogus-direction-check.patch
new file mode 100644 (file)
index 0000000..0fd70ce
--- /dev/null
@@ -0,0 +1,129 @@
+From d741950da7f6cc641e85d0e67a613a5d07f42f68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 16:00:34 +0100
+Subject: netfilter: nf_nat: remove bogus direction check
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 5ec8ca26fe93103577c904644b0957f069d0051a ]
+
+Jakub reports spurious failures of the 'conntrack_reverse_clash.sh'
+selftest.  A bogus test makes nat core resort to port rewrite even
+though there is no need for this.
+
+When the test is made, nf_nat_used_tuple() would already have caused us
+to return if no other CPU had added a colliding entry.
+Moreover, nf_nat_used_tuple() would have ignored the colliding entry if
+their origin tuples had been the same.
+
+All that is left to check is if the colliding entry in the hash table
+is subject to NAT, and, if its not, if our entry matches in the reverse
+direction, e.g. hash table has
+
+addr1:1234 -> addr2:80, and we want to commit
+addr2:80   -> addr1:1234.
+
+Because we already checked that neither the new nor the committed entry is
+subject to NAT we only have to check origin vs. reply tuple:
+for non-nat entries, the reply tuple is always the inverted original.
+
+Just in case there are more problems extend the error reporting
+in the selftest while at it and dump conntrack table/stats on error.
+
+Reported-by: Jakub Kicinski <kuba@kernel.org>
+Closes: https://lore.kernel.org/netdev/20251206175135.4a56591b@kernel.org/
+Fixes: d8f84a9bc7c4 ("netfilter: nf_nat: don't try nat source port reallocation for reverse dir clash")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_nat_core.c                        | 14 +-------------
+ .../net/netfilter/conntrack_reverse_clash.c        | 13 +++++++++----
+ .../net/netfilter/conntrack_reverse_clash.sh       |  2 ++
+ 3 files changed, 12 insertions(+), 17 deletions(-)
+
+diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
+index 02f10a46fab7c..746acd124ea28 100644
+--- a/net/netfilter/nf_nat_core.c
++++ b/net/netfilter/nf_nat_core.c
+@@ -298,25 +298,13 @@ nf_nat_used_tuple_new(const struct nf_conntrack_tuple *tuple,
+       ct = nf_ct_tuplehash_to_ctrack(thash);
+-      /* NB: IP_CT_DIR_ORIGINAL should be impossible because
+-       * nf_nat_used_tuple() handles origin collisions.
+-       *
+-       * Handle remote chance other CPU confirmed its ct right after.
+-       */
+-      if (thash->tuple.dst.dir != IP_CT_DIR_REPLY)
+-              goto out;
+-
+       /* clashing connection subject to NAT? Retry with new tuple. */
+       if (READ_ONCE(ct->status) & uses_nat)
+               goto out;
+       if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+-                            &ignored_ct->tuplehash[IP_CT_DIR_REPLY].tuple) &&
+-          nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
+-                            &ignored_ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple)) {
++                            &ignored_ct->tuplehash[IP_CT_DIR_REPLY].tuple))
+               taken = false;
+-              goto out;
+-      }
+ out:
+       nf_ct_put(ct);
+       return taken;
+diff --git a/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.c b/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.c
+index 507930cee8cb6..462d628cc3bdb 100644
+--- a/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.c
++++ b/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.c
+@@ -33,9 +33,14 @@ static void die(const char *e)
+       exit(111);
+ }
+-static void die_port(uint16_t got, uint16_t want)
++static void die_port(const struct sockaddr_in *sin, uint16_t want)
+ {
+-      fprintf(stderr, "Port number changed, wanted %d got %d\n", want, ntohs(got));
++      uint16_t got = ntohs(sin->sin_port);
++      char str[INET_ADDRSTRLEN];
++
++      inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str));
++
++      fprintf(stderr, "Port number changed, wanted %d got %d from %s\n", want, got, str);
+       exit(1);
+ }
+@@ -100,7 +105,7 @@ int main(int argc, char *argv[])
+                               die("child recvfrom");
+                       if (peer.sin_port != htons(PORT))
+-                              die_port(peer.sin_port, PORT);
++                              die_port(&peer, PORT);
+               } else {
+                       if (sendto(s2, buf, LEN, 0, (struct sockaddr *)&sa1, sizeof(sa1)) != LEN)
+                               continue;
+@@ -109,7 +114,7 @@ int main(int argc, char *argv[])
+                               die("parent recvfrom");
+                       if (peer.sin_port != htons((PORT + 1)))
+-                              die_port(peer.sin_port, PORT + 1);
++                              die_port(&peer, PORT + 1);
+               }
+       }
+diff --git a/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.sh b/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.sh
+index a24c896347a88..dc7e9d6da0624 100755
+--- a/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.sh
++++ b/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.sh
+@@ -45,6 +45,8 @@ if ip netns exec "$ns0" ./conntrack_reverse_clash; then
+       echo "PASS: No SNAT performed for null bindings"
+ else
+       echo "ERROR: SNAT performed without any matching snat rule"
++      ip netns exec "$ns0" conntrack -L
++      ip netns exec "$ns0" conntrack -S
+       exit 1
+ fi
+-- 
+2.51.0
+
diff --git a/queue-6.12/netfilter-nf_tables-remove-redundant-chain-validatio.patch b/queue-6.12/netfilter-nf_tables-remove-redundant-chain-validatio.patch
new file mode 100644 (file)
index 0000000..ef77c7a
--- /dev/null
@@ -0,0 +1,59 @@
+From 67493ab8c62efacf710dce88eb69412dd50ef829 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Nov 2025 13:42:05 +0100
+Subject: netfilter: nf_tables: remove redundant chain validation on register
+ store
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit a67fd55f6a09f4119b7232c19e0f348fe31ab0db ]
+
+This validation predates the introduction of the state machine that
+determines when to enter slow path validation for error reporting.
+
+Currently, table validation is perform when:
+
+- new rule contains expressions that need validation.
+- new set element with jump/goto verdict.
+
+Validation on register store skips most checks with no basechains, still
+this walks the graph searching for loops and ensuring expressions are
+called from the right hook. Remove this.
+
+Fixes: a654de8fdc18 ("netfilter: nf_tables: fix chain dependency validation")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index e1c617b488889..b4741fb337988 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -11211,21 +11211,10 @@ static int nft_validate_register_store(const struct nft_ctx *ctx,
+                                      enum nft_data_types type,
+                                      unsigned int len)
+ {
+-      int err;
+-
+       switch (reg) {
+       case NFT_REG_VERDICT:
+               if (type != NFT_DATA_VERDICT)
+                       return -EINVAL;
+-
+-              if (data != NULL &&
+-                  (data->verdict.code == NFT_GOTO ||
+-                   data->verdict.code == NFT_JUMP)) {
+-                      err = nft_chain_validate(ctx, data->verdict.chain);
+-                      if (err < 0)
+-                              return err;
+-              }
+-
+               break;
+       default:
+               if (type != NFT_DATA_VALUE)
+-- 
+2.51.0
+
diff --git a/queue-6.12/netrom-fix-memory-leak-in-nr_sendmsg.patch b/queue-6.12/netrom-fix-memory-leak-in-nr_sendmsg.patch
new file mode 100644 (file)
index 0000000..59e8c77
--- /dev/null
@@ -0,0 +1,74 @@
+From 505eccb8c5767c5e1784559f032b408c455da0d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Nov 2025 12:13:15 +0800
+Subject: netrom: Fix memory leak in nr_sendmsg()
+
+From: Wang Liang <wangliang74@huawei.com>
+
+[ Upstream commit 613d12dd794e078be8ff3cf6b62a6b9acf7f4619 ]
+
+syzbot reported a memory leak [1].
+
+When function sock_alloc_send_skb() return NULL in nr_output(), the
+original skb is not freed, which was allocated in nr_sendmsg(). Fix this
+by freeing it before return.
+
+[1]
+BUG: memory leak
+unreferenced object 0xffff888129f35500 (size 240):
+  comm "syz.0.17", pid 6119, jiffies 4294944652
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+    00 00 00 00 00 00 00 00 00 10 52 28 81 88 ff ff  ..........R(....
+  backtrace (crc 1456a3e4):
+    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
+    slab_post_alloc_hook mm/slub.c:4983 [inline]
+    slab_alloc_node mm/slub.c:5288 [inline]
+    kmem_cache_alloc_node_noprof+0x36f/0x5e0 mm/slub.c:5340
+    __alloc_skb+0x203/0x240 net/core/skbuff.c:660
+    alloc_skb include/linux/skbuff.h:1383 [inline]
+    alloc_skb_with_frags+0x69/0x3f0 net/core/skbuff.c:6671
+    sock_alloc_send_pskb+0x379/0x3e0 net/core/sock.c:2965
+    sock_alloc_send_skb include/net/sock.h:1859 [inline]
+    nr_sendmsg+0x287/0x450 net/netrom/af_netrom.c:1105
+    sock_sendmsg_nosec net/socket.c:727 [inline]
+    __sock_sendmsg net/socket.c:742 [inline]
+    sock_write_iter+0x293/0x2a0 net/socket.c:1195
+    new_sync_write fs/read_write.c:593 [inline]
+    vfs_write+0x45d/0x710 fs/read_write.c:686
+    ksys_write+0x143/0x170 fs/read_write.c:738
+    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+    do_syscall_64+0xa4/0xfa0 arch/x86/entry/syscall_64.c:94
+    entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Reported-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=d7abc36bbbb6d7d40b58
+Tested-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Wang Liang <wangliang74@huawei.com>
+Link: https://patch.msgid.link/20251129041315.1550766-1-wangliang74@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netrom/nr_out.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/netrom/nr_out.c b/net/netrom/nr_out.c
+index 5e531394a724b..2b3cbceb0b52d 100644
+--- a/net/netrom/nr_out.c
++++ b/net/netrom/nr_out.c
+@@ -43,8 +43,10 @@ void nr_output(struct sock *sk, struct sk_buff *skb)
+               frontlen = skb_headroom(skb);
+               while (skb->len > 0) {
+-                      if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL)
++                      if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL) {
++                              kfree_skb(skb);
+                               return;
++                      }
+                       skb_reserve(skbn, frontlen);
+-- 
+2.51.0
+
diff --git a/queue-6.12/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch b/queue-6.12/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch
new file mode 100644 (file)
index 0000000..f689de5
--- /dev/null
@@ -0,0 +1,37 @@
+From 2fba550b3985efa5a36fc53bd0bb8c14a81c943e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 09:56:39 +0300
+Subject: nfc: pn533: Fix error code in pn533_acr122_poweron_rdr()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 885bebac9909994050bbbeed0829c727e42bd1b7 ]
+
+Set the error code if "transferred != sizeof(cmd)" instead of
+returning success.
+
+Fixes: dbafc28955fa ("NFC: pn533: don't send USB data off of the stack")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/aTfIJ9tZPmeUF4W1@stanley.mountain
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/pn533/usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c
+index ffd7367ce1194..018a80674f06e 100644
+--- a/drivers/nfc/pn533/usb.c
++++ b/drivers/nfc/pn533/usb.c
+@@ -406,7 +406,7 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy)
+       if (rc || (transferred != sizeof(cmd))) {
+               nfc_err(&phy->udev->dev,
+                       "Reader power on cmd error %d\n", rc);
+-              return rc;
++              return rc ?: -EINVAL;
+       }
+       rc =  usb_submit_urb(phy->in_urb, GFP_KERNEL);
+-- 
+2.51.0
+
diff --git a/queue-6.12/selftests-netfilter-packetdrill-avoid-failure-on-hz-.patch b/queue-6.12/selftests-netfilter-packetdrill-avoid-failure-on-hz-.patch
new file mode 100644 (file)
index 0000000..71277ac
--- /dev/null
@@ -0,0 +1,41 @@
+From c07d7adb1efa70d6d1ca503d6b94065f8fb24c5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 13:16:49 +0100
+Subject: selftests: netfilter: packetdrill: avoid failure on HZ=100 kernel
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit fec7b0795548b43e2c3c46e3143c34ef6070341c ]
+
+packetdrill --ip_version=ipv4 --mtu=1500 --tolerance_usecs=1000000 --non_fatal packet conntrack_syn_challenge_ack.pkt
+conntrack v1.4.8 (conntrack-tools): 1 flow entries have been shown.
+conntrack_syn_challenge_ack.pkt:32: error executing `conntrack -f $NFCT_IP_VERSION \
+-L -p tcp --dport 8080 | grep UNREPLIED | grep -q SYN_SENT` command: non-zero status 1
+
+Affected kernel had CONFIG_HZ=100; reset packet was still sitting in
+backlog.
+
+Reported-by: Yi Chen <yiche@redhat.com>
+Fixes: a8a388c2aae4 ("selftests: netfilter: add packetdrill based conntrack tests")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/netfilter/packetdrill/conntrack_syn_challenge_ack.pkt   | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/netfilter/packetdrill/conntrack_syn_challenge_ack.pkt b/tools/testing/selftests/net/netfilter/packetdrill/conntrack_syn_challenge_ack.pkt
+index 3442cd29bc932..cdb3910af95b4 100644
+--- a/tools/testing/selftests/net/netfilter/packetdrill/conntrack_syn_challenge_ack.pkt
++++ b/tools/testing/selftests/net/netfilter/packetdrill/conntrack_syn_challenge_ack.pkt
+@@ -26,7 +26,7 @@
+ +0.01 > R 643160523:643160523(0) win 0
+-+0.01 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null | grep UNREPLIED | grep -q SYN_SENT`
+++0.1 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null | grep UNREPLIED | grep -q SYN_SENT`
+ // Must go through.
+ +0.01 > S 0:0(0) win 65535 <mss 1460,sackOK,TS val 1 ecr 0,nop,wscale 8>
+-- 
+2.51.0
+
index 7cc312b701a1733a88748dd2223d466a83d1d3a0..0d234f2e374043bac012ef9d4eb56dfa6695a1b4 100644 (file)
@@ -42,3 +42,36 @@ bluetooth-btusb-mt7920-add-vid-pid-0489-e135.patch
 bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch
 bluetooth-btusb-add-new-vid-pid-0x0489-0xe12f-for-rt.patch
 gfs2-fix-use-of-bio_chain.patch
 bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch
 bluetooth-btusb-add-new-vid-pid-0x0489-0xe12f-for-rt.patch
 gfs2-fix-use-of-bio_chain.patch
+net-fec-err007885-workaround-for-xdp-tx-path.patch
+netrom-fix-memory-leak-in-nr_sendmsg.patch
+net-sched-ets-always-remove-class-from-active-list-b.patch
+ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch
+mlxsw-spectrum_router-fix-possible-neighbour-referen.patch
+mlxsw-spectrum_router-fix-neighbour-use-after-free.patch
+mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch
+bnxt_en-fix-xdp_tx-path.patch
+net-openvswitch-fix-middle-attribute-validation-in-p.patch
+broadcom-b44-prevent-uninitialized-value-usage.patch
+netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch
+ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch
+caif-fix-integer-underflow-in-cffrml_receive.patch
+net-sched-ets-remove-drr-class-from-the-active-list-.patch
+nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch
+netfilter-nf_nat-remove-bogus-direction-check.patch
+netfilter-nf_tables-remove-redundant-chain-validatio.patch
+selftests-netfilter-packetdrill-avoid-failure-on-hz-.patch
+iommufd-selftest-add-coverage-for-reporting-max_pasi.patch
+iommufd-selftest-update-hw_info-coverage-for-an-inpu.patch
+iommufd-selftest-make-it-clearer-to-gcc-that-the-acc.patch
+iommufd-selftest-check-for-overflow-in-iommu_test_op.patch
+ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch
+net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch
+net-mlx5-drain-firmware-reset-in-shutdown-callback.patch
+net-mlx5-fw_tracer-validate-format-string-parameters.patch
+net-mlx5-fw_tracer-handle-escaped-percent-properly.patch
+net-mlx5-serialize-firmware-reset-with-devlink.patch
+net-handshake-duplicate-handshake-cancellations-leak.patch
+net-enetc-do-not-transmit-redirected-xdp-frames-when.patch
+net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch
+net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch
+net-hns3-add-vlan-id-validation-before-using.patch
diff --git a/queue-6.18/bnxt_en-fix-xdp_tx-path.patch b/queue-6.18/bnxt_en-fix-xdp_tx-path.patch
new file mode 100644 (file)
index 0000000..b640f4e
--- /dev/null
@@ -0,0 +1,74 @@
+From 27f5af46c0c8a38985bc2e4633391663b3e1fad0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 16:30:24 -0800
+Subject: bnxt_en: Fix XDP_TX path
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit 0373d5c387f24de749cc22e694a14b3a7c7eb515 ]
+
+For XDP_TX action in bnxt_rx_xdp(), clearing of the event flags is not
+correct.  __bnxt_poll_work() -> bnxt_rx_pkt() -> bnxt_rx_xdp() may be
+looping within NAPI and some event flags may be set in earlier
+iterations.  In particular, if BNXT_TX_EVENT is set earlier indicating
+some XDP_TX packets are ready and pending, it will be cleared if it is
+XDP_TX action again.  Normally, we will set BNXT_TX_EVENT again when we
+successfully call __bnxt_xmit_xdp().  But if the TX ring has no more
+room, the flag will not be set.  This will cause the TX producer to be
+ahead but the driver will not hit the TX doorbell.
+
+For multi-buf XDP_TX, there is no need to clear the event flags and set
+BNXT_AGG_EVENT.  The BNXT_AGG_EVENT flag should have been set earlier in
+bnxt_rx_pkt().
+
+The visible symptom of this is that the RX ring associated with the
+TX XDP ring will eventually become empty and all packets will be dropped.
+Because this condition will cause the driver to not refill the RX ring
+seeing that the TX ring has forever pending XDP_TX packets.
+
+The fix is to only clear BNXT_RX_EVENT when we have successfully
+called __bnxt_xmit_xdp().
+
+Fixes: 7f0a168b0441 ("bnxt_en: Add completion ring pointer in TX and RX ring structures")
+Reported-by: Pavel Dubovitsky <pdubovitsky@meta.com>
+Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
+Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20251203003024.2246699-1-michael.chan@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+index 3e77a96e5a3e3..c94a391b1ba5b 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+@@ -268,13 +268,11 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
+       case XDP_TX:
+               rx_buf = &rxr->rx_buf_ring[cons];
+               mapping = rx_buf->mapping - bp->rx_dma_offset;
+-              *event &= BNXT_TX_CMP_EVENT;
+               if (unlikely(xdp_buff_has_frags(xdp))) {
+                       struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);
+                       tx_needed += sinfo->nr_frags;
+-                      *event = BNXT_AGG_EVENT;
+               }
+               if (tx_avail < tx_needed) {
+@@ -287,6 +285,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
+               dma_sync_single_for_device(&pdev->dev, mapping + offset, *len,
+                                          bp->rx_dir);
++              *event &= ~BNXT_RX_EVENT;
+               *event |= BNXT_TX_EVENT;
+               __bnxt_xmit_xdp(bp, txr, mapping + offset, *len,
+                               NEXT_RX(rxr->rx_prod), xdp);
+-- 
+2.51.0
+
diff --git a/queue-6.18/broadcom-b44-prevent-uninitialized-value-usage.patch b/queue-6.18/broadcom-b44-prevent-uninitialized-value-usage.patch
new file mode 100644 (file)
index 0000000..cca84d9
--- /dev/null
@@ -0,0 +1,45 @@
+From b665ba585b9a17e8c91e77884f85d45a5ec561c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 18:58:16 +0300
+Subject: broadcom: b44: prevent uninitialized value usage
+
+From: Alexey Simakov <bigalex934@gmail.com>
+
+[ Upstream commit 50b3db3e11864cb4e18ff099cfb38e11e7f87a68 ]
+
+On execution path with raised B44_FLAG_EXTERNAL_PHY, b44_readphy()
+leaves bmcr value uninitialized and it is used later in the code.
+
+Add check of this flag at the beginning of the b44_nway_reset() and
+exit early of the function with restarting autonegotiation if an
+external PHY is used.
+
+Fixes: 753f492093da ("[B44]: port to native ssb support")
+Reviewed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Alexey Simakov <bigalex934@gmail.com>
+Reviewed-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20251205155815.4348-1-bigalex934@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/b44.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
+index 0353359c3fe96..073d7d490d4b6 100644
+--- a/drivers/net/ethernet/broadcom/b44.c
++++ b/drivers/net/ethernet/broadcom/b44.c
+@@ -1789,6 +1789,9 @@ static int b44_nway_reset(struct net_device *dev)
+       u32 bmcr;
+       int r;
++      if (bp->flags & B44_FLAG_EXTERNAL_PHY)
++              return phy_ethtool_nway_reset(dev);
++
+       spin_lock_irq(&bp->lock);
+       b44_readphy(bp, MII_BMCR, &bmcr);
+       b44_readphy(bp, MII_BMCR, &bmcr);
+-- 
+2.51.0
+
diff --git a/queue-6.18/caif-fix-integer-underflow-in-cffrml_receive.patch b/queue-6.18/caif-fix-integer-underflow-in-cffrml_receive.patch
new file mode 100644 (file)
index 0000000..864d520
--- /dev/null
@@ -0,0 +1,58 @@
+From 7f401d0b83f02f589b05857ec760a920f62358ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Dec 2025 21:30:47 +0800
+Subject: caif: fix integer underflow in cffrml_receive()
+
+From: Junrui Luo <moonafterrain@outlook.com>
+
+[ Upstream commit 8a11ff0948b5ad09b71896b7ccc850625f9878d1 ]
+
+The cffrml_receive() function extracts a length field from the packet
+header and, when FCS is disabled, subtracts 2 from this length without
+validating that len >= 2.
+
+If an attacker sends a malicious packet with a length field of 0 or 1
+to an interface with FCS disabled, the subtraction causes an integer
+underflow.
+
+This can lead to memory exhaustion and kernel instability, potential
+information disclosure if padding contains uninitialized kernel memory.
+
+Fix this by validating that len >= 2 before performing the subtraction.
+
+Reported-by: Yuhao Jiang <danisjiang@gmail.com>
+Reported-by: Junrui Luo <moonafterrain@outlook.com>
+Fixes: b482cd2053e3 ("net-caif: add CAIF core protocol stack")
+Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/SYBPR01MB7881511122BAFEA8212A1608AFA6A@SYBPR01MB7881.ausprd01.prod.outlook.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/caif/cffrml.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c
+index 6651a8dc62e04..d4d63586053ad 100644
+--- a/net/caif/cffrml.c
++++ b/net/caif/cffrml.c
+@@ -92,8 +92,15 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
+       len = le16_to_cpu(tmp);
+       /* Subtract for FCS on length if FCS is not used. */
+-      if (!this->dofcs)
++      if (!this->dofcs) {
++              if (len < 2) {
++                      ++cffrml_rcv_error;
++                      pr_err("Invalid frame length (%d)\n", len);
++                      cfpkt_destroy(pkt);
++                      return -EPROTO;
++              }
+               len -= 2;
++      }
+       if (cfpkt_setlen(pkt, len) < 0) {
+               ++cffrml_rcv_error;
+-- 
+2.51.0
+
diff --git a/queue-6.18/can-j1939-make-j1939_sk_bind-fail-if-device-is-no-lo.patch b/queue-6.18/can-j1939-make-j1939_sk_bind-fail-if-device-is-no-lo.patch
new file mode 100644 (file)
index 0000000..3ac1cbd
--- /dev/null
@@ -0,0 +1,54 @@
+From e006f63bc5ac902e241dcf50dbdc5a11b26202ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 22:43:12 +0900
+Subject: can: j1939: make j1939_sk_bind() fail if device is no longer
+ registered
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+[ Upstream commit 46cea215dc9444ec32a76b1b6a9cb809e17b64d5 ]
+
+There is a theoretical race window in j1939_sk_netdev_event_unregister()
+where two j1939_sk_bind() calls jump in between read_unlock_bh() and
+lock_sock().
+
+The assumption jsk->priv == priv can fail if the first j1939_sk_bind()
+call once made jsk->priv == NULL due to failed j1939_local_ecu_get() call
+and the second j1939_sk_bind() call again made jsk->priv != NULL due to
+successful j1939_local_ecu_get() call.
+
+Since the socket lock is held by both j1939_sk_netdev_event_unregister()
+and j1939_sk_bind(), checking ndev->reg_state with the socket lock held can
+reliably make the second j1939_sk_bind() call fail (and close this race
+window).
+
+Fixes: 7fcbe5b2c6a4 ("can: j1939: implement NETDEV_UNREGISTER notification handler")
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/5732921e-247e-4957-a364-da74bd7031d7@I-love.SAKURA.ne.jp
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/socket.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c
+index 88e7160d42489..e3ba2e9fc0e9b 100644
+--- a/net/can/j1939/socket.c
++++ b/net/can/j1939/socket.c
+@@ -482,6 +482,12 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr *uaddr, int len)
+                       goto out_release_sock;
+               }
++              if (ndev->reg_state != NETREG_REGISTERED) {
++                      dev_put(ndev);
++                      ret = -ENODEV;
++                      goto out_release_sock;
++              }
++
+               can_ml = can_get_ml_priv(ndev);
+               if (!can_ml) {
+                       dev_put(ndev);
+-- 
+2.51.0
+
diff --git a/queue-6.18/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch b/queue-6.18/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch
new file mode 100644 (file)
index 0000000..6b1295e
--- /dev/null
@@ -0,0 +1,159 @@
+From c409cedbeee44bebcaa6fb7e3d8cf6c080fef8d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 14:19:01 +0200
+Subject: ethtool: Avoid overflowing userspace buffer on stats query
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 7b07be1ff1cb6c49869910518650e8d0abc7d25f ]
+
+The ethtool -S command operates across three ioctl calls:
+ETHTOOL_GSSET_INFO for the size, ETHTOOL_GSTRINGS for the names, and
+ETHTOOL_GSTATS for the values.
+
+If the number of stats changes between these calls (e.g., due to device
+reconfiguration), userspace's buffer allocation will be incorrect,
+potentially leading to buffer overflow.
+
+Drivers are generally expected to maintain stable stat counts, but some
+drivers (e.g., mlx5, bnx2x, bna, ksz884x) use dynamic counters, making
+this scenario possible.
+
+Some drivers try to handle this internally:
+- bnad_get_ethtool_stats() returns early in case stats.n_stats is not
+  equal to the driver's stats count.
+- micrel/ksz884x also makes sure not to write anything beyond
+  stats.n_stats and overflow the buffer.
+
+However, both use stats.n_stats which is already assigned with the value
+returned from get_sset_count(), hence won't solve the issue described
+here.
+
+Change ethtool_get_strings(), ethtool_get_stats(),
+ethtool_get_phy_stats() to not return anything in case of a mismatch
+between userspace's size and get_sset_size(), to prevent buffer
+overflow.
+The returned n_stats value will be equal to zero, to reflect that
+nothing has been returned.
+
+This could result in one of two cases when using upstream ethtool,
+depending on when the size change is detected:
+1. When detected in ethtool_get_strings():
+    # ethtool -S eth2
+    no stats available
+
+2. When detected in get stats, all stats will be reported as zero.
+
+Both cases are presumably transient, and a subsequent ethtool call
+should succeed.
+
+Other than the overflow avoidance, these two cases are very evident (no
+output/cleared stats), which is arguably better than presenting
+incorrect/shifted stats.
+I also considered returning an error instead of a "silent" response, but
+that seems more destructive towards userspace apps.
+
+Notes:
+- This patch does not claim to fix the inherent race, it only makes sure
+  that we do not overflow the userspace buffer, and makes for a more
+  predictable behavior.
+
+- RTNL lock is held during each ioctl, the race window exists between
+  the separate ioctl calls when the lock is released.
+
+- Userspace ethtool always fills stats.n_stats, but it is likely that
+  these stats ioctls are implemented in other userspace applications
+  which might not fill it. The added code checks that it's not zero,
+  to prevent any regressions.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Link: https://patch.msgid.link/20251208121901.3203692-1-gal@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 30 ++++++++++++++++++++++++------
+ 1 file changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index fa83ddade4f81..9431e305b2333 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -2383,7 +2383,10 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
+               return -ENOMEM;
+       WARN_ON_ONCE(!ret);
+-      gstrings.len = ret;
++      if (gstrings.len && gstrings.len != ret)
++              gstrings.len = 0;
++      else
++              gstrings.len = ret;
+       if (gstrings.len) {
+               data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
+@@ -2509,10 +2512,13 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       if (copy_from_user(&stats, useraddr, sizeof(stats)))
+               return -EFAULT;
+-      stats.n_stats = n_stats;
++      if (stats.n_stats && stats.n_stats != n_stats)
++              stats.n_stats = 0;
++      else
++              stats.n_stats = n_stats;
+-      if (n_stats) {
+-              data = vzalloc(array_size(n_stats, sizeof(u64)));
++      if (stats.n_stats) {
++              data = vzalloc(array_size(stats.n_stats, sizeof(u64)));
+               if (!data)
+                       return -ENOMEM;
+               ops->get_ethtool_stats(dev, &stats, data);
+@@ -2524,7 +2530,9 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       if (copy_to_user(useraddr, &stats, sizeof(stats)))
+               goto out;
+       useraddr += sizeof(stats);
+-      if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
++      if (stats.n_stats &&
++          copy_to_user(useraddr, data,
++                       array_size(stats.n_stats, sizeof(u64))))
+               goto out;
+       ret = 0;
+@@ -2560,6 +2568,10 @@ static int ethtool_get_phy_stats_phydev(struct phy_device *phydev,
+               return -EOPNOTSUPP;
+       n_stats = phy_ops->get_sset_count(phydev);
++      if (stats->n_stats && stats->n_stats != n_stats) {
++              stats->n_stats = 0;
++              return 0;
++      }
+       ret = ethtool_vzalloc_stats_array(n_stats, data);
+       if (ret)
+@@ -2580,6 +2592,10 @@ static int ethtool_get_phy_stats_ethtool(struct net_device *dev,
+               return -EOPNOTSUPP;
+       n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
++      if (stats->n_stats && stats->n_stats != n_stats) {
++              stats->n_stats = 0;
++              return 0;
++      }
+       ret = ethtool_vzalloc_stats_array(n_stats, data);
+       if (ret)
+@@ -2616,7 +2632,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       }
+       useraddr += sizeof(stats);
+-      if (copy_to_user(useraddr, data, array_size(stats.n_stats, sizeof(u64))))
++      if (stats.n_stats &&
++          copy_to_user(useraddr, data,
++                       array_size(stats.n_stats, sizeof(u64))))
+               ret = -EFAULT;
+  out:
+-- 
+2.51.0
+
diff --git a/queue-6.18/inet-frags-add-inet_frag_queue_flush.patch b/queue-6.18/inet-frags-add-inet_frag_queue_flush.patch
new file mode 100644 (file)
index 0000000..7116914
--- /dev/null
@@ -0,0 +1,96 @@
+From 84aebf278962baf9f86d4b6fe4bed47aea68e42d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Dec 2025 17:09:40 -0800
+Subject: inet: frags: add inet_frag_queue_flush()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 1231eec6994be29d6bb5c303dfa54731ed9fc0e6 ]
+
+Instead of exporting inet_frag_rbtree_purge() which requires that
+caller takes care of memory accounting, add a new helper. We will
+need to call it from a few places in the next patch.
+
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251207010942.1672972-3-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 006a5035b495 ("inet: frags: flush pending skbs in fqdir_pre_exit()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet_frag.h  |  5 ++---
+ net/ipv4/inet_fragment.c | 15 ++++++++++++---
+ net/ipv4/ip_fragment.c   |  6 +-----
+ 3 files changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
+index 0eccd9c3a883f..3ffaceee7bbc0 100644
+--- a/include/net/inet_frag.h
++++ b/include/net/inet_frag.h
+@@ -141,9 +141,8 @@ void inet_frag_kill(struct inet_frag_queue *q, int *refs);
+ void inet_frag_destroy(struct inet_frag_queue *q);
+ struct inet_frag_queue *inet_frag_find(struct fqdir *fqdir, void *key);
+-/* Free all skbs in the queue; return the sum of their truesizes. */
+-unsigned int inet_frag_rbtree_purge(struct rb_root *root,
+-                                  enum skb_drop_reason reason);
++void inet_frag_queue_flush(struct inet_frag_queue *q,
++                         enum skb_drop_reason reason);
+ static inline void inet_frag_putn(struct inet_frag_queue *q, int refs)
+ {
+diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
+index 30f4fa50ee2d7..1bf969b5a1cb5 100644
+--- a/net/ipv4/inet_fragment.c
++++ b/net/ipv4/inet_fragment.c
+@@ -263,8 +263,8 @@ static void inet_frag_destroy_rcu(struct rcu_head *head)
+       kmem_cache_free(f->frags_cachep, q);
+ }
+-unsigned int inet_frag_rbtree_purge(struct rb_root *root,
+-                                  enum skb_drop_reason reason)
++static unsigned int
++inet_frag_rbtree_purge(struct rb_root *root, enum skb_drop_reason reason)
+ {
+       struct rb_node *p = rb_first(root);
+       unsigned int sum = 0;
+@@ -284,7 +284,16 @@ unsigned int inet_frag_rbtree_purge(struct rb_root *root,
+       }
+       return sum;
+ }
+-EXPORT_SYMBOL(inet_frag_rbtree_purge);
++
++void inet_frag_queue_flush(struct inet_frag_queue *q,
++                         enum skb_drop_reason reason)
++{
++      unsigned int sum;
++
++      sum = inet_frag_rbtree_purge(&q->rb_fragments, reason);
++      sub_frag_mem_limit(q->fqdir, sum);
++}
++EXPORT_SYMBOL(inet_frag_queue_flush);
+ void inet_frag_destroy(struct inet_frag_queue *q)
+ {
+diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
+index d7bccdc9dc693..32f1c1a46ba72 100644
+--- a/net/ipv4/ip_fragment.c
++++ b/net/ipv4/ip_fragment.c
+@@ -240,14 +240,10 @@ static int ip_frag_too_far(struct ipq *qp)
+ static int ip_frag_reinit(struct ipq *qp)
+ {
+-      unsigned int sum_truesize = 0;
+-
+       if (!mod_timer_pending(&qp->q.timer, jiffies + qp->q.fqdir->timeout))
+               return -ETIMEDOUT;
+-      sum_truesize = inet_frag_rbtree_purge(&qp->q.rb_fragments,
+-                                            SKB_DROP_REASON_FRAG_TOO_FAR);
+-      sub_frag_mem_limit(qp->q.fqdir, sum_truesize);
++      inet_frag_queue_flush(&qp->q, SKB_DROP_REASON_FRAG_TOO_FAR);
+       qp->q.flags = 0;
+       qp->q.len = 0;
+-- 
+2.51.0
+
diff --git a/queue-6.18/inet-frags-avoid-theoretical-race-in-ip_frag_reinit.patch b/queue-6.18/inet-frags-avoid-theoretical-race-in-ip_frag_reinit.patch
new file mode 100644 (file)
index 0000000..9c3771f
--- /dev/null
@@ -0,0 +1,67 @@
+From f5ff9aa6ba0479713ff73c5bcade81d184095eb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Dec 2025 17:09:39 -0800
+Subject: inet: frags: avoid theoretical race in ip_frag_reinit()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 8ef522c8a59a048117f7e05eb5213043c02f986f ]
+
+In ip_frag_reinit() we want to move the frag timeout timer into
+the future. If the timer fires in the meantime we inadvertently
+scheduled it again, and since the timer assumes a ref on frag_queue
+we need to acquire one to balance things out.
+
+This is technically racy, we should have acquired the reference
+_before_ we touch the timer, it may fire again before we take the ref.
+Avoid this entire dance by using mod_timer_pending() which only modifies
+the timer if its pending (and which exists since Linux v2.6.30)
+
+Note that this was the only place we ever took a ref on frag_queue
+since Eric's conversion to RCU. So we could potentially replace
+the whole refcnt field with an atomic flag and a bit more RCU.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251207010942.1672972-2-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/inet_fragment.c | 4 +++-
+ net/ipv4/ip_fragment.c   | 4 +---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
+index 025895eb6ec59..30f4fa50ee2d7 100644
+--- a/net/ipv4/inet_fragment.c
++++ b/net/ipv4/inet_fragment.c
+@@ -327,7 +327,9 @@ static struct inet_frag_queue *inet_frag_alloc(struct fqdir *fqdir,
+       timer_setup(&q->timer, f->frag_expire, 0);
+       spin_lock_init(&q->lock);
+-      /* One reference for the timer, one for the hash table. */
++      /* One reference for the timer, one for the hash table.
++       * We never take any extra references, only decrement this field.
++       */
+       refcount_set(&q->refcnt, 2);
+       return q;
+diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
+index f7012479713ba..d7bccdc9dc693 100644
+--- a/net/ipv4/ip_fragment.c
++++ b/net/ipv4/ip_fragment.c
+@@ -242,10 +242,8 @@ static int ip_frag_reinit(struct ipq *qp)
+ {
+       unsigned int sum_truesize = 0;
+-      if (!mod_timer(&qp->q.timer, jiffies + qp->q.fqdir->timeout)) {
+-              refcount_inc(&qp->q.refcnt);
++      if (!mod_timer_pending(&qp->q.timer, jiffies + qp->q.fqdir->timeout))
+               return -ETIMEDOUT;
+-      }
+       sum_truesize = inet_frag_rbtree_purge(&qp->q.rb_fragments,
+                                             SKB_DROP_REASON_FRAG_TOO_FAR);
+-- 
+2.51.0
+
diff --git a/queue-6.18/inet-frags-flush-pending-skbs-in-fqdir_pre_exit.patch b/queue-6.18/inet-frags-flush-pending-skbs-in-fqdir_pre_exit.patch
new file mode 100644 (file)
index 0000000..1dbb14b
--- /dev/null
@@ -0,0 +1,186 @@
+From 5ecc617cfb33ee1825ec7061628ad7681ebb8509 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Dec 2025 17:09:41 -0800
+Subject: inet: frags: flush pending skbs in fqdir_pre_exit()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 006a5035b495dec008805df249f92c22c89c3d2e ]
+
+We have been seeing occasional deadlocks on pernet_ops_rwsem since
+September in NIPA. The stuck task was usually modprobe (often loading
+a driver like ipvlan), trying to take the lock as a Writer.
+lockdep does not track readers for rwsems so the read wasn't obvious
+from the reports.
+
+On closer inspection the Reader holding the lock was conntrack looping
+forever in nf_conntrack_cleanup_net_list(). Based on past experience
+with occasional NIPA crashes I looked thru the tests which run before
+the crash and noticed that the crash follows ip_defrag.sh. An immediate
+red flag. Scouring thru (de)fragmentation queues reveals skbs sitting
+around, holding conntrack references.
+
+The problem is that since conntrack depends on nf_defrag_ipv6,
+nf_defrag_ipv6 will load first. Since nf_defrag_ipv6 loads first its
+netns exit hooks run _after_ conntrack's netns exit hook.
+
+Flush all fragment queue SKBs during fqdir_pre_exit() to release
+conntrack references before conntrack cleanup runs. Also flush
+the queues in timer expiry handlers when they discover fqdir->dead
+is set, in case packet sneaks in while we're running the pre_exit
+flush.
+
+The commit under Fixes is not exactly the culprit, but I think
+previously the timer firing would eventually unblock the spinning
+conntrack.
+
+Fixes: d5dd88794a13 ("inet: fix various use-after-free in defrags units")
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20251207010942.1672972-4-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet_frag.h  | 13 +------------
+ include/net/ipv6_frag.h  |  9 ++++++---
+ net/ipv4/inet_fragment.c | 36 ++++++++++++++++++++++++++++++++++++
+ net/ipv4/ip_fragment.c   | 12 +++++++-----
+ 4 files changed, 50 insertions(+), 20 deletions(-)
+
+diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
+index 3ffaceee7bbc0..365925c9d2628 100644
+--- a/include/net/inet_frag.h
++++ b/include/net/inet_frag.h
+@@ -123,18 +123,7 @@ void inet_frags_fini(struct inet_frags *);
+ int fqdir_init(struct fqdir **fqdirp, struct inet_frags *f, struct net *net);
+-static inline void fqdir_pre_exit(struct fqdir *fqdir)
+-{
+-      /* Prevent creation of new frags.
+-       * Pairs with READ_ONCE() in inet_frag_find().
+-       */
+-      WRITE_ONCE(fqdir->high_thresh, 0);
+-
+-      /* Pairs with READ_ONCE() in inet_frag_kill(), ip_expire()
+-       * and ip6frag_expire_frag_queue().
+-       */
+-      WRITE_ONCE(fqdir->dead, true);
+-}
++void fqdir_pre_exit(struct fqdir *fqdir);
+ void fqdir_exit(struct fqdir *fqdir);
+ void inet_frag_kill(struct inet_frag_queue *q, int *refs);
+diff --git a/include/net/ipv6_frag.h b/include/net/ipv6_frag.h
+index 38ef66826939e..41d9fc6965f9a 100644
+--- a/include/net/ipv6_frag.h
++++ b/include/net/ipv6_frag.h
+@@ -69,9 +69,6 @@ ip6frag_expire_frag_queue(struct net *net, struct frag_queue *fq)
+       int refs = 1;
+       rcu_read_lock();
+-      /* Paired with the WRITE_ONCE() in fqdir_pre_exit(). */
+-      if (READ_ONCE(fq->q.fqdir->dead))
+-              goto out_rcu_unlock;
+       spin_lock(&fq->q.lock);
+       if (fq->q.flags & INET_FRAG_COMPLETE)
+@@ -80,6 +77,12 @@ ip6frag_expire_frag_queue(struct net *net, struct frag_queue *fq)
+       fq->q.flags |= INET_FRAG_DROP;
+       inet_frag_kill(&fq->q, &refs);
++      /* Paired with the WRITE_ONCE() in fqdir_pre_exit(). */
++      if (READ_ONCE(fq->q.fqdir->dead)) {
++              inet_frag_queue_flush(&fq->q, 0);
++              goto out;
++      }
++
+       dev = dev_get_by_index_rcu(net, fq->iif);
+       if (!dev)
+               goto out;
+diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
+index 1bf969b5a1cb5..001ee5c4d962e 100644
+--- a/net/ipv4/inet_fragment.c
++++ b/net/ipv4/inet_fragment.c
+@@ -218,6 +218,41 @@ static int __init inet_frag_wq_init(void)
+ pure_initcall(inet_frag_wq_init);
++void fqdir_pre_exit(struct fqdir *fqdir)
++{
++      struct inet_frag_queue *fq;
++      struct rhashtable_iter hti;
++
++      /* Prevent creation of new frags.
++       * Pairs with READ_ONCE() in inet_frag_find().
++       */
++      WRITE_ONCE(fqdir->high_thresh, 0);
++
++      /* Pairs with READ_ONCE() in inet_frag_kill(), ip_expire()
++       * and ip6frag_expire_frag_queue().
++       */
++      WRITE_ONCE(fqdir->dead, true);
++
++      rhashtable_walk_enter(&fqdir->rhashtable, &hti);
++      rhashtable_walk_start(&hti);
++
++      while ((fq = rhashtable_walk_next(&hti))) {
++              if (IS_ERR(fq)) {
++                      if (PTR_ERR(fq) != -EAGAIN)
++                              break;
++                      continue;
++              }
++              spin_lock_bh(&fq->lock);
++              if (!(fq->flags & INET_FRAG_COMPLETE))
++                      inet_frag_queue_flush(fq, 0);
++              spin_unlock_bh(&fq->lock);
++      }
++
++      rhashtable_walk_stop(&hti);
++      rhashtable_walk_exit(&hti);
++}
++EXPORT_SYMBOL(fqdir_pre_exit);
++
+ void fqdir_exit(struct fqdir *fqdir)
+ {
+       INIT_WORK(&fqdir->destroy_work, fqdir_work_fn);
+@@ -290,6 +325,7 @@ void inet_frag_queue_flush(struct inet_frag_queue *q,
+ {
+       unsigned int sum;
++      reason = reason ?: SKB_DROP_REASON_FRAG_REASM_TIMEOUT;
+       sum = inet_frag_rbtree_purge(&q->rb_fragments, reason);
+       sub_frag_mem_limit(q->fqdir, sum);
+ }
+diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
+index 32f1c1a46ba72..56b0f738d2f27 100644
+--- a/net/ipv4/ip_fragment.c
++++ b/net/ipv4/ip_fragment.c
+@@ -134,11 +134,6 @@ static void ip_expire(struct timer_list *t)
+       net = qp->q.fqdir->net;
+       rcu_read_lock();
+-
+-      /* Paired with WRITE_ONCE() in fqdir_pre_exit(). */
+-      if (READ_ONCE(qp->q.fqdir->dead))
+-              goto out_rcu_unlock;
+-
+       spin_lock(&qp->q.lock);
+       if (qp->q.flags & INET_FRAG_COMPLETE)
+@@ -146,6 +141,13 @@ static void ip_expire(struct timer_list *t)
+       qp->q.flags |= INET_FRAG_DROP;
+       inet_frag_kill(&qp->q, &refs);
++
++      /* Paired with WRITE_ONCE() in fqdir_pre_exit(). */
++      if (READ_ONCE(qp->q.fqdir->dead)) {
++              inet_frag_queue_flush(&qp->q, 0);
++              goto out;
++      }
++
+       __IP_INC_STATS(net, IPSTATS_MIB_REASMFAILS);
+       __IP_INC_STATS(net, IPSTATS_MIB_REASMTIMEOUT);
+-- 
+2.51.0
+
diff --git a/queue-6.18/iommufd-selftest-check-for-overflow-in-iommu_test_op.patch b/queue-6.18/iommufd-selftest-check-for-overflow-in-iommu_test_op.patch
new file mode 100644 (file)
index 0000000..72408a4
--- /dev/null
@@ -0,0 +1,57 @@
+From 28996d0009abf5ae7c4372a3516a44596342a881 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Dec 2025 11:53:40 -0400
+Subject: iommufd/selftest: Check for overflow in IOMMU_TEST_OP_ADD_RESERVED
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit e6a973af11135439de32ece3b9cbe3bfc043bea8 ]
+
+syzkaller found it could overflow math in the test infrastructure and
+cause a WARN_ON by corrupting the reserved interval tree. This only
+effects test kernels with CONFIG_IOMMUFD_TEST.
+
+Validate the user input length in the test ioctl.
+
+Fixes: f4b20bb34c83 ("iommufd: Add kernel support for testing iommufd")
+Link: https://patch.msgid.link/r/0-v1-cd99f6049ba5+51-iommufd_syz_add_resv_jgg@nvidia.com
+Reviewed-by: Samiullah Khawaja <skhawaja@google.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Tested-by: Yi Liu <yi.l.liu@intel.com>
+Reported-by: syzbot+57fdb0cf6a0c5d1f15a2@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/69368129.a70a0220.38f243.008f.GAE@google.com
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/iommufd/selftest.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
+index de178827a078a..dc0947aaac625 100644
+--- a/drivers/iommu/iommufd/selftest.c
++++ b/drivers/iommu/iommufd/selftest.c
+@@ -1257,14 +1257,20 @@ static int iommufd_test_add_reserved(struct iommufd_ucmd *ucmd,
+                                    unsigned int mockpt_id,
+                                    unsigned long start, size_t length)
+ {
++      unsigned long last;
+       struct iommufd_ioas *ioas;
+       int rc;
++      if (!length)
++              return -EINVAL;
++      if (check_add_overflow(start, length - 1, &last))
++              return -EOVERFLOW;
++
+       ioas = iommufd_get_ioas(ucmd->ictx, mockpt_id);
+       if (IS_ERR(ioas))
+               return PTR_ERR(ioas);
+       down_write(&ioas->iopt.iova_rwsem);
+-      rc = iopt_reserve_iova(&ioas->iopt, start, start + length - 1, NULL);
++      rc = iopt_reserve_iova(&ioas->iopt, start, last, NULL);
+       up_write(&ioas->iopt.iova_rwsem);
+       iommufd_put_object(ucmd->ictx, &ioas->obj);
+       return rc;
+-- 
+2.51.0
+
diff --git a/queue-6.18/iommufd-selftest-make-it-clearer-to-gcc-that-the-acc.patch b/queue-6.18/iommufd-selftest-make-it-clearer-to-gcc-that-the-acc.patch
new file mode 100644 (file)
index 0000000..eb61052
--- /dev/null
@@ -0,0 +1,71 @@
+From 0101957307e6345bc8a06191f38d9ce18f42d642 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 14:56:12 -0400
+Subject: iommufd/selftest: Make it clearer to gcc that the access is not out
+ of bounds
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit 5b244b077c0b0e76573fbb9542cf038e42368901 ]
+
+GCC gets a bit confused and reports:
+
+   In function '_test_cmd_get_hw_info',
+       inlined from 'iommufd_ioas_get_hw_info' at iommufd.c:779:3,
+       inlined from 'wrapper_iommufd_ioas_get_hw_info' at iommufd.c:752:1:
+>> iommufd_utils.h:804:37: warning: array subscript 'struct iommu_test_hw_info[0]' is partly outside array bounds of 'struct iommu_test_hw_info_buffer_smaller[1]' [-Warray-bounds=]
+     804 |                         assert(!info->flags);
+         |                                 ~~~~^~~~~~~
+   iommufd.c: In function 'wrapper_iommufd_ioas_get_hw_info':
+   iommufd.c:761:11: note: object 'buffer_smaller' of size 4
+     761 |         } buffer_smaller;
+         |           ^~~~~~~~~~~~~~
+
+While it is true that "struct iommu_test_hw_info[0]" is partly out of
+bounds of the input pointer, it is not true that info->flags is out of
+bounds. Unclear why it warns on this.
+
+Reuse an existing properly sized stack buffer and pass a truncated length
+instead to test the same thing.
+
+Fixes: af4fde93c319 ("iommufd/selftest: Add coverage for IOMMU_GET_HW_INFO ioctl")
+Link: https://patch.msgid.link/r/0-v1-63a2cffb09da+4486-iommufd_gcc_bounds_jgg@nvidia.com
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202512032344.kaAcKFIM-lkp@intel.com/
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/iommu/iommufd.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
+index bb4d33dde3c89..1f52140d9d9ee 100644
+--- a/tools/testing/selftests/iommu/iommufd.c
++++ b/tools/testing/selftests/iommu/iommufd.c
+@@ -758,9 +758,6 @@ TEST_F(iommufd_ioas, get_hw_info)
+               struct iommu_test_hw_info info;
+               uint64_t trailing_bytes;
+       } buffer_larger;
+-      struct iommu_test_hw_info_buffer_smaller {
+-              __u32 flags;
+-      } buffer_smaller;
+       if (self->device_id) {
+               uint8_t max_pasid = 0;
+@@ -792,8 +789,9 @@ TEST_F(iommufd_ioas, get_hw_info)
+                * the fields within the size range still gets updated.
+                */
+               test_cmd_get_hw_info(self->device_id,
+-                                   IOMMU_HW_INFO_TYPE_DEFAULT,
+-                                   &buffer_smaller, sizeof(buffer_smaller));
++                                   IOMMU_HW_INFO_TYPE_DEFAULT, &buffer_exact,
++                                   offsetofend(struct iommu_test_hw_info,
++                                               flags));
+               test_cmd_get_hw_info_pasid(self->device_id, &max_pasid);
+               ASSERT_EQ(0, max_pasid);
+               if (variant->pasid_capable) {
+-- 
+2.51.0
+
diff --git a/queue-6.18/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch b/queue-6.18/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch
new file mode 100644 (file)
index 0000000..88dfff5
--- /dev/null
@@ -0,0 +1,48 @@
+From ecaaf1c258cd1c7ae42d88734236dd56f844bf0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 13:39:03 +0300
+Subject: ipvlan: Ignore PACKET_LOOPBACK in handle_mode_l2()
+
+From: Dmitry Skorodumov <skorodumov.dmitry@huawei.com>
+
+[ Upstream commit 0c57ff008a11f24f7f05fa760222692a00465fec ]
+
+Packets with pkt_type == PACKET_LOOPBACK are captured by
+handle_frame() function, but they don't have L2 header.
+We should not process them in handle_mode_l2().
+
+This doesn't affect old L2 functionality, since handling
+was anyway incorrect.
+
+Handle them the same way as in br_handle_frame():
+just pass the skb.
+
+To observe invalid behaviour, just start "ping -b" on bcast address
+of port-interface.
+
+Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
+Signed-off-by: Dmitry Skorodumov <skorodumov.dmitry@huawei.com>
+Link: https://patch.msgid.link/20251202103906.4087675-1-skorodumov.dmitry@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ipvlan/ipvlan_core.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
+index d7e3ddbcab6f4..baf2ef3bcd54b 100644
+--- a/drivers/net/ipvlan/ipvlan_core.c
++++ b/drivers/net/ipvlan/ipvlan_core.c
+@@ -737,6 +737,9 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,
+       struct ethhdr *eth = eth_hdr(skb);
+       rx_handler_result_t ret = RX_HANDLER_PASS;
++      if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
++              return RX_HANDLER_PASS;
++
+       if (is_multicast_ether_addr(eth->h_dest)) {
+               if (ipvlan_external_frame(skb, port)) {
+                       struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
+-- 
+2.51.0
+
diff --git a/queue-6.18/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch b/queue-6.18/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch
new file mode 100644 (file)
index 0000000..4799f52
--- /dev/null
@@ -0,0 +1,80 @@
+From 886b168d163aaa51575ef5e9c965dcdc6015f5dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 16:52:13 +0800
+Subject: ipvs: fix ipv4 null-ptr-deref in route error path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Slavin Liu <slavin452@gmail.com>
+
+[ Upstream commit ad891bb3d079a46a821bf2b8867854645191bab0 ]
+
+The IPv4 code path in __ip_vs_get_out_rt() calls dst_link_failure()
+without ensuring skb->dev is set, leading to a NULL pointer dereference
+in fib_compute_spec_dst() when ipv4_link_failure() attempts to send
+ICMP destination unreachable messages.
+
+The issue emerged after commit ed0de45a1008 ("ipv4: recompile ip options
+in ipv4_link_failure") started calling __ip_options_compile() from
+ipv4_link_failure(). This code path eventually calls fib_compute_spec_dst()
+which dereferences skb->dev. An attempt was made to fix the NULL skb->dev
+dereference in commit 0113d9c9d1cc ("ipv4: fix null-deref in
+ipv4_link_failure"), but it only addressed the immediate dev_net(skb->dev)
+dereference by using a fallback device. The fix was incomplete because
+fib_compute_spec_dst() later in the call chain still accesses skb->dev
+directly, which remains NULL when IPVS calls dst_link_failure().
+
+The crash occurs when:
+1. IPVS processes a packet in NAT mode with a misconfigured destination
+2. Route lookup fails in __ip_vs_get_out_rt() before establishing a route
+3. The error path calls dst_link_failure(skb) with skb->dev == NULL
+4. ipv4_link_failure() â†’ ipv4_send_dest_unreach() â†’
+   __ip_options_compile() â†’ fib_compute_spec_dst()
+5. fib_compute_spec_dst() dereferences NULL skb->dev
+
+Apply the same fix used for IPv6 in commit 326bf17ea5d4 ("ipvs: fix
+ipv6 route unreach panic"): set skb->dev from skb_dst(skb)->dev before
+calling dst_link_failure().
+
+KASAN: null-ptr-deref in range [0x0000000000000328-0x000000000000032f]
+CPU: 1 PID: 12732 Comm: syz.1.3469 Not tainted 6.6.114 #2
+RIP: 0010:__in_dev_get_rcu include/linux/inetdevice.h:233
+RIP: 0010:fib_compute_spec_dst+0x17a/0x9f0 net/ipv4/fib_frontend.c:285
+Call Trace:
+  <TASK>
+  spec_dst_fill net/ipv4/ip_options.c:232
+  spec_dst_fill net/ipv4/ip_options.c:229
+  __ip_options_compile+0x13a1/0x17d0 net/ipv4/ip_options.c:330
+  ipv4_send_dest_unreach net/ipv4/route.c:1252
+  ipv4_link_failure+0x702/0xb80 net/ipv4/route.c:1265
+  dst_link_failure include/net/dst.h:437
+  __ip_vs_get_out_rt+0x15fd/0x19e0 net/netfilter/ipvs/ip_vs_xmit.c:412
+  ip_vs_nat_xmit+0x1d8/0xc80 net/netfilter/ipvs/ip_vs_xmit.c:764
+
+Fixes: ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure")
+Signed-off-by: Slavin Liu <slavin452@gmail.com>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
+index 95af252b29397..618fbe1240b54 100644
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -409,6 +409,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+       return -1;
+ err_unreach:
++      if (!skb->dev)
++              skb->dev = skb_dst(skb)->dev;
++
+       dst_link_failure(skb);
+       return -1;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.18/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch b/queue-6.18/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch
new file mode 100644 (file)
index 0000000..eec8660
--- /dev/null
@@ -0,0 +1,96 @@
+From 28b737fe91c09d4b9c5f14ff03c33dcc5659d856 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:13 +0100
+Subject: mlxsw: spectrum_mr: Fix use-after-free when updating multicast route
+ stats
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 8ac1dacec458f55f871f7153242ed6ab60373b90 ]
+
+Cited commit added a dedicated mutex (instead of RTNL) to protect the
+multicast route list, so that it will not change while the driver
+periodically traverses it in order to update the kernel about multicast
+route stats that were queried from the device.
+
+One instance of list entry deletion (during route replace) was missed
+and it can result in a use-after-free [1].
+
+Fix by acquiring the mutex before deleting the entry from the list and
+releasing it afterwards.
+
+[1]
+BUG: KASAN: slab-use-after-free in mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum]
+Read of size 8 at addr ffff8881523c2fa8 by task kworker/2:5/22043
+
+CPU: 2 UID: 0 PID: 22043 Comm: kworker/2:5 Not tainted 6.18.0-rc1-custom-g1a3d6d7cd014 #1 PREEMPT(full)
+Hardware name: Mellanox Technologies Ltd. MSN2010/SA002610, BIOS 5.6.5 08/24/2017
+Workqueue: mlxsw_core mlxsw_sp_mr_stats_update [mlxsw_spectrum]
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xba/0x110
+ print_report+0x174/0x4f5
+ kasan_report+0xdf/0x110
+ mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+Allocated by task 29933:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0x8f/0xa0
+ mlxsw_sp_mr_route_add+0xd8/0x4770 [mlxsw_spectrum]
+ mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+
+Freed by task 29933:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3b/0x70
+ __kasan_slab_free+0x43/0x70
+ kfree+0x14e/0x700
+ mlxsw_sp_mr_route_add+0x2dea/0x4770 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:444 [mlxsw_spectrum]
+ mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+
+Fixes: f38656d06725 ("mlxsw: spectrum_mr: Protect multicast route list with a lock")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/f996feecfd59fde297964bfc85040b6d83ec6089.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+index 5afe6b155ef0d..81935f87bfcd7 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+@@ -440,7 +440,9 @@ int mlxsw_sp_mr_route_add(struct mlxsw_sp_mr_table *mr_table,
+               rhashtable_remove_fast(&mr_table->route_ht,
+                                      &mr_orig_route->ht_node,
+                                      mlxsw_sp_mr_route_ht_params);
++              mutex_lock(&mr_table->route_list_lock);
+               list_del(&mr_orig_route->node);
++              mutex_unlock(&mr_table->route_list_lock);
+               mlxsw_sp_mr_route_destroy(mr_table, mr_orig_route);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.18/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch b/queue-6.18/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch
new file mode 100644 (file)
index 0000000..927f6f2
--- /dev/null
@@ -0,0 +1,199 @@
+From 8746306369cf5081aff8f5c7352b93221bf410f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:12 +0100
+Subject: mlxsw: spectrum_router: Fix neighbour use-after-free
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 8b0e69763ef948fb872a7767df4be665d18f5fd4 ]
+
+We sometimes observe use-after-free when dereferencing a neighbour [1].
+The problem seems to be that the driver stores a pointer to the
+neighbour, but without holding a reference on it. A reference is only
+taken when the neighbour is used by a nexthop.
+
+Fix by simplifying the reference counting scheme. Always take a
+reference when storing a neighbour pointer in a neighbour entry. Avoid
+taking a referencing when the neighbour is used by a nexthop as the
+neighbour entry associated with the nexthop already holds a reference.
+
+Tested by running the test that uncovered the problem over 300 times.
+Without this patch the problem was reproduced after a handful of
+iterations.
+
+[1]
+BUG: KASAN: slab-use-after-free in mlxsw_sp_neigh_entry_update+0x2d4/0x310
+Read of size 8 at addr ffff88817f8e3420 by task ip/3929
+
+CPU: 3 UID: 0 PID: 3929 Comm: ip Not tainted 6.18.0-rc4-virtme-g36b21a067510 #3 PREEMPT(full)
+Hardware name: Nvidia SN5600/VMOD0013, BIOS 5.13 05/31/2023
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x6f/0xa0
+ print_address_description.constprop.0+0x6e/0x300
+ print_report+0xfc/0x1fb
+ kasan_report+0xe4/0x110
+ mlxsw_sp_neigh_entry_update+0x2d4/0x310
+ mlxsw_sp_router_rif_gone_sync+0x35f/0x510
+ mlxsw_sp_rif_destroy+0x1ea/0x730
+ mlxsw_sp_inetaddr_port_vlan_event+0xa1/0x1b0
+ __mlxsw_sp_inetaddr_lag_event+0xcc/0x130
+ __mlxsw_sp_inetaddr_event+0xf5/0x3c0
+ mlxsw_sp_router_netdevice_event+0x1015/0x1580
+ notifier_call_chain+0xcc/0x150
+ call_netdevice_notifiers_info+0x7e/0x100
+ __netdev_upper_dev_unlink+0x10b/0x210
+ netdev_upper_dev_unlink+0x79/0xa0
+ vrf_del_slave+0x18/0x50
+ do_set_master+0x146/0x7d0
+ do_setlink.isra.0+0x9a0/0x2880
+ rtnl_newlink+0x637/0xb20
+ rtnetlink_rcv_msg+0x6fe/0xb90
+ netlink_rcv_skb+0x123/0x380
+ netlink_unicast+0x4a3/0x770
+ netlink_sendmsg+0x75b/0xc90
+ __sock_sendmsg+0xbe/0x160
+ ____sys_sendmsg+0x5b2/0x7d0
+ ___sys_sendmsg+0xfd/0x180
+ __sys_sendmsg+0x124/0x1c0
+ do_syscall_64+0xbb/0xfd0
+ entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[...]
+
+Allocated by task 109:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0x7b/0x90
+ __kmalloc_noprof+0x2c1/0x790
+ neigh_alloc+0x6af/0x8f0
+ ___neigh_create+0x63/0xe90
+ mlxsw_sp_nexthop_neigh_init+0x430/0x7e0
+ mlxsw_sp_nexthop_type_init+0x212/0x960
+ mlxsw_sp_nexthop6_group_info_init.constprop.0+0x81f/0x1280
+ mlxsw_sp_nexthop6_group_get+0x392/0x6a0
+ mlxsw_sp_fib6_entry_create+0x46a/0xfd0
+ mlxsw_sp_router_fib6_replace+0x1ed/0x5f0
+ mlxsw_sp_router_fib6_event_work+0x10a/0x2a0
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Freed by task 154:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3b/0x60
+ __kasan_slab_free+0x43/0x70
+ kmem_cache_free_bulk.part.0+0x1eb/0x5e0
+ kvfree_rcu_bulk+0x1f2/0x260
+ kfree_rcu_work+0x130/0x1b0
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Last potentially related work creation:
+ kasan_save_stack+0x30/0x50
+ kasan_record_aux_stack+0x8c/0xa0
+ kvfree_call_rcu+0x93/0x5b0
+ mlxsw_sp_router_neigh_event_work+0x67d/0x860
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Fixes: 6cf3c971dc84 ("mlxsw: spectrum_router: Add private neigh table")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/92d75e21d95d163a41b5cea67a15cd33f547cba6.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlxsw/spectrum_router.c   | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index f4e9ecaeb104f..2d0e89bd2fb9c 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -2265,6 +2265,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
+       if (!neigh_entry)
+               return NULL;
++      neigh_hold(n);
+       neigh_entry->key.n = n;
+       neigh_entry->rif = rif;
+       INIT_LIST_HEAD(&neigh_entry->nexthop_list);
+@@ -2274,6 +2275,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
+ static void mlxsw_sp_neigh_entry_free(struct mlxsw_sp_neigh_entry *neigh_entry)
+ {
++      neigh_release(neigh_entry->key.n);
+       kfree(neigh_entry);
+ }
+@@ -4320,6 +4322,8 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
+       if (err)
+               goto err_neigh_entry_insert;
++      neigh_release(old_n);
++
+       read_lock_bh(&n->lock);
+       nud_state = n->nud_state;
+       dead = n->dead;
+@@ -4328,14 +4332,10 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
+       list_for_each_entry(nh, &neigh_entry->nexthop_list,
+                           neigh_list_node) {
+-              neigh_release(old_n);
+-              neigh_clone(n);
+               __mlxsw_sp_nexthop_neigh_update(nh, !entry_connected);
+               mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp);
+       }
+-      neigh_release(n);
+-
+       return 0;
+ err_neigh_entry_insert:
+@@ -4428,6 +4428,11 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
+               }
+       }
++      /* Release the reference taken by neigh_lookup() / neigh_create() since
++       * neigh_entry already holds one.
++       */
++      neigh_release(n);
++
+       /* If that is the first nexthop connected to that neigh, add to
+        * nexthop_neighs_list
+        */
+@@ -4454,11 +4459,9 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
+                                       struct mlxsw_sp_nexthop *nh)
+ {
+       struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
+-      struct neighbour *n;
+       if (!neigh_entry)
+               return;
+-      n = neigh_entry->key.n;
+       __mlxsw_sp_nexthop_neigh_update(nh, true);
+       list_del(&nh->neigh_list_node);
+@@ -4472,8 +4475,6 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
+       if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list))
+               mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
+-
+-      neigh_release(n);
+ }
+ static bool mlxsw_sp_ipip_netdev_ul_up(struct net_device *ol_dev)
+-- 
+2.51.0
+
diff --git a/queue-6.18/mlxsw-spectrum_router-fix-possible-neighbour-referen.patch b/queue-6.18/mlxsw-spectrum_router-fix-possible-neighbour-referen.patch
new file mode 100644 (file)
index 0000000..0a2e09a
--- /dev/null
@@ -0,0 +1,64 @@
+From 3bef36dd4be67e84765cf52f66eea7f18cff72c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:11 +0100
+Subject: mlxsw: spectrum_router: Fix possible neighbour reference count leak
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit b6b638bda240395dff49a87403b2e32493e56d2a ]
+
+mlxsw_sp_router_schedule_work() takes a reference on a neighbour,
+expecting a work item to release it later on. However, we might fail to
+schedule the work item, in which case the neighbour reference count will
+be leaked.
+
+Fix by taking the reference just before scheduling the work item. Note
+that mlxsw_sp_router_schedule_work() can receive a NULL neighbour
+pointer, but neigh_clone() handles that correctly.
+
+Spotted during code review, did not actually observe the reference count
+leak.
+
+Fixes: 151b89f6025a ("mlxsw: spectrum_router: Reuse work neighbor initialization in work scheduler")
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/ec2934ae4aca187a8d8c9329a08ce93cca411378.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index a2033837182e8..f4e9ecaeb104f 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -2858,6 +2858,11 @@ static int mlxsw_sp_router_schedule_work(struct net *net,
+       if (!net_work)
+               return NOTIFY_BAD;
++      /* Take a reference to ensure the neighbour won't be destructed until
++       * we drop the reference in the work item.
++       */
++      neigh_clone(n);
++
+       INIT_WORK(&net_work->work, cb);
+       net_work->mlxsw_sp = router->mlxsw_sp;
+       net_work->n = n;
+@@ -2881,11 +2886,6 @@ static int mlxsw_sp_router_schedule_neigh_work(struct mlxsw_sp_router *router,
+       struct net *net;
+       net = neigh_parms_net(n->parms);
+-
+-      /* Take a reference to ensure the neighbour won't be destructed until we
+-       * drop the reference in delayed work.
+-       */
+-      neigh_clone(n);
+       return mlxsw_sp_router_schedule_work(net, router, n,
+                                            mlxsw_sp_router_neigh_event_work);
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-enetc-do-not-transmit-redirected-xdp-frames-when.patch b/queue-6.18/net-enetc-do-not-transmit-redirected-xdp-frames-when.patch
new file mode 100644 (file)
index 0000000..9f4a683
--- /dev/null
@@ -0,0 +1,66 @@
+From d7d8a336443be4b64c120b55ba3313e08efbb9c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:09:19 +0800
+Subject: net: enetc: do not transmit redirected XDP frames when the link is
+ down
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit 2939203ffee818f1e5ebd60bbb85a174d63aab9c ]
+
+In the current implementation, the enetc_xdp_xmit() always transmits
+redirected XDP frames even if the link is down, but the frames cannot
+be transmitted from TX BD rings when the link is down, so the frames
+are still kept in the TX BD rings. If the XDP program is uninstalled,
+users will see the following warning logs.
+
+fsl_enetc 0000:00:00.0 eno0: timeout for tx ring #6 clear
+
+More worse, the TX BD ring cannot work properly anymore, because the
+HW PIR and CIR are not equal after the re-initialization of the TX
+BD ring. At this point, the BDs between CIR and PIR are invalid,
+which will cause a hardware malfunction.
+
+Another reason is that there is internal context in the ring prefetch
+logic that will retain the state from the first incarnation of the ring
+and continue prefetching from the stale location when we re-initialize
+the ring. The internal context is only reset by an FLR. That is to say,
+for LS1028A ENETC, software cannot set the HW CIR and PIR when
+initializing the TX BD ring.
+
+It does not make sense to transmit redirected XDP frames when the link is
+down. Add a link status check to prevent transmission in this condition.
+This fixes part of the issue, but more complex cases remain. For example,
+the TX BD ring may still contain unsent frames when the link goes down.
+Those situations require additional patches, which will build on this
+one.
+
+Fixes: 9d2b68cc108d ("net: enetc: add support for XDP_REDIRECT")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Reviewed-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20251211020919.121113-1-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index 0535e92404e3c..f410c245ea918 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -1778,7 +1778,8 @@ int enetc_xdp_xmit(struct net_device *ndev, int num_frames,
+       int xdp_tx_bd_cnt, i, k;
+       int xdp_tx_frm_cnt = 0;
+-      if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags)))
++      if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags) ||
++                   !netif_carrier_ok(ndev)))
+               return -ENETDOWN;
+       enetc_lock_mdio();
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-fec-err007885-workaround-for-xdp-tx-path.patch b/queue-6.18/net-fec-err007885-workaround-for-xdp-tx-path.patch
new file mode 100644 (file)
index 0000000..389bc06
--- /dev/null
@@ -0,0 +1,49 @@
+From 4faf0d7eb045ad493b1d913bec3362ef0f7036c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Nov 2025 10:59:15 +0800
+Subject: net: fec: ERR007885 Workaround for XDP TX path
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit e8e032cd24dda7cceaa27bc2eb627f82843f0466 ]
+
+The ERR007885 will lead to a TDAR race condition for mutliQ when the
+driver sets TDAR and the UDMA clears TDAR simultaneously or in a small
+window (2-4 cycles). And it will cause the udma_tx and udma_tx_arbiter
+state machines to hang. Therefore, the commit 53bb20d1faba ("net: fec:
+add variable reg_desc_active to speed things up") and the commit
+a179aad12bad ("net: fec: ERR007885 Workaround for conventional TX") have
+added the workaround to fix the potential issue for the conventional TX
+path. Similarly, the XDP TX path should also have the potential hang
+issue, so add the workaround for XDP TX path.
+
+Fixes: 6d6b39f180b8 ("net: fec: add initial XDP support")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251128025915.2486943-1-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_main.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index 3222359ac15b7..e2b75d1970ae6 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -3948,7 +3948,12 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep,
+       txq->bd.cur = bdp;
+       /* Trigger transmission start */
+-      writel(0, txq->bd.reg_desc_active);
++      if (!(fep->quirks & FEC_QUIRK_ERR007885) ||
++          !readl(txq->bd.reg_desc_active) ||
++          !readl(txq->bd.reg_desc_active) ||
++          !readl(txq->bd.reg_desc_active) ||
++          !readl(txq->bd.reg_desc_active))
++              writel(0, txq->bd.reg_desc_active);
+       return 0;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-handshake-duplicate-handshake-cancellations-leak.patch b/queue-6.18/net-handshake-duplicate-handshake-cancellations-leak.patch
new file mode 100644 (file)
index 0000000..da1c8db
--- /dev/null
@@ -0,0 +1,61 @@
+From ab880bdf65c96fea9f7d0e061cd814f1f28703c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:30:15 -0500
+Subject: net/handshake: duplicate handshake cancellations leak socket
+
+From: Scott Mayhew <smayhew@redhat.com>
+
+[ Upstream commit 15564bd67e2975002f2a8e9defee33e321d3183f ]
+
+When a handshake request is cancelled it is removed from the
+handshake_net->hn_requests list, but it is still present in the
+handshake_rhashtbl until it is destroyed.
+
+If a second cancellation request arrives for the same handshake request,
+then remove_pending() will return false... and assuming
+HANDSHAKE_F_REQ_COMPLETED isn't set in req->hr_flags, we'll continue
+processing through the out_true label, where we put another reference on
+the sock and a refcount underflow occurs.
+
+This can happen for example if a handshake times out - particularly if
+the SUNRPC client sends the AUTH_TLS probe to the server but doesn't
+follow it up with the ClientHello due to a problem with tlshd.  When the
+timeout is hit on the server, the server will send a FIN, which triggers
+a cancellation request via xs_reset_transport().  When the timeout is
+hit on the client, another cancellation request happens via
+xs_tls_handshake_sync().
+
+Add a test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED) in the pending cancel
+path so duplicate cancels can be detected.
+
+Fixes: 3b3009ea8abb ("net/handshake: Create a NETLINK service for handling handshake requests")
+Suggested-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Scott Mayhew <smayhew@redhat.com>
+Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
+Link: https://patch.msgid.link/20251209193015.3032058-1-smayhew@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/request.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 274d2c89b6b20..f78091680bca5 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -324,7 +324,11 @@ bool handshake_req_cancel(struct sock *sk)
+       hn = handshake_pernet(net);
+       if (hn && remove_pending(hn, req)) {
+-              /* Request hadn't been accepted */
++              /* Request hadn't been accepted - mark cancelled */
++              if (test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) {
++                      trace_handshake_cancel_busy(net, req, sk);
++                      return false;
++              }
+               goto out_true;
+       }
+       if (test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) {
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-hns3-add-vlan-id-validation-before-using.patch b/queue-6.18/net-hns3-add-vlan-id-validation-before-using.patch
new file mode 100644 (file)
index 0000000..b08b965
--- /dev/null
@@ -0,0 +1,46 @@
+From 6416028abcd2ed0e0146bb209a358522838bebbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:37 +0800
+Subject: net: hns3: add VLAN id validation before using
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit 6ef935e65902bfed53980ad2754b06a284ea8ac1 ]
+
+Currently, the VLAN id may be used without validation when
+receive a VLAN configuration mailbox from VF. The length of
+vlan_del_fail_bmap is BITS_TO_LONGS(VLAN_N_VID). It may cause
+out-of-bounds memory access once the VLAN id is bigger than
+or equal to VLAN_N_VID.
+
+Therefore, VLAN id needs to be checked to ensure it is within
+the range of VLAN_N_VID.
+
+Fixes: fe4144d47eef ("net: hns3: sync VLAN filter entries when kill VLAN ID failed")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-4-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index 782bb48c9f3d7..1b103d1154da9 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -10562,6 +10562,9 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
+       bool writen_to_tbl = false;
+       int ret = 0;
++      if (vlan_id >= VLAN_N_VID)
++              return -EINVAL;
++
+       /* When device is resetting or reset failed, firmware is unable to
+        * handle mailbox. Just record the vlan id, and remove it after
+        * reset finished.
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch b/queue-6.18/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch
new file mode 100644 (file)
index 0000000..52d6ff0
--- /dev/null
@@ -0,0 +1,52 @@
+From dadff4afc50a1c65424b53c3532aba87a072a85a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:35 +0800
+Subject: net: hns3: using the num_tqps in the vf driver to apply for resources
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit c2a16269742e176fccdd0ef9c016a233491a49ad ]
+
+Currently, hdev->htqp is allocated using hdev->num_tqps, and kinfo->tqp
+is allocated using kinfo->num_tqps. However, kinfo->num_tqps is set to
+min(new_tqps, hdev->num_tqps);  Therefore, kinfo->num_tqps may be smaller
+than hdev->num_tqps, which causes some hdev->htqp[i] to remain
+uninitialized in hclgevf_knic_setup().
+
+Thus, this patch allocates hdev->htqp and kinfo->tqp using hdev->num_tqps,
+ensuring that the lengths of hdev->htqp and kinfo->tqp are consistent
+and that all elements are properly initialized.
+
+Fixes: e2cb1dec9779 ("net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-2-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+index 8fcf220a120d2..70327a73dee32 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -368,12 +368,12 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev)
+       new_tqps = kinfo->rss_size * num_tc;
+       kinfo->num_tqps = min(new_tqps, hdev->num_tqps);
+-      kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps,
++      kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps,
+                                 sizeof(struct hnae3_queue *), GFP_KERNEL);
+       if (!kinfo->tqp)
+               return -ENOMEM;
+-      for (i = 0; i < kinfo->num_tqps; i++) {
++      for (i = 0; i < hdev->num_tqps; i++) {
+               hdev->htqp[i].q.handle = &hdev->nic;
+               hdev->htqp[i].q.tqp_index = i;
+               kinfo->tqp[i] = &hdev->htqp[i].q;
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch b/queue-6.18/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch
new file mode 100644 (file)
index 0000000..3437ece
--- /dev/null
@@ -0,0 +1,49 @@
+From a82144265416d9b6494befd37c7693a94be97ffa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:36 +0800
+Subject: net: hns3: using the num_tqps to check whether tqp_index is out of
+ range when vf get ring info from mbx
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit d180c11aa8a6fa735f9ac2c72c61364a9afc2ba7 ]
+
+Currently, rss_size = num_tqps / tc_num. If tc_num is 1, then num_tqps
+equals rss_size. However, if the tc_num is greater than 1, then rss_size
+will be less than num_tqps, causing the tqp_index check for subsequent TCs
+using rss_size to always fail.
+
+This patch uses the num_tqps to check whether tqp_index is out of range,
+instead of rss_size.
+
+Fixes: 326334aad024 ("net: hns3: add a check for tqp_index in hclge_get_ring_chain_from_mbx()")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-3-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+index c7ff12a6c0764..b7d4e06a55d40 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+@@ -193,10 +193,10 @@ static int hclge_get_ring_chain_from_mbx(
+               return -EINVAL;
+       for (i = 0; i < ring_num; i++) {
+-              if (req->msg.param[i].tqp_index >= vport->nic.kinfo.rss_size) {
++              if (req->msg.param[i].tqp_index >= vport->nic.kinfo.num_tqps) {
+                       dev_err(&hdev->pdev->dev, "tqp index(%u) is out of range(0-%u)\n",
+                               req->msg.param[i].tqp_index,
+-                              vport->nic.kinfo.rss_size - 1U);
++                              vport->nic.kinfo.num_tqps - 1U);
+                       return -EINVAL;
+               }
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-mlx5-drain-firmware-reset-in-shutdown-callback.patch b/queue-6.18/net-mlx5-drain-firmware-reset-in-shutdown-callback.patch
new file mode 100644 (file)
index 0000000..836ef5d
--- /dev/null
@@ -0,0 +1,38 @@
+From b2c10891be1d2923665c4e0ca024862dbf5641f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:10 +0200
+Subject: net/mlx5: Drain firmware reset in shutdown callback
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 5846a365fc6476b02d6766963cf0985520f0385f ]
+
+Invoke drain_fw_reset() in the shutdown callback to ensure all
+firmware reset handling is completed before shutdown proceeds.
+
+Fixes: 16d42d313350 ("net/mlx5: Drain fw_reset when removing device")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Shay Drori <shayd@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-3-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 70c156591b0ba..9e0c9e6266a47 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -2189,6 +2189,7 @@ static void shutdown(struct pci_dev *pdev)
+       mlx5_core_info(dev, "Shutdown was called\n");
+       set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state);
++      mlx5_drain_fw_reset(dev);
+       mlx5_drain_health_wq(dev);
+       err = mlx5_try_fast_unload(dev);
+       if (err)
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-mlx5-fix-double-unregister-of-hca_ports-componen.patch b/queue-6.18/net-mlx5-fix-double-unregister-of-hca_ports-componen.patch
new file mode 100644 (file)
index 0000000..0e2f06b
--- /dev/null
@@ -0,0 +1,82 @@
+From 98be4d972034cd2db29bc2c0aa461adaffa52835 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 12:12:57 +0100
+Subject: net/mlx5: Fix double unregister of HCA_PORTS component
+
+From: Gerd Bayer <gbayer@linux.ibm.com>
+
+[ Upstream commit 6a107cfe9c99a079e578a4c5eb70038101a3599f ]
+
+Clear hca_devcom_comp in device's private data after unregistering it in
+LAG teardown. Otherwise a slightly lagging second pass through
+mlx5_unload_one() might try to unregister it again and trip over
+use-after-free.
+
+On s390 almost all PCI level recovery events trigger two passes through
+mxl5_unload_one() - one through the poll_health() method and one through
+mlx5_pci_err_detected() as callback from generic PCI error recovery.
+While testing PCI error recovery paths with more kernel debug features
+enabled, this issue reproducibly led to kernel panics with the following
+call chain:
+
+ Unable to handle kernel pointer dereference in virtual kernel address space
+ Failing address: 6b6b6b6b6b6b6000 TEID: 6b6b6b6b6b6b6803 ESOP-2 FSI
+ Fault in home space mode while using kernel ASCE.
+ AS:00000000705c4007 R3:0000000000000024
+ Oops: 0038 ilc:3 [#1]SMP
+
+ CPU: 14 UID: 0 PID: 156 Comm: kmcheck Kdump: loaded Not tainted
+      6.18.0-20251130.rc7.git0.16131a59cab1.300.fc43.s390x+debug #1 PREEMPT
+
+ Krnl PSW : 0404e00180000000 0000020fc86aa1dc (__lock_acquire+0x5c/0x15f0)
+            R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 RI:0 EA:3
+ Krnl GPRS: 0000000000000000 0000020f00000001 6b6b6b6b6b6b6c33 0000000000000000
+            0000000000000000 0000000000000000 0000000000000001 0000000000000000
+            0000000000000000 0000020fca28b820 0000000000000000 0000010a1ced8100
+            0000010a1ced8100 0000020fc9775068 0000018fce14f8b8 0000018fce14f7f8
+ Krnl Code: 0000020fc86aa1cc: e3b003400004        lg      %r11,832
+            0000020fc86aa1d2: a7840211           brc     8,0000020fc86aa5f4
+           *0000020fc86aa1d6: c09000df0b25       larl    %r9,0000020fca28b820
+           >0000020fc86aa1dc: d50790002000       clc     0(8,%r9),0(%r2)
+            0000020fc86aa1e2: a7840209           brc     8,0000020fc86aa5f4
+            0000020fc86aa1e6: c0e001100401       larl    %r14,0000020fca8aa9e8
+            0000020fc86aa1ec: c01000e25a00       larl    %r1,0000020fca2f55ec
+            0000020fc86aa1f2: a7eb00e8           aghi    %r14,232
+
+ Call Trace:
+  __lock_acquire+0x5c/0x15f0
+  lock_acquire.part.0+0xf8/0x270
+  lock_acquire+0xb0/0x1b0
+  down_write+0x5a/0x250
+  mlx5_detach_device+0x42/0x110 [mlx5_core]
+  mlx5_unload_one_devl_locked+0x50/0xc0 [mlx5_core]
+  mlx5_unload_one+0x42/0x60 [mlx5_core]
+  mlx5_pci_err_detected+0x94/0x150 [mlx5_core]
+  zpci_event_attempt_error_recovery+0xcc/0x388
+
+Fixes: 5a977b5833b7 ("net/mlx5: Lag, move devcom registration to LAG layer")
+Signed-off-by: Gerd Bayer <gbayer@linux.ibm.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Acked-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20251202-fix_lag-v1-1-59e8177ffce0@linux.ibm.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+index 3db0387bf6dcb..8ec04a5f434dd 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+@@ -1413,6 +1413,7 @@ static int __mlx5_lag_dev_add_mdev(struct mlx5_core_dev *dev)
+ static void mlx5_lag_unregister_hca_devcom_comp(struct mlx5_core_dev *dev)
+ {
+       mlx5_devcom_unregister_component(dev->priv.hca_devcom_comp);
++      dev->priv.hca_devcom_comp = NULL;
+ }
+ static int mlx5_lag_register_hca_devcom_comp(struct mlx5_core_dev *dev)
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch b/queue-6.18/net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch
new file mode 100644 (file)
index 0000000..afd67d5
--- /dev/null
@@ -0,0 +1,45 @@
+From 98f12e0f3f7b5e02bdf6a4c95b875be26c808b91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:09 +0200
+Subject: net/mlx5: fw reset, clear reset requested on drain_fw_reset
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 89a898d63f6f588acf5c104c65c94a38b68c69a6 ]
+
+drain_fw_reset() waits for ongoing firmware reset events and blocks new
+event handling, but does not clear the reset requested flag, and may
+keep sync reset polling.
+
+To fix it, call mlx5_sync_reset_clear_reset_requested() to clear the
+flag, stop sync reset polling, and resume health polling, ensuring
+health issues are still detected after the firmware reset drain.
+
+Fixes: 16d42d313350 ("net/mlx5: Drain fw_reset when removing device")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Shay Drori <shayd@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-2-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 89e399606877b..33df0418e5754 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -843,7 +843,8 @@ void mlx5_drain_fw_reset(struct mlx5_core_dev *dev)
+       cancel_work_sync(&fw_reset->reset_reload_work);
+       cancel_work_sync(&fw_reset->reset_now_work);
+       cancel_work_sync(&fw_reset->reset_abort_work);
+-      cancel_delayed_work(&fw_reset->reset_timeout_work);
++      if (test_bit(MLX5_FW_RESET_FLAGS_RESET_REQUESTED, &fw_reset->reset_flags))
++              mlx5_sync_reset_clear_reset_requested(dev, true);
+ }
+ static const struct devlink_param mlx5_fw_reset_devlink_params[] = {
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch b/queue-6.18/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch
new file mode 100644 (file)
index 0000000..d22edea
--- /dev/null
@@ -0,0 +1,84 @@
+From c9fa15846514fe115887c756210f53e371d3a787 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:12 +0200
+Subject: net/mlx5: fw_tracer, Handle escaped percent properly
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit c0289f67f7d6a0dfba0e92cfe661a5c70c8c6e92 ]
+
+The firmware tracer's format string validation and parameter counting
+did not properly handle escaped percent signs (%%). This caused
+fw_tracer to count more parameters when trace format strings contained
+literal percent characters.
+
+To fix it, allow %% to pass string validation and skip %% sequences when
+counting parameters since they represent literal percent signs rather
+than format specifiers.
+
+Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reported-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 20 +++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 9c86c8c72d049..0b82a6a133d6c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -368,11 +368,11 @@ static bool mlx5_is_valid_spec(const char *str)
+       while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l')
+               str++;
+-      /* Check if it's a valid integer/hex specifier:
++      /* Check if it's a valid integer/hex specifier or %%:
+        * Valid formats: %x, %d, %i, %u, etc.
+        */
+       if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' &&
+-          *str != 'u' && *str != 'c')
++          *str != 'u' && *str != 'c' && *str != '%')
+               return false;
+       return true;
+@@ -390,7 +390,11 @@ static bool mlx5_tracer_validate_params(const char *str)
+               if (!mlx5_is_valid_spec(substr + 1))
+                       return false;
+-              substr = strstr(substr + 1, PARAM_CHAR);
++              if (*(substr + 1) == '%')
++                      substr = strstr(substr + 2, PARAM_CHAR);
++              else
++                      substr = strstr(substr + 1, PARAM_CHAR);
++
+       }
+       return true;
+@@ -469,11 +473,15 @@ static int mlx5_tracer_get_num_of_params(char *str)
+               substr = strstr(pstr, VAL_PARM);
+       }
+-      /* count all the % characters */
++      /* count all the % characters, but skip %% (escaped percent) */
+       substr = strstr(str, PARAM_CHAR);
+       while (substr) {
+-              num_of_params += 1;
+-              str = substr + 1;
++              if (*(substr + 1) != '%') {
++                      num_of_params += 1;
++                      str = substr + 1;
++              } else {
++                      str = substr + 2;
++              }
+               substr = strstr(str, PARAM_CHAR);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-mlx5-fw_tracer-validate-format-string-parameters.patch b/queue-6.18/net-mlx5-fw_tracer-validate-format-string-parameters.patch
new file mode 100644 (file)
index 0000000..11af89c
--- /dev/null
@@ -0,0 +1,195 @@
+From 2ee514d50589b370a170f6f4d06a2a42a6777b90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:11 +0200
+Subject: net/mlx5: fw_tracer, Validate format string parameters
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit b35966042d20b14e2d83330049f77deec5229749 ]
+
+Add validation for format string parameters in the firmware tracer to
+prevent potential security vulnerabilities and crashes from malformed
+format strings received from firmware.
+
+The firmware tracer receives format strings from the device firmware and
+uses them to format trace messages. Without proper validation, bad
+firmware could provide format strings with invalid format specifiers
+(e.g., %s, %p, %n) that could lead to crashes, or other undefined
+behavior.
+
+Add mlx5_tracer_validate_params() to validate that all format specifiers
+in trace strings are limited to safe integer/hex formats (%x, %d, %i,
+%u, %llx, %lx, etc.). Reject strings containing other format types that
+could be used to access arbitrary memory or cause crashes.
+Invalid format strings are added to the trace output for visibility with
+"BAD_FORMAT: " prefix.
+
+Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Reported-by: Breno Leitao <leitao@debian.org>
+Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-4-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 83 ++++++++++++++++---
+ .../mellanox/mlx5/core/diag/fw_tracer.h       |  1 +
+ 2 files changed, 74 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 080e7eab52c7e..9c86c8c72d049 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -33,6 +33,7 @@
+ #include "lib/eq.h"
+ #include "fw_tracer.h"
+ #include "fw_tracer_tracepoint.h"
++#include <linux/ctype.h>
+ static int mlx5_query_mtrc_caps(struct mlx5_fw_tracer *tracer)
+ {
+@@ -358,6 +359,43 @@ static const char *VAL_PARM               = "%llx";
+ static const char *REPLACE_64_VAL_PARM        = "%x%x";
+ static const char *PARAM_CHAR         = "%";
++static bool mlx5_is_valid_spec(const char *str)
++{
++      /* Parse format specifiers to find the actual type.
++       * Structure: %[flags][width][.precision][length]type
++       * Skip flags, width, precision & length.
++       */
++      while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l')
++              str++;
++
++      /* Check if it's a valid integer/hex specifier:
++       * Valid formats: %x, %d, %i, %u, etc.
++       */
++      if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' &&
++          *str != 'u' && *str != 'c')
++              return false;
++
++      return true;
++}
++
++static bool mlx5_tracer_validate_params(const char *str)
++{
++      const char *substr = str;
++
++      if (!str)
++              return false;
++
++      substr = strstr(substr, PARAM_CHAR);
++      while (substr) {
++              if (!mlx5_is_valid_spec(substr + 1))
++                      return false;
++
++              substr = strstr(substr + 1, PARAM_CHAR);
++      }
++
++      return true;
++}
++
+ static int mlx5_tracer_message_hash(u32 message_id)
+ {
+       return jhash_1word(message_id, 0) & (MESSAGE_HASH_SIZE - 1);
+@@ -419,6 +457,10 @@ static int mlx5_tracer_get_num_of_params(char *str)
+       char *substr, *pstr = str;
+       int num_of_params = 0;
++      /* Validate that all parameters are valid before processing */
++      if (!mlx5_tracer_validate_params(str))
++              return -EINVAL;
++
+       /* replace %llx with %x%x */
+       substr = strstr(pstr, VAL_PARM);
+       while (substr) {
+@@ -570,14 +612,17 @@ void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt,
+ {
+       char    tmp[512];
+-      snprintf(tmp, sizeof(tmp), str_frmt->string,
+-               str_frmt->params[0],
+-               str_frmt->params[1],
+-               str_frmt->params[2],
+-               str_frmt->params[3],
+-               str_frmt->params[4],
+-               str_frmt->params[5],
+-               str_frmt->params[6]);
++      if (str_frmt->invalid_string)
++              snprintf(tmp, sizeof(tmp), "BAD_FORMAT: %s", str_frmt->string);
++      else
++              snprintf(tmp, sizeof(tmp), str_frmt->string,
++                       str_frmt->params[0],
++                       str_frmt->params[1],
++                       str_frmt->params[2],
++                       str_frmt->params[3],
++                       str_frmt->params[4],
++                       str_frmt->params[5],
++                       str_frmt->params[6]);
+       trace_mlx5_fw(dev->tracer, trace_timestamp, str_frmt->lost,
+                     str_frmt->event_id, tmp);
+@@ -609,6 +654,13 @@ static int mlx5_tracer_handle_raw_string(struct mlx5_fw_tracer *tracer,
+       return 0;
+ }
++static void mlx5_tracer_handle_bad_format_string(struct mlx5_fw_tracer *tracer,
++                                               struct tracer_string_format *cur_string)
++{
++      cur_string->invalid_string = true;
++      list_add_tail(&cur_string->list, &tracer->ready_strings_list);
++}
++
+ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                          struct tracer_event *tracer_event)
+ {
+@@ -619,12 +671,18 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+               if (!cur_string)
+                       return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+-              cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
+-              cur_string->last_param_num = 0;
+               cur_string->event_id = tracer_event->event_id;
+               cur_string->tmsn = tracer_event->string_event.tmsn;
+               cur_string->timestamp = tracer_event->string_event.timestamp;
+               cur_string->lost = tracer_event->lost_event;
++              cur_string->last_param_num = 0;
++              cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
++              if (cur_string->num_of_params < 0) {
++                      pr_debug("%s Invalid format string parameters\n",
++                               __func__);
++                      mlx5_tracer_handle_bad_format_string(tracer, cur_string);
++                      return 0;
++              }
+               if (cur_string->num_of_params == 0) /* trace with no params */
+                       list_add_tail(&cur_string->list, &tracer->ready_strings_list);
+       } else {
+@@ -634,6 +692,11 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                __func__, tracer_event->string_event.tmsn);
+                       return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+               }
++              if (cur_string->num_of_params < 0) {
++                      pr_debug("%s string parameter of invalid string, dumping\n",
++                               __func__);
++                      return 0;
++              }
+               cur_string->last_param_num += 1;
+               if (cur_string->last_param_num > TRACER_MAX_PARAMS) {
+                       pr_debug("%s Number of params exceeds the max (%d)\n",
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+index 5c548bb74f07b..30d0bcba88479 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+@@ -125,6 +125,7 @@ struct tracer_string_format {
+       struct list_head list;
+       u32 timestamp;
+       bool lost;
++      bool invalid_string;
+ };
+ enum mlx5_fw_tracer_ownership_state {
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-mlx5-make-enable_mpesw-idempotent.patch b/queue-6.18/net-mlx5-make-enable_mpesw-idempotent.patch
new file mode 100644 (file)
index 0000000..e9bf2c0
--- /dev/null
@@ -0,0 +1,58 @@
+From 3e334e7c3cf3ee987e72cc2b30df6397714d5888 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Dec 2025 17:13:27 +0200
+Subject: net/mlx5: make enable_mpesw idempotent
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit cd7671ef4cf2edf73cd2a3dca3a2f522a4525bf5 ]
+
+The enable_mpesw() function returns -EINVAL if ldev->mode is not
+MLX5_LAG_MODE_NONE. This means attempting to enable MPESW mode when it's
+already enabled will fail. In contrast, disable_mpesw() properly checks
+if the mode is MLX5_LAG_MODE_MPESW before proceeding, making it
+naturally idempotent and safe to call multiple times.
+
+Fix enable_mpesw() to return success if mpesw is already enabled.
+
+Fixes: a32327a3a02c ("net/mlx5: Lag, Control MultiPort E-Switch single FDB mode")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Shay Drori <shayd@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/1764602008-1334866-2-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
+index aad52d3a90e68..2d86af8f0d9b8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
+@@ -67,12 +67,19 @@ static int mlx5_mpesw_metadata_set(struct mlx5_lag *ldev)
+ static int enable_mpesw(struct mlx5_lag *ldev)
+ {
+-      int idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
+       struct mlx5_core_dev *dev0;
+       int err;
++      int idx;
+       int i;
+-      if (idx < 0 || ldev->mode != MLX5_LAG_MODE_NONE)
++      if (ldev->mode == MLX5_LAG_MODE_MPESW)
++              return 0;
++
++      if (ldev->mode != MLX5_LAG_MODE_NONE)
++              return -EINVAL;
++
++      idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
++      if (idx < 0)
+               return -EINVAL;
+       dev0 = ldev->pf[idx].dev;
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-mlx5-serialize-firmware-reset-with-devlink.patch b/queue-6.18/net-mlx5-serialize-firmware-reset-with-devlink.patch
new file mode 100644 (file)
index 0000000..cc7f170
--- /dev/null
@@ -0,0 +1,209 @@
+From 6150f84808fd7854d1679bbc6302a816b575502b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:13 +0200
+Subject: net/mlx5: Serialize firmware reset with devlink
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 367e501f8b095eca08d2eb0ba4ccea5b5e82c169 ]
+
+The firmware reset mechanism can be triggered by asynchronous events,
+which may race with other devlink operations like devlink reload or
+devlink dev eswitch set, potentially leading to inconsistent states.
+
+This patch addresses the race by using the devl_lock to serialize the
+firmware reset against other devlink operations. When a reset is
+requested, the driver attempts to acquire the lock. If successful, it
+sets a flag to block devlink reload or eswitch changes, ACKs the reset
+to firmware and then releases the lock. If the lock is already held by
+another operation, the driver NACKs the firmware reset request,
+indicating that the reset cannot proceed.
+
+Firmware reset does not keep the devl_lock and instead uses an internal
+firmware reset bit. This is because firmware resets can be triggered by
+asynchronous events, and processed in different threads. It is illegal
+and unsafe to acquire a lock in one thread and attempt to release it in
+another, as lock ownership is intrinsically thread-specific.
+
+This change ensures that firmware resets and other devlink operations
+are mutually exclusive during the critical reset request phase,
+preventing race conditions.
+
+Fixes: 38b9f903f22b ("net/mlx5: Handle sync reset request event")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Mateusz Berezecki <mberezecki@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-6-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/devlink.c |  5 +++
+ .../mellanox/mlx5/core/eswitch_offloads.c     |  6 +++
+ .../ethernet/mellanox/mlx5/core/fw_reset.c    | 45 +++++++++++++++++--
+ .../ethernet/mellanox/mlx5/core/fw_reset.h    |  1 +
+ 4 files changed, 53 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 887adf4807d16..ea77fbd98396a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -197,6 +197,11 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
+       struct pci_dev *pdev = dev->pdev;
+       int ret = 0;
++      if (mlx5_fw_reset_in_progress(dev)) {
++              NL_SET_ERR_MSG_MOD(extack, "Can't reload during firmware reset");
++              return -EBUSY;
++      }
++
+       if (mlx5_dev_is_lightweight(dev)) {
+               if (action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT)
+                       return -EOPNOTSUPP;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index 44a142a041b2f..784130cdf6c07 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -52,6 +52,7 @@
+ #include "devlink.h"
+ #include "lag/lag.h"
+ #include "en/tc/post_meter.h"
++#include "fw_reset.h"
+ /* There are two match-all miss flows, one for unicast dst mac and
+  * one for multicast.
+@@ -3807,6 +3808,11 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
+       if (IS_ERR(esw))
+               return PTR_ERR(esw);
++      if (mlx5_fw_reset_in_progress(esw->dev)) {
++              NL_SET_ERR_MSG_MOD(extack, "Can't change eswitch mode during firmware reset");
++              return -EBUSY;
++      }
++
+       if (esw_mode_from_devlink(mode, &mlx5_mode))
+               return -EINVAL;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 33df0418e5754..4544f1968f73f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -15,6 +15,7 @@ enum {
+       MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
+       MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED,
+       MLX5_FW_RESET_FLAGS_UNLOAD_EVENT,
++      MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS,
+ };
+ struct mlx5_fw_reset {
+@@ -127,6 +128,16 @@ int mlx5_fw_reset_query(struct mlx5_core_dev *dev, u8 *reset_level, u8 *reset_ty
+       return mlx5_reg_mfrl_query(dev, reset_level, reset_type, NULL, NULL);
+ }
++bool mlx5_fw_reset_in_progress(struct mlx5_core_dev *dev)
++{
++      struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
++
++      if (!fw_reset)
++              return false;
++
++      return test_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
++}
++
+ static int mlx5_fw_reset_get_reset_method(struct mlx5_core_dev *dev,
+                                         u8 *reset_method)
+ {
+@@ -242,6 +253,8 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
+                                                       BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE));
+               devl_unlock(devlink);
+       }
++
++      clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
+ }
+ static void mlx5_stop_sync_reset_poll(struct mlx5_core_dev *dev)
+@@ -461,27 +474,48 @@ static void mlx5_sync_reset_request_event(struct work_struct *work)
+       struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
+                                                     reset_request_work);
+       struct mlx5_core_dev *dev = fw_reset->dev;
++      bool nack_request = false;
++      struct devlink *devlink;
+       int err;
+       err = mlx5_fw_reset_get_reset_method(dev, &fw_reset->reset_method);
+-      if (err)
++      if (err) {
++              nack_request = true;
+               mlx5_core_warn(dev, "Failed reading MFRL, err %d\n", err);
++      } else if (!mlx5_is_reset_now_capable(dev, fw_reset->reset_method) ||
++                 test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
++                          &fw_reset->reset_flags)) {
++              nack_request = true;
++      }
+-      if (err || test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) ||
+-          !mlx5_is_reset_now_capable(dev, fw_reset->reset_method)) {
++      devlink = priv_to_devlink(dev);
++      /* For external resets, try to acquire devl_lock. Skip if devlink reset is
++       * pending (lock already held)
++       */
++      if (nack_request ||
++          (!test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP,
++                     &fw_reset->reset_flags) &&
++           !devl_trylock(devlink))) {
+               err = mlx5_fw_reset_set_reset_sync_nack(dev);
+               mlx5_core_warn(dev, "PCI Sync FW Update Reset Nack %s",
+                              err ? "Failed" : "Sent");
+               return;
+       }
++
+       if (mlx5_sync_reset_set_reset_requested(dev))
+-              return;
++              goto unlock;
++
++      set_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
+       err = mlx5_fw_reset_set_reset_sync_ack(dev);
+       if (err)
+               mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack Failed. Error code: %d\n", err);
+       else
+               mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack. Device reset is expected.\n");
++
++unlock:
++      if (!test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags))
++              devl_unlock(devlink);
+ }
+ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev, u16 dev_id)
+@@ -721,6 +755,8 @@ static void mlx5_sync_reset_abort_event(struct work_struct *work)
+       if (mlx5_sync_reset_clear_reset_requested(dev, true))
+               return;
++
++      clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
+       mlx5_core_warn(dev, "PCI Sync FW Update Reset Aborted.\n");
+ }
+@@ -757,6 +793,7 @@ static void mlx5_sync_reset_timeout_work(struct work_struct *work)
+       if (mlx5_sync_reset_clear_reset_requested(dev, true))
+               return;
++      clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
+       mlx5_core_warn(dev, "PCI Sync FW Update Reset Timeout.\n");
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+index d5b28525c960d..2d96b2adc1cdf 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+@@ -10,6 +10,7 @@ int mlx5_fw_reset_query(struct mlx5_core_dev *dev, u8 *reset_level, u8 *reset_ty
+ int mlx5_fw_reset_set_reset_sync(struct mlx5_core_dev *dev, u8 reset_type_sel,
+                                struct netlink_ext_ack *extack);
+ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev);
++bool mlx5_fw_reset_in_progress(struct mlx5_core_dev *dev);
+ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev);
+ void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked);
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-mlx5e-avoid-unregistering-psp-twice.patch b/queue-6.18/net-mlx5e-avoid-unregistering-psp-twice.patch
new file mode 100644 (file)
index 0000000..f4f66d5
--- /dev/null
@@ -0,0 +1,58 @@
+From 6bae7d8d5096cd5c385bd6f33c25463a149c51a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Dec 2025 17:13:28 +0200
+Subject: net/mlx5e: Avoid unregistering PSP twice
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit 35e93736f69963337912594eb3951ab320b77521 ]
+
+PSP is unregistered twice in:
+_mlx5e_remove -> mlx5e_psp_unregister
+mlx5e_nic_cleanup -> mlx5e_psp_unregister
+
+This leads to a refcount underflow in some conditions:
+------------[ cut here ]------------
+refcount_t: underflow; use-after-free.
+WARNING: CPU: 2 PID: 1694 at lib/refcount.c:28 refcount_warn_saturate+0xd8/0xe0
+[...]
+ mlx5e_psp_unregister+0x26/0x50 [mlx5_core]
+ mlx5e_nic_cleanup+0x26/0x90 [mlx5_core]
+ mlx5e_remove+0xe6/0x1f0 [mlx5_core]
+ auxiliary_bus_remove+0x18/0x30
+ device_release_driver_internal+0x194/0x1f0
+ bus_remove_device+0xc6/0x130
+ device_del+0x159/0x3c0
+ mlx5_rescan_drivers_locked+0xbc/0x2a0 [mlx5_core]
+[...]
+
+Do not directly remove psp from the _mlx5e_remove path, the PSP cleanup
+happens as part of profile cleanup.
+
+Fixes: 89ee2d92f66c ("net/mlx5e: Support PSP offload functionality")
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/1764602008-1334866-3-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 5e17eae81f4b3..1545f9c008f49 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -6805,7 +6805,6 @@ static void _mlx5e_remove(struct auxiliary_device *adev)
+        * is already unregistered before changing to NIC profile.
+        */
+       if (priv->netdev->reg_state == NETREG_REGISTERED) {
+-              mlx5e_psp_unregister(priv);
+               unregister_netdev(priv->netdev);
+               _mlx5e_suspend(adev, false);
+       } else {
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-mlx5e-don-t-include-psp-in-the-hard-mtu-calculat.patch b/queue-6.18/net-mlx5e-don-t-include-psp-in-the-hard-mtu-calculat.patch
new file mode 100644 (file)
index 0000000..5f2565a
--- /dev/null
@@ -0,0 +1,53 @@
+From e2c475063147bd5dd3e74cd143fb7d55717c9c32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:17 +0200
+Subject: net/mlx5e: Don't include PSP in the hard MTU calculations
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit 4198a14c8c6252fd1191afaa742dd515dcaf3487 ]
+
+Commit [1] added the 40 bytes required by the PSP header+trailer and the
+UDP header to MLX5E_ETH_HARD_MTU, which limits the device-wide max
+software MTU that could be set. This is not okay, because most packets
+are not PSP packets and it doesn't make sense to always reserve space
+for headers which won't get added in most cases.
+
+As it turns out, for TCP connections, PSP overhead is already taken into
+account in the TCP MSS calculations via inet_csk(sk)->icsk_ext_hdr_len.
+This was added in commit [2]. This means that the extra space reserved
+in the hard MTU for mlx5 ends up unused and wasted.
+
+Remove the unnecessary 40 byte reservation from hard MTU.
+
+[1] commit e5a1861a298e ("net/mlx5e: Implement PSP Tx data path")
+[2] commit e97269257fe4 ("net: psp: update the TCP MSS to reflect PSP
+packet overhead")
+
+Fixes: e5a1861a298e ("net/mlx5e: Implement PSP Tx data path")
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Shahar Shitrit <shshitrit@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-10-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+index a163f81f07c13..a6479e4d8d8c6 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+@@ -69,7 +69,7 @@ struct page_pool;
+ #define MLX5E_METADATA_ETHER_TYPE (0x8CE4)
+ #define MLX5E_METADATA_ETHER_LEN 8
+-#define MLX5E_ETH_HARD_MTU (ETH_HLEN + PSP_ENCAP_HLEN + PSP_TRL_SIZE + VLAN_HLEN + ETH_FCS_LEN)
++#define MLX5E_ETH_HARD_MTU (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
+ #define MLX5E_HW2SW_MTU(params, hwmtu) ((hwmtu) - ((params)->hard_mtu))
+ #define MLX5E_SW2HW_MTU(params, swmtu) ((swmtu) + ((params)->hard_mtu))
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-mlx5e-trigger-neighbor-resolution-for-unresolved.patch b/queue-6.18/net-mlx5e-trigger-neighbor-resolution-for-unresolved.patch
new file mode 100644 (file)
index 0000000..daef2b2
--- /dev/null
@@ -0,0 +1,60 @@
+From a6a9c9885bf0de63ec9d74b3d44e5e5290e8ee03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:15 +0200
+Subject: net/mlx5e: Trigger neighbor resolution for unresolved destinations
+
+From: Jianbo Liu <jianbol@nvidia.com>
+
+[ Upstream commit 9ab89bde13e5251e1d0507e1cc426edcdfe19142 ]
+
+When initializing the MAC addresses for an outbound IPsec packet offload
+rule in mlx5e_ipsec_init_macs, the call to dst_neigh_lookup is used to
+find the next-hop neighbor (typically the gateway in tunnel mode).
+This call might create a new neighbor entry if one doesn't already
+exist. This newly created entry starts in the INCOMPLETE state, as the
+kernel hasn't yet sent an ARP or NDISC probe to resolve the MAC
+address. In this case, neigh_ha_snapshot will correctly return an
+all-zero MAC address.
+
+IPsec packet offload requires the actual next-hop MAC address to
+program the rule correctly. If the neighbor state is INCOMPLETE when
+the rule is created, the hardware rule is programmed with an all-zero
+destination MAC address. Packets sent using this rule will be
+subsequently dropped by the receiving network infrastructure or host.
+
+This patch adds a check specifically for the outbound offload path. If
+neigh_ha_snapshot returns an all-zero MAC address, it proactively
+calls neigh_event_send(n, NULL). This ensures the kernel immediately
+sends the initial ARP or NDISC probe if one isn't already pending,
+accelerating the resolution process. This helps prevent the hardware
+rule from being programmed with an invalid MAC address and avoids
+packet drops due to unresolved neighbors.
+
+Fixes: 71670f766b8f ("net/mlx5e: Support routed networks during IPsec MACs initialization")
+Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-8-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+index 6c79b9cea2efb..a8fb4bec369cf 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+@@ -358,6 +358,9 @@ static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry,
+       neigh_ha_snapshot(addr, n, netdev);
+       ether_addr_copy(dst, addr);
++      if (attrs->dir == XFRM_DEV_OFFLOAD_OUT &&
++          is_zero_ether_addr(addr))
++              neigh_event_send(n, NULL);
+       dst_release(rt_dst_entry);
+       neigh_release(n);
+       return;
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-mlx5e-use-ip6_dst_lookup-instead-of-ipv6_dst_loo.patch b/queue-6.18/net-mlx5e-use-ip6_dst_lookup-instead-of-ipv6_dst_loo.patch
new file mode 100644 (file)
index 0000000..e4a887a
--- /dev/null
@@ -0,0 +1,50 @@
+From 9d1d1f419b2c51ec92b664ab944e07034baf7156 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:14 +0200
+Subject: net/mlx5e: Use ip6_dst_lookup instead of ipv6_dst_lookup_flow for MAC
+ init
+
+From: Jianbo Liu <jianbol@nvidia.com>
+
+[ Upstream commit e35d7da8dd9e55b37c3e8ab548f6793af0c2ab49 ]
+
+Replace ipv6_stub->ipv6_dst_lookup_flow() with ip6_dst_lookup() in
+mlx5e_ipsec_init_macs() since IPsec transformations are not needed
+during Security Association setup - only basic routing information is
+required for nexthop MAC address resolution.
+
+This resolves an issue where XfrmOutNoStates error counter would be
+incremented when xfrm policy is configured before xfrm state, as the
+IPsec-aware routing function would attempt policy checks during SA
+initialization.
+
+Fixes: 71670f766b8f ("net/mlx5e: Support routed networks during IPsec MACs initialization")
+Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-7-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+index 35d9530037a65..6c79b9cea2efb 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+@@ -342,9 +342,8 @@ static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry,
+               rt_dst_entry = &rt->dst;
+               break;
+       case AF_INET6:
+-              rt_dst_entry = ipv6_stub->ipv6_dst_lookup_flow(
+-                      dev_net(netdev), NULL, &fl6, NULL);
+-              if (IS_ERR(rt_dst_entry))
++              if (!IS_ENABLED(CONFIG_IPV6) ||
++                  ip6_dst_lookup(dev_net(netdev), NULL, &rt_dst_entry, &fl6))
+                       goto neigh;
+               break;
+       default:
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-openvswitch-fix-middle-attribute-validation-in-p.patch b/queue-6.18/net-openvswitch-fix-middle-attribute-validation-in-p.patch
new file mode 100644 (file)
index 0000000..ccde01d
--- /dev/null
@@ -0,0 +1,112 @@
+From d7e5658bcb2f8f2e330ae57a372239d56ad6254a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Dec 2025 11:53:32 +0100
+Subject: net: openvswitch: fix middle attribute validation in push_nsh()
+ action
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 5ace7ef87f059d68b5f50837ef3e8a1a4870c36e ]
+
+The push_nsh() action structure looks like this:
+
+ OVS_ACTION_ATTR_PUSH_NSH(OVS_KEY_ATTR_NSH(OVS_NSH_KEY_ATTR_BASE,...))
+
+The outermost OVS_ACTION_ATTR_PUSH_NSH attribute is OK'ed by the
+nla_for_each_nested() inside __ovs_nla_copy_actions().  The innermost
+OVS_NSH_KEY_ATTR_BASE/MD1/MD2 are OK'ed by the nla_for_each_nested()
+inside nsh_key_put_from_nlattr().  But nothing checks if the attribute
+in the middle is OK.  We don't even check that this attribute is the
+OVS_KEY_ATTR_NSH.  We just do a double unwrap with a pair of nla_data()
+calls - first time directly while calling validate_push_nsh() and the
+second time as part of the nla_for_each_nested() macro, which isn't
+safe, potentially causing invalid memory access if the size of this
+attribute is incorrect.  The failure may not be noticed during
+validation due to larger netlink buffer, but cause trouble later during
+action execution where the buffer is allocated exactly to the size:
+
+ BUG: KASAN: slab-out-of-bounds in nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch]
+ Read of size 184 at addr ffff88816459a634 by task a.out/22624
+
+ CPU: 8 UID: 0 PID: 22624 6.18.0-rc7+ #115 PREEMPT(voluntary)
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x51/0x70
+  print_address_description.constprop.0+0x2c/0x390
+  kasan_report+0xdd/0x110
+  kasan_check_range+0x35/0x1b0
+  __asan_memcpy+0x20/0x60
+  nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch]
+  push_nsh+0x82/0x120 [openvswitch]
+  do_execute_actions+0x1405/0x2840 [openvswitch]
+  ovs_execute_actions+0xd5/0x3b0 [openvswitch]
+  ovs_packet_cmd_execute+0x949/0xdb0 [openvswitch]
+  genl_family_rcv_msg_doit+0x1d6/0x2b0
+  genl_family_rcv_msg+0x336/0x580
+  genl_rcv_msg+0x9f/0x130
+  netlink_rcv_skb+0x11f/0x370
+  genl_rcv+0x24/0x40
+  netlink_unicast+0x73e/0xaa0
+  netlink_sendmsg+0x744/0xbf0
+  __sys_sendto+0x3d6/0x450
+  do_syscall_64+0x79/0x2c0
+  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+  </TASK>
+
+Let's add some checks that the attribute is properly sized and it's
+the only one attribute inside the action.  Technically, there is no
+real reason for OVS_KEY_ATTR_NSH to be there, as we know that we're
+pushing an NSH header already, it just creates extra nesting, but
+that's how uAPI works today.  So, keeping as it is.
+
+Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support")
+Reported-by: Junvy Yang <zhuque@tencent.com>
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Eelco Chaudron echaudro@redhat.com
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Link: https://patch.msgid.link/20251204105334.900379-1-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/flow_netlink.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
+index 1cb4f97335d87..2d536901309ea 100644
+--- a/net/openvswitch/flow_netlink.c
++++ b/net/openvswitch/flow_netlink.c
+@@ -2802,13 +2802,20 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
+       return err;
+ }
+-static bool validate_push_nsh(const struct nlattr *attr, bool log)
++static bool validate_push_nsh(const struct nlattr *a, bool log)
+ {
++      struct nlattr *nsh_key = nla_data(a);
+       struct sw_flow_match match;
+       struct sw_flow_key key;
++      /* There must be one and only one NSH header. */
++      if (!nla_ok(nsh_key, nla_len(a)) ||
++          nla_total_size(nla_len(nsh_key)) != nla_len(a) ||
++          nla_type(nsh_key) != OVS_KEY_ATTR_NSH)
++              return false;
++
+       ovs_match_init(&match, &key, true, NULL);
+-      return !nsh_key_put_from_nlattr(attr, &match, false, true, log);
++      return !nsh_key_put_from_nlattr(nsh_key, &match, false, true, log);
+ }
+ /* Return false if there are any non-masked bits set.
+@@ -3389,7 +3396,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
+                                       return -EINVAL;
+                       }
+                       mac_proto = MAC_PROTO_NONE;
+-                      if (!validate_push_nsh(nla_data(a), log))
++                      if (!validate_push_nsh(a, log))
+                               return -EINVAL;
+                       break;
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-phy-realtek-allow-clkout-to-be-disabled-on-rtl82.patch b/queue-6.18/net-phy-realtek-allow-clkout-to-be-disabled-on-rtl82.patch
new file mode 100644 (file)
index 0000000..174211c
--- /dev/null
@@ -0,0 +1,112 @@
+From b08ce64531ce5951280e7d19860265796e7ba077 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Nov 2025 01:40:31 +0200
+Subject: net: phy: realtek: allow CLKOUT to be disabled on
+ RTL8211F(D)(I)-VD-CG
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit e1a31c41bef678afe0d99b7f0dc3711a80c68447 ]
+
+Add CLKOUT disable support for RTL8211F(D)(I)-VD-CG. Like with other PHY
+variants, this feature might be requested by customers when the clock
+output is not used, in order to reduce electromagnetic interference (EMI).
+
+In the common driver, the CLKOUT configuration is done through PHYCR2.
+The RTL_8211FVD_PHYID is singled out as not having that register, and
+execution in rtl8211f_config_init() returns early after commit
+2c67301584f2 ("net: phy: realtek: Avoid PHYCR2 access if PHYCR2 not
+present").
+
+But actually CLKOUT is configured through a different register for this
+PHY. Instead of pretending this is PHYCR2 (which it is not), just add
+some code for modifying this register inside the rtl8211f_disable_clk_out()
+function, and move that outside the code portion that runs only if
+PHYCR2 exists.
+
+In practice this reorders the PHYCR2 writes to disable PHY-mode EEE and
+to disable the CLKOUT for the normal RTL8211F variants, but this should
+be perfectly fine.
+
+It was not noted that RTL8211F(D)(I)-VD-CG would need a genphy_soft_reset()
+call after disabling the CLKOUT. Despite that, we do it out of caution
+and for symmetry with the other RTL8211F models.
+
+Co-developed-by: Clark Wang <xiaoning.wang@nxp.com>
+Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20251117234033.345679-5-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 4f0638b12451 ("net: phy: RTL8211FVD: Restore disabling of PHY-mode EEE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 31 ++++++++++++++++++--------
+ 1 file changed, 22 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
+index daf2457b378bf..f0348b92beec3 100644
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -89,6 +89,14 @@
+ #define RTL8211F_LEDCR_MASK                   GENMASK(4, 0)
+ #define RTL8211F_LEDCR_SHIFT                  5
++/* RTL8211F(D)(I)-VD-CG CLKOUT configuration is specified via magic values
++ * to undocumented register pages. The names here do not reflect the datasheet.
++ * Unlike other PHY models, CLKOUT configuration does not go through PHYCR2.
++ */
++#define RTL8211FVD_CLKOUT_PAGE                        0xd05
++#define RTL8211FVD_CLKOUT_REG                 0x11
++#define RTL8211FVD_CLKOUT_EN                  BIT(8)
++
+ /* RTL8211F RGMII configuration */
+ #define RTL8211F_RGMII_PAGE                   0xd08
+@@ -626,8 +634,13 @@ static int rtl8211f_config_clk_out(struct phy_device *phydev)
+       if (!priv->disable_clk_out)
+               return 0;
+-      ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
+-                             RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, 0);
++      if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
++              ret = phy_modify_paged(phydev, RTL8211FVD_CLKOUT_PAGE,
++                                     RTL8211FVD_CLKOUT_REG,
++                                     RTL8211FVD_CLKOUT_EN, 0);
++      else
++              ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
++                                     RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, 0);
+       if (ret)
+               return ret;
+@@ -653,6 +666,13 @@ static int rtl8211f_config_init(struct phy_device *phydev)
+       if (ret)
+               return ret;
++      ret = rtl8211f_config_clk_out(phydev);
++      if (ret) {
++              dev_err(dev, "clkout configuration failed: %pe\n",
++                      ERR_PTR(ret));
++              return ret;
++      }
++
+       /* RTL8211FVD has no PHYCR2 register */
+       if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
+               return 0;
+@@ -663,13 +683,6 @@ static int rtl8211f_config_init(struct phy_device *phydev)
+       if (ret)
+               return ret;
+-      ret = rtl8211f_config_clk_out(phydev);
+-      if (ret) {
+-              dev_err(dev, "clkout configuration failed: %pe\n",
+-                      ERR_PTR(ret));
+-              return ret;
+-      }
+-
+       return 0;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-phy-realtek-create-rtl8211f_config_phy_eee-helpe.patch b/queue-6.18/net-phy-realtek-create-rtl8211f_config_phy_eee-helpe.patch
new file mode 100644 (file)
index 0000000..cbbaa3a
--- /dev/null
@@ -0,0 +1,69 @@
+From 3383ef741ca76eb06cff2d5db5b18b924c693100 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Nov 2025 01:40:33 +0200
+Subject: net: phy: realtek: create rtl8211f_config_phy_eee() helper
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 4465ae435ddc0162d5033a543658449d53d46d08 ]
+
+To simplify the rtl8211f_config_init() control flow and get rid of
+"early" returns for PHYs where the PHYCR2 register is absent, move the
+entire logic sub-block that deals with disabling PHY-mode EEE to a
+separate function. There, it is much more obvious what the early
+"return 0" skips, and it becomes more difficult to accidentally skip
+unintended stuff.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20251117234033.345679-7-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 4f0638b12451 ("net: phy: RTL8211FVD: Restore disabling of PHY-mode EEE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
+index 35f40bfdaf113..2c661346050f1 100644
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -662,6 +662,17 @@ static int rtl8211f_config_aldps(struct phy_device *phydev)
+                               mask, mask);
+ }
++static int rtl8211f_config_phy_eee(struct phy_device *phydev)
++{
++      /* RTL8211FVD has no PHYCR2 register */
++      if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
++              return 0;
++
++      /* Disable PHY-mode EEE so LPI is passed to the MAC */
++      return phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
++                              RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
++}
++
+ static int rtl8211f_config_init(struct phy_device *phydev)
+ {
+       struct device *dev = &phydev->mdio.dev;
+@@ -685,17 +696,7 @@ static int rtl8211f_config_init(struct phy_device *phydev)
+               return ret;
+       }
+-      /* RTL8211FVD has no PHYCR2 register */
+-      if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
+-              return 0;
+-
+-      /* Disable PHY-mode EEE so LPI is passed to the MAC */
+-      ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
+-                             RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
+-      if (ret)
+-              return ret;
+-
+-      return 0;
++      return rtl8211f_config_phy_eee(phydev);
+ }
+ static int rtl821x_suspend(struct phy_device *phydev)
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-phy-realtek-eliminate-has_phycr2-variable.patch b/queue-6.18/net-phy-realtek-eliminate-has_phycr2-variable.patch
new file mode 100644 (file)
index 0000000..b17bc94
--- /dev/null
@@ -0,0 +1,66 @@
+From 3f9f0ea232dec6ab6bdbfe91ce8e93841f5c703a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Nov 2025 01:40:30 +0200
+Subject: net: phy: realtek: eliminate has_phycr2 variable
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 910ac7bfb1af1ae4cd141ef80e03a6729213c189 ]
+
+This variable is assigned in rtl821x_probe() and used in
+rtl8211f_config_init(), which is more complex than it needs to be.
+Simply testing the same condition from rtl821x_probe() in
+rtl8211f_config_init() yields the same result (the PHY driver ID is a
+runtime invariant), but with one temporary variable less.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20251117234033.345679-4-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 4f0638b12451 ("net: phy: RTL8211FVD: Restore disabling of PHY-mode EEE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
+index 1625919a47be8..daf2457b378bf 100644
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -167,7 +167,6 @@ MODULE_LICENSE("GPL");
+ struct rtl821x_priv {
+       u16 phycr1;
+-      bool has_phycr2;
+       bool disable_clk_out;
+       struct clk *clk;
+       /* rtl8211f */
+@@ -218,7 +217,6 @@ static int rtl821x_probe(struct phy_device *phydev)
+ {
+       struct device *dev = &phydev->mdio.dev;
+       struct rtl821x_priv *priv;
+-      u32 phy_id = phydev->drv->phy_id;
+       int ret;
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+@@ -238,7 +236,6 @@ static int rtl821x_probe(struct phy_device *phydev)
+       if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
+               priv->phycr1 |= RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF;
+-      priv->has_phycr2 = !(phy_id == RTL_8211FVD_PHYID);
+       priv->disable_clk_out = of_property_read_bool(dev->of_node,
+                                                     "realtek,clkout-disable");
+@@ -656,7 +653,8 @@ static int rtl8211f_config_init(struct phy_device *phydev)
+       if (ret)
+               return ret;
+-      if (!priv->has_phycr2)
++      /* RTL8211FVD has no PHYCR2 register */
++      if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
+               return 0;
+       /* Disable PHY-mode EEE so LPI is passed to the MAC */
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-phy-realtek-eliminate-priv-phycr1-variable.patch b/queue-6.18/net-phy-realtek-eliminate-priv-phycr1-variable.patch
new file mode 100644 (file)
index 0000000..1c1ce0d
--- /dev/null
@@ -0,0 +1,118 @@
+From 7a1f905e22d2ce2c2dc90683dbde628093649d23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Nov 2025 01:40:32 +0200
+Subject: net: phy: realtek: eliminate priv->phycr1 variable
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit bb78b71faf60d11a15f07e3390fcfd31e5e523bb ]
+
+Previous changes have replaced the machine-level priv->phycr2 with a
+high-level priv->disable_clk_out. This created a discrepancy with
+priv->phycr1 which is resolved here, for uniformity.
+
+One advantage of this new implementation is that we don't read
+priv->phycr1 in rtl821x_probe() if we're never going to modify it.
+
+We never test the positive return code from phy_modify_mmd_changed(), so
+we could just as well use phy_modify_mmd().
+
+I took the ALDPS feature description from commit d90db36a9e74 ("net:
+phy: realtek: add dt property to enable ALDPS mode") and transformed it
+into a function comment - the feature is sufficiently non-obvious to
+deserve that.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20251117234033.345679-6-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 4f0638b12451 ("net: phy: RTL8211FVD: Restore disabling of PHY-mode EEE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 44 ++++++++++++++++----------
+ 1 file changed, 28 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
+index f0348b92beec3..35f40bfdaf113 100644
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -174,7 +174,7 @@ MODULE_AUTHOR("Johnson Leung");
+ MODULE_LICENSE("GPL");
+ struct rtl821x_priv {
+-      u16 phycr1;
++      bool enable_aldps;
+       bool disable_clk_out;
+       struct clk *clk;
+       /* rtl8211f */
+@@ -225,7 +225,6 @@ static int rtl821x_probe(struct phy_device *phydev)
+ {
+       struct device *dev = &phydev->mdio.dev;
+       struct rtl821x_priv *priv;
+-      int ret;
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+@@ -236,14 +235,8 @@ static int rtl821x_probe(struct phy_device *phydev)
+               return dev_err_probe(dev, PTR_ERR(priv->clk),
+                                    "failed to get phy clock\n");
+-      ret = phy_read_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1);
+-      if (ret < 0)
+-              return ret;
+-
+-      priv->phycr1 = ret & (RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF);
+-      if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
+-              priv->phycr1 |= RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF;
+-
++      priv->enable_aldps = of_property_read_bool(dev->of_node,
++                                                 "realtek,aldps-enable");
+       priv->disable_clk_out = of_property_read_bool(dev->of_node,
+                                                     "realtek,clkout-disable");
+@@ -647,17 +640,36 @@ static int rtl8211f_config_clk_out(struct phy_device *phydev)
+       return genphy_soft_reset(phydev);
+ }
+-static int rtl8211f_config_init(struct phy_device *phydev)
++/* Advance Link Down Power Saving (ALDPS) mode changes crystal/clock behaviour,
++ * which causes the RXC clock signal to stop for tens to hundreds of
++ * milliseconds.
++ *
++ * Some MACs need the RXC clock to support their internal RX logic, so ALDPS is
++ * only enabled based on an opt-in device tree property.
++ */
++static int rtl8211f_config_aldps(struct phy_device *phydev)
+ {
+       struct rtl821x_priv *priv = phydev->priv;
++      u16 mask = RTL8211F_ALDPS_PLL_OFF |
++                 RTL8211F_ALDPS_ENABLE |
++                 RTL8211F_ALDPS_XTAL_OFF;
++
++      /* The value is preserved if the device tree property is absent */
++      if (!priv->enable_aldps)
++              return 0;
++
++      return phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1,
++                              mask, mask);
++}
++
++static int rtl8211f_config_init(struct phy_device *phydev)
++{
+       struct device *dev = &phydev->mdio.dev;
+       int ret;
+-      ret = phy_modify_paged_changed(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1,
+-                                     RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF,
+-                                     priv->phycr1);
+-      if (ret < 0) {
+-              dev_err(dev, "aldps mode  configuration failed: %pe\n",
++      ret = rtl8211f_config_aldps(phydev);
++      if (ret) {
++              dev_err(dev, "aldps mode configuration failed: %pe\n",
+                       ERR_PTR(ret));
+               return ret;
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-phy-realtek-eliminate-priv-phycr2-variable.patch b/queue-6.18/net-phy-realtek-eliminate-priv-phycr2-variable.patch
new file mode 100644 (file)
index 0000000..30b47a5
--- /dev/null
@@ -0,0 +1,112 @@
+From 8a85881e510d36d36c9d21a23f11ba6950918ba1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Nov 2025 01:40:29 +0200
+Subject: net: phy: realtek: eliminate priv->phycr2 variable
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 27033d06917758d47162581da7e9de8004049dee ]
+
+The RTL8211F(D)(I)-VD-CG PHY also has support for disabling the CLKOUT,
+and we'd like to introduce the "realtek,clkout-disable" property for
+that.
+
+But it isn't done through the PHYCR2 register, and it becomes awkward to
+have the driver pretend that it is. So just replace the machine-level
+"u16 phycr2" variable with a logical "bool disable_clk_out", which
+scales better to the other PHY as well.
+
+The change is a complete functional equivalent. Before, if the device
+tree property was absent, priv->phycr2 would contain the RTL8211F_CLKOUT_EN
+bit as read from hardware. Now, we don't save priv->phycr2, but we just
+don't call phy_modify_paged() on it. Also, we can simply call
+phy_modify_paged() with the "set" argument to 0.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20251117234033.345679-3-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 4f0638b12451 ("net: phy: RTL8211FVD: Restore disabling of PHY-mode EEE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 38 ++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
+index b26f4d1c6bbfa..1625919a47be8 100644
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -167,8 +167,8 @@ MODULE_LICENSE("GPL");
+ struct rtl821x_priv {
+       u16 phycr1;
+-      u16 phycr2;
+       bool has_phycr2;
++      bool disable_clk_out;
+       struct clk *clk;
+       /* rtl8211f */
+       u16 iner;
+@@ -239,15 +239,8 @@ static int rtl821x_probe(struct phy_device *phydev)
+               priv->phycr1 |= RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF;
+       priv->has_phycr2 = !(phy_id == RTL_8211FVD_PHYID);
+-      if (priv->has_phycr2) {
+-              ret = phy_read_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2);
+-              if (ret < 0)
+-                      return ret;
+-
+-              priv->phycr2 = ret & RTL8211F_CLKOUT_EN;
+-              if (of_property_read_bool(dev->of_node, "realtek,clkout-disable"))
+-                      priv->phycr2 &= ~RTL8211F_CLKOUT_EN;
+-      }
++      priv->disable_clk_out = of_property_read_bool(dev->of_node,
++                                                    "realtek,clkout-disable");
+       phydev->priv = priv;
+@@ -627,6 +620,23 @@ static int rtl8211f_config_rgmii_delay(struct phy_device *phydev)
+       return 0;
+ }
++static int rtl8211f_config_clk_out(struct phy_device *phydev)
++{
++      struct rtl821x_priv *priv = phydev->priv;
++      int ret;
++
++      /* The value is preserved if the device tree property is absent */
++      if (!priv->disable_clk_out)
++              return 0;
++
++      ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
++                             RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, 0);
++      if (ret)
++              return ret;
++
++      return genphy_soft_reset(phydev);
++}
++
+ static int rtl8211f_config_init(struct phy_device *phydev)
+ {
+       struct rtl821x_priv *priv = phydev->priv;
+@@ -655,16 +665,14 @@ static int rtl8211f_config_init(struct phy_device *phydev)
+       if (ret)
+               return ret;
+-      ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE,
+-                             RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN,
+-                             priv->phycr2);
+-      if (ret < 0) {
++      ret = rtl8211f_config_clk_out(phydev);
++      if (ret) {
+               dev_err(dev, "clkout configuration failed: %pe\n",
+                       ERR_PTR(ret));
+               return ret;
+       }
+-      return genphy_soft_reset(phydev);
++      return 0;
+ }
+ static int rtl821x_suspend(struct phy_device *phydev)
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-phy-rtl8211fvd-restore-disabling-of-phy-mode-eee.patch b/queue-6.18/net-phy-rtl8211fvd-restore-disabling-of-phy-mode-eee.patch
new file mode 100644 (file)
index 0000000..4b4f906
--- /dev/null
@@ -0,0 +1,71 @@
+From f5fe162183ed67188148861c3f1b31494e5d9520 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 10:07:42 +0100
+Subject: net: phy: RTL8211FVD: Restore disabling of PHY-mode EEE
+
+From: Ivan Galkin <ivan.galkin@axis.com>
+
+[ Upstream commit 4f0638b12451112de4138689fa679315c8d388dc ]
+
+When support for RTL8211F(D)(I)-VD-CG was introduced in commit
+bb726b753f75 ("net: phy: realtek: add support for RTL8211F(D)(I)-VD-CG")
+the implementation assumed that this PHY model doesn't have the
+control register PHYCR2 (Page 0xa43 Address 0x19). This
+assumption was based on the differences in CLKOUT configurations
+between RTL8211FVD and the remaining RTL8211F PHYs. In the latter
+commit 2c67301584f2
+("net: phy: realtek: Avoid PHYCR2 access if PHYCR2 not present")
+this assumption was expanded to the PHY-mode EEE.
+
+I performed tests on RTL8211FI-VD-CG and confirmed that disabling
+PHY-mode EEE works correctly and is uniform with other PHYs
+supported by the driver. To validate the correctness,
+I contacted Realtek support. Realtek confirmed that PHY-mode EEE on
+RTL8211F(D)(I)-VD-CG is configured via Page 0xa43 Address 0x19 bit 5.
+
+Moreover, Realtek informed me that the most recent datasheet
+for RTL8211F(D)(I)-VD-CG v1.1 is incomplete and the naming of
+control registers is partly inconsistent. The errata I
+received from Realtek corrects the naming as follows:
+
+| Register                | Datasheet v1.1 | Errata |
+|-------------------------|----------------|--------|
+| Page 0xa44 Address 0x11 | PHYCR2         | PHYCR3 |
+| Page 0xa43 Address 0x19 | N/A            | PHYCR2 |
+
+This information confirms that the supposedly missing control register,
+PHYCR2, exists in the RTL8211F(D)(I)-VD-CG under the same address and
+the same name. It controls widely the same configs as other PHYs from
+the RTL8211F series (e.g. PHY-mode EEE). Clock out configuration is an
+exception.
+
+Given all this information, restore disabling of the PHY-mode EEE.
+
+Fixes: 2c67301584f2 ("net: phy: realtek: Avoid PHYCR2 access if PHYCR2 not present")
+Signed-off-by: Ivan Galkin <ivan.galkin@axis.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20251202-phy_eee-v1-1-fe0bf6ab3df0@axis.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/realtek/realtek_main.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
+index 2c661346050f1..7c3d277efaf07 100644
+--- a/drivers/net/phy/realtek/realtek_main.c
++++ b/drivers/net/phy/realtek/realtek_main.c
+@@ -664,10 +664,6 @@ static int rtl8211f_config_aldps(struct phy_device *phydev)
+ static int rtl8211f_config_phy_eee(struct phy_device *phydev)
+ {
+-      /* RTL8211FVD has no PHYCR2 register */
+-      if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
+-              return 0;
+-
+       /* Disable PHY-mode EEE so LPI is passed to the MAC */
+       return phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
+                               RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-sched-ets-always-remove-class-from-active-list-b.patch b/queue-6.18/net-sched-ets-always-remove-class-from-active-list-b.patch
new file mode 100644 (file)
index 0000000..b66ac6d
--- /dev/null
@@ -0,0 +1,232 @@
+From 79a8ef846bac934d8f609b925314bf6a15c0f166 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Nov 2025 10:19:19 -0500
+Subject: net/sched: ets: Always remove class from active list before deleting
+ in ets_qdisc_change
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit ce052b9402e461a9aded599f5b47e76bc727f7de ]
+
+zdi-disclosures@trendmicro.com says:
+
+The vulnerability is a race condition between `ets_qdisc_dequeue` and
+`ets_qdisc_change`.  It leads to UAF on `struct Qdisc` object.
+Attacker requires the capability to create new user and network namespace
+in order to trigger the bug.
+See my additional commentary at the end of the analysis.
+
+Analysis:
+
+static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+                          struct netlink_ext_ack *extack)
+{
+...
+
+      // (1) this lock is preventing .change handler (`ets_qdisc_change`)
+      //to race with .dequeue handler (`ets_qdisc_dequeue`)
+      sch_tree_lock(sch);
+
+      for (i = nbands; i < oldbands; i++) {
+              if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
+                      list_del_init(&q->classes[i].alist);
+              qdisc_purge_queue(q->classes[i].qdisc);
+      }
+
+      WRITE_ONCE(q->nbands, nbands);
+      for (i = nstrict; i < q->nstrict; i++) {
+              if (q->classes[i].qdisc->q.qlen) {
+                     // (2) the class is added to the q->active
+                      list_add_tail(&q->classes[i].alist, &q->active);
+                      q->classes[i].deficit = quanta[i];
+              }
+      }
+      WRITE_ONCE(q->nstrict, nstrict);
+      memcpy(q->prio2band, priomap, sizeof(priomap));
+
+      for (i = 0; i < q->nbands; i++)
+              WRITE_ONCE(q->classes[i].quantum, quanta[i]);
+
+      for (i = oldbands; i < q->nbands; i++) {
+              q->classes[i].qdisc = queues[i];
+              if (q->classes[i].qdisc != &noop_qdisc)
+                      qdisc_hash_add(q->classes[i].qdisc, true);
+      }
+
+      // (3) the qdisc is unlocked, now dequeue can be called in parallel
+      // to the rest of .change handler
+      sch_tree_unlock(sch);
+
+      ets_offload_change(sch);
+      for (i = q->nbands; i < oldbands; i++) {
+             // (4) we're reducing the refcount for our class's qdisc and
+             //  freeing it
+              qdisc_put(q->classes[i].qdisc);
+             // (5) If we call .dequeue between (4) and (5), we will have
+             // a strong UAF and we can control RIP
+              q->classes[i].qdisc = NULL;
+              WRITE_ONCE(q->classes[i].quantum, 0);
+              q->classes[i].deficit = 0;
+              gnet_stats_basic_sync_init(&q->classes[i].bstats);
+              memset(&q->classes[i].qstats, 0, sizeof(q->classes[i].qstats));
+      }
+      return 0;
+}
+
+Comment:
+This happens because some of the classes have their qdiscs assigned to
+NULL, but remain in the active list. This commit fixes this issue by always
+removing the class from the active list before deleting and freeing its
+associated qdisc
+
+Reproducer Steps
+(trimmed version of what was sent by zdi-disclosures@trendmicro.com)
+
+```
+DEV="${DEV:-lo}"
+ROOT_HANDLE="${ROOT_HANDLE:-1:}"
+BAND2_HANDLE="${BAND2_HANDLE:-20:}"   # child under 1:2
+PING_BYTES="${PING_BYTES:-48}"
+PING_COUNT="${PING_COUNT:-200000}"
+PING_DST="${PING_DST:-127.0.0.1}"
+
+SLOW_TBF_RATE="${SLOW_TBF_RATE:-8bit}"
+SLOW_TBF_BURST="${SLOW_TBF_BURST:-100b}"
+SLOW_TBF_LAT="${SLOW_TBF_LAT:-1s}"
+
+cleanup() {
+  tc qdisc del dev "$DEV" root 2>/dev/null
+}
+trap cleanup EXIT
+
+ip link set "$DEV" up
+
+tc qdisc del dev "$DEV" root 2>/dev/null || true
+
+tc qdisc add dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
+
+tc qdisc add dev "$DEV" parent 1:2 handle "$BAND2_HANDLE" \
+  tbf rate "$SLOW_TBF_RATE" burst "$SLOW_TBF_BURST" latency "$SLOW_TBF_LAT"
+
+tc filter add dev "$DEV" parent 1: protocol all prio 1 u32 match u32 0 0 flowid 1:2
+tc -s qdisc ls dev $DEV
+
+ping -I "$DEV" -f -c "$PING_COUNT" -s "$PING_BYTES" -W 0.001 "$PING_DST" \
+  >/dev/null 2>&1 &
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 0
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
+tc -s qdisc ls dev $DEV
+tc qdisc del dev "$DEV" parent 1:2 || true
+tc -s qdisc ls dev $DEV
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 1 strict 1
+```
+
+KASAN report
+```
+==================================================================
+BUG: KASAN: slab-use-after-free in ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
+Read of size 8 at addr ffff8880502fc018 by task ping/12308
+>
+CPU: 0 UID: 0 PID: 12308 Comm: ping Not tainted 6.18.0-rc4-dirty #1 PREEMPT(full)
+Hardware name: QEMU Ubuntu 25.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <IRQ>
+ __dump_stack kernel/lib/dump_stack.c:94
+ dump_stack_lvl+0x100/0x190 kernel/lib/dump_stack.c:120
+ print_address_description kernel/mm/kasan/report.c:378
+ print_report+0x156/0x4c9 kernel/mm/kasan/report.c:482
+ kasan_report+0xdf/0x110 kernel/mm/kasan/report.c:595
+ ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
+ dequeue_skb kernel/net/sched/sch_generic.c:294
+ qdisc_restart kernel/net/sched/sch_generic.c:399
+ __qdisc_run+0x1c9/0x1b00 kernel/net/sched/sch_generic.c:417
+ __dev_xmit_skb kernel/net/core/dev.c:4221
+ __dev_queue_xmit+0x2848/0x4410 kernel/net/core/dev.c:4729
+ dev_queue_xmit kernel/./include/linux/netdevice.h:3365
+[...]
+
+Allocated by task 17115:
+ kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
+ kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
+ poison_kmalloc_redzone kernel/mm/kasan/common.c:400
+ __kasan_kmalloc+0xaa/0xb0 kernel/mm/kasan/common.c:417
+ kasan_kmalloc kernel/./include/linux/kasan.h:262
+ __do_kmalloc_node kernel/mm/slub.c:5642
+ __kmalloc_node_noprof+0x34e/0x990 kernel/mm/slub.c:5648
+ kmalloc_node_noprof kernel/./include/linux/slab.h:987
+ qdisc_alloc+0xb8/0xc30 kernel/net/sched/sch_generic.c:950
+ qdisc_create_dflt+0x93/0x490 kernel/net/sched/sch_generic.c:1012
+ ets_class_graft+0x4fd/0x800 kernel/net/sched/sch_ets.c:261
+ qdisc_graft+0x3e4/0x1780 kernel/net/sched/sch_api.c:1196
+[...]
+
+Freed by task 9905:
+ kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
+ kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
+ __kasan_save_free_info+0x3b/0x70 kernel/mm/kasan/generic.c:587
+ kasan_save_free_info kernel/mm/kasan/kasan.h:406
+ poison_slab_object kernel/mm/kasan/common.c:252
+ __kasan_slab_free+0x5f/0x80 kernel/mm/kasan/common.c:284
+ kasan_slab_free kernel/./include/linux/kasan.h:234
+ slab_free_hook kernel/mm/slub.c:2539
+ slab_free kernel/mm/slub.c:6630
+ kfree+0x144/0x700 kernel/mm/slub.c:6837
+ rcu_do_batch kernel/kernel/rcu/tree.c:2605
+ rcu_core+0x7c0/0x1500 kernel/kernel/rcu/tree.c:2861
+ handle_softirqs+0x1ea/0x8a0 kernel/kernel/softirq.c:622
+ __do_softirq kernel/kernel/softirq.c:656
+[...]
+
+Commentary:
+
+1. Maher Azzouzi working with Trend Micro Zero Day Initiative was reported as
+the person who found the issue. I requested to get a proper email to add to the
+reported-by tag but got no response. For this reason i will credit the person
+i exchanged emails with i.e zdi-disclosures@trendmicro.com
+
+2. Neither i nor Victor who did a much more thorough testing was able to
+reproduce a UAF with the PoC or other approaches we tried. We were both able to
+reproduce a null ptr deref. After exchange with zdi-disclosures@trendmicro.com
+they sent a small change to be made to the code to add an extra delay which
+was able to simulate the UAF. i.e, this:
+   qdisc_put(q->classes[i].qdisc);
+   mdelay(90);
+   q->classes[i].qdisc = NULL;
+
+I was informed by Thomas Gleixner(tglx@linutronix.de) that adding delays was
+acceptable approach for demonstrating the bug, quote:
+"Adding such delays is common exploit validation practice"
+The equivalent delay could happen "by virt scheduling the vCPU out, SMIs,
+NMIs, PREEMPT_RT enabled kernel"
+
+3. I asked the OP to test and report back but got no response and after a
+few days gave up and proceeded to submit this fix.
+
+Fixes: de6d25924c2a ("net/sched: sch_ets: don't peek at classes beyond 'nbands'")
+Reported-by: zdi-disclosures@trendmicro.com
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20251128151919.576920-1-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_ets.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index 82635dd2cfa59..ae46643e596d3 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -652,7 +652,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+       sch_tree_lock(sch);
+       for (i = nbands; i < oldbands; i++) {
+-              if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
++              if (cl_is_active(&q->classes[i]))
+                       list_del_init(&q->classes[i].alist);
+               qdisc_purge_queue(q->classes[i].qdisc);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-sched-ets-remove-drr-class-from-the-active-list-.patch b/queue-6.18/net-sched-ets-remove-drr-class-from-the-active-list-.patch
new file mode 100644 (file)
index 0000000..5a5e01f
--- /dev/null
@@ -0,0 +1,88 @@
+From bc0aea7ce3ca53393892c749d81fc995c26b753d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 16:01:24 -0300
+Subject: net/sched: ets: Remove drr class from the active list if it changes
+ to strict
+
+From: Victor Nogueira <victor@mojatatu.com>
+
+[ Upstream commit b1e125ae425aba9b45252e933ca8df52a843ec70 ]
+
+Whenever a user issues an ets qdisc change command, transforming a
+drr class into a strict one, the ets code isn't checking whether that
+class was in the active list and removing it. This means that, if a
+user changes a strict class (which was in the active list) back to a drr
+one, that class will be added twice to the active list [1].
+
+Doing so with the following commands:
+
+tc qdisc add dev lo root handle 1: ets bands 2 strict 1
+tc qdisc add dev lo parent 1:2 handle 20: \
+    tbf rate 8bit burst 100b latency 1s
+tc filter add dev lo parent 1: basic classid 1:2
+ping -c1 -W0.01 -s 56 127.0.0.1
+tc qdisc change dev lo root handle 1: ets bands 2 strict 2
+tc qdisc change dev lo root handle 1: ets bands 2 strict 1
+ping -c1 -W0.01 -s 56 127.0.0.1
+
+Will trigger the following splat with list debug turned on:
+
+[   59.279014][  T365] ------------[ cut here ]------------
+[   59.279452][  T365] list_add double add: new=ffff88801d60e350, prev=ffff88801d60e350, next=ffff88801d60e2c0.
+[   59.280153][  T365] WARNING: CPU: 3 PID: 365 at lib/list_debug.c:35 __list_add_valid_or_report+0x17f/0x220
+[   59.280860][  T365] Modules linked in:
+[   59.281165][  T365] CPU: 3 UID: 0 PID: 365 Comm: tc Not tainted 6.18.0-rc7-00105-g7e9f13163c13-dirty #239 PREEMPT(voluntary)
+[   59.281977][  T365] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+[   59.282391][  T365] RIP: 0010:__list_add_valid_or_report+0x17f/0x220
+[   59.282842][  T365] Code: 89 c6 e8 d4 b7 0d ff 90 0f 0b 90 90 31 c0 e9 31 ff ff ff 90 48 c7 c7 e0 a0 22 9f 48 89 f2 48 89 c1 4c 89 c6 e8 b2 b7 0d ff 90 <0f> 0b 90 90 31 c0 e9 0f ff ff ff 48 89 f7 48 89 44 24 10 4c 89 44
+...
+[   59.288812][  T365] Call Trace:
+[   59.289056][  T365]  <TASK>
+[   59.289224][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.289546][  T365]  ets_qdisc_change+0xd2b/0x1e80
+[   59.289891][  T365]  ? __lock_acquire+0x7e7/0x1be0
+[   59.290223][  T365]  ? __pfx_ets_qdisc_change+0x10/0x10
+[   59.290546][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.290898][  T365]  ? __mutex_trylock_common+0xda/0x240
+[   59.291228][  T365]  ? __pfx___mutex_trylock_common+0x10/0x10
+[   59.291655][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.291993][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.292313][  T365]  ? trace_contention_end+0xc8/0x110
+[   59.292656][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.293022][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.293351][  T365]  tc_modify_qdisc+0x63a/0x1cf0
+
+Fix this by always checking and removing an ets class from the active list
+when changing it to strict.
+
+[1] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/tree/net/sched/sch_ets.c?id=ce052b9402e461a9aded599f5b47e76bc727f7de#n663
+
+Fixes: cd9b50adc6bb9 ("net/sched: ets: fix crash when flipping from 'strict' to 'quantum'")
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/20251208190125.1868423-1-victor@mojatatu.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_ets.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index ae46643e596d3..306e046276d46 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -664,6 +664,10 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+                       q->classes[i].deficit = quanta[i];
+               }
+       }
++      for (i = q->nstrict; i < nstrict; i++) {
++              if (cl_is_active(&q->classes[i]))
++                      list_del_init(&q->classes[i].alist);
++      }
+       WRITE_ONCE(q->nstrict, nstrict);
+       memcpy(q->prio2band, priomap, sizeof(priomap));
+-- 
+2.51.0
+
diff --git a/queue-6.18/net-ti-icssg-prueth-add-ptp_1588_clock_optional-depe.patch b/queue-6.18/net-ti-icssg-prueth-add-ptp_1588_clock_optional-depe.patch
new file mode 100644 (file)
index 0000000..9493455
--- /dev/null
@@ -0,0 +1,55 @@
+From 6ed8fe45a42be35aae6ea10b1e22ed99e21b8348 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Dec 2025 11:01:28 +0100
+Subject: net: ti: icssg-prueth: add PTP_1588_CLOCK_OPTIONAL dependency
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 9e7477a427449a8a3cd00c188e20a880e3d94638 ]
+
+The new icssg-prueth driver needs the same dependency as the other parts
+that use the ptp-1588:
+
+WARNING: unmet direct dependencies detected for TI_ICSS_IEP
+  Depends on [m]: NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_TI [=y] && PTP_1588_CLOCK_OPTIONAL [=m] && TI_PRUSS [=y]
+  Selected by [y]:
+  - TI_PRUETH [=y] && NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_TI [=y] && PRU_REMOTEPROC [=y] && NET_SWITCHDEV [=y]
+
+Add the correct dependency on the two drivers missing it, and remove
+the pointless 'imply' in the process.
+
+Fixes: e654b85a693e ("net: ti: icssg-prueth: Add ICSSG Ethernet driver for AM65x SR1.0 platforms")
+Fixes: 511f6c1ae093 ("net: ti: icssm-prueth: Adds ICSSM Ethernet driver")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Link: https://patch.msgid.link/20251204100138.1034175-1-arnd@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
+index a54d71155263c..fe5b2926d8ab0 100644
+--- a/drivers/net/ethernet/ti/Kconfig
++++ b/drivers/net/ethernet/ti/Kconfig
+@@ -209,6 +209,7 @@ config TI_ICSSG_PRUETH_SR1
+       depends on PRU_REMOTEPROC
+       depends on NET_SWITCHDEV
+       depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
++      depends on PTP_1588_CLOCK_OPTIONAL
+       help
+         Support dual Gigabit Ethernet ports over the ICSSG PRU Subsystem.
+         This subsystem is available on the AM65 SR1.0 platform.
+@@ -234,7 +235,7 @@ config TI_PRUETH
+       depends on PRU_REMOTEPROC
+       depends on NET_SWITCHDEV
+       select TI_ICSS_IEP
+-      imply PTP_1588_CLOCK
++      depends on PTP_1588_CLOCK_OPTIONAL
+       help
+         Some TI SoCs has Programmable Realtime Unit (PRU) cores which can
+         support Single or Dual Ethernet ports with the help of firmware code
+-- 
+2.51.0
+
diff --git a/queue-6.18/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch b/queue-6.18/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch
new file mode 100644 (file)
index 0000000..d24ddd0
--- /dev/null
@@ -0,0 +1,90 @@
+From 17f3c6a36d5a32eb18719cab7a05e6a047dace18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 12:58:01 +0100
+Subject: netfilter: nf_conncount: fix leaked ct in error paths
+
+From: Fernando Fernandez Mancera <fmancera@suse.de>
+
+[ Upstream commit 2e2a720766886190a6d35c116794693aabd332b6 ]
+
+There are some situations where ct might be leaked as error paths are
+skipping the refcounted check and return immediately. In order to solve
+it make sure that the check is always called.
+
+Fixes: be102eb6a0e7 ("netfilter: nf_conncount: rework API to use sk_buff directly")
+Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conncount.c | 25 ++++++++++++++-----------
+ 1 file changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
+index b84cfb5616df4..3c1b155f7a0ea 100644
+--- a/net/netfilter/nf_conncount.c
++++ b/net/netfilter/nf_conncount.c
+@@ -172,14 +172,14 @@ static int __nf_conncount_add(struct net *net,
+       struct nf_conn *found_ct;
+       unsigned int collect = 0;
+       bool refcounted = false;
++      int err = 0;
+       if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted))
+               return -ENOENT;
+       if (ct && nf_ct_is_confirmed(ct)) {
+-              if (refcounted)
+-                      nf_ct_put(ct);
+-              return -EEXIST;
++              err = -EEXIST;
++              goto out_put;
+       }
+       if ((u32)jiffies == list->last_gc)
+@@ -231,12 +231,16 @@ static int __nf_conncount_add(struct net *net,
+       }
+ add_new_node:
+-      if (WARN_ON_ONCE(list->count > INT_MAX))
+-              return -EOVERFLOW;
++      if (WARN_ON_ONCE(list->count > INT_MAX)) {
++              err = -EOVERFLOW;
++              goto out_put;
++      }
+       conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC);
+-      if (conn == NULL)
+-              return -ENOMEM;
++      if (conn == NULL) {
++              err = -ENOMEM;
++              goto out_put;
++      }
+       conn->tuple = tuple;
+       conn->zone = *zone;
+@@ -249,7 +253,7 @@ static int __nf_conncount_add(struct net *net,
+ out_put:
+       if (refcounted)
+               nf_ct_put(ct);
+-      return 0;
++      return err;
+ }
+ int nf_conncount_add_skb(struct net *net,
+@@ -446,11 +450,10 @@ insert_tree(struct net *net,
+               rb_link_node_rcu(&rbconn->node, parent, rbnode);
+               rb_insert_color(&rbconn->node, root);
+-
+-              if (refcounted)
+-                      nf_ct_put(ct);
+       }
+ out_unlock:
++      if (refcounted)
++              nf_ct_put(ct);
+       spin_unlock_bh(&nf_conncount_locks[hash]);
+       return count;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.18/netfilter-nf_nat-remove-bogus-direction-check.patch b/queue-6.18/netfilter-nf_nat-remove-bogus-direction-check.patch
new file mode 100644 (file)
index 0000000..bb259e6
--- /dev/null
@@ -0,0 +1,129 @@
+From fd6e7e2a2d434f8da34ba840707b2d5345881fcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 16:00:34 +0100
+Subject: netfilter: nf_nat: remove bogus direction check
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 5ec8ca26fe93103577c904644b0957f069d0051a ]
+
+Jakub reports spurious failures of the 'conntrack_reverse_clash.sh'
+selftest.  A bogus test makes nat core resort to port rewrite even
+though there is no need for this.
+
+When the test is made, nf_nat_used_tuple() would already have caused us
+to return if no other CPU had added a colliding entry.
+Moreover, nf_nat_used_tuple() would have ignored the colliding entry if
+their origin tuples had been the same.
+
+All that is left to check is if the colliding entry in the hash table
+is subject to NAT, and, if its not, if our entry matches in the reverse
+direction, e.g. hash table has
+
+addr1:1234 -> addr2:80, and we want to commit
+addr2:80   -> addr1:1234.
+
+Because we already checked that neither the new nor the committed entry is
+subject to NAT we only have to check origin vs. reply tuple:
+for non-nat entries, the reply tuple is always the inverted original.
+
+Just in case there are more problems extend the error reporting
+in the selftest while at it and dump conntrack table/stats on error.
+
+Reported-by: Jakub Kicinski <kuba@kernel.org>
+Closes: https://lore.kernel.org/netdev/20251206175135.4a56591b@kernel.org/
+Fixes: d8f84a9bc7c4 ("netfilter: nf_nat: don't try nat source port reallocation for reverse dir clash")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_nat_core.c                        | 14 +-------------
+ .../net/netfilter/conntrack_reverse_clash.c        | 13 +++++++++----
+ .../net/netfilter/conntrack_reverse_clash.sh       |  2 ++
+ 3 files changed, 12 insertions(+), 17 deletions(-)
+
+diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
+index 78a61dac4ade8..e6b24586d2fed 100644
+--- a/net/netfilter/nf_nat_core.c
++++ b/net/netfilter/nf_nat_core.c
+@@ -294,25 +294,13 @@ nf_nat_used_tuple_new(const struct nf_conntrack_tuple *tuple,
+       ct = nf_ct_tuplehash_to_ctrack(thash);
+-      /* NB: IP_CT_DIR_ORIGINAL should be impossible because
+-       * nf_nat_used_tuple() handles origin collisions.
+-       *
+-       * Handle remote chance other CPU confirmed its ct right after.
+-       */
+-      if (thash->tuple.dst.dir != IP_CT_DIR_REPLY)
+-              goto out;
+-
+       /* clashing connection subject to NAT? Retry with new tuple. */
+       if (READ_ONCE(ct->status) & uses_nat)
+               goto out;
+       if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+-                            &ignored_ct->tuplehash[IP_CT_DIR_REPLY].tuple) &&
+-          nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
+-                            &ignored_ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple)) {
++                            &ignored_ct->tuplehash[IP_CT_DIR_REPLY].tuple))
+               taken = false;
+-              goto out;
+-      }
+ out:
+       nf_ct_put(ct);
+       return taken;
+diff --git a/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.c b/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.c
+index 507930cee8cb6..462d628cc3bdb 100644
+--- a/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.c
++++ b/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.c
+@@ -33,9 +33,14 @@ static void die(const char *e)
+       exit(111);
+ }
+-static void die_port(uint16_t got, uint16_t want)
++static void die_port(const struct sockaddr_in *sin, uint16_t want)
+ {
+-      fprintf(stderr, "Port number changed, wanted %d got %d\n", want, ntohs(got));
++      uint16_t got = ntohs(sin->sin_port);
++      char str[INET_ADDRSTRLEN];
++
++      inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str));
++
++      fprintf(stderr, "Port number changed, wanted %d got %d from %s\n", want, got, str);
+       exit(1);
+ }
+@@ -100,7 +105,7 @@ int main(int argc, char *argv[])
+                               die("child recvfrom");
+                       if (peer.sin_port != htons(PORT))
+-                              die_port(peer.sin_port, PORT);
++                              die_port(&peer, PORT);
+               } else {
+                       if (sendto(s2, buf, LEN, 0, (struct sockaddr *)&sa1, sizeof(sa1)) != LEN)
+                               continue;
+@@ -109,7 +114,7 @@ int main(int argc, char *argv[])
+                               die("parent recvfrom");
+                       if (peer.sin_port != htons((PORT + 1)))
+-                              die_port(peer.sin_port, PORT + 1);
++                              die_port(&peer, PORT + 1);
+               }
+       }
+diff --git a/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.sh b/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.sh
+index a24c896347a88..dc7e9d6da0624 100755
+--- a/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.sh
++++ b/tools/testing/selftests/net/netfilter/conntrack_reverse_clash.sh
+@@ -45,6 +45,8 @@ if ip netns exec "$ns0" ./conntrack_reverse_clash; then
+       echo "PASS: No SNAT performed for null bindings"
+ else
+       echo "ERROR: SNAT performed without any matching snat rule"
++      ip netns exec "$ns0" conntrack -L
++      ip netns exec "$ns0" conntrack -S
+       exit 1
+ fi
+-- 
+2.51.0
+
diff --git a/queue-6.18/netfilter-nf_tables-remove-redundant-chain-validatio.patch b/queue-6.18/netfilter-nf_tables-remove-redundant-chain-validatio.patch
new file mode 100644 (file)
index 0000000..c7e3bfb
--- /dev/null
@@ -0,0 +1,59 @@
+From c03f4545f4164b898ad793aaa728d9b0f11ca4eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Nov 2025 13:42:05 +0100
+Subject: netfilter: nf_tables: remove redundant chain validation on register
+ store
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit a67fd55f6a09f4119b7232c19e0f348fe31ab0db ]
+
+This validation predates the introduction of the state machine that
+determines when to enter slow path validation for error reporting.
+
+Currently, table validation is perform when:
+
+- new rule contains expressions that need validation.
+- new set element with jump/goto verdict.
+
+Validation on register store skips most checks with no basechains, still
+this walks the graph searching for loops and ensuring expressions are
+called from the right hook. Remove this.
+
+Fixes: a654de8fdc18 ("netfilter: nf_tables: fix chain dependency validation")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index eed434e0a9702..1a204f6371ad1 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -11678,21 +11678,10 @@ static int nft_validate_register_store(const struct nft_ctx *ctx,
+                                      enum nft_data_types type,
+                                      unsigned int len)
+ {
+-      int err;
+-
+       switch (reg) {
+       case NFT_REG_VERDICT:
+               if (type != NFT_DATA_VERDICT)
+                       return -EINVAL;
+-
+-              if (data != NULL &&
+-                  (data->verdict.code == NFT_GOTO ||
+-                   data->verdict.code == NFT_JUMP)) {
+-                      err = nft_chain_validate(ctx, data->verdict.chain);
+-                      if (err < 0)
+-                              return err;
+-              }
+-
+               break;
+       default:
+               if (type != NFT_DATA_VALUE)
+-- 
+2.51.0
+
diff --git a/queue-6.18/netrom-fix-memory-leak-in-nr_sendmsg.patch b/queue-6.18/netrom-fix-memory-leak-in-nr_sendmsg.patch
new file mode 100644 (file)
index 0000000..d4a06cb
--- /dev/null
@@ -0,0 +1,74 @@
+From 7dbd3be06f02e7890c7778e61ea2e7988349049f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Nov 2025 12:13:15 +0800
+Subject: netrom: Fix memory leak in nr_sendmsg()
+
+From: Wang Liang <wangliang74@huawei.com>
+
+[ Upstream commit 613d12dd794e078be8ff3cf6b62a6b9acf7f4619 ]
+
+syzbot reported a memory leak [1].
+
+When function sock_alloc_send_skb() return NULL in nr_output(), the
+original skb is not freed, which was allocated in nr_sendmsg(). Fix this
+by freeing it before return.
+
+[1]
+BUG: memory leak
+unreferenced object 0xffff888129f35500 (size 240):
+  comm "syz.0.17", pid 6119, jiffies 4294944652
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+    00 00 00 00 00 00 00 00 00 10 52 28 81 88 ff ff  ..........R(....
+  backtrace (crc 1456a3e4):
+    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
+    slab_post_alloc_hook mm/slub.c:4983 [inline]
+    slab_alloc_node mm/slub.c:5288 [inline]
+    kmem_cache_alloc_node_noprof+0x36f/0x5e0 mm/slub.c:5340
+    __alloc_skb+0x203/0x240 net/core/skbuff.c:660
+    alloc_skb include/linux/skbuff.h:1383 [inline]
+    alloc_skb_with_frags+0x69/0x3f0 net/core/skbuff.c:6671
+    sock_alloc_send_pskb+0x379/0x3e0 net/core/sock.c:2965
+    sock_alloc_send_skb include/net/sock.h:1859 [inline]
+    nr_sendmsg+0x287/0x450 net/netrom/af_netrom.c:1105
+    sock_sendmsg_nosec net/socket.c:727 [inline]
+    __sock_sendmsg net/socket.c:742 [inline]
+    sock_write_iter+0x293/0x2a0 net/socket.c:1195
+    new_sync_write fs/read_write.c:593 [inline]
+    vfs_write+0x45d/0x710 fs/read_write.c:686
+    ksys_write+0x143/0x170 fs/read_write.c:738
+    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+    do_syscall_64+0xa4/0xfa0 arch/x86/entry/syscall_64.c:94
+    entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Reported-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=d7abc36bbbb6d7d40b58
+Tested-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Wang Liang <wangliang74@huawei.com>
+Link: https://patch.msgid.link/20251129041315.1550766-1-wangliang74@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netrom/nr_out.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/netrom/nr_out.c b/net/netrom/nr_out.c
+index 5e531394a724b..2b3cbceb0b52d 100644
+--- a/net/netrom/nr_out.c
++++ b/net/netrom/nr_out.c
+@@ -43,8 +43,10 @@ void nr_output(struct sock *sk, struct sk_buff *skb)
+               frontlen = skb_headroom(skb);
+               while (skb->len > 0) {
+-                      if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL)
++                      if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL) {
++                              kfree_skb(skb);
+                               return;
++                      }
+                       skb_reserve(skbn, frontlen);
+-- 
+2.51.0
+
diff --git a/queue-6.18/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch b/queue-6.18/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch
new file mode 100644 (file)
index 0000000..c3171ee
--- /dev/null
@@ -0,0 +1,37 @@
+From 0ed33f78f905e0fee357441c7f5dfe71c9956206 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 09:56:39 +0300
+Subject: nfc: pn533: Fix error code in pn533_acr122_poweron_rdr()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 885bebac9909994050bbbeed0829c727e42bd1b7 ]
+
+Set the error code if "transferred != sizeof(cmd)" instead of
+returning success.
+
+Fixes: dbafc28955fa ("NFC: pn533: don't send USB data off of the stack")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/aTfIJ9tZPmeUF4W1@stanley.mountain
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/pn533/usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c
+index ffd7367ce1194..018a80674f06e 100644
+--- a/drivers/nfc/pn533/usb.c
++++ b/drivers/nfc/pn533/usb.c
+@@ -406,7 +406,7 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy)
+       if (rc || (transferred != sizeof(cmd))) {
+               nfc_err(&phy->udev->dev,
+                       "Reader power on cmd error %d\n", rc);
+-              return rc;
++              return rc ?: -EINVAL;
+       }
+       rc =  usb_submit_urb(phy->in_urb, GFP_KERNEL);
+-- 
+2.51.0
+
diff --git a/queue-6.18/selftest-af_unix-support-compilers-without-flex-arra.patch b/queue-6.18/selftest-af_unix-support-compilers-without-flex-arra.patch
new file mode 100644 (file)
index 0000000..ebb8ffd
--- /dev/null
@@ -0,0 +1,47 @@
+From da0e3f60cd2f70e2a06414ffd03bc09adb0a612a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 09:10:00 -0800
+Subject: selftest: af_unix: Support compilers without
+ flex-array-member-not-at-end support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 06f7cae92fe346fa49a8a9b161124b26cc5c3ed1 ]
+
+Fix:
+
+gcc: error: unrecognized command-line option â€˜-Wflex-array-member-not-at-end’
+
+by making the compiler option dependent on its support.
+
+Fixes: 1838731f1072c ("selftest: af_unix: Add -Wall and -Wflex-array-member-not-at-end to CFLAGS.")
+Cc: Kuniyuki Iwashima <kuniyu@google.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://patch.msgid.link/20251205171010.515236-7-linux@roeck-us.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/af_unix/Makefile | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/af_unix/Makefile b/tools/testing/selftests/net/af_unix/Makefile
+index 528d14c598bb5..2889403e35468 100644
+--- a/tools/testing/selftests/net/af_unix/Makefile
++++ b/tools/testing/selftests/net/af_unix/Makefile
+@@ -1,4 +1,9 @@
+-CFLAGS += $(KHDR_INCLUDES) -Wall -Wflex-array-member-not-at-end
++top_srcdir := ../../../../..
++include $(top_srcdir)/scripts/Makefile.compiler
++
++cc-option = $(call __cc-option, $(CC),,$(1),$(2))
++
++CFLAGS += $(KHDR_INCLUDES) -Wall $(call cc-option,-Wflex-array-member-not-at-end)
+ TEST_GEN_PROGS := \
+       diag_uid \
+-- 
+2.51.0
+
diff --git a/queue-6.18/selftests-net-fix-build-warnings.patch b/queue-6.18/selftests-net-fix-build-warnings.patch
new file mode 100644 (file)
index 0000000..c420801
--- /dev/null
@@ -0,0 +1,60 @@
+From d897ed1a38c1c3aab5590fd1bafa8506c105a33d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 09:10:04 -0800
+Subject: selftests: net: Fix build warnings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 59546e874403c1dd0cbc42df06fdf8c113f72022 ]
+
+Fix
+
+ksft.h: In function â€˜ksft_ready’:
+ksft.h:27:9: warning: ignoring return value of â€˜write’ declared with attribute â€˜warn_unused_result’
+
+ksft.h: In function â€˜ksft_wait’:
+ksft.h:51:9: warning: ignoring return value of â€˜read’ declared with attribute â€˜warn_unused_result’
+
+by checking the return value of the affected functions and displaying
+an error message if an error is seen.
+
+Fixes: 2b6d490b82668 ("selftests: drv-net: Factor out ksft C helpers")
+Cc: Joe Damato <jdamato@fastly.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://patch.msgid.link/20251205171010.515236-11-linux@roeck-us.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/lib/ksft.h | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/net/lib/ksft.h b/tools/testing/selftests/net/lib/ksft.h
+index 17dc34a612c64..03912902a6d30 100644
+--- a/tools/testing/selftests/net/lib/ksft.h
++++ b/tools/testing/selftests/net/lib/ksft.h
+@@ -24,7 +24,8 @@ static inline void ksft_ready(void)
+               fd = STDOUT_FILENO;
+       }
+-      write(fd, msg, sizeof(msg));
++      if (write(fd, msg, sizeof(msg)) < 0)
++              perror("write()");
+       if (fd != STDOUT_FILENO)
+               close(fd);
+ }
+@@ -48,7 +49,8 @@ static inline void ksft_wait(void)
+               fd = STDIN_FILENO;
+       }
+-      read(fd, &byte, sizeof(byte));
++      if (read(fd, &byte, sizeof(byte)) < 0)
++              perror("read()");
+       if (fd != STDIN_FILENO)
+               close(fd);
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.18/selftests-net-tfo-fix-build-warning.patch b/queue-6.18/selftests-net-tfo-fix-build-warning.patch
new file mode 100644 (file)
index 0000000..dd23775
--- /dev/null
@@ -0,0 +1,47 @@
+From 66d8659b9d7c89b53201c23e854900a9d7ebf360 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 09:10:07 -0800
+Subject: selftests: net: tfo: Fix build warning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 91dc09a609d9443e6b34bdb355a18d579a95e132 ]
+
+Fix
+
+tfo.c: In function â€˜run_server’:
+tfo.c:84:9: warning: ignoring return value of â€˜read’ declared with attribute â€˜warn_unused_result’
+
+by evaluating the return value from read() and displaying an error message
+if it reports an error.
+
+Fixes: c65b5bb2329e3 ("selftests: net: add passive TFO test binary")
+Cc: David Wei <dw@davidwei.uk>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://patch.msgid.link/20251205171010.515236-14-linux@roeck-us.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/tfo.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/tfo.c b/tools/testing/selftests/net/tfo.c
+index eb3cac5e583c9..8d82140f0f767 100644
+--- a/tools/testing/selftests/net/tfo.c
++++ b/tools/testing/selftests/net/tfo.c
+@@ -81,7 +81,8 @@ static void run_server(void)
+       if (getsockopt(connfd, SOL_SOCKET, SO_INCOMING_NAPI_ID, &opt, &len) < 0)
+               error(1, errno, "getsockopt(SO_INCOMING_NAPI_ID)");
+-      read(connfd, buf, 64);
++      if (read(connfd, buf, 64) < 0)
++              perror("read()");
+       fprintf(outfile, "%d\n", opt);
+       fclose(outfile);
+-- 
+2.51.0
+
diff --git a/queue-6.18/selftests-netfilter-packetdrill-avoid-failure-on-hz-.patch b/queue-6.18/selftests-netfilter-packetdrill-avoid-failure-on-hz-.patch
new file mode 100644 (file)
index 0000000..3dd6fbe
--- /dev/null
@@ -0,0 +1,41 @@
+From 80162dffdc5131f775d19955090ffc5007f6690b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 13:16:49 +0100
+Subject: selftests: netfilter: packetdrill: avoid failure on HZ=100 kernel
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit fec7b0795548b43e2c3c46e3143c34ef6070341c ]
+
+packetdrill --ip_version=ipv4 --mtu=1500 --tolerance_usecs=1000000 --non_fatal packet conntrack_syn_challenge_ack.pkt
+conntrack v1.4.8 (conntrack-tools): 1 flow entries have been shown.
+conntrack_syn_challenge_ack.pkt:32: error executing `conntrack -f $NFCT_IP_VERSION \
+-L -p tcp --dport 8080 | grep UNREPLIED | grep -q SYN_SENT` command: non-zero status 1
+
+Affected kernel had CONFIG_HZ=100; reset packet was still sitting in
+backlog.
+
+Reported-by: Yi Chen <yiche@redhat.com>
+Fixes: a8a388c2aae4 ("selftests: netfilter: add packetdrill based conntrack tests")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/netfilter/packetdrill/conntrack_syn_challenge_ack.pkt   | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/netfilter/packetdrill/conntrack_syn_challenge_ack.pkt b/tools/testing/selftests/net/netfilter/packetdrill/conntrack_syn_challenge_ack.pkt
+index 3442cd29bc932..cdb3910af95b4 100644
+--- a/tools/testing/selftests/net/netfilter/packetdrill/conntrack_syn_challenge_ack.pkt
++++ b/tools/testing/selftests/net/netfilter/packetdrill/conntrack_syn_challenge_ack.pkt
+@@ -26,7 +26,7 @@
+ +0.01 > R 643160523:643160523(0) win 0
+-+0.01 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null | grep UNREPLIED | grep -q SYN_SENT`
+++0.1 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null | grep UNREPLIED | grep -q SYN_SENT`
+ // Must go through.
+ +0.01 > S 0:0(0) win 65535 <mss 1460,sackOK,TS val 1 ecr 0,nop,wscale 8>
+-- 
+2.51.0
+
diff --git a/queue-6.18/selftests-netfilter-prefer-xfail-in-case-race-wasn-t.patch b/queue-6.18/selftests-netfilter-prefer-xfail-in-case-race-wasn-t.patch
new file mode 100644 (file)
index 0000000..c71c20d
--- /dev/null
@@ -0,0 +1,65 @@
+From 20c56dc0efa322716621492de3baac6cfe5c186a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 00:03:36 +0100
+Subject: selftests: netfilter: prefer xfail in case race wasn't triggered
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit b8a81b0ce539e021ac72825238aea1eb657000f0 ]
+
+Jakub says: "We try to reserve SKIP for tests skipped because tool is
+missing in env, something isn't built into the kernel etc."
+
+use xfail, we can't force the race condition to appear at will
+so its expected that the test 'fails' occasionally.
+
+Fixes: 78a588363587 ("selftests: netfilter: add conntrack clash resolution test case")
+Reported-by: Jakub Kicinski <kuba@kernel.org>
+Closes: https://lore.kernel.org/netdev/20251206175647.5c32f419@kernel.org/
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/netfilter/conntrack_clash.sh | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/selftests/net/netfilter/conntrack_clash.sh b/tools/testing/selftests/net/netfilter/conntrack_clash.sh
+index 7fc6c5dbd5516..84b8eb12143ae 100755
+--- a/tools/testing/selftests/net/netfilter/conntrack_clash.sh
++++ b/tools/testing/selftests/net/netfilter/conntrack_clash.sh
+@@ -116,7 +116,7 @@ run_one_clash_test()
+       # not a failure: clash resolution logic did not trigger.
+       # With right timing, xmit completed sequentially and
+       # no parallel insertion occurs.
+-      return $ksft_skip
++      return $ksft_xfail
+ }
+ run_clash_test()
+@@ -133,12 +133,12 @@ run_clash_test()
+               if [ $rv -eq 0 ];then
+                       echo "PASS: clash resolution test for $daddr:$dport on attempt $i"
+                       return 0
+-              elif [ $rv -eq $ksft_skip ]; then
++              elif [ $rv -eq $ksft_xfail ]; then
+                       softerr=1
+               fi
+       done
+-      [ $softerr -eq 1 ] && echo "SKIP: clash resolution for $daddr:$dport did not trigger"
++      [ $softerr -eq 1 ] && echo "XFAIL: clash resolution for $daddr:$dport did not trigger"
+ }
+ ip link add veth0 netns "$nsclient1" type veth peer name veth0 netns "$nsrouter"
+@@ -167,8 +167,7 @@ load_simple_ruleset "$nsclient2"
+ run_clash_test "$nsclient2" "$nsclient2" 127.0.0.1 9001
+ if [ $clash_resolution_active -eq 0 ];then
+-      [ "$ret" -eq 0 ] && ret=$ksft_skip
+-      echo "SKIP: Clash resolution did not trigger"
++      [ "$ret" -eq 0 ] && ret=$ksft_xfail
+ fi
+ exit $ret
+-- 
+2.51.0
+
index 3b072faff5cafaf50da28d2846f71aba8c07b1cf..e9f37a58796f4ea52801aaf7d67a48e65a2a6630 100644 (file)
@@ -50,3 +50,55 @@ bluetooth-btusb-add-new-custom-firmwares.patch
 bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch
 bluetooth-btusb-add-new-vid-pid-0x0489-0xe12f-for-rt.patch
 gfs2-fix-use-of-bio_chain.patch
 bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch
 bluetooth-btusb-add-new-vid-pid-0x0489-0xe12f-for-rt.patch
 gfs2-fix-use-of-bio_chain.patch
+net-fec-err007885-workaround-for-xdp-tx-path.patch
+netrom-fix-memory-leak-in-nr_sendmsg.patch
+net-sched-ets-always-remove-class-from-active-list-b.patch
+net-mlx5-make-enable_mpesw-idempotent.patch
+net-mlx5e-avoid-unregistering-psp-twice.patch
+net-phy-realtek-eliminate-priv-phycr2-variable.patch
+net-phy-realtek-eliminate-has_phycr2-variable.patch
+net-phy-realtek-allow-clkout-to-be-disabled-on-rtl82.patch
+net-phy-realtek-eliminate-priv-phycr1-variable.patch
+net-phy-realtek-create-rtl8211f_config_phy_eee-helpe.patch
+net-phy-rtl8211fvd-restore-disabling-of-phy-mode-eee.patch
+ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch
+net-mlx5-fix-double-unregister-of-hca_ports-componen.patch
+mlxsw-spectrum_router-fix-possible-neighbour-referen.patch
+mlxsw-spectrum_router-fix-neighbour-use-after-free.patch
+mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch
+bnxt_en-fix-xdp_tx-path.patch
+net-openvswitch-fix-middle-attribute-validation-in-p.patch
+net-ti-icssg-prueth-add-ptp_1588_clock_optional-depe.patch
+broadcom-b44-prevent-uninitialized-value-usage.patch
+selftest-af_unix-support-compilers-without-flex-arra.patch
+selftests-net-fix-build-warnings.patch
+selftests-net-tfo-fix-build-warning.patch
+inet-frags-avoid-theoretical-race-in-ip_frag_reinit.patch
+inet-frags-add-inet_frag_queue_flush.patch
+inet-frags-flush-pending-skbs-in-fqdir_pre_exit.patch
+netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch
+ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch
+selftests-netfilter-prefer-xfail-in-case-race-wasn-t.patch
+caif-fix-integer-underflow-in-cffrml_receive.patch
+net-sched-ets-remove-drr-class-from-the-active-list-.patch
+nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch
+netfilter-nf_nat-remove-bogus-direction-check.patch
+netfilter-nf_tables-remove-redundant-chain-validatio.patch
+selftests-netfilter-packetdrill-avoid-failure-on-hz-.patch
+iommufd-selftest-make-it-clearer-to-gcc-that-the-acc.patch
+iommufd-selftest-check-for-overflow-in-iommu_test_op.patch
+can-j1939-make-j1939_sk_bind-fail-if-device-is-no-lo.patch
+ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch
+net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch
+net-mlx5-drain-firmware-reset-in-shutdown-callback.patch
+net-mlx5-fw_tracer-validate-format-string-parameters.patch
+net-mlx5-fw_tracer-handle-escaped-percent-properly.patch
+net-mlx5-serialize-firmware-reset-with-devlink.patch
+net-mlx5e-use-ip6_dst_lookup-instead-of-ipv6_dst_loo.patch
+net-mlx5e-trigger-neighbor-resolution-for-unresolved.patch
+net-mlx5e-don-t-include-psp-in-the-hard-mtu-calculat.patch
+net-handshake-duplicate-handshake-cancellations-leak.patch
+net-enetc-do-not-transmit-redirected-xdp-frames-when.patch
+net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch
+net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch
+net-hns3-add-vlan-id-validation-before-using.patch
diff --git a/queue-6.6/broadcom-b44-prevent-uninitialized-value-usage.patch b/queue-6.6/broadcom-b44-prevent-uninitialized-value-usage.patch
new file mode 100644 (file)
index 0000000..4122bdf
--- /dev/null
@@ -0,0 +1,45 @@
+From dbdb7f9402561de49b81f53cced31105efbcce9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 18:58:16 +0300
+Subject: broadcom: b44: prevent uninitialized value usage
+
+From: Alexey Simakov <bigalex934@gmail.com>
+
+[ Upstream commit 50b3db3e11864cb4e18ff099cfb38e11e7f87a68 ]
+
+On execution path with raised B44_FLAG_EXTERNAL_PHY, b44_readphy()
+leaves bmcr value uninitialized and it is used later in the code.
+
+Add check of this flag at the beginning of the b44_nway_reset() and
+exit early of the function with restarting autonegotiation if an
+external PHY is used.
+
+Fixes: 753f492093da ("[B44]: port to native ssb support")
+Reviewed-by: Jonas Gorski <jonas.gorski@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Alexey Simakov <bigalex934@gmail.com>
+Reviewed-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20251205155815.4348-1-bigalex934@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/b44.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
+index 1be6d14030bcf..ba40549536e46 100644
+--- a/drivers/net/ethernet/broadcom/b44.c
++++ b/drivers/net/ethernet/broadcom/b44.c
+@@ -1789,6 +1789,9 @@ static int b44_nway_reset(struct net_device *dev)
+       u32 bmcr;
+       int r;
++      if (bp->flags & B44_FLAG_EXTERNAL_PHY)
++              return phy_ethtool_nway_reset(dev);
++
+       spin_lock_irq(&bp->lock);
+       b44_readphy(bp, MII_BMCR, &bmcr);
+       b44_readphy(bp, MII_BMCR, &bmcr);
+-- 
+2.51.0
+
diff --git a/queue-6.6/caif-fix-integer-underflow-in-cffrml_receive.patch b/queue-6.6/caif-fix-integer-underflow-in-cffrml_receive.patch
new file mode 100644 (file)
index 0000000..7f0f51e
--- /dev/null
@@ -0,0 +1,58 @@
+From 13db93c3f2a0758fbf8acf6ce3217c7446e11f1f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Dec 2025 21:30:47 +0800
+Subject: caif: fix integer underflow in cffrml_receive()
+
+From: Junrui Luo <moonafterrain@outlook.com>
+
+[ Upstream commit 8a11ff0948b5ad09b71896b7ccc850625f9878d1 ]
+
+The cffrml_receive() function extracts a length field from the packet
+header and, when FCS is disabled, subtracts 2 from this length without
+validating that len >= 2.
+
+If an attacker sends a malicious packet with a length field of 0 or 1
+to an interface with FCS disabled, the subtraction causes an integer
+underflow.
+
+This can lead to memory exhaustion and kernel instability, potential
+information disclosure if padding contains uninitialized kernel memory.
+
+Fix this by validating that len >= 2 before performing the subtraction.
+
+Reported-by: Yuhao Jiang <danisjiang@gmail.com>
+Reported-by: Junrui Luo <moonafterrain@outlook.com>
+Fixes: b482cd2053e3 ("net-caif: add CAIF core protocol stack")
+Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/SYBPR01MB7881511122BAFEA8212A1608AFA6A@SYBPR01MB7881.ausprd01.prod.outlook.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/caif/cffrml.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c
+index 6651a8dc62e04..d4d63586053ad 100644
+--- a/net/caif/cffrml.c
++++ b/net/caif/cffrml.c
+@@ -92,8 +92,15 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
+       len = le16_to_cpu(tmp);
+       /* Subtract for FCS on length if FCS is not used. */
+-      if (!this->dofcs)
++      if (!this->dofcs) {
++              if (len < 2) {
++                      ++cffrml_rcv_error;
++                      pr_err("Invalid frame length (%d)\n", len);
++                      cfpkt_destroy(pkt);
++                      return -EPROTO;
++              }
+               len -= 2;
++      }
+       if (cfpkt_setlen(pkt, len) < 0) {
+               ++cffrml_rcv_error;
+-- 
+2.51.0
+
diff --git a/queue-6.6/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch b/queue-6.6/ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch
new file mode 100644 (file)
index 0000000..2238b30
--- /dev/null
@@ -0,0 +1,159 @@
+From 79b4283e36464d7f138bacb05f4eff4716017866 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 14:19:01 +0200
+Subject: ethtool: Avoid overflowing userspace buffer on stats query
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 7b07be1ff1cb6c49869910518650e8d0abc7d25f ]
+
+The ethtool -S command operates across three ioctl calls:
+ETHTOOL_GSSET_INFO for the size, ETHTOOL_GSTRINGS for the names, and
+ETHTOOL_GSTATS for the values.
+
+If the number of stats changes between these calls (e.g., due to device
+reconfiguration), userspace's buffer allocation will be incorrect,
+potentially leading to buffer overflow.
+
+Drivers are generally expected to maintain stable stat counts, but some
+drivers (e.g., mlx5, bnx2x, bna, ksz884x) use dynamic counters, making
+this scenario possible.
+
+Some drivers try to handle this internally:
+- bnad_get_ethtool_stats() returns early in case stats.n_stats is not
+  equal to the driver's stats count.
+- micrel/ksz884x also makes sure not to write anything beyond
+  stats.n_stats and overflow the buffer.
+
+However, both use stats.n_stats which is already assigned with the value
+returned from get_sset_count(), hence won't solve the issue described
+here.
+
+Change ethtool_get_strings(), ethtool_get_stats(),
+ethtool_get_phy_stats() to not return anything in case of a mismatch
+between userspace's size and get_sset_size(), to prevent buffer
+overflow.
+The returned n_stats value will be equal to zero, to reflect that
+nothing has been returned.
+
+This could result in one of two cases when using upstream ethtool,
+depending on when the size change is detected:
+1. When detected in ethtool_get_strings():
+    # ethtool -S eth2
+    no stats available
+
+2. When detected in get stats, all stats will be reported as zero.
+
+Both cases are presumably transient, and a subsequent ethtool call
+should succeed.
+
+Other than the overflow avoidance, these two cases are very evident (no
+output/cleared stats), which is arguably better than presenting
+incorrect/shifted stats.
+I also considered returning an error instead of a "silent" response, but
+that seems more destructive towards userspace apps.
+
+Notes:
+- This patch does not claim to fix the inherent race, it only makes sure
+  that we do not overflow the userspace buffer, and makes for a more
+  predictable behavior.
+
+- RTNL lock is held during each ioctl, the race window exists between
+  the separate ioctl calls when the lock is released.
+
+- Userspace ethtool always fills stats.n_stats, but it is likely that
+  these stats ioctls are implemented in other userspace applications
+  which might not fill it. The added code checks that it's not zero,
+  to prevent any regressions.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Link: https://patch.msgid.link/20251208121901.3203692-1-gal@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/ioctl.c | 30 ++++++++++++++++++++++++------
+ 1 file changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 4486cbe2faf0c..eaeb514b7e5f6 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -1955,7 +1955,10 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
+               return -ENOMEM;
+       WARN_ON_ONCE(!ret);
+-      gstrings.len = ret;
++      if (gstrings.len && gstrings.len != ret)
++              gstrings.len = 0;
++      else
++              gstrings.len = ret;
+       if (gstrings.len) {
+               data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
+@@ -2070,10 +2073,13 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       if (copy_from_user(&stats, useraddr, sizeof(stats)))
+               return -EFAULT;
+-      stats.n_stats = n_stats;
++      if (stats.n_stats && stats.n_stats != n_stats)
++              stats.n_stats = 0;
++      else
++              stats.n_stats = n_stats;
+-      if (n_stats) {
+-              data = vzalloc(array_size(n_stats, sizeof(u64)));
++      if (stats.n_stats) {
++              data = vzalloc(array_size(stats.n_stats, sizeof(u64)));
+               if (!data)
+                       return -ENOMEM;
+               ops->get_ethtool_stats(dev, &stats, data);
+@@ -2085,7 +2091,9 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
+       if (copy_to_user(useraddr, &stats, sizeof(stats)))
+               goto out;
+       useraddr += sizeof(stats);
+-      if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
++      if (stats.n_stats &&
++          copy_to_user(useraddr, data,
++                       array_size(stats.n_stats, sizeof(u64))))
+               goto out;
+       ret = 0;
+@@ -2121,6 +2129,10 @@ static int ethtool_get_phy_stats_phydev(struct phy_device *phydev,
+               return -EOPNOTSUPP;
+       n_stats = phy_ops->get_sset_count(phydev);
++      if (stats->n_stats && stats->n_stats != n_stats) {
++              stats->n_stats = 0;
++              return 0;
++      }
+       ret = ethtool_vzalloc_stats_array(n_stats, data);
+       if (ret)
+@@ -2141,6 +2153,10 @@ static int ethtool_get_phy_stats_ethtool(struct net_device *dev,
+               return -EOPNOTSUPP;
+       n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
++      if (stats->n_stats && stats->n_stats != n_stats) {
++              stats->n_stats = 0;
++              return 0;
++      }
+       ret = ethtool_vzalloc_stats_array(n_stats, data);
+       if (ret)
+@@ -2177,7 +2193,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
+       }
+       useraddr += sizeof(stats);
+-      if (copy_to_user(useraddr, data, array_size(stats.n_stats, sizeof(u64))))
++      if (stats.n_stats &&
++          copy_to_user(useraddr, data,
++                       array_size(stats.n_stats, sizeof(u64))))
+               ret = -EFAULT;
+  out:
+-- 
+2.51.0
+
diff --git a/queue-6.6/iommufd-selftest-check-for-overflow-in-iommu_test_op.patch b/queue-6.6/iommufd-selftest-check-for-overflow-in-iommu_test_op.patch
new file mode 100644 (file)
index 0000000..99f2d07
--- /dev/null
@@ -0,0 +1,57 @@
+From bdc13c0547c15a75bdeb923fa47f38a877cf8b64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Dec 2025 11:53:40 -0400
+Subject: iommufd/selftest: Check for overflow in IOMMU_TEST_OP_ADD_RESERVED
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit e6a973af11135439de32ece3b9cbe3bfc043bea8 ]
+
+syzkaller found it could overflow math in the test infrastructure and
+cause a WARN_ON by corrupting the reserved interval tree. This only
+effects test kernels with CONFIG_IOMMUFD_TEST.
+
+Validate the user input length in the test ioctl.
+
+Fixes: f4b20bb34c83 ("iommufd: Add kernel support for testing iommufd")
+Link: https://patch.msgid.link/r/0-v1-cd99f6049ba5+51-iommufd_syz_add_resv_jgg@nvidia.com
+Reviewed-by: Samiullah Khawaja <skhawaja@google.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Tested-by: Yi Liu <yi.l.liu@intel.com>
+Reported-by: syzbot+57fdb0cf6a0c5d1f15a2@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/69368129.a70a0220.38f243.008f.GAE@google.com
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/iommufd/selftest.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
+index 00b794d74e03b..8025ff65ed4de 100644
+--- a/drivers/iommu/iommufd/selftest.c
++++ b/drivers/iommu/iommufd/selftest.c
+@@ -512,14 +512,20 @@ static int iommufd_test_add_reserved(struct iommufd_ucmd *ucmd,
+                                    unsigned int mockpt_id,
+                                    unsigned long start, size_t length)
+ {
++      unsigned long last;
+       struct iommufd_ioas *ioas;
+       int rc;
++      if (!length)
++              return -EINVAL;
++      if (check_add_overflow(start, length - 1, &last))
++              return -EOVERFLOW;
++
+       ioas = iommufd_get_ioas(ucmd->ictx, mockpt_id);
+       if (IS_ERR(ioas))
+               return PTR_ERR(ioas);
+       down_write(&ioas->iopt.iova_rwsem);
+-      rc = iopt_reserve_iova(&ioas->iopt, start, start + length - 1, NULL);
++      rc = iopt_reserve_iova(&ioas->iopt, start, last, NULL);
+       up_write(&ioas->iopt.iova_rwsem);
+       iommufd_put_object(&ioas->obj);
+       return rc;
+-- 
+2.51.0
+
diff --git a/queue-6.6/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch b/queue-6.6/ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch
new file mode 100644 (file)
index 0000000..615c170
--- /dev/null
@@ -0,0 +1,48 @@
+From 6ab9b46dad612ea453c7ddd972c8b437abdcae1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 13:39:03 +0300
+Subject: ipvlan: Ignore PACKET_LOOPBACK in handle_mode_l2()
+
+From: Dmitry Skorodumov <skorodumov.dmitry@huawei.com>
+
+[ Upstream commit 0c57ff008a11f24f7f05fa760222692a00465fec ]
+
+Packets with pkt_type == PACKET_LOOPBACK are captured by
+handle_frame() function, but they don't have L2 header.
+We should not process them in handle_mode_l2().
+
+This doesn't affect old L2 functionality, since handling
+was anyway incorrect.
+
+Handle them the same way as in br_handle_frame():
+just pass the skb.
+
+To observe invalid behaviour, just start "ping -b" on bcast address
+of port-interface.
+
+Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
+Signed-off-by: Dmitry Skorodumov <skorodumov.dmitry@huawei.com>
+Link: https://patch.msgid.link/20251202103906.4087675-1-skorodumov.dmitry@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ipvlan/ipvlan_core.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
+index ca62188a317ad..83bd65a227709 100644
+--- a/drivers/net/ipvlan/ipvlan_core.c
++++ b/drivers/net/ipvlan/ipvlan_core.c
+@@ -737,6 +737,9 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,
+       struct ethhdr *eth = eth_hdr(skb);
+       rx_handler_result_t ret = RX_HANDLER_PASS;
++      if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
++              return RX_HANDLER_PASS;
++
+       if (is_multicast_ether_addr(eth->h_dest)) {
+               if (ipvlan_external_frame(skb, port)) {
+                       struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
+-- 
+2.51.0
+
diff --git a/queue-6.6/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch b/queue-6.6/ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch
new file mode 100644 (file)
index 0000000..23ae68a
--- /dev/null
@@ -0,0 +1,80 @@
+From 125af2e18ffe0c55db5a3d2f8aa27b9fd8e07107 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Nov 2025 16:52:13 +0800
+Subject: ipvs: fix ipv4 null-ptr-deref in route error path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Slavin Liu <slavin452@gmail.com>
+
+[ Upstream commit ad891bb3d079a46a821bf2b8867854645191bab0 ]
+
+The IPv4 code path in __ip_vs_get_out_rt() calls dst_link_failure()
+without ensuring skb->dev is set, leading to a NULL pointer dereference
+in fib_compute_spec_dst() when ipv4_link_failure() attempts to send
+ICMP destination unreachable messages.
+
+The issue emerged after commit ed0de45a1008 ("ipv4: recompile ip options
+in ipv4_link_failure") started calling __ip_options_compile() from
+ipv4_link_failure(). This code path eventually calls fib_compute_spec_dst()
+which dereferences skb->dev. An attempt was made to fix the NULL skb->dev
+dereference in commit 0113d9c9d1cc ("ipv4: fix null-deref in
+ipv4_link_failure"), but it only addressed the immediate dev_net(skb->dev)
+dereference by using a fallback device. The fix was incomplete because
+fib_compute_spec_dst() later in the call chain still accesses skb->dev
+directly, which remains NULL when IPVS calls dst_link_failure().
+
+The crash occurs when:
+1. IPVS processes a packet in NAT mode with a misconfigured destination
+2. Route lookup fails in __ip_vs_get_out_rt() before establishing a route
+3. The error path calls dst_link_failure(skb) with skb->dev == NULL
+4. ipv4_link_failure() â†’ ipv4_send_dest_unreach() â†’
+   __ip_options_compile() â†’ fib_compute_spec_dst()
+5. fib_compute_spec_dst() dereferences NULL skb->dev
+
+Apply the same fix used for IPv6 in commit 326bf17ea5d4 ("ipvs: fix
+ipv6 route unreach panic"): set skb->dev from skb_dst(skb)->dev before
+calling dst_link_failure().
+
+KASAN: null-ptr-deref in range [0x0000000000000328-0x000000000000032f]
+CPU: 1 PID: 12732 Comm: syz.1.3469 Not tainted 6.6.114 #2
+RIP: 0010:__in_dev_get_rcu include/linux/inetdevice.h:233
+RIP: 0010:fib_compute_spec_dst+0x17a/0x9f0 net/ipv4/fib_frontend.c:285
+Call Trace:
+  <TASK>
+  spec_dst_fill net/ipv4/ip_options.c:232
+  spec_dst_fill net/ipv4/ip_options.c:229
+  __ip_options_compile+0x13a1/0x17d0 net/ipv4/ip_options.c:330
+  ipv4_send_dest_unreach net/ipv4/route.c:1252
+  ipv4_link_failure+0x702/0xb80 net/ipv4/route.c:1265
+  dst_link_failure include/net/dst.h:437
+  __ip_vs_get_out_rt+0x15fd/0x19e0 net/netfilter/ipvs/ip_vs_xmit.c:412
+  ip_vs_nat_xmit+0x1d8/0xc80 net/netfilter/ipvs/ip_vs_xmit.c:764
+
+Fixes: ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure")
+Signed-off-by: Slavin Liu <slavin452@gmail.com>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
+index 0103c4a4d10a5..2877706f0162f 100644
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -409,6 +409,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+       return -1;
+ err_unreach:
++      if (!skb->dev)
++              skb->dev = skb_dst(skb)->dev;
++
+       dst_link_failure(skb);
+       return -1;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.6/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch b/queue-6.6/mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch
new file mode 100644 (file)
index 0000000..89481c5
--- /dev/null
@@ -0,0 +1,96 @@
+From 89b87fa07cc21adf402b76bbaf3a9c99bfc2fba4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:13 +0100
+Subject: mlxsw: spectrum_mr: Fix use-after-free when updating multicast route
+ stats
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 8ac1dacec458f55f871f7153242ed6ab60373b90 ]
+
+Cited commit added a dedicated mutex (instead of RTNL) to protect the
+multicast route list, so that it will not change while the driver
+periodically traverses it in order to update the kernel about multicast
+route stats that were queried from the device.
+
+One instance of list entry deletion (during route replace) was missed
+and it can result in a use-after-free [1].
+
+Fix by acquiring the mutex before deleting the entry from the list and
+releasing it afterwards.
+
+[1]
+BUG: KASAN: slab-use-after-free in mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum]
+Read of size 8 at addr ffff8881523c2fa8 by task kworker/2:5/22043
+
+CPU: 2 UID: 0 PID: 22043 Comm: kworker/2:5 Not tainted 6.18.0-rc1-custom-g1a3d6d7cd014 #1 PREEMPT(full)
+Hardware name: Mellanox Technologies Ltd. MSN2010/SA002610, BIOS 5.6.5 08/24/2017
+Workqueue: mlxsw_core mlxsw_sp_mr_stats_update [mlxsw_spectrum]
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xba/0x110
+ print_report+0x174/0x4f5
+ kasan_report+0xdf/0x110
+ mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+Allocated by task 29933:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0x8f/0xa0
+ mlxsw_sp_mr_route_add+0xd8/0x4770 [mlxsw_spectrum]
+ mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+
+Freed by task 29933:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3b/0x70
+ __kasan_slab_free+0x43/0x70
+ kfree+0x14e/0x700
+ mlxsw_sp_mr_route_add+0x2dea/0x4770 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:444 [mlxsw_spectrum]
+ mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum]
+ process_one_work+0x9cc/0x18e0
+ worker_thread+0x5df/0xe40
+ kthread+0x3b8/0x730
+ ret_from_fork+0x3e9/0x560
+ ret_from_fork_asm+0x1a/0x30
+
+Fixes: f38656d06725 ("mlxsw: spectrum_mr: Protect multicast route list with a lock")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/f996feecfd59fde297964bfc85040b6d83ec6089.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+index 5afe6b155ef0d..81935f87bfcd7 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+@@ -440,7 +440,9 @@ int mlxsw_sp_mr_route_add(struct mlxsw_sp_mr_table *mr_table,
+               rhashtable_remove_fast(&mr_table->route_ht,
+                                      &mr_orig_route->ht_node,
+                                      mlxsw_sp_mr_route_ht_params);
++              mutex_lock(&mr_table->route_list_lock);
+               list_del(&mr_orig_route->node);
++              mutex_unlock(&mr_table->route_list_lock);
+               mlxsw_sp_mr_route_destroy(mr_table, mr_orig_route);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.6/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch b/queue-6.6/mlxsw-spectrum_router-fix-neighbour-use-after-free.patch
new file mode 100644 (file)
index 0000000..9d96904
--- /dev/null
@@ -0,0 +1,199 @@
+From 630cc1d6e6a73c73fb7edfb6f03511a5e801c19a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:12 +0100
+Subject: mlxsw: spectrum_router: Fix neighbour use-after-free
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 8b0e69763ef948fb872a7767df4be665d18f5fd4 ]
+
+We sometimes observe use-after-free when dereferencing a neighbour [1].
+The problem seems to be that the driver stores a pointer to the
+neighbour, but without holding a reference on it. A reference is only
+taken when the neighbour is used by a nexthop.
+
+Fix by simplifying the reference counting scheme. Always take a
+reference when storing a neighbour pointer in a neighbour entry. Avoid
+taking a referencing when the neighbour is used by a nexthop as the
+neighbour entry associated with the nexthop already holds a reference.
+
+Tested by running the test that uncovered the problem over 300 times.
+Without this patch the problem was reproduced after a handful of
+iterations.
+
+[1]
+BUG: KASAN: slab-use-after-free in mlxsw_sp_neigh_entry_update+0x2d4/0x310
+Read of size 8 at addr ffff88817f8e3420 by task ip/3929
+
+CPU: 3 UID: 0 PID: 3929 Comm: ip Not tainted 6.18.0-rc4-virtme-g36b21a067510 #3 PREEMPT(full)
+Hardware name: Nvidia SN5600/VMOD0013, BIOS 5.13 05/31/2023
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x6f/0xa0
+ print_address_description.constprop.0+0x6e/0x300
+ print_report+0xfc/0x1fb
+ kasan_report+0xe4/0x110
+ mlxsw_sp_neigh_entry_update+0x2d4/0x310
+ mlxsw_sp_router_rif_gone_sync+0x35f/0x510
+ mlxsw_sp_rif_destroy+0x1ea/0x730
+ mlxsw_sp_inetaddr_port_vlan_event+0xa1/0x1b0
+ __mlxsw_sp_inetaddr_lag_event+0xcc/0x130
+ __mlxsw_sp_inetaddr_event+0xf5/0x3c0
+ mlxsw_sp_router_netdevice_event+0x1015/0x1580
+ notifier_call_chain+0xcc/0x150
+ call_netdevice_notifiers_info+0x7e/0x100
+ __netdev_upper_dev_unlink+0x10b/0x210
+ netdev_upper_dev_unlink+0x79/0xa0
+ vrf_del_slave+0x18/0x50
+ do_set_master+0x146/0x7d0
+ do_setlink.isra.0+0x9a0/0x2880
+ rtnl_newlink+0x637/0xb20
+ rtnetlink_rcv_msg+0x6fe/0xb90
+ netlink_rcv_skb+0x123/0x380
+ netlink_unicast+0x4a3/0x770
+ netlink_sendmsg+0x75b/0xc90
+ __sock_sendmsg+0xbe/0x160
+ ____sys_sendmsg+0x5b2/0x7d0
+ ___sys_sendmsg+0xfd/0x180
+ __sys_sendmsg+0x124/0x1c0
+ do_syscall_64+0xbb/0xfd0
+ entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[...]
+
+Allocated by task 109:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0x7b/0x90
+ __kmalloc_noprof+0x2c1/0x790
+ neigh_alloc+0x6af/0x8f0
+ ___neigh_create+0x63/0xe90
+ mlxsw_sp_nexthop_neigh_init+0x430/0x7e0
+ mlxsw_sp_nexthop_type_init+0x212/0x960
+ mlxsw_sp_nexthop6_group_info_init.constprop.0+0x81f/0x1280
+ mlxsw_sp_nexthop6_group_get+0x392/0x6a0
+ mlxsw_sp_fib6_entry_create+0x46a/0xfd0
+ mlxsw_sp_router_fib6_replace+0x1ed/0x5f0
+ mlxsw_sp_router_fib6_event_work+0x10a/0x2a0
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Freed by task 154:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_save_free_info+0x3b/0x60
+ __kasan_slab_free+0x43/0x70
+ kmem_cache_free_bulk.part.0+0x1eb/0x5e0
+ kvfree_rcu_bulk+0x1f2/0x260
+ kfree_rcu_work+0x130/0x1b0
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Last potentially related work creation:
+ kasan_save_stack+0x30/0x50
+ kasan_record_aux_stack+0x8c/0xa0
+ kvfree_call_rcu+0x93/0x5b0
+ mlxsw_sp_router_neigh_event_work+0x67d/0x860
+ process_one_work+0xd57/0x1390
+ worker_thread+0x4d6/0xd40
+ kthread+0x355/0x5b0
+ ret_from_fork+0x1d4/0x270
+ ret_from_fork_asm+0x11/0x20
+
+Fixes: 6cf3c971dc84 ("mlxsw: spectrum_router: Add private neigh table")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/92d75e21d95d163a41b5cea67a15cd33f547cba6.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlxsw/spectrum_router.c   | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index f5c34218ba85b..4cd79473ace54 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -2264,6 +2264,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
+       if (!neigh_entry)
+               return NULL;
++      neigh_hold(n);
+       neigh_entry->key.n = n;
+       neigh_entry->rif = rif;
+       INIT_LIST_HEAD(&neigh_entry->nexthop_list);
+@@ -2273,6 +2274,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
+ static void mlxsw_sp_neigh_entry_free(struct mlxsw_sp_neigh_entry *neigh_entry)
+ {
++      neigh_release(neigh_entry->key.n);
+       kfree(neigh_entry);
+ }
+@@ -4203,6 +4205,8 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
+       if (err)
+               goto err_neigh_entry_insert;
++      neigh_release(old_n);
++
+       read_lock_bh(&n->lock);
+       nud_state = n->nud_state;
+       dead = n->dead;
+@@ -4211,14 +4215,10 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
+       list_for_each_entry(nh, &neigh_entry->nexthop_list,
+                           neigh_list_node) {
+-              neigh_release(old_n);
+-              neigh_clone(n);
+               __mlxsw_sp_nexthop_neigh_update(nh, !entry_connected);
+               mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp);
+       }
+-      neigh_release(n);
+-
+       return 0;
+ err_neigh_entry_insert:
+@@ -4311,6 +4311,11 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
+               }
+       }
++      /* Release the reference taken by neigh_lookup() / neigh_create() since
++       * neigh_entry already holds one.
++       */
++      neigh_release(n);
++
+       /* If that is the first nexthop connected to that neigh, add to
+        * nexthop_neighs_list
+        */
+@@ -4337,11 +4342,9 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
+                                       struct mlxsw_sp_nexthop *nh)
+ {
+       struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
+-      struct neighbour *n;
+       if (!neigh_entry)
+               return;
+-      n = neigh_entry->key.n;
+       __mlxsw_sp_nexthop_neigh_update(nh, true);
+       list_del(&nh->neigh_list_node);
+@@ -4355,8 +4358,6 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
+       if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list))
+               mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
+-
+-      neigh_release(n);
+ }
+ static bool mlxsw_sp_ipip_netdev_ul_up(struct net_device *ol_dev)
+-- 
+2.51.0
+
diff --git a/queue-6.6/mlxsw-spectrum_router-fix-possible-neighbour-referen.patch b/queue-6.6/mlxsw-spectrum_router-fix-possible-neighbour-referen.patch
new file mode 100644 (file)
index 0000000..ddf68ce
--- /dev/null
@@ -0,0 +1,64 @@
+From 434e03e1048d44e1c203b12cb5b905e1e1213aa3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:44:11 +0100
+Subject: mlxsw: spectrum_router: Fix possible neighbour reference count leak
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit b6b638bda240395dff49a87403b2e32493e56d2a ]
+
+mlxsw_sp_router_schedule_work() takes a reference on a neighbour,
+expecting a work item to release it later on. However, we might fail to
+schedule the work item, in which case the neighbour reference count will
+be leaked.
+
+Fix by taking the reference just before scheduling the work item. Note
+that mlxsw_sp_router_schedule_work() can receive a NULL neighbour
+pointer, but neigh_clone() handles that correctly.
+
+Spotted during code review, did not actually observe the reference count
+leak.
+
+Fixes: 151b89f6025a ("mlxsw: spectrum_router: Reuse work neighbor initialization in work scheduler")
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/ec2934ae4aca187a8d8c9329a08ce93cca411378.1764695650.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index 0534b10e29c5c..f5c34218ba85b 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -2857,6 +2857,11 @@ static int mlxsw_sp_router_schedule_work(struct net *net,
+       if (!net_work)
+               return NOTIFY_BAD;
++      /* Take a reference to ensure the neighbour won't be destructed until
++       * we drop the reference in the work item.
++       */
++      neigh_clone(n);
++
+       INIT_WORK(&net_work->work, cb);
+       net_work->mlxsw_sp = router->mlxsw_sp;
+       net_work->n = n;
+@@ -2880,11 +2885,6 @@ static int mlxsw_sp_router_schedule_neigh_work(struct mlxsw_sp_router *router,
+       struct net *net;
+       net = neigh_parms_net(n->parms);
+-
+-      /* Take a reference to ensure the neighbour won't be destructed until we
+-       * drop the reference in delayed work.
+-       */
+-      neigh_clone(n);
+       return mlxsw_sp_router_schedule_work(net, router, n,
+                                            mlxsw_sp_router_neigh_event_work);
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-enetc-do-not-transmit-redirected-xdp-frames-when.patch b/queue-6.6/net-enetc-do-not-transmit-redirected-xdp-frames-when.patch
new file mode 100644 (file)
index 0000000..cf05cbc
--- /dev/null
@@ -0,0 +1,66 @@
+From 246aa74c78963064d0249bb9fbe7ad9d65a95648 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:09:19 +0800
+Subject: net: enetc: do not transmit redirected XDP frames when the link is
+ down
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit 2939203ffee818f1e5ebd60bbb85a174d63aab9c ]
+
+In the current implementation, the enetc_xdp_xmit() always transmits
+redirected XDP frames even if the link is down, but the frames cannot
+be transmitted from TX BD rings when the link is down, so the frames
+are still kept in the TX BD rings. If the XDP program is uninstalled,
+users will see the following warning logs.
+
+fsl_enetc 0000:00:00.0 eno0: timeout for tx ring #6 clear
+
+More worse, the TX BD ring cannot work properly anymore, because the
+HW PIR and CIR are not equal after the re-initialization of the TX
+BD ring. At this point, the BDs between CIR and PIR are invalid,
+which will cause a hardware malfunction.
+
+Another reason is that there is internal context in the ring prefetch
+logic that will retain the state from the first incarnation of the ring
+and continue prefetching from the stale location when we re-initialize
+the ring. The internal context is only reset by an FLR. That is to say,
+for LS1028A ENETC, software cannot set the HW CIR and PIR when
+initializing the TX BD ring.
+
+It does not make sense to transmit redirected XDP frames when the link is
+down. Add a link status check to prevent transmission in this condition.
+This fixes part of the issue, but more complex cases remain. For example,
+the TX BD ring may still contain unsent frames when the link goes down.
+Those situations require additional patches, which will build on this
+one.
+
+Fixes: 9d2b68cc108d ("net: enetc: add support for XDP_REDIRECT")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Reviewed-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20251211020919.121113-1-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index 7accf3a3e9f0d..e3ab6f4f8dbba 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -1429,7 +1429,8 @@ int enetc_xdp_xmit(struct net_device *ndev, int num_frames,
+       int xdp_tx_bd_cnt, i, k;
+       int xdp_tx_frm_cnt = 0;
+-      if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags)))
++      if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags) ||
++                   !netif_carrier_ok(ndev)))
+               return -ENETDOWN;
+       enetc_lock_mdio();
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-fec-err007885-workaround-for-xdp-tx-path.patch b/queue-6.6/net-fec-err007885-workaround-for-xdp-tx-path.patch
new file mode 100644 (file)
index 0000000..d43eb86
--- /dev/null
@@ -0,0 +1,49 @@
+From 10b9633f939f42eda96a92297694f876b776e41b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Nov 2025 10:59:15 +0800
+Subject: net: fec: ERR007885 Workaround for XDP TX path
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit e8e032cd24dda7cceaa27bc2eb627f82843f0466 ]
+
+The ERR007885 will lead to a TDAR race condition for mutliQ when the
+driver sets TDAR and the UDMA clears TDAR simultaneously or in a small
+window (2-4 cycles). And it will cause the udma_tx and udma_tx_arbiter
+state machines to hang. Therefore, the commit 53bb20d1faba ("net: fec:
+add variable reg_desc_active to speed things up") and the commit
+a179aad12bad ("net: fec: ERR007885 Workaround for conventional TX") have
+added the workaround to fix the potential issue for the conventional TX
+path. Similarly, the XDP TX path should also have the potential hang
+issue, so add the workaround for XDP TX path.
+
+Fixes: 6d6b39f180b8 ("net: fec: add initial XDP support")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Link: https://patch.msgid.link/20251128025915.2486943-1-wei.fang@nxp.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/fec_main.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index ee0306ab97714..7efe4e81cf320 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -3935,7 +3935,12 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep,
+       txq->bd.cur = bdp;
+       /* Trigger transmission start */
+-      writel(0, txq->bd.reg_desc_active);
++      if (!(fep->quirks & FEC_QUIRK_ERR007885) ||
++          !readl(txq->bd.reg_desc_active) ||
++          !readl(txq->bd.reg_desc_active) ||
++          !readl(txq->bd.reg_desc_active) ||
++          !readl(txq->bd.reg_desc_active))
++              writel(0, txq->bd.reg_desc_active);
+       return 0;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-handshake-duplicate-handshake-cancellations-leak.patch b/queue-6.6/net-handshake-duplicate-handshake-cancellations-leak.patch
new file mode 100644 (file)
index 0000000..4decc81
--- /dev/null
@@ -0,0 +1,61 @@
+From c97d79af26547edffbba0ae17d2b1195e37a4ffd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:30:15 -0500
+Subject: net/handshake: duplicate handshake cancellations leak socket
+
+From: Scott Mayhew <smayhew@redhat.com>
+
+[ Upstream commit 15564bd67e2975002f2a8e9defee33e321d3183f ]
+
+When a handshake request is cancelled it is removed from the
+handshake_net->hn_requests list, but it is still present in the
+handshake_rhashtbl until it is destroyed.
+
+If a second cancellation request arrives for the same handshake request,
+then remove_pending() will return false... and assuming
+HANDSHAKE_F_REQ_COMPLETED isn't set in req->hr_flags, we'll continue
+processing through the out_true label, where we put another reference on
+the sock and a refcount underflow occurs.
+
+This can happen for example if a handshake times out - particularly if
+the SUNRPC client sends the AUTH_TLS probe to the server but doesn't
+follow it up with the ClientHello due to a problem with tlshd.  When the
+timeout is hit on the server, the server will send a FIN, which triggers
+a cancellation request via xs_reset_transport().  When the timeout is
+hit on the client, another cancellation request happens via
+xs_tls_handshake_sync().
+
+Add a test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED) in the pending cancel
+path so duplicate cancels can be detected.
+
+Fixes: 3b3009ea8abb ("net/handshake: Create a NETLINK service for handling handshake requests")
+Suggested-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Scott Mayhew <smayhew@redhat.com>
+Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
+Link: https://patch.msgid.link/20251209193015.3032058-1-smayhew@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/request.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 94d5cef3e048b..0ac126b0add60 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -325,7 +325,11 @@ bool handshake_req_cancel(struct sock *sk)
+       hn = handshake_pernet(net);
+       if (hn && remove_pending(hn, req)) {
+-              /* Request hadn't been accepted */
++              /* Request hadn't been accepted - mark cancelled */
++              if (test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) {
++                      trace_handshake_cancel_busy(net, req, sk);
++                      return false;
++              }
+               goto out_true;
+       }
+       if (test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) {
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-hns3-add-vlan-id-validation-before-using.patch b/queue-6.6/net-hns3-add-vlan-id-validation-before-using.patch
new file mode 100644 (file)
index 0000000..0fc7043
--- /dev/null
@@ -0,0 +1,46 @@
+From 8a145435480c6524ab63f2aaca40e53766de08de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:37 +0800
+Subject: net: hns3: add VLAN id validation before using
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit 6ef935e65902bfed53980ad2754b06a284ea8ac1 ]
+
+Currently, the VLAN id may be used without validation when
+receive a VLAN configuration mailbox from VF. The length of
+vlan_del_fail_bmap is BITS_TO_LONGS(VLAN_N_VID). It may cause
+out-of-bounds memory access once the VLAN id is bigger than
+or equal to VLAN_N_VID.
+
+Therefore, VLAN id needs to be checked to ensure it is within
+the range of VLAN_N_VID.
+
+Fixes: fe4144d47eef ("net: hns3: sync VLAN filter entries when kill VLAN ID failed")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-4-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index 2fa64099e8be2..2df0c6305b908 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -10479,6 +10479,9 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
+       bool writen_to_tbl = false;
+       int ret = 0;
++      if (vlan_id >= VLAN_N_VID)
++              return -EINVAL;
++
+       /* When device is resetting or reset failed, firmware is unable to
+        * handle mailbox. Just record the vlan id, and remove it after
+        * reset finished.
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch b/queue-6.6/net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch
new file mode 100644 (file)
index 0000000..7b26415
--- /dev/null
@@ -0,0 +1,52 @@
+From f19b0d8ab7bd92fc34dc9a7fe85798bdba6d8bfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:35 +0800
+Subject: net: hns3: using the num_tqps in the vf driver to apply for resources
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit c2a16269742e176fccdd0ef9c016a233491a49ad ]
+
+Currently, hdev->htqp is allocated using hdev->num_tqps, and kinfo->tqp
+is allocated using kinfo->num_tqps. However, kinfo->num_tqps is set to
+min(new_tqps, hdev->num_tqps);  Therefore, kinfo->num_tqps may be smaller
+than hdev->num_tqps, which causes some hdev->htqp[i] to remain
+uninitialized in hclgevf_knic_setup().
+
+Thus, this patch allocates hdev->htqp and kinfo->tqp using hdev->num_tqps,
+ensuring that the lengths of hdev->htqp and kinfo->tqp are consistent
+and that all elements are properly initialized.
+
+Fixes: e2cb1dec9779 ("net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-2-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+index 68a9aeeed3da0..c7e5b83ac4a84 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -333,12 +333,12 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev)
+       new_tqps = kinfo->rss_size * num_tc;
+       kinfo->num_tqps = min(new_tqps, hdev->num_tqps);
+-      kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps,
++      kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps,
+                                 sizeof(struct hnae3_queue *), GFP_KERNEL);
+       if (!kinfo->tqp)
+               return -ENOMEM;
+-      for (i = 0; i < kinfo->num_tqps; i++) {
++      for (i = 0; i < hdev->num_tqps; i++) {
+               hdev->htqp[i].q.handle = &hdev->nic;
+               hdev->htqp[i].q.tqp_index = i;
+               kinfo->tqp[i] = &hdev->htqp[i].q;
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch b/queue-6.6/net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch
new file mode 100644 (file)
index 0000000..8c882ec
--- /dev/null
@@ -0,0 +1,49 @@
+From fa4fe5c3b21f61994135da81ab39a0a56c5ddc3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Dec 2025 10:37:36 +0800
+Subject: net: hns3: using the num_tqps to check whether tqp_index is out of
+ range when vf get ring info from mbx
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit d180c11aa8a6fa735f9ac2c72c61364a9afc2ba7 ]
+
+Currently, rss_size = num_tqps / tc_num. If tc_num is 1, then num_tqps
+equals rss_size. However, if the tc_num is greater than 1, then rss_size
+will be less than num_tqps, causing the tqp_index check for subsequent TCs
+using rss_size to always fail.
+
+This patch uses the num_tqps to check whether tqp_index is out of range,
+instead of rss_size.
+
+Fixes: 326334aad024 ("net: hns3: add a check for tqp_index in hclge_get_ring_chain_from_mbx()")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251211023737.2327018-3-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+index 61e155c4d441e..a961e90a85a67 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+@@ -193,10 +193,10 @@ static int hclge_get_ring_chain_from_mbx(
+               return -EINVAL;
+       for (i = 0; i < ring_num; i++) {
+-              if (req->msg.param[i].tqp_index >= vport->nic.kinfo.rss_size) {
++              if (req->msg.param[i].tqp_index >= vport->nic.kinfo.num_tqps) {
+                       dev_err(&hdev->pdev->dev, "tqp index(%u) is out of range(0-%u)\n",
+                               req->msg.param[i].tqp_index,
+-                              vport->nic.kinfo.rss_size - 1U);
++                              vport->nic.kinfo.num_tqps - 1U);
+                       return -EINVAL;
+               }
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-mlx5-drain-firmware-reset-in-shutdown-callback.patch b/queue-6.6/net-mlx5-drain-firmware-reset-in-shutdown-callback.patch
new file mode 100644 (file)
index 0000000..b82e093
--- /dev/null
@@ -0,0 +1,38 @@
+From 0eff167db5fd2ac3aaf627f0b6d9b269e79258e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:10 +0200
+Subject: net/mlx5: Drain firmware reset in shutdown callback
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 5846a365fc6476b02d6766963cf0985520f0385f ]
+
+Invoke drain_fw_reset() in the shutdown callback to ensure all
+firmware reset handling is completed before shutdown proceeds.
+
+Fixes: 16d42d313350 ("net/mlx5: Drain fw_reset when removing device")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Shay Drori <shayd@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-3-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 8a11e410f7c13..df6eeb0f57bcd 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -2164,6 +2164,7 @@ static void shutdown(struct pci_dev *pdev)
+       mlx5_core_info(dev, "Shutdown was called\n");
+       set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state);
++      mlx5_drain_fw_reset(dev);
+       mlx5_drain_health_wq(dev);
+       err = mlx5_try_fast_unload(dev);
+       if (err)
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch b/queue-6.6/net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch
new file mode 100644 (file)
index 0000000..9b1196a
--- /dev/null
@@ -0,0 +1,45 @@
+From bcb2ab40259b77d3ec5394c9918ae32223ac6269 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:09 +0200
+Subject: net/mlx5: fw reset, clear reset requested on drain_fw_reset
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 89a898d63f6f588acf5c104c65c94a38b68c69a6 ]
+
+drain_fw_reset() waits for ongoing firmware reset events and blocks new
+event handling, but does not clear the reset requested flag, and may
+keep sync reset polling.
+
+To fix it, call mlx5_sync_reset_clear_reset_requested() to clear the
+flag, stop sync reset polling, and resume health polling, ensuring
+health issues are still detected after the firmware reset drain.
+
+Fixes: 16d42d313350 ("net/mlx5: Drain fw_reset when removing device")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Shay Drori <shayd@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-2-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 4d64d179b5dd7..dc7afc9e7777d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -804,7 +804,8 @@ void mlx5_drain_fw_reset(struct mlx5_core_dev *dev)
+       cancel_work_sync(&fw_reset->reset_reload_work);
+       cancel_work_sync(&fw_reset->reset_now_work);
+       cancel_work_sync(&fw_reset->reset_abort_work);
+-      cancel_delayed_work(&fw_reset->reset_timeout_work);
++      if (test_bit(MLX5_FW_RESET_FLAGS_RESET_REQUESTED, &fw_reset->reset_flags))
++              mlx5_sync_reset_clear_reset_requested(dev, true);
+ }
+ static const struct devlink_param mlx5_fw_reset_devlink_params[] = {
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch b/queue-6.6/net-mlx5-fw_tracer-handle-escaped-percent-properly.patch
new file mode 100644 (file)
index 0000000..9974f28
--- /dev/null
@@ -0,0 +1,84 @@
+From dd8866b9504bb82018195e19707623cb8a430de5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:12 +0200
+Subject: net/mlx5: fw_tracer, Handle escaped percent properly
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit c0289f67f7d6a0dfba0e92cfe661a5c70c8c6e92 ]
+
+The firmware tracer's format string validation and parameter counting
+did not properly handle escaped percent signs (%%). This caused
+fw_tracer to count more parameters when trace format strings contained
+literal percent characters.
+
+To fix it, allow %% to pass string validation and skip %% sequences when
+counting parameters since they represent literal percent signs rather
+than format specifiers.
+
+Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reported-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-5-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 20 +++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 197c306d350bf..0a33ab5f53fd3 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -368,11 +368,11 @@ static bool mlx5_is_valid_spec(const char *str)
+       while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l')
+               str++;
+-      /* Check if it's a valid integer/hex specifier:
++      /* Check if it's a valid integer/hex specifier or %%:
+        * Valid formats: %x, %d, %i, %u, etc.
+        */
+       if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' &&
+-          *str != 'u' && *str != 'c')
++          *str != 'u' && *str != 'c' && *str != '%')
+               return false;
+       return true;
+@@ -390,7 +390,11 @@ static bool mlx5_tracer_validate_params(const char *str)
+               if (!mlx5_is_valid_spec(substr + 1))
+                       return false;
+-              substr = strstr(substr + 1, PARAM_CHAR);
++              if (*(substr + 1) == '%')
++                      substr = strstr(substr + 2, PARAM_CHAR);
++              else
++                      substr = strstr(substr + 1, PARAM_CHAR);
++
+       }
+       return true;
+@@ -469,11 +473,15 @@ static int mlx5_tracer_get_num_of_params(char *str)
+               substr = strstr(pstr, VAL_PARM);
+       }
+-      /* count all the % characters */
++      /* count all the % characters, but skip %% (escaped percent) */
+       substr = strstr(str, PARAM_CHAR);
+       while (substr) {
+-              num_of_params += 1;
+-              str = substr + 1;
++              if (*(substr + 1) != '%') {
++                      num_of_params += 1;
++                      str = substr + 1;
++              } else {
++                      str = substr + 2;
++              }
+               substr = strstr(str, PARAM_CHAR);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-mlx5-fw_tracer-validate-format-string-parameters.patch b/queue-6.6/net-mlx5-fw_tracer-validate-format-string-parameters.patch
new file mode 100644 (file)
index 0000000..4b80912
--- /dev/null
@@ -0,0 +1,195 @@
+From aa54a5302b85b67ba0a7a54dd1906ff8e719f2c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:11 +0200
+Subject: net/mlx5: fw_tracer, Validate format string parameters
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit b35966042d20b14e2d83330049f77deec5229749 ]
+
+Add validation for format string parameters in the firmware tracer to
+prevent potential security vulnerabilities and crashes from malformed
+format strings received from firmware.
+
+The firmware tracer receives format strings from the device firmware and
+uses them to format trace messages. Without proper validation, bad
+firmware could provide format strings with invalid format specifiers
+(e.g., %s, %p, %n) that could lead to crashes, or other undefined
+behavior.
+
+Add mlx5_tracer_validate_params() to validate that all format specifiers
+in trace strings are limited to safe integer/hex formats (%x, %d, %i,
+%u, %llx, %lx, etc.). Reject strings containing other format types that
+could be used to access arbitrary memory or cause crashes.
+Invalid format strings are added to the trace output for visibility with
+"BAD_FORMAT: " prefix.
+
+Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Reported-by: Breno Leitao <leitao@debian.org>
+Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-4-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/diag/fw_tracer.c       | 83 ++++++++++++++++---
+ .../mellanox/mlx5/core/diag/fw_tracer.h       |  1 +
+ 2 files changed, 74 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 85d3bfa0780c6..197c306d350bf 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -33,6 +33,7 @@
+ #include "lib/eq.h"
+ #include "fw_tracer.h"
+ #include "fw_tracer_tracepoint.h"
++#include <linux/ctype.h>
+ static int mlx5_query_mtrc_caps(struct mlx5_fw_tracer *tracer)
+ {
+@@ -358,6 +359,43 @@ static const char *VAL_PARM               = "%llx";
+ static const char *REPLACE_64_VAL_PARM        = "%x%x";
+ static const char *PARAM_CHAR         = "%";
++static bool mlx5_is_valid_spec(const char *str)
++{
++      /* Parse format specifiers to find the actual type.
++       * Structure: %[flags][width][.precision][length]type
++       * Skip flags, width, precision & length.
++       */
++      while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l')
++              str++;
++
++      /* Check if it's a valid integer/hex specifier:
++       * Valid formats: %x, %d, %i, %u, etc.
++       */
++      if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' &&
++          *str != 'u' && *str != 'c')
++              return false;
++
++      return true;
++}
++
++static bool mlx5_tracer_validate_params(const char *str)
++{
++      const char *substr = str;
++
++      if (!str)
++              return false;
++
++      substr = strstr(substr, PARAM_CHAR);
++      while (substr) {
++              if (!mlx5_is_valid_spec(substr + 1))
++                      return false;
++
++              substr = strstr(substr + 1, PARAM_CHAR);
++      }
++
++      return true;
++}
++
+ static int mlx5_tracer_message_hash(u32 message_id)
+ {
+       return jhash_1word(message_id, 0) & (MESSAGE_HASH_SIZE - 1);
+@@ -419,6 +457,10 @@ static int mlx5_tracer_get_num_of_params(char *str)
+       char *substr, *pstr = str;
+       int num_of_params = 0;
++      /* Validate that all parameters are valid before processing */
++      if (!mlx5_tracer_validate_params(str))
++              return -EINVAL;
++
+       /* replace %llx with %x%x */
+       substr = strstr(pstr, VAL_PARM);
+       while (substr) {
+@@ -570,14 +612,17 @@ void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt,
+ {
+       char    tmp[512];
+-      snprintf(tmp, sizeof(tmp), str_frmt->string,
+-               str_frmt->params[0],
+-               str_frmt->params[1],
+-               str_frmt->params[2],
+-               str_frmt->params[3],
+-               str_frmt->params[4],
+-               str_frmt->params[5],
+-               str_frmt->params[6]);
++      if (str_frmt->invalid_string)
++              snprintf(tmp, sizeof(tmp), "BAD_FORMAT: %s", str_frmt->string);
++      else
++              snprintf(tmp, sizeof(tmp), str_frmt->string,
++                       str_frmt->params[0],
++                       str_frmt->params[1],
++                       str_frmt->params[2],
++                       str_frmt->params[3],
++                       str_frmt->params[4],
++                       str_frmt->params[5],
++                       str_frmt->params[6]);
+       trace_mlx5_fw(dev->tracer, trace_timestamp, str_frmt->lost,
+                     str_frmt->event_id, tmp);
+@@ -609,6 +654,13 @@ static int mlx5_tracer_handle_raw_string(struct mlx5_fw_tracer *tracer,
+       return 0;
+ }
++static void mlx5_tracer_handle_bad_format_string(struct mlx5_fw_tracer *tracer,
++                                               struct tracer_string_format *cur_string)
++{
++      cur_string->invalid_string = true;
++      list_add_tail(&cur_string->list, &tracer->ready_strings_list);
++}
++
+ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                          struct tracer_event *tracer_event)
+ {
+@@ -619,12 +671,18 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+               if (!cur_string)
+                       return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+-              cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
+-              cur_string->last_param_num = 0;
+               cur_string->event_id = tracer_event->event_id;
+               cur_string->tmsn = tracer_event->string_event.tmsn;
+               cur_string->timestamp = tracer_event->string_event.timestamp;
+               cur_string->lost = tracer_event->lost_event;
++              cur_string->last_param_num = 0;
++              cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
++              if (cur_string->num_of_params < 0) {
++                      pr_debug("%s Invalid format string parameters\n",
++                               __func__);
++                      mlx5_tracer_handle_bad_format_string(tracer, cur_string);
++                      return 0;
++              }
+               if (cur_string->num_of_params == 0) /* trace with no params */
+                       list_add_tail(&cur_string->list, &tracer->ready_strings_list);
+       } else {
+@@ -634,6 +692,11 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
+                                __func__, tracer_event->string_event.tmsn);
+                       return mlx5_tracer_handle_raw_string(tracer, tracer_event);
+               }
++              if (cur_string->num_of_params < 0) {
++                      pr_debug("%s string parameter of invalid string, dumping\n",
++                               __func__);
++                      return 0;
++              }
+               cur_string->last_param_num += 1;
+               if (cur_string->last_param_num > TRACER_MAX_PARAMS) {
+                       pr_debug("%s Number of params exceeds the max (%d)\n",
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+index 5c548bb74f07b..30d0bcba88479 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h
+@@ -125,6 +125,7 @@ struct tracer_string_format {
+       struct list_head list;
+       u32 timestamp;
+       bool lost;
++      bool invalid_string;
+ };
+ enum mlx5_fw_tracer_ownership_state {
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-mlx5-serialize-firmware-reset-with-devlink.patch b/queue-6.6/net-mlx5-serialize-firmware-reset-with-devlink.patch
new file mode 100644 (file)
index 0000000..8836928
--- /dev/null
@@ -0,0 +1,209 @@
+From d10eb48c91b28a5a6779da747df3e7fa7fd3e46d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 14:56:13 +0200
+Subject: net/mlx5: Serialize firmware reset with devlink
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 367e501f8b095eca08d2eb0ba4ccea5b5e82c169 ]
+
+The firmware reset mechanism can be triggered by asynchronous events,
+which may race with other devlink operations like devlink reload or
+devlink dev eswitch set, potentially leading to inconsistent states.
+
+This patch addresses the race by using the devl_lock to serialize the
+firmware reset against other devlink operations. When a reset is
+requested, the driver attempts to acquire the lock. If successful, it
+sets a flag to block devlink reload or eswitch changes, ACKs the reset
+to firmware and then releases the lock. If the lock is already held by
+another operation, the driver NACKs the firmware reset request,
+indicating that the reset cannot proceed.
+
+Firmware reset does not keep the devl_lock and instead uses an internal
+firmware reset bit. This is because firmware resets can be triggered by
+asynchronous events, and processed in different threads. It is illegal
+and unsafe to acquire a lock in one thread and attempt to release it in
+another, as lock ownership is intrinsically thread-specific.
+
+This change ensures that firmware resets and other devlink operations
+are mutually exclusive during the critical reset request phase,
+preventing race conditions.
+
+Fixes: 38b9f903f22b ("net/mlx5: Handle sync reset request event")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Mateusz Berezecki <mberezecki@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-6-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/devlink.c |  5 +++
+ .../mellanox/mlx5/core/eswitch_offloads.c     |  6 +++
+ .../ethernet/mellanox/mlx5/core/fw_reset.c    | 45 +++++++++++++++++--
+ .../ethernet/mellanox/mlx5/core/fw_reset.h    |  1 +
+ 4 files changed, 53 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 8489b5087d9c6..b2532b1c9565a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -144,6 +144,11 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
+       bool sf_dev_allocated;
+       int ret = 0;
++      if (mlx5_fw_reset_in_progress(dev)) {
++              NL_SET_ERR_MSG_MOD(extack, "Can't reload during firmware reset");
++              return -EBUSY;
++      }
++
+       if (mlx5_dev_is_lightweight(dev)) {
+               if (action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT)
+                       return -EOPNOTSUPP;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index 86fb8197594f5..c218593dc40f4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -51,6 +51,7 @@
+ #include "devlink.h"
+ #include "lag/lag.h"
+ #include "en/tc/post_meter.h"
++#include "fw_reset.h"
+ /* There are two match-all miss flows, one for unicast dst mac and
+  * one for multicast.
+@@ -3716,6 +3717,11 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
+       if (IS_ERR(esw))
+               return PTR_ERR(esw);
++      if (mlx5_fw_reset_in_progress(esw->dev)) {
++              NL_SET_ERR_MSG_MOD(extack, "Can't change eswitch mode during firmware reset");
++              return -EBUSY;
++      }
++
+       if (esw_mode_from_devlink(mode, &mlx5_mode))
+               return -EINVAL;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index bdcd9e5306331..f7e139279f5f8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -15,6 +15,7 @@ enum {
+       MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
+       MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED,
+       MLX5_FW_RESET_FLAGS_UNLOAD_EVENT,
++      MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS,
+ };
+ struct mlx5_fw_reset {
+@@ -125,6 +126,16 @@ int mlx5_fw_reset_query(struct mlx5_core_dev *dev, u8 *reset_level, u8 *reset_ty
+       return mlx5_reg_mfrl_query(dev, reset_level, reset_type, NULL, NULL);
+ }
++bool mlx5_fw_reset_in_progress(struct mlx5_core_dev *dev)
++{
++      struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
++
++      if (!fw_reset)
++              return false;
++
++      return test_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
++}
++
+ static int mlx5_fw_reset_get_reset_method(struct mlx5_core_dev *dev,
+                                         u8 *reset_method)
+ {
+@@ -240,6 +251,8 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
+                                                       BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE));
+               devl_unlock(devlink);
+       }
++
++      clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
+ }
+ static void mlx5_stop_sync_reset_poll(struct mlx5_core_dev *dev)
+@@ -431,27 +444,48 @@ static void mlx5_sync_reset_request_event(struct work_struct *work)
+       struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
+                                                     reset_request_work);
+       struct mlx5_core_dev *dev = fw_reset->dev;
++      bool nack_request = false;
++      struct devlink *devlink;
+       int err;
+       err = mlx5_fw_reset_get_reset_method(dev, &fw_reset->reset_method);
+-      if (err)
++      if (err) {
++              nack_request = true;
+               mlx5_core_warn(dev, "Failed reading MFRL, err %d\n", err);
++      } else if (!mlx5_is_reset_now_capable(dev, fw_reset->reset_method) ||
++                 test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
++                          &fw_reset->reset_flags)) {
++              nack_request = true;
++      }
+-      if (err || test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) ||
+-          !mlx5_is_reset_now_capable(dev, fw_reset->reset_method)) {
++      devlink = priv_to_devlink(dev);
++      /* For external resets, try to acquire devl_lock. Skip if devlink reset is
++       * pending (lock already held)
++       */
++      if (nack_request ||
++          (!test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP,
++                     &fw_reset->reset_flags) &&
++           !devl_trylock(devlink))) {
+               err = mlx5_fw_reset_set_reset_sync_nack(dev);
+               mlx5_core_warn(dev, "PCI Sync FW Update Reset Nack %s",
+                              err ? "Failed" : "Sent");
+               return;
+       }
++
+       if (mlx5_sync_reset_set_reset_requested(dev))
+-              return;
++              goto unlock;
++
++      set_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
+       err = mlx5_fw_reset_set_reset_sync_ack(dev);
+       if (err)
+               mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack Failed. Error code: %d\n", err);
+       else
+               mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack. Device reset is expected.\n");
++
++unlock:
++      if (!test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags))
++              devl_unlock(devlink);
+ }
+ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev, u16 dev_id)
+@@ -685,6 +719,8 @@ static void mlx5_sync_reset_abort_event(struct work_struct *work)
+       if (mlx5_sync_reset_clear_reset_requested(dev, true))
+               return;
++
++      clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
+       mlx5_core_warn(dev, "PCI Sync FW Update Reset Aborted.\n");
+ }
+@@ -721,6 +757,7 @@ static void mlx5_sync_reset_timeout_work(struct work_struct *work)
+       if (mlx5_sync_reset_clear_reset_requested(dev, true))
+               return;
++      clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
+       mlx5_core_warn(dev, "PCI Sync FW Update Reset Timeout.\n");
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+index d5b28525c960d..2d96b2adc1cdf 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+@@ -10,6 +10,7 @@ int mlx5_fw_reset_query(struct mlx5_core_dev *dev, u8 *reset_level, u8 *reset_ty
+ int mlx5_fw_reset_set_reset_sync(struct mlx5_core_dev *dev, u8 reset_type_sel,
+                                struct netlink_ext_ack *extack);
+ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev);
++bool mlx5_fw_reset_in_progress(struct mlx5_core_dev *dev);
+ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev);
+ void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked);
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-mlx5-skip-hotplug-check-on-sync-reset-using-hot-.patch b/queue-6.6/net-mlx5-skip-hotplug-check-on-sync-reset-using-hot-.patch
new file mode 100644 (file)
index 0000000..8da02b3
--- /dev/null
@@ -0,0 +1,66 @@
+From 42f3b9e01942489cc0ef6e55403aaaf1c225a77d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Sep 2024 13:17:53 -0700
+Subject: net/mlx5: Skip HotPlug check on sync reset using hot reset
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 48bb52b0bc6693afb17a6024bab925b25fec44a1 ]
+
+Sync reset request is nacked by the driver when PCIe bridge connected to
+mlx5 device has HotPlug interrupt enabled. However, when using reset
+method of hot reset this check can be skipped as Hotplug is supported on
+this reset method.
+
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20240911201757.1505453-12-saeed@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 367e501f8b09 ("net/mlx5: Serialize firmware reset with devlink")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index dc7afc9e7777d..bdcd9e5306331 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -396,7 +396,8 @@ static int mlx5_check_dev_ids(struct mlx5_core_dev *dev, u16 dev_id)
+       return 0;
+ }
+-static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev)
++static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev,
++                                    u8 reset_method)
+ {
+       u16 dev_id;
+       int err;
+@@ -412,9 +413,11 @@ static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev)
+       }
+ #if IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)
+-      err = mlx5_check_hotplug_interrupt(dev);
+-      if (err)
+-              return false;
++      if (reset_method != MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET) {
++              err = mlx5_check_hotplug_interrupt(dev);
++              if (err)
++                      return false;
++      }
+ #endif
+       err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &dev_id);
+@@ -435,7 +438,7 @@ static void mlx5_sync_reset_request_event(struct work_struct *work)
+               mlx5_core_warn(dev, "Failed reading MFRL, err %d\n", err);
+       if (err || test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) ||
+-          !mlx5_is_reset_now_capable(dev)) {
++          !mlx5_is_reset_now_capable(dev, fw_reset->reset_method)) {
+               err = mlx5_fw_reset_set_reset_sync_nack(dev);
+               mlx5_core_warn(dev, "PCI Sync FW Update Reset Nack %s",
+                              err ? "Failed" : "Sent");
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-openvswitch-fix-middle-attribute-validation-in-p.patch b/queue-6.6/net-openvswitch-fix-middle-attribute-validation-in-p.patch
new file mode 100644 (file)
index 0000000..e345274
--- /dev/null
@@ -0,0 +1,112 @@
+From c9981f012de41c84613e083f1b75433cecf005b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Dec 2025 11:53:32 +0100
+Subject: net: openvswitch: fix middle attribute validation in push_nsh()
+ action
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 5ace7ef87f059d68b5f50837ef3e8a1a4870c36e ]
+
+The push_nsh() action structure looks like this:
+
+ OVS_ACTION_ATTR_PUSH_NSH(OVS_KEY_ATTR_NSH(OVS_NSH_KEY_ATTR_BASE,...))
+
+The outermost OVS_ACTION_ATTR_PUSH_NSH attribute is OK'ed by the
+nla_for_each_nested() inside __ovs_nla_copy_actions().  The innermost
+OVS_NSH_KEY_ATTR_BASE/MD1/MD2 are OK'ed by the nla_for_each_nested()
+inside nsh_key_put_from_nlattr().  But nothing checks if the attribute
+in the middle is OK.  We don't even check that this attribute is the
+OVS_KEY_ATTR_NSH.  We just do a double unwrap with a pair of nla_data()
+calls - first time directly while calling validate_push_nsh() and the
+second time as part of the nla_for_each_nested() macro, which isn't
+safe, potentially causing invalid memory access if the size of this
+attribute is incorrect.  The failure may not be noticed during
+validation due to larger netlink buffer, but cause trouble later during
+action execution where the buffer is allocated exactly to the size:
+
+ BUG: KASAN: slab-out-of-bounds in nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch]
+ Read of size 184 at addr ffff88816459a634 by task a.out/22624
+
+ CPU: 8 UID: 0 PID: 22624 6.18.0-rc7+ #115 PREEMPT(voluntary)
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x51/0x70
+  print_address_description.constprop.0+0x2c/0x390
+  kasan_report+0xdd/0x110
+  kasan_check_range+0x35/0x1b0
+  __asan_memcpy+0x20/0x60
+  nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch]
+  push_nsh+0x82/0x120 [openvswitch]
+  do_execute_actions+0x1405/0x2840 [openvswitch]
+  ovs_execute_actions+0xd5/0x3b0 [openvswitch]
+  ovs_packet_cmd_execute+0x949/0xdb0 [openvswitch]
+  genl_family_rcv_msg_doit+0x1d6/0x2b0
+  genl_family_rcv_msg+0x336/0x580
+  genl_rcv_msg+0x9f/0x130
+  netlink_rcv_skb+0x11f/0x370
+  genl_rcv+0x24/0x40
+  netlink_unicast+0x73e/0xaa0
+  netlink_sendmsg+0x744/0xbf0
+  __sys_sendto+0x3d6/0x450
+  do_syscall_64+0x79/0x2c0
+  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+  </TASK>
+
+Let's add some checks that the attribute is properly sized and it's
+the only one attribute inside the action.  Technically, there is no
+real reason for OVS_KEY_ATTR_NSH to be there, as we know that we're
+pushing an NSH header already, it just creates extra nesting, but
+that's how uAPI works today.  So, keeping as it is.
+
+Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support")
+Reported-by: Junvy Yang <zhuque@tencent.com>
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Eelco Chaudron echaudro@redhat.com
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Link: https://patch.msgid.link/20251204105334.900379-1-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/flow_netlink.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
+index 836e8e705d40e..1d9a44d6216af 100644
+--- a/net/openvswitch/flow_netlink.c
++++ b/net/openvswitch/flow_netlink.c
+@@ -2788,13 +2788,20 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
+       return err;
+ }
+-static bool validate_push_nsh(const struct nlattr *attr, bool log)
++static bool validate_push_nsh(const struct nlattr *a, bool log)
+ {
++      struct nlattr *nsh_key = nla_data(a);
+       struct sw_flow_match match;
+       struct sw_flow_key key;
++      /* There must be one and only one NSH header. */
++      if (!nla_ok(nsh_key, nla_len(a)) ||
++          nla_total_size(nla_len(nsh_key)) != nla_len(a) ||
++          nla_type(nsh_key) != OVS_KEY_ATTR_NSH)
++              return false;
++
+       ovs_match_init(&match, &key, true, NULL);
+-      return !nsh_key_put_from_nlattr(attr, &match, false, true, log);
++      return !nsh_key_put_from_nlattr(nsh_key, &match, false, true, log);
+ }
+ /* Return false if there are any non-masked bits set.
+@@ -3351,7 +3358,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
+                                       return -EINVAL;
+                       }
+                       mac_proto = MAC_PROTO_NONE;
+-                      if (!validate_push_nsh(nla_data(a), log))
++                      if (!validate_push_nsh(a, log))
+                               return -EINVAL;
+                       break;
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-sched-ets-always-remove-class-from-active-list-b.patch b/queue-6.6/net-sched-ets-always-remove-class-from-active-list-b.patch
new file mode 100644 (file)
index 0000000..41a0884
--- /dev/null
@@ -0,0 +1,232 @@
+From 6aca0bb3b30b4dc25e167985cc52c450a3deefcb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Nov 2025 10:19:19 -0500
+Subject: net/sched: ets: Always remove class from active list before deleting
+ in ets_qdisc_change
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit ce052b9402e461a9aded599f5b47e76bc727f7de ]
+
+zdi-disclosures@trendmicro.com says:
+
+The vulnerability is a race condition between `ets_qdisc_dequeue` and
+`ets_qdisc_change`.  It leads to UAF on `struct Qdisc` object.
+Attacker requires the capability to create new user and network namespace
+in order to trigger the bug.
+See my additional commentary at the end of the analysis.
+
+Analysis:
+
+static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+                          struct netlink_ext_ack *extack)
+{
+...
+
+      // (1) this lock is preventing .change handler (`ets_qdisc_change`)
+      //to race with .dequeue handler (`ets_qdisc_dequeue`)
+      sch_tree_lock(sch);
+
+      for (i = nbands; i < oldbands; i++) {
+              if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
+                      list_del_init(&q->classes[i].alist);
+              qdisc_purge_queue(q->classes[i].qdisc);
+      }
+
+      WRITE_ONCE(q->nbands, nbands);
+      for (i = nstrict; i < q->nstrict; i++) {
+              if (q->classes[i].qdisc->q.qlen) {
+                     // (2) the class is added to the q->active
+                      list_add_tail(&q->classes[i].alist, &q->active);
+                      q->classes[i].deficit = quanta[i];
+              }
+      }
+      WRITE_ONCE(q->nstrict, nstrict);
+      memcpy(q->prio2band, priomap, sizeof(priomap));
+
+      for (i = 0; i < q->nbands; i++)
+              WRITE_ONCE(q->classes[i].quantum, quanta[i]);
+
+      for (i = oldbands; i < q->nbands; i++) {
+              q->classes[i].qdisc = queues[i];
+              if (q->classes[i].qdisc != &noop_qdisc)
+                      qdisc_hash_add(q->classes[i].qdisc, true);
+      }
+
+      // (3) the qdisc is unlocked, now dequeue can be called in parallel
+      // to the rest of .change handler
+      sch_tree_unlock(sch);
+
+      ets_offload_change(sch);
+      for (i = q->nbands; i < oldbands; i++) {
+             // (4) we're reducing the refcount for our class's qdisc and
+             //  freeing it
+              qdisc_put(q->classes[i].qdisc);
+             // (5) If we call .dequeue between (4) and (5), we will have
+             // a strong UAF and we can control RIP
+              q->classes[i].qdisc = NULL;
+              WRITE_ONCE(q->classes[i].quantum, 0);
+              q->classes[i].deficit = 0;
+              gnet_stats_basic_sync_init(&q->classes[i].bstats);
+              memset(&q->classes[i].qstats, 0, sizeof(q->classes[i].qstats));
+      }
+      return 0;
+}
+
+Comment:
+This happens because some of the classes have their qdiscs assigned to
+NULL, but remain in the active list. This commit fixes this issue by always
+removing the class from the active list before deleting and freeing its
+associated qdisc
+
+Reproducer Steps
+(trimmed version of what was sent by zdi-disclosures@trendmicro.com)
+
+```
+DEV="${DEV:-lo}"
+ROOT_HANDLE="${ROOT_HANDLE:-1:}"
+BAND2_HANDLE="${BAND2_HANDLE:-20:}"   # child under 1:2
+PING_BYTES="${PING_BYTES:-48}"
+PING_COUNT="${PING_COUNT:-200000}"
+PING_DST="${PING_DST:-127.0.0.1}"
+
+SLOW_TBF_RATE="${SLOW_TBF_RATE:-8bit}"
+SLOW_TBF_BURST="${SLOW_TBF_BURST:-100b}"
+SLOW_TBF_LAT="${SLOW_TBF_LAT:-1s}"
+
+cleanup() {
+  tc qdisc del dev "$DEV" root 2>/dev/null
+}
+trap cleanup EXIT
+
+ip link set "$DEV" up
+
+tc qdisc del dev "$DEV" root 2>/dev/null || true
+
+tc qdisc add dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
+
+tc qdisc add dev "$DEV" parent 1:2 handle "$BAND2_HANDLE" \
+  tbf rate "$SLOW_TBF_RATE" burst "$SLOW_TBF_BURST" latency "$SLOW_TBF_LAT"
+
+tc filter add dev "$DEV" parent 1: protocol all prio 1 u32 match u32 0 0 flowid 1:2
+tc -s qdisc ls dev $DEV
+
+ping -I "$DEV" -f -c "$PING_COUNT" -s "$PING_BYTES" -W 0.001 "$PING_DST" \
+  >/dev/null 2>&1 &
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 0
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
+tc -s qdisc ls dev $DEV
+tc qdisc del dev "$DEV" parent 1:2 || true
+tc -s qdisc ls dev $DEV
+tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 1 strict 1
+```
+
+KASAN report
+```
+==================================================================
+BUG: KASAN: slab-use-after-free in ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
+Read of size 8 at addr ffff8880502fc018 by task ping/12308
+>
+CPU: 0 UID: 0 PID: 12308 Comm: ping Not tainted 6.18.0-rc4-dirty #1 PREEMPT(full)
+Hardware name: QEMU Ubuntu 25.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <IRQ>
+ __dump_stack kernel/lib/dump_stack.c:94
+ dump_stack_lvl+0x100/0x190 kernel/lib/dump_stack.c:120
+ print_address_description kernel/mm/kasan/report.c:378
+ print_report+0x156/0x4c9 kernel/mm/kasan/report.c:482
+ kasan_report+0xdf/0x110 kernel/mm/kasan/report.c:595
+ ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481
+ dequeue_skb kernel/net/sched/sch_generic.c:294
+ qdisc_restart kernel/net/sched/sch_generic.c:399
+ __qdisc_run+0x1c9/0x1b00 kernel/net/sched/sch_generic.c:417
+ __dev_xmit_skb kernel/net/core/dev.c:4221
+ __dev_queue_xmit+0x2848/0x4410 kernel/net/core/dev.c:4729
+ dev_queue_xmit kernel/./include/linux/netdevice.h:3365
+[...]
+
+Allocated by task 17115:
+ kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
+ kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
+ poison_kmalloc_redzone kernel/mm/kasan/common.c:400
+ __kasan_kmalloc+0xaa/0xb0 kernel/mm/kasan/common.c:417
+ kasan_kmalloc kernel/./include/linux/kasan.h:262
+ __do_kmalloc_node kernel/mm/slub.c:5642
+ __kmalloc_node_noprof+0x34e/0x990 kernel/mm/slub.c:5648
+ kmalloc_node_noprof kernel/./include/linux/slab.h:987
+ qdisc_alloc+0xb8/0xc30 kernel/net/sched/sch_generic.c:950
+ qdisc_create_dflt+0x93/0x490 kernel/net/sched/sch_generic.c:1012
+ ets_class_graft+0x4fd/0x800 kernel/net/sched/sch_ets.c:261
+ qdisc_graft+0x3e4/0x1780 kernel/net/sched/sch_api.c:1196
+[...]
+
+Freed by task 9905:
+ kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56
+ kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77
+ __kasan_save_free_info+0x3b/0x70 kernel/mm/kasan/generic.c:587
+ kasan_save_free_info kernel/mm/kasan/kasan.h:406
+ poison_slab_object kernel/mm/kasan/common.c:252
+ __kasan_slab_free+0x5f/0x80 kernel/mm/kasan/common.c:284
+ kasan_slab_free kernel/./include/linux/kasan.h:234
+ slab_free_hook kernel/mm/slub.c:2539
+ slab_free kernel/mm/slub.c:6630
+ kfree+0x144/0x700 kernel/mm/slub.c:6837
+ rcu_do_batch kernel/kernel/rcu/tree.c:2605
+ rcu_core+0x7c0/0x1500 kernel/kernel/rcu/tree.c:2861
+ handle_softirqs+0x1ea/0x8a0 kernel/kernel/softirq.c:622
+ __do_softirq kernel/kernel/softirq.c:656
+[...]
+
+Commentary:
+
+1. Maher Azzouzi working with Trend Micro Zero Day Initiative was reported as
+the person who found the issue. I requested to get a proper email to add to the
+reported-by tag but got no response. For this reason i will credit the person
+i exchanged emails with i.e zdi-disclosures@trendmicro.com
+
+2. Neither i nor Victor who did a much more thorough testing was able to
+reproduce a UAF with the PoC or other approaches we tried. We were both able to
+reproduce a null ptr deref. After exchange with zdi-disclosures@trendmicro.com
+they sent a small change to be made to the code to add an extra delay which
+was able to simulate the UAF. i.e, this:
+   qdisc_put(q->classes[i].qdisc);
+   mdelay(90);
+   q->classes[i].qdisc = NULL;
+
+I was informed by Thomas Gleixner(tglx@linutronix.de) that adding delays was
+acceptable approach for demonstrating the bug, quote:
+"Adding such delays is common exploit validation practice"
+The equivalent delay could happen "by virt scheduling the vCPU out, SMIs,
+NMIs, PREEMPT_RT enabled kernel"
+
+3. I asked the OP to test and report back but got no response and after a
+few days gave up and proceeded to submit this fix.
+
+Fixes: de6d25924c2a ("net/sched: sch_ets: don't peek at classes beyond 'nbands'")
+Reported-by: zdi-disclosures@trendmicro.com
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20251128151919.576920-1-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_ets.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index 9873f4ae90c3a..b732d09ede99a 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -652,7 +652,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+       sch_tree_lock(sch);
+       for (i = nbands; i < oldbands; i++) {
+-              if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
++              if (cl_is_active(&q->classes[i]))
+                       list_del_init(&q->classes[i].alist);
+               qdisc_purge_queue(q->classes[i].qdisc);
+       }
+-- 
+2.51.0
+
diff --git a/queue-6.6/net-sched-ets-remove-drr-class-from-the-active-list-.patch b/queue-6.6/net-sched-ets-remove-drr-class-from-the-active-list-.patch
new file mode 100644 (file)
index 0000000..92568b6
--- /dev/null
@@ -0,0 +1,88 @@
+From bce07d0ec8482466a34c10b295df2d33b899e639 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 16:01:24 -0300
+Subject: net/sched: ets: Remove drr class from the active list if it changes
+ to strict
+
+From: Victor Nogueira <victor@mojatatu.com>
+
+[ Upstream commit b1e125ae425aba9b45252e933ca8df52a843ec70 ]
+
+Whenever a user issues an ets qdisc change command, transforming a
+drr class into a strict one, the ets code isn't checking whether that
+class was in the active list and removing it. This means that, if a
+user changes a strict class (which was in the active list) back to a drr
+one, that class will be added twice to the active list [1].
+
+Doing so with the following commands:
+
+tc qdisc add dev lo root handle 1: ets bands 2 strict 1
+tc qdisc add dev lo parent 1:2 handle 20: \
+    tbf rate 8bit burst 100b latency 1s
+tc filter add dev lo parent 1: basic classid 1:2
+ping -c1 -W0.01 -s 56 127.0.0.1
+tc qdisc change dev lo root handle 1: ets bands 2 strict 2
+tc qdisc change dev lo root handle 1: ets bands 2 strict 1
+ping -c1 -W0.01 -s 56 127.0.0.1
+
+Will trigger the following splat with list debug turned on:
+
+[   59.279014][  T365] ------------[ cut here ]------------
+[   59.279452][  T365] list_add double add: new=ffff88801d60e350, prev=ffff88801d60e350, next=ffff88801d60e2c0.
+[   59.280153][  T365] WARNING: CPU: 3 PID: 365 at lib/list_debug.c:35 __list_add_valid_or_report+0x17f/0x220
+[   59.280860][  T365] Modules linked in:
+[   59.281165][  T365] CPU: 3 UID: 0 PID: 365 Comm: tc Not tainted 6.18.0-rc7-00105-g7e9f13163c13-dirty #239 PREEMPT(voluntary)
+[   59.281977][  T365] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+[   59.282391][  T365] RIP: 0010:__list_add_valid_or_report+0x17f/0x220
+[   59.282842][  T365] Code: 89 c6 e8 d4 b7 0d ff 90 0f 0b 90 90 31 c0 e9 31 ff ff ff 90 48 c7 c7 e0 a0 22 9f 48 89 f2 48 89 c1 4c 89 c6 e8 b2 b7 0d ff 90 <0f> 0b 90 90 31 c0 e9 0f ff ff ff 48 89 f7 48 89 44 24 10 4c 89 44
+...
+[   59.288812][  T365] Call Trace:
+[   59.289056][  T365]  <TASK>
+[   59.289224][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.289546][  T365]  ets_qdisc_change+0xd2b/0x1e80
+[   59.289891][  T365]  ? __lock_acquire+0x7e7/0x1be0
+[   59.290223][  T365]  ? __pfx_ets_qdisc_change+0x10/0x10
+[   59.290546][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.290898][  T365]  ? __mutex_trylock_common+0xda/0x240
+[   59.291228][  T365]  ? __pfx___mutex_trylock_common+0x10/0x10
+[   59.291655][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.291993][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.292313][  T365]  ? trace_contention_end+0xc8/0x110
+[   59.292656][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.293022][  T365]  ? srso_alias_return_thunk+0x5/0xfbef5
+[   59.293351][  T365]  tc_modify_qdisc+0x63a/0x1cf0
+
+Fix this by always checking and removing an ets class from the active list
+when changing it to strict.
+
+[1] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/tree/net/sched/sch_ets.c?id=ce052b9402e461a9aded599f5b47e76bc727f7de#n663
+
+Fixes: cd9b50adc6bb9 ("net/sched: ets: fix crash when flipping from 'strict' to 'quantum'")
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/20251208190125.1868423-1-victor@mojatatu.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_ets.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index b732d09ede99a..6ff619277ffd9 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -664,6 +664,10 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
+                       q->classes[i].deficit = quanta[i];
+               }
+       }
++      for (i = q->nstrict; i < nstrict; i++) {
++              if (cl_is_active(&q->classes[i]))
++                      list_del_init(&q->classes[i].alist);
++      }
+       WRITE_ONCE(q->nstrict, nstrict);
+       memcpy(q->prio2band, priomap, sizeof(priomap));
+-- 
+2.51.0
+
diff --git a/queue-6.6/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch b/queue-6.6/netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch
new file mode 100644 (file)
index 0000000..2688d87
--- /dev/null
@@ -0,0 +1,90 @@
+From 6e22db53c5f7fb68cb62355a0a747ed56d86ebf7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Dec 2025 12:58:01 +0100
+Subject: netfilter: nf_conncount: fix leaked ct in error paths
+
+From: Fernando Fernandez Mancera <fmancera@suse.de>
+
+[ Upstream commit 2e2a720766886190a6d35c116794693aabd332b6 ]
+
+There are some situations where ct might be leaked as error paths are
+skipping the refcounted check and return immediately. In order to solve
+it make sure that the check is always called.
+
+Fixes: be102eb6a0e7 ("netfilter: nf_conncount: rework API to use sk_buff directly")
+Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conncount.c | 25 ++++++++++++++-----------
+ 1 file changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
+index 97b631a81484d..c00b8e522c5a7 100644
+--- a/net/netfilter/nf_conncount.c
++++ b/net/netfilter/nf_conncount.c
+@@ -172,14 +172,14 @@ static int __nf_conncount_add(struct net *net,
+       struct nf_conn *found_ct;
+       unsigned int collect = 0;
+       bool refcounted = false;
++      int err = 0;
+       if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted))
+               return -ENOENT;
+       if (ct && nf_ct_is_confirmed(ct)) {
+-              if (refcounted)
+-                      nf_ct_put(ct);
+-              return -EEXIST;
++              err = -EEXIST;
++              goto out_put;
+       }
+       if ((u32)jiffies == list->last_gc)
+@@ -231,12 +231,16 @@ static int __nf_conncount_add(struct net *net,
+       }
+ add_new_node:
+-      if (WARN_ON_ONCE(list->count > INT_MAX))
+-              return -EOVERFLOW;
++      if (WARN_ON_ONCE(list->count > INT_MAX)) {
++              err = -EOVERFLOW;
++              goto out_put;
++      }
+       conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC);
+-      if (conn == NULL)
+-              return -ENOMEM;
++      if (conn == NULL) {
++              err = -ENOMEM;
++              goto out_put;
++      }
+       conn->tuple = tuple;
+       conn->zone = *zone;
+@@ -249,7 +253,7 @@ static int __nf_conncount_add(struct net *net,
+ out_put:
+       if (refcounted)
+               nf_ct_put(ct);
+-      return 0;
++      return err;
+ }
+ int nf_conncount_add_skb(struct net *net,
+@@ -446,11 +450,10 @@ insert_tree(struct net *net,
+               rb_link_node_rcu(&rbconn->node, parent, rbnode);
+               rb_insert_color(&rbconn->node, root);
+-
+-              if (refcounted)
+-                      nf_ct_put(ct);
+       }
+ out_unlock:
++      if (refcounted)
++              nf_ct_put(ct);
+       spin_unlock_bh(&nf_conncount_locks[hash]);
+       return count;
+ }
+-- 
+2.51.0
+
diff --git a/queue-6.6/netfilter-nf_tables-allow-loads-only-when-register-i.patch b/queue-6.6/netfilter-nf_tables-allow-loads-only-when-register-i.patch
new file mode 100644 (file)
index 0000000..e7a2d98
--- /dev/null
@@ -0,0 +1,152 @@
+From d2a666a73d84b8ee921a648cdfc7c5b3ffe4bde1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Aug 2024 11:56:13 +0200
+Subject: netfilter: nf_tables: allow loads only when register is initialized
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 14fb07130c7ddd257e30079b87499b3f89097b09 ]
+
+Reject rules where a load occurs from a register that has not seen a store
+early in the same rule.
+
+commit 4c905f6740a3 ("netfilter: nf_tables: initialize registers in
+nft_do_chain()")
+had to add a unconditional memset to the nftables register space to avoid
+leaking stack information to userspace.
+
+This memset shows up in benchmarks.  After this change, this commit can
+be reverted again.
+
+Note that this breaks userspace compatibility, because theoretically
+you can do
+
+  rule 1: reg2 := meta load iif, reg2  == 1 jump ...
+  rule 2: reg2 == 2 jump ...   // read access with no store in this rule
+
+... after this change this is rejected.
+
+Neither nftables nor iptables-nft generate such rules, each rule is
+always standalone.
+
+This resuts in a small increase of nft_ctx structure by sizeof(long).
+
+To cope with hypothetical rulesets like the example above one could emit
+on-demand "reg[x] = 0" store when generating the datapath blob in
+nf_tables_commit_chain_prepare().
+
+A patch that does this is linked to below.
+
+For now, lets disable this.  In nf_tables, a rule is the smallest
+unit that can be replaced from userspace, i.e. a hypothetical ruleset
+that relies on earlier initialisations of registers can't be changed
+at will as register usage would need to be coordinated.
+
+Link: https://lore.kernel.org/netfilter-devel/20240627135330.17039-4-fw@strlen.de/
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: a67fd55f6a09 ("netfilter: nf_tables: remove redundant chain validation on register store")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netfilter/nf_tables.h |  1 +
+ net/netfilter/nf_tables_api.c     | 38 +++++++++++++++++++++++++++----
+ 2 files changed, 35 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index 917edb4380e58..a8fcbdb37a7f9 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -221,6 +221,7 @@ struct nft_ctx {
+       u8                              family;
+       u8                              level;
+       bool                            report;
++      DECLARE_BITMAP(reg_inited, NFT_REG32_NUM);
+ };
+ enum nft_data_desc_flags {
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 7bccfb1a8a725..8b8895e4372d9 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -146,6 +146,8 @@ static void nft_ctx_init(struct nft_ctx *ctx,
+       ctx->report     = nlmsg_report(nlh);
+       ctx->flags      = nlh->nlmsg_flags;
+       ctx->seq        = nlh->nlmsg_seq;
++
++      bitmap_zero(ctx->reg_inited, NFT_REG32_NUM);
+ }
+ static struct nft_trans *nft_trans_alloc_gfp(const struct nft_ctx *ctx,
+@@ -10915,8 +10917,8 @@ static int nft_validate_register_load(enum nft_registers reg, unsigned int len)
+ int nft_parse_register_load(const struct nft_ctx *ctx,
+                           const struct nlattr *attr, u8 *sreg, u32 len)
+ {
+-      u32 reg;
+-      int err;
++      int err, invalid_reg;
++      u32 reg, next_register;
+       err = nft_parse_register(attr, &reg);
+       if (err < 0)
+@@ -10926,11 +10928,36 @@ int nft_parse_register_load(const struct nft_ctx *ctx,
+       if (err < 0)
+               return err;
++      next_register = DIV_ROUND_UP(len, NFT_REG32_SIZE) + reg;
++
++      /* Can't happen: nft_validate_register_load() should have failed */
++      if (WARN_ON_ONCE(next_register > NFT_REG32_NUM))
++              return -EINVAL;
++
++      /* find first register that did not see an earlier store. */
++      invalid_reg = find_next_zero_bit(ctx->reg_inited, NFT_REG32_NUM, reg);
++
++      /* invalid register within the range that we're loading from? */
++      if (invalid_reg < next_register)
++              return -ENODATA;
++
+       *sreg = reg;
+       return 0;
+ }
+ EXPORT_SYMBOL_GPL(nft_parse_register_load);
++static void nft_saw_register_store(const struct nft_ctx *__ctx,
++                                 int reg, unsigned int len)
++{
++      unsigned int registers = DIV_ROUND_UP(len, NFT_REG32_SIZE);
++      struct nft_ctx *ctx = (struct nft_ctx *)__ctx;
++
++      if (WARN_ON_ONCE(len == 0 || reg < 0))
++              return;
++
++      bitmap_set(ctx->reg_inited, reg, registers);
++}
++
+ static int nft_validate_register_store(const struct nft_ctx *ctx,
+                                      enum nft_registers reg,
+                                      const struct nft_data *data,
+@@ -10952,7 +10979,7 @@ static int nft_validate_register_store(const struct nft_ctx *ctx,
+                               return err;
+               }
+-              return 0;
++              break;
+       default:
+               if (type != NFT_DATA_VALUE)
+                       return -EINVAL;
+@@ -10965,8 +10992,11 @@ static int nft_validate_register_store(const struct nft_ctx *ctx,
+                   sizeof_field(struct nft_regs, data))
+                       return -ERANGE;
+-              return 0;
++              break;
+       }
++
++      nft_saw_register_store(ctx, reg, len);
++      return 0;
+ }
+ int nft_parse_register_store(const struct nft_ctx *ctx,
+-- 
+2.51.0
+
diff --git a/queue-6.6/netfilter-nf_tables-pass-context-structure-to-nft_pa.patch b/queue-6.6/netfilter-nf_tables-pass-context-structure-to-nft_pa.patch
new file mode 100644 (file)
index 0000000..e281183
--- /dev/null
@@ -0,0 +1,470 @@
+From ab7faf5a67d1bc3f4761a53f5b89267655188c96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Aug 2024 11:56:12 +0200
+Subject: netfilter: nf_tables: pass context structure to
+ nft_parse_register_load
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 7ea0522ef81a335c2d3a0ab1c8a4fab9a23c4a03 ]
+
+Mechanical transformation, no logical changes intended.
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: a67fd55f6a09 ("netfilter: nf_tables: remove redundant chain validation on register store")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netfilter/nf_tables.h      | 3 ++-
+ net/bridge/netfilter/nft_meta_bridge.c | 2 +-
+ net/ipv4/netfilter/nft_dup_ipv4.c      | 4 ++--
+ net/ipv6/netfilter/nft_dup_ipv6.c      | 4 ++--
+ net/netfilter/nf_tables_api.c          | 3 ++-
+ net/netfilter/nft_bitwise.c            | 4 ++--
+ net/netfilter/nft_byteorder.c          | 2 +-
+ net/netfilter/nft_cmp.c                | 6 +++---
+ net/netfilter/nft_ct.c                 | 2 +-
+ net/netfilter/nft_dup_netdev.c         | 2 +-
+ net/netfilter/nft_dynset.c             | 4 ++--
+ net/netfilter/nft_exthdr.c             | 2 +-
+ net/netfilter/nft_fwd_netdev.c         | 6 +++---
+ net/netfilter/nft_hash.c               | 2 +-
+ net/netfilter/nft_lookup.c             | 2 +-
+ net/netfilter/nft_masq.c               | 4 ++--
+ net/netfilter/nft_meta.c               | 2 +-
+ net/netfilter/nft_nat.c                | 8 ++++----
+ net/netfilter/nft_objref.c             | 2 +-
+ net/netfilter/nft_payload.c            | 2 +-
+ net/netfilter/nft_queue.c              | 2 +-
+ net/netfilter/nft_range.c              | 2 +-
+ net/netfilter/nft_redir.c              | 4 ++--
+ net/netfilter/nft_tproxy.c             | 4 ++--
+ 24 files changed, 40 insertions(+), 38 deletions(-)
+
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index 32606d5430605..917edb4380e58 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -254,7 +254,8 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
+ int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest);
+ int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg);
+-int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
++int nft_parse_register_load(const struct nft_ctx *ctx,
++                          const struct nlattr *attr, u8 *sreg, u32 len);
+ int nft_parse_register_store(const struct nft_ctx *ctx,
+                            const struct nlattr *attr, u8 *dreg,
+                            const struct nft_data *data,
+diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
+index affb740c8685e..d12a221366d60 100644
+--- a/net/bridge/netfilter/nft_meta_bridge.c
++++ b/net/bridge/netfilter/nft_meta_bridge.c
+@@ -142,7 +142,7 @@ static int nft_meta_bridge_set_init(const struct nft_ctx *ctx,
+       }
+       priv->len = len;
+-      err = nft_parse_register_load(tb[NFTA_META_SREG], &priv->sreg, len);
++      err = nft_parse_register_load(ctx, tb[NFTA_META_SREG], &priv->sreg, len);
+       if (err < 0)
+               return err;
+diff --git a/net/ipv4/netfilter/nft_dup_ipv4.c b/net/ipv4/netfilter/nft_dup_ipv4.c
+index a522c3a3be523..ef5dd88107ddb 100644
+--- a/net/ipv4/netfilter/nft_dup_ipv4.c
++++ b/net/ipv4/netfilter/nft_dup_ipv4.c
+@@ -40,13 +40,13 @@ static int nft_dup_ipv4_init(const struct nft_ctx *ctx,
+       if (tb[NFTA_DUP_SREG_ADDR] == NULL)
+               return -EINVAL;
+-      err = nft_parse_register_load(tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr,
++      err = nft_parse_register_load(ctx, tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr,
+                                     sizeof(struct in_addr));
+       if (err < 0)
+               return err;
+       if (tb[NFTA_DUP_SREG_DEV])
+-              err = nft_parse_register_load(tb[NFTA_DUP_SREG_DEV],
++              err = nft_parse_register_load(ctx, tb[NFTA_DUP_SREG_DEV],
+                                             &priv->sreg_dev, sizeof(int));
+       return err;
+diff --git a/net/ipv6/netfilter/nft_dup_ipv6.c b/net/ipv6/netfilter/nft_dup_ipv6.c
+index c82f3fdd4a65d..492a811828a71 100644
+--- a/net/ipv6/netfilter/nft_dup_ipv6.c
++++ b/net/ipv6/netfilter/nft_dup_ipv6.c
+@@ -38,13 +38,13 @@ static int nft_dup_ipv6_init(const struct nft_ctx *ctx,
+       if (tb[NFTA_DUP_SREG_ADDR] == NULL)
+               return -EINVAL;
+-      err = nft_parse_register_load(tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr,
++      err = nft_parse_register_load(ctx, tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr,
+                                     sizeof(struct in6_addr));
+       if (err < 0)
+               return err;
+       if (tb[NFTA_DUP_SREG_DEV])
+-              err = nft_parse_register_load(tb[NFTA_DUP_SREG_DEV],
++              err = nft_parse_register_load(ctx, tb[NFTA_DUP_SREG_DEV],
+                                             &priv->sreg_dev, sizeof(int));
+       return err;
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 80443b4eaeff0..7bccfb1a8a725 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -10912,7 +10912,8 @@ static int nft_validate_register_load(enum nft_registers reg, unsigned int len)
+       return 0;
+ }
+-int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len)
++int nft_parse_register_load(const struct nft_ctx *ctx,
++                          const struct nlattr *attr, u8 *sreg, u32 len)
+ {
+       u32 reg;
+       int err;
+diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
+index ca857afbf0616..7de95674fd8c4 100644
+--- a/net/netfilter/nft_bitwise.c
++++ b/net/netfilter/nft_bitwise.c
+@@ -171,7 +171,7 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
+       priv->len = len;
+-      err = nft_parse_register_load(tb[NFTA_BITWISE_SREG], &priv->sreg,
++      err = nft_parse_register_load(ctx, tb[NFTA_BITWISE_SREG], &priv->sreg,
+                                     priv->len);
+       if (err < 0)
+               return err;
+@@ -365,7 +365,7 @@ static int nft_bitwise_fast_init(const struct nft_ctx *ctx,
+       struct nft_bitwise_fast_expr *priv = nft_expr_priv(expr);
+       int err;
+-      err = nft_parse_register_load(tb[NFTA_BITWISE_SREG], &priv->sreg,
++      err = nft_parse_register_load(ctx, tb[NFTA_BITWISE_SREG], &priv->sreg,
+                                     sizeof(u32));
+       if (err < 0)
+               return err;
+diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
+index f6e791a681015..2f82a444d21bf 100644
+--- a/net/netfilter/nft_byteorder.c
++++ b/net/netfilter/nft_byteorder.c
+@@ -139,7 +139,7 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
+       priv->len = len;
+-      err = nft_parse_register_load(tb[NFTA_BYTEORDER_SREG], &priv->sreg,
++      err = nft_parse_register_load(ctx, tb[NFTA_BYTEORDER_SREG], &priv->sreg,
+                                     priv->len);
+       if (err < 0)
+               return err;
+diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
+index cd4652259095c..2605f43737bc9 100644
+--- a/net/netfilter/nft_cmp.c
++++ b/net/netfilter/nft_cmp.c
+@@ -83,7 +83,7 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
+       if (err < 0)
+               return err;
+-      err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len);
++      err = nft_parse_register_load(ctx, tb[NFTA_CMP_SREG], &priv->sreg, desc.len);
+       if (err < 0)
+               return err;
+@@ -222,7 +222,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx,
+       if (err < 0)
+               return err;
+-      err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len);
++      err = nft_parse_register_load(ctx, tb[NFTA_CMP_SREG], &priv->sreg, desc.len);
+       if (err < 0)
+               return err;
+@@ -323,7 +323,7 @@ static int nft_cmp16_fast_init(const struct nft_ctx *ctx,
+       if (err < 0)
+               return err;
+-      err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len);
++      err = nft_parse_register_load(ctx, tb[NFTA_CMP_SREG], &priv->sreg, desc.len);
+       if (err < 0)
+               return err;
+diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
+index ab1214da99ff3..3ec63852d058f 100644
+--- a/net/netfilter/nft_ct.c
++++ b/net/netfilter/nft_ct.c
+@@ -608,7 +608,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
+       }
+       priv->len = len;
+-      err = nft_parse_register_load(tb[NFTA_CT_SREG], &priv->sreg, len);
++      err = nft_parse_register_load(ctx, tb[NFTA_CT_SREG], &priv->sreg, len);
+       if (err < 0)
+               goto err1;
+diff --git a/net/netfilter/nft_dup_netdev.c b/net/netfilter/nft_dup_netdev.c
+index e5739a59ebf10..0573f96ce0791 100644
+--- a/net/netfilter/nft_dup_netdev.c
++++ b/net/netfilter/nft_dup_netdev.c
+@@ -40,7 +40,7 @@ static int nft_dup_netdev_init(const struct nft_ctx *ctx,
+       if (tb[NFTA_DUP_SREG_DEV] == NULL)
+               return -EINVAL;
+-      return nft_parse_register_load(tb[NFTA_DUP_SREG_DEV], &priv->sreg_dev,
++      return nft_parse_register_load(ctx, tb[NFTA_DUP_SREG_DEV], &priv->sreg_dev,
+                                      sizeof(int));
+ }
+diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
+index a81bd69b059b3..9a0aaeed23602 100644
+--- a/net/netfilter/nft_dynset.c
++++ b/net/netfilter/nft_dynset.c
+@@ -214,7 +214,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
+                       return err;
+       }
+-      err = nft_parse_register_load(tb[NFTA_DYNSET_SREG_KEY], &priv->sreg_key,
++      err = nft_parse_register_load(ctx, tb[NFTA_DYNSET_SREG_KEY], &priv->sreg_key,
+                                     set->klen);
+       if (err < 0)
+               return err;
+@@ -225,7 +225,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
+               if (set->dtype == NFT_DATA_VERDICT)
+                       return -EOPNOTSUPP;
+-              err = nft_parse_register_load(tb[NFTA_DYNSET_SREG_DATA],
++              err = nft_parse_register_load(ctx, tb[NFTA_DYNSET_SREG_DATA],
+                                             &priv->sreg_data, set->dlen);
+               if (err < 0)
+                       return err;
+diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
+index cfa90ab660cfe..1d4c9632072c8 100644
+--- a/net/netfilter/nft_exthdr.c
++++ b/net/netfilter/nft_exthdr.c
+@@ -586,7 +586,7 @@ static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx,
+       priv->flags  = flags;
+       priv->op     = op;
+-      return nft_parse_register_load(tb[NFTA_EXTHDR_SREG], &priv->sreg,
++      return nft_parse_register_load(ctx, tb[NFTA_EXTHDR_SREG], &priv->sreg,
+                                      priv->len);
+ }
+diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c
+index fa9e4ae00b16a..42ba31dfc0359 100644
+--- a/net/netfilter/nft_fwd_netdev.c
++++ b/net/netfilter/nft_fwd_netdev.c
+@@ -52,7 +52,7 @@ static int nft_fwd_netdev_init(const struct nft_ctx *ctx,
+       if (tb[NFTA_FWD_SREG_DEV] == NULL)
+               return -EINVAL;
+-      return nft_parse_register_load(tb[NFTA_FWD_SREG_DEV], &priv->sreg_dev,
++      return nft_parse_register_load(ctx, tb[NFTA_FWD_SREG_DEV], &priv->sreg_dev,
+                                      sizeof(int));
+ }
+@@ -178,12 +178,12 @@ static int nft_fwd_neigh_init(const struct nft_ctx *ctx,
+               return -EOPNOTSUPP;
+       }
+-      err = nft_parse_register_load(tb[NFTA_FWD_SREG_DEV], &priv->sreg_dev,
++      err = nft_parse_register_load(ctx, tb[NFTA_FWD_SREG_DEV], &priv->sreg_dev,
+                                     sizeof(int));
+       if (err < 0)
+               return err;
+-      return nft_parse_register_load(tb[NFTA_FWD_SREG_ADDR], &priv->sreg_addr,
++      return nft_parse_register_load(ctx, tb[NFTA_FWD_SREG_ADDR], &priv->sreg_addr,
+                                      addr_len);
+ }
+diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
+index 92d47e4692046..c91f2bef58694 100644
+--- a/net/netfilter/nft_hash.c
++++ b/net/netfilter/nft_hash.c
+@@ -91,7 +91,7 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
+       priv->len = len;
+-      err = nft_parse_register_load(tb[NFTA_HASH_SREG], &priv->sreg, len);
++      err = nft_parse_register_load(ctx, tb[NFTA_HASH_SREG], &priv->sreg, len);
+       if (err < 0)
+               return err;
+diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
+index dd5441f92fdb0..aeaf6988efd67 100644
+--- a/net/netfilter/nft_lookup.c
++++ b/net/netfilter/nft_lookup.c
+@@ -113,7 +113,7 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
+       if (IS_ERR(set))
+               return PTR_ERR(set);
+-      err = nft_parse_register_load(tb[NFTA_LOOKUP_SREG], &priv->sreg,
++      err = nft_parse_register_load(ctx, tb[NFTA_LOOKUP_SREG], &priv->sreg,
+                                     set->klen);
+       if (err < 0)
+               return err;
+diff --git a/net/netfilter/nft_masq.c b/net/netfilter/nft_masq.c
+index eee05394c5339..868bd4d735555 100644
+--- a/net/netfilter/nft_masq.c
++++ b/net/netfilter/nft_masq.c
+@@ -51,13 +51,13 @@ static int nft_masq_init(const struct nft_ctx *ctx,
+               priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS]));
+       if (tb[NFTA_MASQ_REG_PROTO_MIN]) {
+-              err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MIN],
++              err = nft_parse_register_load(ctx, tb[NFTA_MASQ_REG_PROTO_MIN],
+                                             &priv->sreg_proto_min, plen);
+               if (err < 0)
+                       return err;
+               if (tb[NFTA_MASQ_REG_PROTO_MAX]) {
+-                      err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MAX],
++                      err = nft_parse_register_load(ctx, tb[NFTA_MASQ_REG_PROTO_MAX],
+                                                     &priv->sreg_proto_max,
+                                                     plen);
+                       if (err < 0)
+diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
+index dec76d28a0ac6..8c8eb14d647b0 100644
+--- a/net/netfilter/nft_meta.c
++++ b/net/netfilter/nft_meta.c
+@@ -655,7 +655,7 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
+       }
+       priv->len = len;
+-      err = nft_parse_register_load(tb[NFTA_META_SREG], &priv->sreg, len);
++      err = nft_parse_register_load(ctx, tb[NFTA_META_SREG], &priv->sreg, len);
+       if (err < 0)
+               return err;
+diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
+index 3d3e639a7a837..6e21f72c5b574 100644
+--- a/net/netfilter/nft_nat.c
++++ b/net/netfilter/nft_nat.c
+@@ -213,13 +213,13 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
+       priv->family = family;
+       if (tb[NFTA_NAT_REG_ADDR_MIN]) {
+-              err = nft_parse_register_load(tb[NFTA_NAT_REG_ADDR_MIN],
++              err = nft_parse_register_load(ctx, tb[NFTA_NAT_REG_ADDR_MIN],
+                                             &priv->sreg_addr_min, alen);
+               if (err < 0)
+                       return err;
+               if (tb[NFTA_NAT_REG_ADDR_MAX]) {
+-                      err = nft_parse_register_load(tb[NFTA_NAT_REG_ADDR_MAX],
++                      err = nft_parse_register_load(ctx, tb[NFTA_NAT_REG_ADDR_MAX],
+                                                     &priv->sreg_addr_max,
+                                                     alen);
+                       if (err < 0)
+@@ -233,13 +233,13 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
+       plen = sizeof_field(struct nf_nat_range, min_proto.all);
+       if (tb[NFTA_NAT_REG_PROTO_MIN]) {
+-              err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MIN],
++              err = nft_parse_register_load(ctx, tb[NFTA_NAT_REG_PROTO_MIN],
+                                             &priv->sreg_proto_min, plen);
+               if (err < 0)
+                       return err;
+               if (tb[NFTA_NAT_REG_PROTO_MAX]) {
+-                      err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MAX],
++                      err = nft_parse_register_load(ctx, tb[NFTA_NAT_REG_PROTO_MAX],
+                                                     &priv->sreg_proto_max,
+                                                     plen);
+                       if (err < 0)
+diff --git a/net/netfilter/nft_objref.c b/net/netfilter/nft_objref.c
+index 08a27433e2f5f..1ee17098de0c4 100644
+--- a/net/netfilter/nft_objref.c
++++ b/net/netfilter/nft_objref.c
+@@ -173,7 +173,7 @@ static int nft_objref_map_init(const struct nft_ctx *ctx,
+       if (!(set->flags & NFT_SET_OBJECT))
+               return -EINVAL;
+-      err = nft_parse_register_load(tb[NFTA_OBJREF_SET_SREG], &priv->sreg,
++      err = nft_parse_register_load(ctx, tb[NFTA_OBJREF_SET_SREG], &priv->sreg,
+                                     set->klen);
+       if (err < 0)
+               return err;
+diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
+index 2db38c06bedeb..7dfc5343dae46 100644
+--- a/net/netfilter/nft_payload.c
++++ b/net/netfilter/nft_payload.c
+@@ -984,7 +984,7 @@ static int nft_payload_set_init(const struct nft_ctx *ctx,
+       }
+       priv->csum_type = csum_type;
+-      return nft_parse_register_load(tb[NFTA_PAYLOAD_SREG], &priv->sreg,
++      return nft_parse_register_load(ctx, tb[NFTA_PAYLOAD_SREG], &priv->sreg,
+                                      priv->len);
+ }
+diff --git a/net/netfilter/nft_queue.c b/net/netfilter/nft_queue.c
+index b8ebb187814f2..344fe311878fe 100644
+--- a/net/netfilter/nft_queue.c
++++ b/net/netfilter/nft_queue.c
+@@ -135,7 +135,7 @@ static int nft_queue_sreg_init(const struct nft_ctx *ctx,
+       struct nft_queue *priv = nft_expr_priv(expr);
+       int err;
+-      err = nft_parse_register_load(tb[NFTA_QUEUE_SREG_QNUM],
++      err = nft_parse_register_load(ctx, tb[NFTA_QUEUE_SREG_QNUM],
+                                     &priv->sreg_qnum, sizeof(u32));
+       if (err < 0)
+               return err;
+diff --git a/net/netfilter/nft_range.c b/net/netfilter/nft_range.c
+index 51ae64cd268f4..ea382f7bbd78d 100644
+--- a/net/netfilter/nft_range.c
++++ b/net/netfilter/nft_range.c
+@@ -83,7 +83,7 @@ static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr
+               goto err2;
+       }
+-      err = nft_parse_register_load(tb[NFTA_RANGE_SREG], &priv->sreg,
++      err = nft_parse_register_load(ctx, tb[NFTA_RANGE_SREG], &priv->sreg,
+                                     desc_from.len);
+       if (err < 0)
+               goto err2;
+diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
+index 9051863509f31..95eedad85c835 100644
+--- a/net/netfilter/nft_redir.c
++++ b/net/netfilter/nft_redir.c
+@@ -50,13 +50,13 @@ static int nft_redir_init(const struct nft_ctx *ctx,
+       plen = sizeof_field(struct nf_nat_range, min_proto.all);
+       if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
+-              err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MIN],
++              err = nft_parse_register_load(ctx, tb[NFTA_REDIR_REG_PROTO_MIN],
+                                             &priv->sreg_proto_min, plen);
+               if (err < 0)
+                       return err;
+               if (tb[NFTA_REDIR_REG_PROTO_MAX]) {
+-                      err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MAX],
++                      err = nft_parse_register_load(ctx, tb[NFTA_REDIR_REG_PROTO_MAX],
+                                                     &priv->sreg_proto_max,
+                                                     plen);
+                       if (err < 0)
+diff --git a/net/netfilter/nft_tproxy.c b/net/netfilter/nft_tproxy.c
+index ed344af2a439b..50481280abd26 100644
+--- a/net/netfilter/nft_tproxy.c
++++ b/net/netfilter/nft_tproxy.c
+@@ -254,14 +254,14 @@ static int nft_tproxy_init(const struct nft_ctx *ctx,
+       }
+       if (tb[NFTA_TPROXY_REG_ADDR]) {
+-              err = nft_parse_register_load(tb[NFTA_TPROXY_REG_ADDR],
++              err = nft_parse_register_load(ctx, tb[NFTA_TPROXY_REG_ADDR],
+                                             &priv->sreg_addr, alen);
+               if (err < 0)
+                       return err;
+       }
+       if (tb[NFTA_TPROXY_REG_PORT]) {
+-              err = nft_parse_register_load(tb[NFTA_TPROXY_REG_PORT],
++              err = nft_parse_register_load(ctx, tb[NFTA_TPROXY_REG_PORT],
+                                             &priv->sreg_port, sizeof(u16));
+               if (err < 0)
+                       return err;
+-- 
+2.51.0
+
diff --git a/queue-6.6/netfilter-nf_tables-remove-redundant-chain-validatio.patch b/queue-6.6/netfilter-nf_tables-remove-redundant-chain-validatio.patch
new file mode 100644 (file)
index 0000000..4fbd7e6
--- /dev/null
@@ -0,0 +1,59 @@
+From 5478fedf7b3b9cb61dc467b894613de7769fd32a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Nov 2025 13:42:05 +0100
+Subject: netfilter: nf_tables: remove redundant chain validation on register
+ store
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit a67fd55f6a09f4119b7232c19e0f348fe31ab0db ]
+
+This validation predates the introduction of the state machine that
+determines when to enter slow path validation for error reporting.
+
+Currently, table validation is perform when:
+
+- new rule contains expressions that need validation.
+- new set element with jump/goto verdict.
+
+Validation on register store skips most checks with no basechains, still
+this walks the graph searching for loops and ensuring expressions are
+called from the right hook. Remove this.
+
+Fixes: a654de8fdc18 ("netfilter: nf_tables: fix chain dependency validation")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 8b8895e4372d9..394ee65e1d35f 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -10964,21 +10964,10 @@ static int nft_validate_register_store(const struct nft_ctx *ctx,
+                                      enum nft_data_types type,
+                                      unsigned int len)
+ {
+-      int err;
+-
+       switch (reg) {
+       case NFT_REG_VERDICT:
+               if (type != NFT_DATA_VERDICT)
+                       return -EINVAL;
+-
+-              if (data != NULL &&
+-                  (data->verdict.code == NFT_GOTO ||
+-                   data->verdict.code == NFT_JUMP)) {
+-                      err = nft_chain_validate(ctx, data->verdict.chain);
+-                      if (err < 0)
+-                              return err;
+-              }
+-
+               break;
+       default:
+               if (type != NFT_DATA_VALUE)
+-- 
+2.51.0
+
diff --git a/queue-6.6/netrom-fix-memory-leak-in-nr_sendmsg.patch b/queue-6.6/netrom-fix-memory-leak-in-nr_sendmsg.patch
new file mode 100644 (file)
index 0000000..3daa210
--- /dev/null
@@ -0,0 +1,74 @@
+From 0544b4c981e0e614a31c261c4618e0d949197bba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Nov 2025 12:13:15 +0800
+Subject: netrom: Fix memory leak in nr_sendmsg()
+
+From: Wang Liang <wangliang74@huawei.com>
+
+[ Upstream commit 613d12dd794e078be8ff3cf6b62a6b9acf7f4619 ]
+
+syzbot reported a memory leak [1].
+
+When function sock_alloc_send_skb() return NULL in nr_output(), the
+original skb is not freed, which was allocated in nr_sendmsg(). Fix this
+by freeing it before return.
+
+[1]
+BUG: memory leak
+unreferenced object 0xffff888129f35500 (size 240):
+  comm "syz.0.17", pid 6119, jiffies 4294944652
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+    00 00 00 00 00 00 00 00 00 10 52 28 81 88 ff ff  ..........R(....
+  backtrace (crc 1456a3e4):
+    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
+    slab_post_alloc_hook mm/slub.c:4983 [inline]
+    slab_alloc_node mm/slub.c:5288 [inline]
+    kmem_cache_alloc_node_noprof+0x36f/0x5e0 mm/slub.c:5340
+    __alloc_skb+0x203/0x240 net/core/skbuff.c:660
+    alloc_skb include/linux/skbuff.h:1383 [inline]
+    alloc_skb_with_frags+0x69/0x3f0 net/core/skbuff.c:6671
+    sock_alloc_send_pskb+0x379/0x3e0 net/core/sock.c:2965
+    sock_alloc_send_skb include/net/sock.h:1859 [inline]
+    nr_sendmsg+0x287/0x450 net/netrom/af_netrom.c:1105
+    sock_sendmsg_nosec net/socket.c:727 [inline]
+    __sock_sendmsg net/socket.c:742 [inline]
+    sock_write_iter+0x293/0x2a0 net/socket.c:1195
+    new_sync_write fs/read_write.c:593 [inline]
+    vfs_write+0x45d/0x710 fs/read_write.c:686
+    ksys_write+0x143/0x170 fs/read_write.c:738
+    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+    do_syscall_64+0xa4/0xfa0 arch/x86/entry/syscall_64.c:94
+    entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Reported-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=d7abc36bbbb6d7d40b58
+Tested-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Wang Liang <wangliang74@huawei.com>
+Link: https://patch.msgid.link/20251129041315.1550766-1-wangliang74@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netrom/nr_out.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/netrom/nr_out.c b/net/netrom/nr_out.c
+index 5e531394a724b..2b3cbceb0b52d 100644
+--- a/net/netrom/nr_out.c
++++ b/net/netrom/nr_out.c
+@@ -43,8 +43,10 @@ void nr_output(struct sock *sk, struct sk_buff *skb)
+               frontlen = skb_headroom(skb);
+               while (skb->len > 0) {
+-                      if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL)
++                      if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL) {
++                              kfree_skb(skb);
+                               return;
++                      }
+                       skb_reserve(skbn, frontlen);
+-- 
+2.51.0
+
diff --git a/queue-6.6/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch b/queue-6.6/nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch
new file mode 100644 (file)
index 0000000..65eafe1
--- /dev/null
@@ -0,0 +1,37 @@
+From bfce31e49e00581d72ec016dcb193656efdca69b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 09:56:39 +0300
+Subject: nfc: pn533: Fix error code in pn533_acr122_poweron_rdr()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 885bebac9909994050bbbeed0829c727e42bd1b7 ]
+
+Set the error code if "transferred != sizeof(cmd)" instead of
+returning success.
+
+Fixes: dbafc28955fa ("NFC: pn533: don't send USB data off of the stack")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/aTfIJ9tZPmeUF4W1@stanley.mountain
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/pn533/usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c
+index a187f0e0b0f7d..9e079be43583e 100644
+--- a/drivers/nfc/pn533/usb.c
++++ b/drivers/nfc/pn533/usb.c
+@@ -407,7 +407,7 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy)
+       if (rc || (transferred != sizeof(cmd))) {
+               nfc_err(&phy->udev->dev,
+                       "Reader power on cmd error %d\n", rc);
+-              return rc;
++              return rc ?: -EINVAL;
+       }
+       rc =  usb_submit_urb(phy->in_urb, GFP_KERNEL);
+-- 
+2.51.0
+
index 6e3e53dce902f2975cb70483f783bd6765d28dd4..da37bda8cc8d7e5ffe419492cc8af9134158b309 100644 (file)
@@ -328,3 +328,33 @@ ksmbd-vfs-fix-race-on-m_flags-in-vfs_cache.patch
 bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch
 bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch
 gfs2-fix-use-of-bio_chain.patch
 bluetooth-btusb-add-new-vid-pid-2b89-6275-for-rtl876.patch
 bluetooth-btusb-add-new-vid-pid-13d3-3533-for-rtl882.patch
 gfs2-fix-use-of-bio_chain.patch
+net-fec-err007885-workaround-for-xdp-tx-path.patch
+netrom-fix-memory-leak-in-nr_sendmsg.patch
+net-sched-ets-always-remove-class-from-active-list-b.patch
+ipvlan-ignore-packet_loopback-in-handle_mode_l2.patch
+mlxsw-spectrum_router-fix-possible-neighbour-referen.patch
+mlxsw-spectrum_router-fix-neighbour-use-after-free.patch
+mlxsw-spectrum_mr-fix-use-after-free-when-updating-m.patch
+net-openvswitch-fix-middle-attribute-validation-in-p.patch
+broadcom-b44-prevent-uninitialized-value-usage.patch
+netfilter-nf_conncount-fix-leaked-ct-in-error-paths.patch
+ipvs-fix-ipv4-null-ptr-deref-in-route-error-path.patch
+caif-fix-integer-underflow-in-cffrml_receive.patch
+net-sched-ets-remove-drr-class-from-the-active-list-.patch
+nfc-pn533-fix-error-code-in-pn533_acr122_poweron_rdr.patch
+netfilter-nf_tables-pass-context-structure-to-nft_pa.patch
+netfilter-nf_tables-allow-loads-only-when-register-i.patch
+netfilter-nf_tables-remove-redundant-chain-validatio.patch
+iommufd-selftest-check-for-overflow-in-iommu_test_op.patch
+ethtool-avoid-overflowing-userspace-buffer-on-stats-.patch
+net-mlx5-fw-reset-clear-reset-requested-on-drain_fw_.patch
+net-mlx5-drain-firmware-reset-in-shutdown-callback.patch
+net-mlx5-fw_tracer-validate-format-string-parameters.patch
+net-mlx5-fw_tracer-handle-escaped-percent-properly.patch
+net-mlx5-skip-hotplug-check-on-sync-reset-using-hot-.patch
+net-mlx5-serialize-firmware-reset-with-devlink.patch
+net-handshake-duplicate-handshake-cancellations-leak.patch
+net-enetc-do-not-transmit-redirected-xdp-frames-when.patch
+net-hns3-using-the-num_tqps-in-the-vf-driver-to-appl.patch
+net-hns3-using-the-num_tqps-to-check-whether-tqp_ind.patch
+net-hns3-add-vlan-id-validation-before-using.patch