]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for all trees master
authorSasha Levin <sashal@kernel.org>
Wed, 3 Jun 2026 01:32:16 +0000 (21:32 -0400)
committerSasha Levin <sashal@kernel.org>
Wed, 3 Jun 2026 01:32:16 +0000 (21:32 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
406 files changed:
queue-5.10/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch [new file with mode: 0644]
queue-5.10/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch [new file with mode: 0644]
queue-5.10/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch [new file with mode: 0644]
queue-5.10/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch [new file with mode: 0644]
queue-5.10/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch [new file with mode: 0644]
queue-5.10/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch [new file with mode: 0644]
queue-5.10/kernel-fork-validate-exit_signal-in-kernel_clone.patch [new file with mode: 0644]
queue-5.10/net-iucv-fix-locking-in-.getsockopt.patch [new file with mode: 0644]
queue-5.10/net-netlink-don-t-set-nsid-on-local-notifications.patch [new file with mode: 0644]
queue-5.10/net-netlink-fix-sending-unassigned-nsid-after-assign.patch [new file with mode: 0644]
queue-5.10/net-sched-revert-net-sched-restrict-conditions-for-a.patch [new file with mode: 0644]
queue-5.10/net-smc-do-not-re-initialize-smc-hashtables.patch [new file with mode: 0644]
queue-5.10/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch [new file with mode: 0644]
queue-5.10/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch [new file with mode: 0644]
queue-5.10/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch [new file with mode: 0644]
queue-5.10/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch [new file with mode: 0644]
queue-5.10/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch [new file with mode: 0644]
queue-5.10/nfc-llcp-protect-nfc_llcp_sock_unlink-calls.patch [new file with mode: 0644]
queue-5.10/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch [new file with mode: 0644]
queue-5.10/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch [new file with mode: 0644]
queue-5.10/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch [new file with mode: 0644]
queue-5.10/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch [new file with mode: 0644]
queue-5.10/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch [new file with mode: 0644]
queue-5.10/xfrm-check-for-underflow-in-xfrm_state_mtu.patch [new file with mode: 0644]
queue-5.15/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch [new file with mode: 0644]
queue-5.15/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch [new file with mode: 0644]
queue-5.15/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch [new file with mode: 0644]
queue-5.15/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch [new file with mode: 0644]
queue-5.15/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch [new file with mode: 0644]
queue-5.15/bonding-refuse-to-enslave-can-devices.patch [new file with mode: 0644]
queue-5.15/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch [new file with mode: 0644]
queue-5.15/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch [new file with mode: 0644]
queue-5.15/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch [new file with mode: 0644]
queue-5.15/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch [new file with mode: 0644]
queue-5.15/kernel-fork-validate-exit_signal-in-kernel_clone.patch [new file with mode: 0644]
queue-5.15/net-iucv-fix-locking-in-.getsockopt.patch [new file with mode: 0644]
queue-5.15/net-netlink-don-t-set-nsid-on-local-notifications.patch [new file with mode: 0644]
queue-5.15/net-netlink-fix-sending-unassigned-nsid-after-assign.patch [new file with mode: 0644]
queue-5.15/net-sched-revert-net-sched-restrict-conditions-for-a.patch [new file with mode: 0644]
queue-5.15/net-smc-do-not-re-initialize-smc-hashtables.patch [new file with mode: 0644]
queue-5.15/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch [new file with mode: 0644]
queue-5.15/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch [new file with mode: 0644]
queue-5.15/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch [new file with mode: 0644]
queue-5.15/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch [new file with mode: 0644]
queue-5.15/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch [new file with mode: 0644]
queue-5.15/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch [new file with mode: 0644]
queue-5.15/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch [new file with mode: 0644]
queue-5.15/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch [new file with mode: 0644]
queue-5.15/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch [new file with mode: 0644]
queue-5.15/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch [new file with mode: 0644]
queue-5.15/xfrm-check-for-underflow-in-xfrm_state_mtu.patch [new file with mode: 0644]
queue-6.1/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch [new file with mode: 0644]
queue-6.1/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch [new file with mode: 0644]
queue-6.1/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch [new file with mode: 0644]
queue-6.1/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch [new file with mode: 0644]
queue-6.1/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch [new file with mode: 0644]
queue-6.1/bonding-refuse-to-enslave-can-devices.patch [new file with mode: 0644]
queue-6.1/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch [new file with mode: 0644]
queue-6.1/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch [new file with mode: 0644]
queue-6.1/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch [new file with mode: 0644]
queue-6.1/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch [new file with mode: 0644]
queue-6.1/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch [new file with mode: 0644]
queue-6.1/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch [new file with mode: 0644]
queue-6.1/kernel-fork-validate-exit_signal-in-kernel_clone.patch [new file with mode: 0644]
queue-6.1/net-hsr-fix-potential-oob-access-in-supervision-fram.patch [new file with mode: 0644]
queue-6.1/net-iucv-fix-locking-in-.getsockopt.patch [new file with mode: 0644]
queue-6.1/net-mana-add-null-guards-in-teardown-path-to-prevent.patch [new file with mode: 0644]
queue-6.1/net-netlink-don-t-set-nsid-on-local-notifications.patch [new file with mode: 0644]
queue-6.1/net-netlink-fix-sending-unassigned-nsid-after-assign.patch [new file with mode: 0644]
queue-6.1/net-sched-revert-net-sched-restrict-conditions-for-a.patch [new file with mode: 0644]
queue-6.1/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch [new file with mode: 0644]
queue-6.1/net-smc-do-not-re-initialize-smc-hashtables.patch [new file with mode: 0644]
queue-6.1/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch [new file with mode: 0644]
queue-6.1/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch [new file with mode: 0644]
queue-6.1/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch [new file with mode: 0644]
queue-6.1/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch [new file with mode: 0644]
queue-6.1/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch [new file with mode: 0644]
queue-6.1/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch [new file with mode: 0644]
queue-6.1/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/tools-bootconfig-cleanup-bootconfig-footer-size-calc.patch [new file with mode: 0644]
queue-6.1/tools-bootconfig-fix-buf-leaks-in-apply_xbc.patch [new file with mode: 0644]
queue-6.1/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch [new file with mode: 0644]
queue-6.1/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch [new file with mode: 0644]
queue-6.1/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch [new file with mode: 0644]
queue-6.1/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch [new file with mode: 0644]
queue-6.1/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch [new file with mode: 0644]
queue-6.1/xfrm-check-for-underflow-in-xfrm_state_mtu.patch [new file with mode: 0644]
queue-6.12/accel-ivpu-prevent-uninitialized-data-bug-in-debugfs.patch [new file with mode: 0644]
queue-6.12/alsa-pcm-oss-fix-setup-list-uaf-on-proc-write-error.patch [new file with mode: 0644]
queue-6.12/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch [new file with mode: 0644]
queue-6.12/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch [new file with mode: 0644]
queue-6.12/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch [new file with mode: 0644]
queue-6.12/bluetooth-hci_sync-set-hci_cmd_drain_workqueue-durin.patch [new file with mode: 0644]
queue-6.12/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch [new file with mode: 0644]
queue-6.12/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch [new file with mode: 0644]
queue-6.12/bonding-refuse-to-enslave-can-devices.patch [new file with mode: 0644]
queue-6.12/cxl-test-update-mock-dev-array-before-calling-platfo.patch [new file with mode: 0644]
queue-6.12/ethtool-cmis-fix-u16-to-u8-truncation-of-msleep_pre_.patch [new file with mode: 0644]
queue-6.12/ethtool-cmis-require-exact-cdb-reply-length.patch [new file with mode: 0644]
queue-6.12/ethtool-cmis-validate-fw-size-against-start_cmd_payl.patch [new file with mode: 0644]
queue-6.12/ethtool-cmis-validate-start_cmd_payload_size-from-mo.patch [new file with mode: 0644]
queue-6.12/ethtool-coalesce-cap-profile-updates-at-net_dim_para.patch [new file with mode: 0644]
queue-6.12/ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch [new file with mode: 0644]
queue-6.12/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch [new file with mode: 0644]
queue-6.12/ethtool-linkstate-fix-unbalanced-ethnl_ops_complete-.patch [new file with mode: 0644]
queue-6.12/ethtool-module-avoid-leaking-a-netdev-ref-on-module-.patch [new file with mode: 0644]
queue-6.12/ethtool-module-check-fw_flash_in_progress-under-rtnl.patch [new file with mode: 0644]
queue-6.12/ethtool-module-fix-cleanup-if-socket-used-for-flashi.patch [new file with mode: 0644]
queue-6.12/ethtool-pse-pd-fix-missing-ethnl_ops_complete.patch [new file with mode: 0644]
queue-6.12/ethtool-rss-fix-hkey-leak-when-indir_size-is-0.patch [new file with mode: 0644]
queue-6.12/ethtool-strset-fix-header-attribute-index-in-ethnl_r.patch [new file with mode: 0644]
queue-6.12/gpio-mxc-fix-irq_high-handling.patch [new file with mode: 0644]
queue-6.12/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch [new file with mode: 0644]
queue-6.12/gpio-virtuser-fix-uninitialized-data-bug-in-gpio_vir.patch [new file with mode: 0644]
queue-6.12/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch [new file with mode: 0644]
queue-6.12/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch [new file with mode: 0644]
queue-6.12/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch [new file with mode: 0644]
queue-6.12/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch [new file with mode: 0644]
queue-6.12/kernel-fork-validate-exit_signal-in-kernel_clone.patch [new file with mode: 0644]
queue-6.12/kunit-fix-use-after-free-in-debugfs-when-using-kunit.patch [new file with mode: 0644]
queue-6.12/net-avoid-checksumming-unreadable-skb-tail-on-trim.patch [new file with mode: 0644]
queue-6.12/net-ethtool-add-new-parameters-and-a-function-to-sup.patch [new file with mode: 0644]
queue-6.12/net-ethtool-add-support-for-writing-firmware-blocks-.patch [new file with mode: 0644]
queue-6.12/net-handshake-drain-pending-requests-at-net-namespac.patch [new file with mode: 0644]
queue-6.12/net-handshake-pass-negative-errno-through-handshake_.patch [new file with mode: 0644]
queue-6.12/net-handshake-take-a-long-lived-file-reference-at-su.patch [new file with mode: 0644]
queue-6.12/net-handshake-use-spin_lock_bh-for-hn_lock.patch [new file with mode: 0644]
queue-6.12/net-hsr-fix-potential-oob-access-in-supervision-fram.patch [new file with mode: 0644]
queue-6.12/net-introduce-skb-tc-depth-field-to-track-packet-loo.patch [new file with mode: 0644]
queue-6.12/net-iucv-fix-locking-in-.getsockopt.patch [new file with mode: 0644]
queue-6.12/net-mana-add-null-guards-in-teardown-path-to-prevent.patch [new file with mode: 0644]
queue-6.12/net-netlink-don-t-set-nsid-on-local-notifications.patch [new file with mode: 0644]
queue-6.12/net-netlink-fix-sending-unassigned-nsid-after-assign.patch [new file with mode: 0644]
queue-6.12/net-sched-act_mirred-add-loop-detection.patch [new file with mode: 0644]
queue-6.12/net-sched-act_mirred-fix-return-code-in-early-mirred.patch [new file with mode: 0644]
queue-6.12/net-sched-act_mirred-move-the-recursion-counter-stru.patch [new file with mode: 0644]
queue-6.12/net-sched-fix-ethx-ingress-ethy-egress-ethx-ingress-.patch [new file with mode: 0644]
queue-6.12/net-sched-fix-packet-loop-on-netem-when-duplicate-is.patch [new file with mode: 0644]
queue-6.12/net-sched-revert-net-sched-restrict-conditions-for-a.patch [new file with mode: 0644]
queue-6.12/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch [new file with mode: 0644]
queue-6.12/net-smc-do-not-re-initialize-smc-hashtables.patch [new file with mode: 0644]
queue-6.12/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch [new file with mode: 0644]
queue-6.12/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch [new file with mode: 0644]
queue-6.12/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch [new file with mode: 0644]
queue-6.12/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch [new file with mode: 0644]
queue-6.12/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch [new file with mode: 0644]
queue-6.12/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch [new file with mode: 0644]
queue-6.12/nvme-tcp-store-negative-errno-in-queue-tls_err.patch [new file with mode: 0644]
queue-6.12/remove-pointless-includes-of-linux-fdtable.h.patch [new file with mode: 0644]
queue-6.12/scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch [new file with mode: 0644]
queue-6.12/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch [new file with mode: 0644]
queue-6.12/series
queue-6.12/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch [new file with mode: 0644]
queue-6.12/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch [new file with mode: 0644]
queue-6.12/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch [new file with mode: 0644]
queue-6.12/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch [new file with mode: 0644]
queue-6.12/vsock-keep-poll-shutdown-state-consistent.patch [new file with mode: 0644]
queue-6.12/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch [new file with mode: 0644]
queue-6.12/xfrm-check-for-underflow-in-xfrm_state_mtu.patch [new file with mode: 0644]
queue-6.18/accel-rocket-fix-uaf-via-dangling-gem-handle-in-crea.patch [new file with mode: 0644]
queue-6.18/alsa-pcm-oss-fix-setup-list-uaf-on-proc-write-error.patch [new file with mode: 0644]
queue-6.18/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch [new file with mode: 0644]
queue-6.18/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch [new file with mode: 0644]
queue-6.18/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch [new file with mode: 0644]
queue-6.18/bluetooth-hci_sync-reset-device-counters-in-hci_dev_.patch [new file with mode: 0644]
queue-6.18/bluetooth-hci_sync-set-hci_cmd_drain_workqueue-durin.patch [new file with mode: 0644]
queue-6.18/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch [new file with mode: 0644]
queue-6.18/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch [new file with mode: 0644]
queue-6.18/bonding-refuse-to-enslave-can-devices.patch [new file with mode: 0644]
queue-6.18/bridge-fix-sleep-in-atomic-context-in-netlink-path.patch [new file with mode: 0644]
queue-6.18/bridge-fix-sleep-in-atomic-context-in-sysfs-path.patch [new file with mode: 0644]
queue-6.18/cxl-test-update-mock-dev-array-before-calling-platfo.patch [new file with mode: 0644]
queue-6.18/drm-xe-restore-idledly-regiter-on-engine-reset.patch [new file with mode: 0644]
queue-6.18/ethtool-cmis-fix-u16-to-u8-truncation-of-msleep_pre_.patch [new file with mode: 0644]
queue-6.18/ethtool-cmis-require-exact-cdb-reply-length.patch [new file with mode: 0644]
queue-6.18/ethtool-cmis-validate-fw-size-against-start_cmd_payl.patch [new file with mode: 0644]
queue-6.18/ethtool-cmis-validate-start_cmd_payload_size-from-mo.patch [new file with mode: 0644]
queue-6.18/ethtool-coalesce-cap-profile-updates-at-net_dim_para.patch [new file with mode: 0644]
queue-6.18/ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch [new file with mode: 0644]
queue-6.18/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch [new file with mode: 0644]
queue-6.18/ethtool-linkstate-fix-unbalanced-ethnl_ops_complete-.patch [new file with mode: 0644]
queue-6.18/ethtool-module-avoid-leaking-a-netdev-ref-on-module-.patch [new file with mode: 0644]
queue-6.18/ethtool-module-avoid-racy-updates-to-dev-ethtool-bit.patch [new file with mode: 0644]
queue-6.18/ethtool-module-call-ethnl_ops_complete-on-module-fla.patch [new file with mode: 0644]
queue-6.18/ethtool-module-check-fw_flash_in_progress-under-rtnl.patch [new file with mode: 0644]
queue-6.18/ethtool-module-fix-cleanup-if-socket-used-for-flashi.patch [new file with mode: 0644]
queue-6.18/ethtool-pse-pd-fix-missing-ethnl_ops_complete.patch [new file with mode: 0644]
queue-6.18/ethtool-rss-add-missing-errno-on-rss-context-delete.patch [new file with mode: 0644]
queue-6.18/ethtool-rss-avoid-device-context-leak-on-reply-build.patch [new file with mode: 0644]
queue-6.18/ethtool-rss-avoid-modifying-the-rss-context-response.patch [new file with mode: 0644]
queue-6.18/ethtool-rss-fix-falsely-ignoring-indir-table-updates.patch [new file with mode: 0644]
queue-6.18/ethtool-rss-fix-hkey-leak-when-indir_size-is-0.patch [new file with mode: 0644]
queue-6.18/ethtool-rss-fix-indir_table-and-hkey-leak-on-get_rxf.patch [new file with mode: 0644]
queue-6.18/ethtool-strset-fix-header-attribute-index-in-ethnl_r.patch [new file with mode: 0644]
queue-6.18/ethtool-tsconfig-fix-missing-ethnl_ops_complete.patch [new file with mode: 0644]
queue-6.18/ethtool-tsconfig-fix-reply-error-handling.patch [new file with mode: 0644]
queue-6.18/ethtool-tsinfo-don-t-pass-err_ptr-to-genlmsg_cancel-.patch [new file with mode: 0644]
queue-6.18/ethtool-tsinfo-fix-uninitialized-stats-on-the-by-phc.patch [new file with mode: 0644]
queue-6.18/gpio-adnp-fix-flow-control-regression-caused-by-scop.patch [new file with mode: 0644]
queue-6.18/gpio-mxc-fix-irq_high-handling.patch [new file with mode: 0644]
queue-6.18/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch [new file with mode: 0644]
queue-6.18/gpio-rockchip-teardown-bugs-and-resource-leaks.patch [new file with mode: 0644]
queue-6.18/gpio-virtuser-fix-uninitialized-data-bug-in-gpio_vir.patch [new file with mode: 0644]
queue-6.18/hid-remove-duplicate-hid_warn_ratelimited-definition.patch [new file with mode: 0644]
queue-6.18/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch [new file with mode: 0644]
queue-6.18/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch [new file with mode: 0644]
queue-6.18/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch [new file with mode: 0644]
queue-6.18/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch [new file with mode: 0644]
queue-6.18/kernel-fork-validate-exit_signal-in-kernel_clone.patch [new file with mode: 0644]
queue-6.18/ksmbd-fix-fsctl-permission-bypass-by-adding-a-permis.patch [new file with mode: 0644]
queue-6.18/kunit-fix-use-after-free-in-debugfs-when-using-kunit.patch [new file with mode: 0644]
queue-6.18/media-rc-fix-race-between-unregister-and-urb-irq-cal.patch [new file with mode: 0644]
queue-6.18/media-rc-ttusbir-fix-inverted-error-logic.patch [new file with mode: 0644]
queue-6.18/net-avoid-checksumming-unreadable-skb-tail-on-trim.patch [new file with mode: 0644]
queue-6.18/net-handshake-pass-negative-errno-through-handshake_.patch [new file with mode: 0644]
queue-6.18/net-handshake-use-spin_lock_bh-for-hn_lock.patch [new file with mode: 0644]
queue-6.18/net-hibmcge-disable-relaxed-ordering-to-fix-rx-packe.patch [new file with mode: 0644]
queue-6.18/net-hsr-fix-potential-oob-access-in-supervision-fram.patch [new file with mode: 0644]
queue-6.18/net-iucv-fix-locking-in-.getsockopt.patch [new file with mode: 0644]
queue-6.18/net-mana-add-null-guards-in-teardown-path-to-prevent.patch [new file with mode: 0644]
queue-6.18/net-mana-skip-redundant-detach-on-already-detached-p.patch [new file with mode: 0644]
queue-6.18/net-mlx5-hws-reject-unsupported-remove-header-action.patch [new file with mode: 0644]
queue-6.18/net-netlink-don-t-set-nsid-on-local-notifications.patch [new file with mode: 0644]
queue-6.18/net-netlink-fix-sending-unassigned-nsid-after-assign.patch [new file with mode: 0644]
queue-6.18/net-sched-revert-net-sched-restrict-conditions-for-a.patch [new file with mode: 0644]
queue-6.18/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch [new file with mode: 0644]
queue-6.18/net-smc-do-not-re-initialize-smc-hashtables.patch [new file with mode: 0644]
queue-6.18/net-team-fix-null-pointer-dereference-in-team_xmit-d.patch [new file with mode: 0644]
queue-6.18/net-team-remove-unused-team_mode_op-port_enabled.patch [new file with mode: 0644]
queue-6.18/net-team-rename-port_disabled-team-mode-op-to-port_t.patch [new file with mode: 0644]
queue-6.18/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch [new file with mode: 0644]
queue-6.18/netfilter-nf_tables-fix-dst-corruption-in-same-regis.patch [new file with mode: 0644]
queue-6.18/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch [new file with mode: 0644]
queue-6.18/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch [new file with mode: 0644]
queue-6.18/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch [new file with mode: 0644]
queue-6.18/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch [new file with mode: 0644]
queue-6.18/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch [new file with mode: 0644]
queue-6.18/nvme-tcp-store-negative-errno-in-queue-tls_err.patch [new file with mode: 0644]
queue-6.18/scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch [new file with mode: 0644]
queue-6.18/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch [new file with mode: 0644]
queue-6.18/series
queue-6.18/tools-bootconfig-fix-buf-leaks-in-apply_xbc.patch [new file with mode: 0644]
queue-6.18/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch [new file with mode: 0644]
queue-6.18/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch [new file with mode: 0644]
queue-6.18/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch [new file with mode: 0644]
queue-6.18/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch [new file with mode: 0644]
queue-6.18/vsock-keep-poll-shutdown-state-consistent.patch [new file with mode: 0644]
queue-6.18/vsock-virtio-bind-uarg-before-filling-zerocopy-skb.patch [new file with mode: 0644]
queue-6.18/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch [new file with mode: 0644]
queue-6.18/xfrm-check-for-underflow-in-xfrm_state_mtu.patch [new file with mode: 0644]
queue-6.6/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch [new file with mode: 0644]
queue-6.6/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch [new file with mode: 0644]
queue-6.6/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch [new file with mode: 0644]
queue-6.6/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch [new file with mode: 0644]
queue-6.6/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch [new file with mode: 0644]
queue-6.6/bonding-refuse-to-enslave-can-devices.patch [new file with mode: 0644]
queue-6.6/ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch [new file with mode: 0644]
queue-6.6/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch [new file with mode: 0644]
queue-6.6/gpio-mxc-fix-irq_high-handling.patch [new file with mode: 0644]
queue-6.6/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch [new file with mode: 0644]
queue-6.6/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch [new file with mode: 0644]
queue-6.6/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch [new file with mode: 0644]
queue-6.6/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch [new file with mode: 0644]
queue-6.6/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch [new file with mode: 0644]
queue-6.6/kernel-fork-validate-exit_signal-in-kernel_clone.patch [new file with mode: 0644]
queue-6.6/ksmbd-fix-fsctl-permission-bypass-by-adding-a-permis.patch [new file with mode: 0644]
queue-6.6/net-hsr-fix-potential-oob-access-in-supervision-fram.patch [new file with mode: 0644]
queue-6.6/net-iucv-fix-locking-in-.getsockopt.patch [new file with mode: 0644]
queue-6.6/net-mana-add-null-guards-in-teardown-path-to-prevent.patch [new file with mode: 0644]
queue-6.6/net-netlink-don-t-set-nsid-on-local-notifications.patch [new file with mode: 0644]
queue-6.6/net-netlink-fix-sending-unassigned-nsid-after-assign.patch [new file with mode: 0644]
queue-6.6/net-sched-revert-net-sched-restrict-conditions-for-a.patch [new file with mode: 0644]
queue-6.6/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch [new file with mode: 0644]
queue-6.6/net-smc-do-not-re-initialize-smc-hashtables.patch [new file with mode: 0644]
queue-6.6/netfilter-bitwise-add-support-for-doing-and-or-and-x.patch [new file with mode: 0644]
queue-6.6/netfilter-bitwise-rename-some-boolean-operation-func.patch [new file with mode: 0644]
queue-6.6/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch [new file with mode: 0644]
queue-6.6/netfilter-nf_tables-fix-dst-corruption-in-same-regis.patch [new file with mode: 0644]
queue-6.6/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch [new file with mode: 0644]
queue-6.6/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch [new file with mode: 0644]
queue-6.6/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch [new file with mode: 0644]
queue-6.6/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch [new file with mode: 0644]
queue-6.6/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch [new file with mode: 0644]
queue-6.6/scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch [new file with mode: 0644]
queue-6.6/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch [new file with mode: 0644]
queue-6.6/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch [new file with mode: 0644]
queue-6.6/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch [new file with mode: 0644]
queue-6.6/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch [new file with mode: 0644]
queue-6.6/vsock-keep-poll-shutdown-state-consistent.patch [new file with mode: 0644]
queue-6.6/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch [new file with mode: 0644]
queue-6.6/xfrm-check-for-underflow-in-xfrm_state_mtu.patch [new file with mode: 0644]
queue-7.0/accel-ivpu-prevent-uninitialized-data-bug-in-debugfs.patch [new file with mode: 0644]
queue-7.0/accel-rocket-fix-uaf-via-dangling-gem-handle-in-crea.patch [new file with mode: 0644]
queue-7.0/alsa-hda-cs35l56-fix-system-name-string-leaks.patch [new file with mode: 0644]
queue-7.0/alsa-pcm-oss-fix-setup-list-uaf-on-proc-write-error.patch [new file with mode: 0644]
queue-7.0/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch [new file with mode: 0644]
queue-7.0/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch [new file with mode: 0644]
queue-7.0/blk-mq-reinsert-cached-request-to-the-list.patch [new file with mode: 0644]
queue-7.0/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch [new file with mode: 0644]
queue-7.0/bluetooth-hci_sync-reset-device-counters-in-hci_dev_.patch [new file with mode: 0644]
queue-7.0/bluetooth-hci_sync-set-hci_cmd_drain_workqueue-durin.patch [new file with mode: 0644]
queue-7.0/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch [new file with mode: 0644]
queue-7.0/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch [new file with mode: 0644]
queue-7.0/bonding-refuse-to-enslave-can-devices.patch [new file with mode: 0644]
queue-7.0/bridge-fix-sleep-in-atomic-context-in-netlink-path.patch [new file with mode: 0644]
queue-7.0/bridge-fix-sleep-in-atomic-context-in-sysfs-path.patch [new file with mode: 0644]
queue-7.0/cxl-test-update-mock-dev-array-before-calling-platfo.patch [new file with mode: 0644]
queue-7.0/dpll-export-__dpll_device_change_ntf-for-use-under-d.patch [new file with mode: 0644]
queue-7.0/dpll-zl3073x-add-die-temperature-reporting-for-suppo.patch [new file with mode: 0644]
queue-7.0/dpll-zl3073x-detect-dpll-channel-count-from-chip-id-.patch [new file with mode: 0644]
queue-7.0/dpll-zl3073x-use-__dpll_device_change_ntf-and-remove.patch [new file with mode: 0644]
queue-7.0/drm-i915-aux-use-polling-when-irqs-are-unavailable.patch [new file with mode: 0644]
queue-7.0/drm-xe-restore-idledly-regiter-on-engine-reset.patch [new file with mode: 0644]
queue-7.0/esp-fix-page-frag-reference-leak-on-skb_to_sgvec-fai.patch [new file with mode: 0644]
queue-7.0/ethtool-cmis-fix-u16-to-u8-truncation-of-msleep_pre_.patch [new file with mode: 0644]
queue-7.0/ethtool-cmis-require-exact-cdb-reply-length.patch [new file with mode: 0644]
queue-7.0/ethtool-cmis-validate-fw-size-against-start_cmd_payl.patch [new file with mode: 0644]
queue-7.0/ethtool-cmis-validate-start_cmd_payload_size-from-mo.patch [new file with mode: 0644]
queue-7.0/ethtool-coalesce-cap-profile-updates-at-net_dim_para.patch [new file with mode: 0644]
queue-7.0/ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch [new file with mode: 0644]
queue-7.0/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch [new file with mode: 0644]
queue-7.0/ethtool-linkstate-fix-unbalanced-ethnl_ops_complete-.patch [new file with mode: 0644]
queue-7.0/ethtool-module-avoid-leaking-a-netdev-ref-on-module-.patch [new file with mode: 0644]
queue-7.0/ethtool-module-avoid-racy-updates-to-dev-ethtool-bit.patch [new file with mode: 0644]
queue-7.0/ethtool-module-call-ethnl_ops_complete-on-module-fla.patch [new file with mode: 0644]
queue-7.0/ethtool-module-check-fw_flash_in_progress-under-rtnl.patch [new file with mode: 0644]
queue-7.0/ethtool-module-fix-cleanup-if-socket-used-for-flashi.patch [new file with mode: 0644]
queue-7.0/ethtool-pse-pd-fix-missing-ethnl_ops_complete.patch [new file with mode: 0644]
queue-7.0/ethtool-rss-add-missing-errno-on-rss-context-delete.patch [new file with mode: 0644]
queue-7.0/ethtool-rss-avoid-device-context-leak-on-reply-build.patch [new file with mode: 0644]
queue-7.0/ethtool-rss-avoid-modifying-the-rss-context-response.patch [new file with mode: 0644]
queue-7.0/ethtool-rss-fix-falsely-ignoring-indir-table-updates.patch [new file with mode: 0644]
queue-7.0/ethtool-rss-fix-hkey-leak-when-indir_size-is-0.patch [new file with mode: 0644]
queue-7.0/ethtool-rss-fix-indir_table-and-hkey-leak-on-get_rxf.patch [new file with mode: 0644]
queue-7.0/ethtool-strset-fix-header-attribute-index-in-ethnl_r.patch [new file with mode: 0644]
queue-7.0/ethtool-tsconfig-fix-missing-ethnl_ops_complete.patch [new file with mode: 0644]
queue-7.0/ethtool-tsconfig-fix-reply-error-handling.patch [new file with mode: 0644]
queue-7.0/ethtool-tsinfo-don-t-pass-err_ptr-to-genlmsg_cancel-.patch [new file with mode: 0644]
queue-7.0/ethtool-tsinfo-fix-uninitialized-stats-on-the-by-phc.patch [new file with mode: 0644]
queue-7.0/gpio-adnp-fix-flow-control-regression-caused-by-scop.patch [new file with mode: 0644]
queue-7.0/gpio-mxc-fix-irq_high-handling.patch [new file with mode: 0644]
queue-7.0/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch [new file with mode: 0644]
queue-7.0/gpio-rockchip-teardown-bugs-and-resource-leaks.patch [new file with mode: 0644]
queue-7.0/gpio-virtuser-fix-uninitialized-data-bug-in-gpio_vir.patch [new file with mode: 0644]
queue-7.0/hid-remove-duplicate-hid_warn_ratelimited-definition.patch [new file with mode: 0644]
queue-7.0/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch [new file with mode: 0644]
queue-7.0/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch [new file with mode: 0644]
queue-7.0/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch [new file with mode: 0644]
queue-7.0/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch [new file with mode: 0644]
queue-7.0/kernel-fork-validate-exit_signal-in-kernel_clone.patch [new file with mode: 0644]
queue-7.0/ksmbd-fix-fsctl-permission-bypass-by-adding-a-permis.patch [new file with mode: 0644]
queue-7.0/kunit-fix-use-after-free-in-debugfs-when-using-kunit.patch [new file with mode: 0644]
queue-7.0/net-avoid-checksumming-unreadable-skb-tail-on-trim.patch [new file with mode: 0644]
queue-7.0/net-handshake-drain-pending-requests-at-net-namespac.patch [new file with mode: 0644]
queue-7.0/net-handshake-hand-off-the-pinned-file-reference-to-.patch [new file with mode: 0644]
queue-7.0/net-handshake-pass-negative-errno-through-handshake_.patch [new file with mode: 0644]
queue-7.0/net-handshake-take-a-long-lived-file-reference-at-su.patch [new file with mode: 0644]
queue-7.0/net-handshake-use-spin_lock_bh-for-hn_lock.patch [new file with mode: 0644]
queue-7.0/net-hibmcge-disable-relaxed-ordering-to-fix-rx-packe.patch [new file with mode: 0644]
queue-7.0/net-hibmcge-move-dma_rmb-after-dma_sync_single_for_c.patch [new file with mode: 0644]
queue-7.0/net-hsr-fix-potential-oob-access-in-supervision-fram.patch [new file with mode: 0644]
queue-7.0/net-introduce-skb-tc-depth-field-to-track-packet-loo.patch [new file with mode: 0644]
queue-7.0/net-iucv-fix-locking-in-.getsockopt.patch [new file with mode: 0644]
queue-7.0/net-mana-add-null-guards-in-teardown-path-to-prevent.patch [new file with mode: 0644]
queue-7.0/net-mana-skip-redundant-detach-on-already-detached-p.patch [new file with mode: 0644]
queue-7.0/net-mlx5-hws-reject-unsupported-remove-header-action.patch [new file with mode: 0644]
queue-7.0/net-netlink-don-t-set-nsid-on-local-notifications.patch [new file with mode: 0644]
queue-7.0/net-netlink-fix-sending-unassigned-nsid-after-assign.patch [new file with mode: 0644]
queue-7.0/net-pcs-pcs-mtk-lynxi-fix-bpi-r3-serdes-configuratio.patch [new file with mode: 0644]
queue-7.0/net-sched-act_mirred-fix-blockcast-recursion-bypass-.patch [new file with mode: 0644]
queue-7.0/net-sched-act_mirred-fix-return-code-in-early-mirred.patch [new file with mode: 0644]
queue-7.0/net-sched-fix-ethx-ingress-ethy-egress-ethx-ingress-.patch [new file with mode: 0644]
queue-7.0/net-sched-fix-packet-loop-on-netem-when-duplicate-is.patch [new file with mode: 0644]
queue-7.0/net-sched-revert-net-sched-restrict-conditions-for-a.patch [new file with mode: 0644]
queue-7.0/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch [new file with mode: 0644]
queue-7.0/net-smc-do-not-re-initialize-smc-hashtables.patch [new file with mode: 0644]
queue-7.0/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch [new file with mode: 0644]
queue-7.0/netfilter-nf_tables-fix-dst-corruption-in-same-regis.patch [new file with mode: 0644]
queue-7.0/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch [new file with mode: 0644]
queue-7.0/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch [new file with mode: 0644]
queue-7.0/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch [new file with mode: 0644]
queue-7.0/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch [new file with mode: 0644]
queue-7.0/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch [new file with mode: 0644]
queue-7.0/nvme-tcp-store-negative-errno-in-queue-tls_err.patch [new file with mode: 0644]
queue-7.0/revert-ipv6-preserve-insertion-order-for-same-scope-.patch [new file with mode: 0644]
queue-7.0/scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch [new file with mode: 0644]
queue-7.0/scsi-scsi_debug-add-missing-newline-in-scsi_debug_de.patch [new file with mode: 0644]
queue-7.0/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch [new file with mode: 0644]
queue-7.0/series
queue-7.0/tap-free-page-on-error-paths-in-tap_get_user_xdp.patch [new file with mode: 0644]
queue-7.0/tools-bootconfig-fix-buf-leaks-in-apply_xbc.patch [new file with mode: 0644]
queue-7.0/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch [new file with mode: 0644]
queue-7.0/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch [new file with mode: 0644]
queue-7.0/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch [new file with mode: 0644]
queue-7.0/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch [new file with mode: 0644]
queue-7.0/vsock-keep-poll-shutdown-state-consistent.patch [new file with mode: 0644]
queue-7.0/vsock-virtio-bind-uarg-before-filling-zerocopy-skb.patch [new file with mode: 0644]
queue-7.0/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch [new file with mode: 0644]
queue-7.0/xfrm-check-for-underflow-in-xfrm_state_mtu.patch [new file with mode: 0644]

diff --git a/queue-5.10/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch b/queue-5.10/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
new file mode 100644 (file)
index 0000000..cb2f959
--- /dev/null
@@ -0,0 +1,112 @@
+From 9092c214fb76e695a77cc426b15e3a8282c4ebd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 13:51:47 -0300
+Subject: ASoC: Intel: bytcht_es8316: Fix MCLK leak on init errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit afb2a3a9d8369d18122a0d7cd294eba9a98259c6 ]
+
+byt_cht_es8316_init() enables MCLK before configuring the codec sysclk
+and creating the headset jack. If either of those later steps fails, the
+function returns without disabling MCLK, leaving the clock enabled after
+card registration fails.
+
+Track whether this driver enabled MCLK and disable it on the init error
+paths. Add the matching DAI link exit callback so the same clock enable
+is also balanced when ASoC cleans up a successfully initialized link.
+
+Fixes: a03bdaa565cb ("ASoC: Intel: add machine driver for BYT/CHT + ES8316")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260519-asoc-bytcht-es8316-mclk-leak-v1-1-b4a11cdc2afd@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcht_es8316.c | 29 ++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
+index a258a410dd8dfe..ebb63194c44317 100644
+--- a/sound/soc/intel/boards/bytcht_es8316.c
++++ b/sound/soc/intel/boards/bytcht_es8316.c
+@@ -39,6 +39,7 @@ struct byt_cht_es8316_private {
+       struct gpio_desc *speaker_en_gpio;
+       struct device *codec_dev;
+       bool speaker_en;
++      bool mclk_enabled;
+ };
+ enum {
+@@ -169,6 +170,15 @@ static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
+       },
+ };
++static void byt_cht_es8316_disable_mclk(struct byt_cht_es8316_private *priv)
++{
++      if (!priv->mclk_enabled)
++              return;
++
++      clk_disable_unprepare(priv->mclk);
++      priv->mclk_enabled = false;
++}
++
+ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+ {
+       struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component;
+@@ -225,12 +235,14 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+       ret = clk_prepare_enable(priv->mclk);
+       if (ret)
+               dev_err(card->dev, "unable to enable MCLK\n");
++      else
++              priv->mclk_enabled = true;
+       ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(runtime, 0), 0, 19200000,
+                                    SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               dev_err(card->dev, "can't set codec clock %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       ret = snd_soc_card_jack_new(card, "Headset",
+@@ -239,13 +251,25 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+                                   ARRAY_SIZE(byt_cht_es8316_jack_pins));
+       if (ret) {
+               dev_err(card->dev, "jack creation failed %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+       snd_soc_component_set_jack(codec, &priv->jack, NULL);
+       return 0;
++
++err_disable_mclk:
++      byt_cht_es8316_disable_mclk(priv);
++      return ret;
++}
++
++static void byt_cht_es8316_exit(struct snd_soc_pcm_runtime *runtime)
++{
++      struct snd_soc_card *card = runtime->card;
++      struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
++
++      byt_cht_es8316_disable_mclk(priv);
+ }
+ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
+@@ -359,6 +383,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
+               .dpcm_playback = 1,
+               .dpcm_capture = 1,
+               .init = byt_cht_es8316_init,
++              .exit = byt_cht_es8316_exit,
+               SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
+       },
+ };
+-- 
+2.53.0
+
diff --git a/queue-5.10/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch b/queue-5.10/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
new file mode 100644 (file)
index 0000000..60c8e51
--- /dev/null
@@ -0,0 +1,40 @@
+From 99097967b8448ea12a6eb9c660d3e25919ada1a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 11:21:39 +0800
+Subject: Bluetooth: 6lowpan: check skb_clone() return value in
+ send_mcast_pkt()
+
+From: Zhao Dongdong <zhaodongdong@kylinos.cn>
+
+[ Upstream commit 3c40d381ce04f9575a5d8b542898183c3b4b38dc ]
+
+The skb_clone() function can return NULL if memory allocation fails.
+send_mcast_pkt() calls skb_clone() without checking the return value, which
+can lead to a NULL pointer dereference in send_pkt() when it dereferences
+skb->data.
+Add a NULL check after skb_clone() and skip the peer if the clone fails.
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Signed-off-by: Zhao Dongdong <zhaodongdong@kylinos.cn>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 9486d66863264f..4ab9a31163b8b9 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -514,6 +514,8 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
+                       int ret;
+                       local_skb = skb_clone(skb, GFP_ATOMIC);
++                      if (!local_skb)
++                              continue;
+                       BT_DBG("xmit %s to %pMR type %d IP %pI6c chan %p",
+                              netdev->name,
+-- 
+2.53.0
+
diff --git a/queue-5.10/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch b/queue-5.10/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
new file mode 100644 (file)
index 0000000..f9fd9ed
--- /dev/null
@@ -0,0 +1,62 @@
+From 6de26b442267ad5e492d04210eda6dc221d170dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 18:51:52 +0800
+Subject: Bluetooth: l2cap: clear chan->ident on ECRED reconfiguration success
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit 00e1950716c6ed67d74777b2db286b0fa23b4be9 ]
+
+l2cap_ecred_reconf_rsp() returns early on success without clearing
+chan->ident. Every other L2CAP response handler (l2cap_ecred_conn_rsp,
+l2cap_le_connect_rsp, l2cap_config_rsp) clears chan->ident after a
+successful transaction to prevent the channel from matching subsequent
+responses with the recycled ident value.
+
+A remote attacker that completed a reconfiguration as the peer can
+replay a failure response with the stale ident, causing the kernel to
+match and destroy the already-established channel via
+l2cap_chan_del(chan, ECONNRESET).
+
+Clear chan->ident for all matching channels on success, and harden the
+failure path by using l2cap_chan_hold_unless_zero() consistent with
+other L2CAP handlers (l2cap_le_command_rej, __l2cap_get_chan_by_ident).
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 45e1e8192e3b63..f30624d20bb09c 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -6432,14 +6432,20 @@ static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
+       BT_DBG("result 0x%4.4x", result);
+-      if (!result)
++      if (!result) {
++              list_for_each_entry(chan, &conn->chan_l, list) {
++                      if (chan->ident == cmd->ident)
++                              chan->ident = 0;
++              }
+               return 0;
++      }
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
+               if (chan->ident != cmd->ident)
+                       continue;
+-              l2cap_chan_hold(chan);
++              if (!l2cap_chan_hold_unless_zero(chan))
++                      continue;
+               l2cap_chan_lock(chan);
+               l2cap_chan_del(chan, ECONNRESET);
+-- 
+2.53.0
+
diff --git a/queue-5.10/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch b/queue-5.10/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
new file mode 100644 (file)
index 0000000..99a7242
--- /dev/null
@@ -0,0 +1,82 @@
+From 97edb9709a81e78c204c6860da277bb0d1ca6831 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 May 2026 12:09:42 -0400
+Subject: Bluetooth: L2CAP: Fix possible crash on l2cap_ecred_conn_rsp
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 41c2713b204e6cb6a94587bc6bf6935107df5479 ]
+
+If dcid is received for an already-assigned destination CID the spec
+requires that both channels to be discarded, but calling l2cap_chan_del
+may invalidate the tmp cursor created by list_for_each_entry_safe and
+in fact it is the wrong procedure as the chan->dcid may be assigned
+previously it really needs to be disconnected.
+
+Calling l2cap_chan_clone directly may still lead to l2cap_chan_del so
+instead schedule l2cap_chan_timeout with delay 0 to close the channel
+asynchronously.
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 27 ++++++++++++++++++++++-----
+ 1 file changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index f30624d20bb09c..89e770f359ef20 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -6232,6 +6232,7 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+       cmd_len -= sizeof(*rsp);
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
++              struct l2cap_chan *orig;
+               u16 dcid;
+               if (chan->ident != cmd->ident ||
+@@ -6253,8 +6254,10 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+               BT_DBG("dcid[%d] 0x%4.4x", i, dcid);
++              orig = __l2cap_get_chan_by_dcid(conn, dcid);
++
+               /* Check if dcid is already in use */
+-              if (dcid && __l2cap_get_chan_by_dcid(conn, dcid)) {
++              if (dcid && orig) {
+                       /* If a device receives a
+                        * L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an
+                        * already-assigned Destination CID, then both the
+@@ -6263,10 +6266,24 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+                        */
+                       l2cap_chan_del(chan, ECONNREFUSED);
+                       l2cap_chan_unlock(chan);
+-                      chan = __l2cap_get_chan_by_dcid(conn, dcid);
+-                      l2cap_chan_lock(chan);
+-                      l2cap_chan_del(chan, ECONNRESET);
+-                      l2cap_chan_unlock(chan);
++
++                      /* Check that the dcid channel mode is
++                       * L2CAP_MODE_EXT_FLOWCTL since this procedure is only
++                       * valid for that mode and shouldn't disconnect a dcid
++                       * in other modes.
++                       */
++                      if (orig->mode == L2CAP_MODE_EXT_FLOWCTL) {
++                              l2cap_chan_lock(orig);
++                              /* Disconnect the original channel as it may be
++                               * considered connected since dcid has already
++                               * been assigned; don't call l2cap_chan_close
++                               * directly since that could lead to
++                               * l2cap_chan_del and then removing the channel
++                               * from the list while we're iterating over it.
++                               */
++                              __set_chan_timer(orig, 0);
++                              l2cap_chan_unlock(orig);
++                      }
+                       continue;
+               }
+-- 
+2.53.0
+
diff --git a/queue-5.10/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch b/queue-5.10/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
new file mode 100644 (file)
index 0000000..c492073
--- /dev/null
@@ -0,0 +1,48 @@
+From 8387223e3a1ab5fa9a207ab58062fb01bcd83491 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 12:21:47 +0000
+Subject: ipv4: free net->ipv4.sysctl_local_reserved_ports after
+ unregister_net_sysctl_table()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 87a1e0fe7776da7ab411be332b4be58ac8840d10 ]
+
+ipv4_sysctl_exit_net() is currently freeing net->ipv4.sysctl_local_reserved_ports
+too soon.
+
+Only after unregister_net_sysctl_table() we can be sure no threads can possibly
+use the sysctls, including /proc/sys/net/ipv4/ip_local_reserved_ports.
+
+Fixes: 122ff243f5f1 ("ipv4: make ip_local_reserved_ports per netns")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Link: https://patch.msgid.link/20260521122147.3584624-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/sysctl_net_ipv4.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 59ba518a85b9c9..56c60af2a32f25 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -1362,10 +1362,10 @@ static __net_exit void ipv4_sysctl_exit_net(struct net *net)
+ {
+       struct ctl_table *table;
+-      kfree(net->ipv4.sysctl_local_reserved_ports);
+       table = net->ipv4.ipv4_hdr->ctl_table_arg;
+       unregister_net_sysctl_table(net->ipv4.ipv4_hdr);
+       kfree(table);
++      kfree(net->ipv4.sysctl_local_reserved_ports);
+ }
+ static __net_initdata struct pernet_operations ipv4_sysctl_ops = {
+-- 
+2.53.0
+
diff --git a/queue-5.10/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch b/queue-5.10/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
new file mode 100644 (file)
index 0000000..57fc587
--- /dev/null
@@ -0,0 +1,62 @@
+From 7683b3ae63a7c9806a2d9fed11de389935ce74c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 21:10:31 +0530
+Subject: ipv6: rpl: fix hdrlen overflow in ipv6_rpl_srh_decompress()
+
+From: Rahul Chandelkar <rc@rexion.ai>
+
+[ Upstream commit 9d5e7a46a9f6d8f503b41bfefef70659845f1679 ]
+
+ipv6_rpl_srh_decompress() computes:
+
+    outhdr->hdrlen = (((n + 1) * sizeof(struct in6_addr)) >> 3);
+
+hdrlen is __u8. For n >= 127 the result exceeds 255 and silently
+truncates. With n=127 (cmpri=15, cmpre=15, pad=0, hdrlen=16):
+
+    (128 * 16) >> 3 = 256, truncated to 0 as __u8
+
+The caller in ipv6_rpl_srh_rcv() then places the compressed header
+at buf + ((ohdr->hdrlen + 1) << 3). With hdrlen=0 this is buf + 8,
+but the decompressed region occupies buf[0..2055] (8-byte header
+plus 128 full addresses). The compressed header overlaps the
+decompressed data, and ipv6_rpl_srh_compress() writes into this
+overlap, corrupting the routing header of the forwarded packet.
+
+The existing guard at exthdrs.c:546 checks (n + 1) > 255, which
+prevents n+1 from overflowing unsigned char (the segments_left
+field), but does not prevent the computed hdrlen from overflowing
+__u8. n=127 passes because 128 <= 255, yet hdrlen=256 does not
+fit.
+
+Tighten the bound to (n + 1) > 127. This caps n at 126, giving
+hdrlen = (127 * 16) >> 3 = 254, which fits in __u8. The compressed
+header then lands at buf + ((254 + 1) << 3) = buf + 2040, exactly
+past the decompressed region (buf[0..2039]). No overlap. 127
+segments is well beyond any realistic RPL deployment.
+
+Fixes: 8610c7c6e3bd ("net: ipv6: add support for rpl sr exthdr")
+Signed-off-by: Rahul Chandelkar <rc@rexion.ai>
+Link: https://patch.msgid.link/20260525154031.2290876-1-rc@rexion.ai
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index 924f3d7901f09c..1bef03e2d8fc98 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -544,7 +544,7 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
+        * unsigned char which is segments_left field. Should not be
+        * higher than that.
+        */
+-      if (r || (n + 1) > 255) {
++      if (r || (n + 1) > 127) {
+               kfree_skb(skb);
+               return -1;
+       }
+-- 
+2.53.0
+
diff --git a/queue-5.10/kernel-fork-validate-exit_signal-in-kernel_clone.patch b/queue-5.10/kernel-fork-validate-exit_signal-in-kernel_clone.patch
new file mode 100644 (file)
index 0000000..4c30f72
--- /dev/null
@@ -0,0 +1,116 @@
+From a0005d47f58bc6f93e86a11077474ff6486760e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Mar 2026 20:49:56 +0530
+Subject: kernel/fork: validate exit_signal in kernel_clone()
+
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+
+[ Upstream commit 09e7827e785729f391c8d46dc71becce70d296ab ]
+
+When a child process exits, it sends exit_signal to its parent via
+do_notify_parent().  The clone() syscall constructs exit_signal as:
+
+(lower_32_bits(clone_flags) & CSIGNAL)
+
+CSIGNAL is 0xff, so values in the range 65-255 are possible.  However,
+valid_signal() only accepts signals up to _NSIG (64 on x86_64).  A
+non-zero non-valid exit_signal acts the same as exit_signal == 0: the
+parent process is not signaled when the child terminates.
+
+The syzkaller reproducer triggers this by calling clone() with flags=0x80,
+resulting in exit_signal = (0x80 & CSIGNAL) = 128, which exceeds _NSIG and
+is not a valid signal.
+
+The v1 of this patch added the check only in the clone() syscall handler,
+which is incomplete.  kernel_clone() has other callers such as
+sys_ia32_clone() which would remain unprotected.  Move the check to
+kernel_clone() to cover all callers.
+
+Since the valid_signal() check is now in kernel_clone() and covers all
+callers including clone3(), the same check in copy_clone_args_from_user()
+becomes redundant and is removed.  The higher 32bits check for clone3() is
+kept as it is clone3() specific.
+
+Note that this is a user-visible change: previously, passing an invalid
+exit_signal to clone() was silently accepted.  The man page for clone()
+does not document any defined behavior for invalid exit_signal values, so
+rejecting them with -EINVAL is the correct behavior.  It is unlikely that
+any sane application relies on passing an invalid exit_signal.
+
+[oleg@redhat.com: the comment above kernel_clone() should be updated]
+  Link: https://lore.kernel.org/abwvgU17W8wuW2-J@redhat.com
+Link: https://lore.kernel.org/20260316151956.563558-1-kartikey406@gmail.com
+Fixes: 3f2c788a1314 ("fork: prevent accidental access to clone3 features")
+Signed-off-by: Deepanshu Kartikey <Kartikey406@gmail.com>
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Reported-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bbe6b99feefc3a0842de
+Tested-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/20260307064202.353405-1-kartikey406@gmail.com/T/ [v1]
+Link: https://lore.kernel.org/all/20260316104536.558108-1-kartikey406@gmail.com/T/ [v2]
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Ben Segall <bsegall@google.com>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Juri Lelli <juri.lelli@redhat.com>
+Cc: Kees Cook <kees@kernel.org>
+Cc: Liam Howlett <liam@infradead.org>
+Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Valentin Schneider <vschneid@redhat.com>
+Cc: Vincent Guittot <vincent.guittot@linaro.org>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/fork.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 531de2d1b3bfeb..d35416380c6344 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -2535,8 +2535,6 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
+  *
+  * It copies the process, and if successful kick-starts
+  * it and waits for it to finish using the VM if required.
+- *
+- * args->exit_signal is expected to be checked for sanity by the caller.
+  */
+ pid_t kernel_clone(struct kernel_clone_args *args)
+ {
+@@ -2561,6 +2559,9 @@ pid_t kernel_clone(struct kernel_clone_args *args)
+           (args->pidfd == args->parent_tid))
+               return -EINVAL;
++      if (!valid_signal(args->exit_signal))
++              return -EINVAL;
++
+       /*
+        * Determine whether and which event to report to ptracer.  When
+        * called from kernel_thread or CLONE_UNTRACED is explicitly
+@@ -2737,11 +2738,9 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
+               return -EINVAL;
+       /*
+-       * Verify that higher 32bits of exit_signal are unset and that
+-       * it is a valid signal
++       * Verify that higher 32bits of exit_signal are unset
+        */
+-      if (unlikely((args.exit_signal & ~((u64)CSIGNAL)) ||
+-                   !valid_signal(args.exit_signal)))
++      if (unlikely(args.exit_signal & ~((u64)CSIGNAL)))
+               return -EINVAL;
+       if ((args.flags & CLONE_INTO_CGROUP) &&
+-- 
+2.53.0
+
diff --git a/queue-5.10/net-iucv-fix-locking-in-.getsockopt.patch b/queue-5.10/net-iucv-fix-locking-in-.getsockopt.patch
new file mode 100644 (file)
index 0000000..9d6cebb
--- /dev/null
@@ -0,0 +1,87 @@
+From 200d1491cb96e9d7785abdab3eda2a5a4047d664 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 07:11:45 -0700
+Subject: net/iucv: fix locking in .getsockopt
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 3589d20a666caf30ad100c960a2de7de390fce88 ]
+
+Mirror iucv_sock_setsockopt() and wrap the whole switch in
+lock_sock()/release_sock(). The pre-existing SO_MSGLIMIT-only lock
+becomes redundant and is removed.
+
+Any AF_IUCV HIPER user can potentially crash the kernel by racing
+recvmsg() with getsockopt(SO_MSGSIZE): the SO_MSGSIZE arm dereferences
+iucv->hs_dev->mtu after iucv_sock_close() (called from the racing
+recvmsg()) has set hs_dev to NULL, producing a NULL pointer dereference
+oops.
+
+Suggested-by: Stanislav Fomichev <sdf.kernel@gmail.com>
+Fixes: 51363b8751a6 ("af_iucv: allow retrieval of maximum message size")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Tested-by: Alexandra Winter <wintera@linux.ibm.com>
+Link: https://patch.msgid.link/20260521-af_iucv_fix2-v1-1-f16b1c510aa9@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index 3d0424e4ae6c9c..8c08f07ce46551 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -1550,7 +1550,7 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       struct sock *sk = sock->sk;
+       struct iucv_sock *iucv = iucv_sk(sk);
+       unsigned int val;
+-      int len;
++      int len, rc;
+       if (level != SOL_IUCV)
+               return -ENOPROTOOPT;
+@@ -1563,26 +1563,34 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       len = min_t(unsigned int, len, sizeof(int));
++      rc = 0;
++
++      lock_sock(sk);
+       switch (optname) {
+       case SO_IPRMDATA_MSG:
+               val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0;
+               break;
+       case SO_MSGLIMIT:
+-              lock_sock(sk);
+               val = (iucv->path != NULL) ? iucv->path->msglim /* connected */
+                                          : iucv->msglimit;    /* default */
+-              release_sock(sk);
+               break;
+       case SO_MSGSIZE:
+-              if (sk->sk_state == IUCV_OPEN)
+-                      return -EBADFD;
++              if (sk->sk_state == IUCV_OPEN) {
++                      rc = -EBADFD;
++                      break;
++              }
+               val = (iucv->hs_dev) ? iucv->hs_dev->mtu -
+                               sizeof(struct af_iucv_trans_hdr) - ETH_HLEN :
+                               0x7fffffff;
+               break;
+       default:
+-              return -ENOPROTOOPT;
++              rc = -ENOPROTOOPT;
++              break;
+       }
++      release_sock(sk);
++
++      if (rc)
++              return rc;
+       if (put_user(len, optlen))
+               return -EFAULT;
+-- 
+2.53.0
+
diff --git a/queue-5.10/net-netlink-don-t-set-nsid-on-local-notifications.patch b/queue-5.10/net-netlink-don-t-set-nsid-on-local-notifications.patch
new file mode 100644 (file)
index 0000000..6f2d0de
--- /dev/null
@@ -0,0 +1,82 @@
+From 6a11c8990d2307fb8af17ef7e5915d8464a1986a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:36 +0200
+Subject: net: netlink: don't set nsid on local notifications
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 88b126b39f9757e9debc322d4679239e9af089c7 ]
+
+In most cases, notifications on sockets with NETLINK_LISTEN_ALL_NSID
+do not contain NSID in their ancillary data in case the event is local
+to the listener.
+
+However, when a self-referential NSID is allocated for a namespace,
+every local notification starts sending this ID to the user space.
+
+This is problematic, because the listener cannot tell if those
+notifications are local or not anymore without making extra requests
+to figure out if the provided NSID is local or not.  The listener
+can also not figure out the local NSID beforehand as it can be
+allocated at any point in time by other processes, changing the
+structure of the future notifications for everyone.
+
+The value is practically not useful, since it's the namespace's own
+ID that the application has to obtain from other sources in order to
+figure out if it's the same or not.  So, for the application it's
+just an extra busy work with no benefits.  Moreover, applications
+that do not know about this quirk may be mishandling notifications
+with NSID set as notifications from remote namespaces.  This is the
+case for ovs-vswitchd and the iproute2's 'ip monitor' that stops
+printing 'current' and starts printing the nsid number mid-session.
+
+Lack of clear documentation for this behavior is also not helping.
+
+A search though open-source projects doesn't reveal any projects
+that use NETNSA_NSID_NOT_ASSIGNED and rely on metadata to contain
+self-referential NSIDs (expected, since the value is not useful).
+Quite the opposite, as already mentioned, there are few applications
+that rely on NSID to not be present in local events.
+
+Since the value is not useful and actively harmful in some cases,
+let's not report it for local events, making the notifications more
+consistent.
+
+Also adding some blank lines for readability.
+
+Fixes: 59324cf35aba ("netlink: allow to listen "all" netns")
+Reported-by: Matteo Perin <matteo.perin@canonical.com>
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-3-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index e8301a36926275..e091b65c9d2b8c 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1478,10 +1478,14 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++
+       NETLINK_CB(p->skb2).nsid_is_set = false;
+-      NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+-      if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+-              NETLINK_CB(p->skb2).nsid_is_set = true;
++      if (!net_eq(sock_net(sk), p->net)) {
++              NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
++              if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
++                      NETLINK_CB(p->skb2).nsid_is_set = true;
++      }
++
+       val = netlink_broadcast_deliver(sk, p->skb2);
+       if (val < 0) {
+               netlink_overrun(sk);
+-- 
+2.53.0
+
diff --git a/queue-5.10/net-netlink-fix-sending-unassigned-nsid-after-assign.patch b/queue-5.10/net-netlink-fix-sending-unassigned-nsid-after-assign.patch
new file mode 100644 (file)
index 0000000..8f7876b
--- /dev/null
@@ -0,0 +1,45 @@
+From e1c9cea05f136a683f0b2f38c317ccfc608060f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:35 +0200
+Subject: net: netlink: fix sending unassigned nsid after assigned one
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 70f8592ee90585272018a725054b6eb2ab7e99ca ]
+
+If the current skb is not shared, it is re-used directly for all the
+sockets subscribed to the notification.  If we have remote all-nsid
+socket receiving a message first, then the 'nsid_is_set' will be
+set to 'true'.  If the nsid is NOT_ASSIGNED for the next socket in
+the list, the 'nsid_is_set' will remain 'true' and the negative value
+is be delivered to the user space.  All subsequent nsid values will be
+delivered as well, since there is no code path that sets the flag
+back to 'false'.
+
+Fix that by always dropping the flag to 'false' first.
+
+Fixes: 7212462fa6fd ("netlink: don't send unknown nsid")
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-2-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 42b7b8574f0994..e8301a36926275 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1478,6 +1478,7 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++      NETLINK_CB(p->skb2).nsid_is_set = false;
+       NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+       if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+               NETLINK_CB(p->skb2).nsid_is_set = true;
+-- 
+2.53.0
+
diff --git a/queue-5.10/net-sched-revert-net-sched-restrict-conditions-for-a.patch b/queue-5.10/net-sched-revert-net-sched-restrict-conditions-for-a.patch
new file mode 100644 (file)
index 0000000..b70abc0
--- /dev/null
@@ -0,0 +1,102 @@
+From 6108f7bd8568b3eef23632da7db59c43bbbd6681 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:49 -0400
+Subject: net/sched: Revert "net/sched: Restrict conditions for adding
+ duplicating netems to qdisc tree"
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit eda0b7f203bb166c98d1418b204135bd566ac83b ]
+
+This reverts commit ec8e0e3d7adef940cdf9475e2352c0680189d14e.
+
+The original patch rejects any tree containing two netems when
+either has duplication set, even when they sit on unrelated classes
+of the same classful parent. That broke configurations that have
+worked since netem was introduced.
+
+The re-entrancy problem the original commit was trying to solve is
+handled by later patch using tc_depth flag.
+
+Doing this revert will (re)expose the original bug with multiple
+netem duplication. When this patch is backported make sure
+and get the full series.
+
+Fixes: ec8e0e3d7ade ("net/sched: Restrict conditions for adding duplicating netems to qdisc tree")
+Reported-by: Ji-Soo Chung <jschung2@proton.me>
+Reported-by: Gerlinde <lrGerlinde@mailfence.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220774
+Reported-by: zyc zyc <zyc199902@zohomail.cn>
+Closes: https://lore.kernel.org/all/19adda5a1e2.12410b78222774.9191120410578703463@zohomail.cn/
+Reported-by: Manas Ghandat <ghandatmanas@gmail.com>
+Closes: https://lore.kernel.org/netdev/f69b2c8f-8325-4c2e-a011-6dbc089f30e4@gmail.com/
+Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-3-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_netem.c | 40 ----------------------------------------
+ 1 file changed, 40 deletions(-)
+
+diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
+index 3e3bced82c564d..3dc6411b0a33c7 100644
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -985,41 +985,6 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
+       return 0;
+ }
+-static const struct Qdisc_class_ops netem_class_ops;
+-
+-static int check_netem_in_tree(struct Qdisc *sch, bool duplicates,
+-                             struct netlink_ext_ack *extack)
+-{
+-      struct Qdisc *root, *q;
+-      unsigned int i;
+-
+-      root = qdisc_root_sleeping(sch);
+-
+-      if (sch != root && root->ops->cl_ops == &netem_class_ops) {
+-              if (duplicates ||
+-                  ((struct netem_sched_data *)qdisc_priv(root))->duplicate)
+-                      goto err;
+-      }
+-
+-      if (!qdisc_dev(root))
+-              return 0;
+-
+-      hash_for_each(qdisc_dev(root)->qdisc_hash, i, q, hash) {
+-              if (sch != q && q->ops->cl_ops == &netem_class_ops) {
+-                      if (duplicates ||
+-                          ((struct netem_sched_data *)qdisc_priv(q))->duplicate)
+-                              goto err;
+-              }
+-      }
+-
+-      return 0;
+-
+-err:
+-      NL_SET_ERR_MSG(extack,
+-                     "netem: cannot mix duplicating netems with other netems in tree");
+-      return -EINVAL;
+-}
+-
+ /* Parse netlink message to set options */
+ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+                       struct netlink_ext_ack *extack)
+@@ -1087,11 +1052,6 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+       q->gap = qopt->gap;
+       q->counter = 0;
+       q->loss = qopt->loss;
+-
+-      ret = check_netem_in_tree(sch, qopt->duplicate, extack);
+-      if (ret)
+-              goto unlock;
+-
+       q->duplicate = qopt->duplicate;
+       /* for compatibility with earlier versions.
+-- 
+2.53.0
+
diff --git a/queue-5.10/net-smc-do-not-re-initialize-smc-hashtables.patch b/queue-5.10/net-smc-do-not-re-initialize-smc-hashtables.patch
new file mode 100644 (file)
index 0000000..e8b00e5
--- /dev/null
@@ -0,0 +1,59 @@
+From c7d3001ab6725bfcfb1afea386cd399ac7757355 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 16:56:39 +0200
+Subject: net/smc: Do not re-initialize smc hashtables
+
+From: Alexandra Winter <wintera@linux.ibm.com>
+
+[ Upstream commit 9e4389b0038781f19f97895186ed941ff8ac1678 ]
+
+INIT_HLIST_HEAD(&smc_v*_hashinfo.ht) are called after smc_nl_init(),
+proto_register() and sock_register(). This can lead to smc_v*_hashinfo.ht
+being reset even though hash entries already exist and are being used,
+possibly resulting in a corrupted list.
+
+Remove unnecessary and dangerous re-initialisation of smc_v*_hashinfo.ht in
+smc_init(); it is implicitly initialised to zero anyhow. Add
+HLIST_HEAD_INIT to the definitions for clarity.
+
+Fixes: f16a7dd5cf27 ("smc: netlink interface for SMC sockets")
+Suggested-by: Halil Pasic <pasic@linux.ibm.com>
+Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
+Acked-by: Halil Pasic <pasic@linux.ibm.com>
+Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
+Link: https://patch.msgid.link/20260521145639.10317-1-wintera@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index d64cfd651c7a16..8e1e38bc0df4b0 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -71,10 +71,12 @@ static void smc_set_keepalive(struct sock *sk, int val)
+ static struct smc_hashinfo smc_v4_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v4_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ static struct smc_hashinfo smc_v6_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v6_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ int smc_hash_sk(struct sock *sk)
+@@ -2586,8 +2588,6 @@ static int __init smc_init(void)
+               pr_err("%s: sock_register fails with %d\n", __func__, rc);
+               goto out_proto6;
+       }
+-      INIT_HLIST_HEAD(&smc_v4_hashinfo.ht);
+-      INIT_HLIST_HEAD(&smc_v6_hashinfo.ht);
+       rc = smc_ib_register_client();
+       if (rc) {
+-- 
+2.53.0
+
diff --git a/queue-5.10/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch b/queue-5.10/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
new file mode 100644 (file)
index 0000000..f3a4a27
--- /dev/null
@@ -0,0 +1,107 @@
+From 726842b11ce35b013de3eccf92eb12f6977b88d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 22:52:07 +0200
+Subject: netfilter: ebtables: fix OOB read in compat_mtw_from_user
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit f438d1786d657d57790c5d138d6db3fc9fdac392 ]
+
+Luxiao Xu says:
+
+ The function compat_mtw_from_user() converts ebtables extensions from
+ 32-bit user structures to kernel native structures. However, it lacks
+ proper validation of the user-supplied match_size/target_size.
+
+ When certain extensions are processed, the kernel-side translation
+ logic may perform memory accesses based on the extension's expected
+ size. If the user provides a size smaller than what the extension
+ requires, it results in an out-of-bounds read as reported by KASAN.
+
+ This fix introduces a check to ensure match_size is at least as large
+ as the extension's required compatsize. This covers matches, watchers,
+ and targets, while maintaining compatibility with standard targets.
+
+AFAIU this is relevant for matches that need to go though
+match->compat_from_user() call.  Those that use plain memcpy with the
+user-provided size are ok because the caller checks that size vs the
+start of the next rule entry offset (which itself is checked vs. total
+size copied from userspace).
+
+The ->compat_from_user() callbacks assume they can read compatsize bytes,
+so they need this extra check.
+
+Based on an earlier patch from Luxiao Xu.
+
+Fixes: 81e675c227ec ("netfilter: ebtables: add CONFIG_COMPAT support")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/netfilter/ebtables.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
+index 14a06d8b1a2d0e..e86695f1ed95b6 100644
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1838,6 +1838,25 @@ enum compat_mwt {
+       EBT_COMPAT_TARGET,
+ };
++static bool match_size_ok(const struct xt_match *match, unsigned int match_size)
++{
++      u16 csize;
++
++      if (match->matchsize == -1) /* cannot validate ebt_among */
++              return true;
++
++      csize = match->compatsize ? : match->matchsize;
++
++      return match_size >= csize;
++}
++
++static bool tgt_size_ok(const struct xt_target *tgt, unsigned int tgt_size)
++{
++      u16 csize = tgt->compatsize ? : tgt->targetsize;
++
++      return tgt_size >= csize;
++}
++
+ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                               enum compat_mwt compat_mwt,
+                               struct ebt_entries_buf_state *state,
+@@ -1863,6 +1882,11 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+               if (IS_ERR(match))
+                       return PTR_ERR(match);
++              if (!match_size_ok(match, match_size)) {
++                      module_put(match->me);
++                      return -EINVAL;
++              }
++
+               off = ebt_compat_match_offset(match, match_size);
+               if (dst) {
+                       if (match->compat_from_user)
+@@ -1882,6 +1906,12 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                                           mwt->u.revision);
+               if (IS_ERR(wt))
+                       return PTR_ERR(wt);
++
++              if (!tgt_size_ok(wt, match_size)) {
++                      module_put(wt->me);
++                      return -EINVAL;
++              }
++
+               off = xt_compat_target_offset(wt);
+               if (dst) {
+-- 
+2.53.0
+
diff --git a/queue-5.10/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch b/queue-5.10/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
new file mode 100644 (file)
index 0000000..3ffe854
--- /dev/null
@@ -0,0 +1,68 @@
+From a423456ef8237a1b0351d7014b8346e020b59428 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 12:36:14 -0700
+Subject: netfilter: synproxy: refresh tcphdr after skb_ensure_writable
+
+From: Chris Mason <clm@meta.com>
+
+[ Upstream commit 92170e6afe927ab2792a3f71902845789c8e31b1 ]
+
+synproxy_tstamp_adjust() rewrites the TCP timestamp option in place
+and then patches the TCP checksum via inet_proto_csum_replace4() on
+the caller-supplied tcphdr pointer.  Both ipv4_synproxy_hook() and
+ipv6_synproxy_hook() obtain that pointer with skb_header_pointer()
+before calling in, so it may either alias skb->head directly or
+point at the caller's on-stack _tcph buffer.
+
+Between obtaining the pointer and using it, the function calls
+skb_ensure_writable(skb, optend), which on a cloned or non-linear
+skb invokes pskb_expand_head() and frees the old skb->head.  After
+that point the cached th is stale:
+
+    caller (ipv[46]_synproxy_hook)
+      th = skb_header_pointer(skb, ..., &_tcph)
+      synproxy_tstamp_adjust(skb, protoff, th, ...)
+        skb_ensure_writable(skb, optend)
+          pskb_expand_head()        /* kfree(old skb->head) */
+        ...
+        inet_proto_csum_replace4(&th->check, ...)
+                                    /* writes into freed head, or
+                                       into the caller's stack copy
+                                       leaving the on-wire checksum
+                                       stale */
+
+The option bytes are written through skb->data and are fine; only
+the checksum update goes through th and so lands in the wrong
+place.  The result is either a write into freed slab memory or a
+packet leaving with a checksum that does not match its payload.
+
+Fix by re-deriving th from skb->data + protoff immediately after
+skb_ensure_writable() succeeds, so the subsequent checksum update
+targets the linear, writable header.
+
+Fixes: 48b1de4c110a ("netfilter: add SYNPROXY core/target")
+Assisted-by: kres (claude-opus-4-7)
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-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_synproxy_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c
+index 2dfc5dae065638..0a97b1a0f53e45 100644
+--- a/net/netfilter/nf_synproxy_core.c
++++ b/net/netfilter/nf_synproxy_core.c
+@@ -199,6 +199,8 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff,
+       if (skb_ensure_writable(skb, optend))
+               return 0;
++      th = (struct tcphdr *)(skb->data + protoff);
++
+       while (optoff < optend) {
+               unsigned char *op = skb->data + optoff;
+-- 
+2.53.0
+
diff --git a/queue-5.10/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch b/queue-5.10/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
new file mode 100644 (file)
index 0000000..a92e3a8
--- /dev/null
@@ -0,0 +1,48 @@
+From b0a577765533a520b2c41a8309930711a56a96f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 20:10:08 +0200
+Subject: netfilter: xt_cpu: prefer raw_smp_processor_id
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit c376f07e16c02239ed44cabb97145d03f65b4d15 ]
+
+With PREEMPT_RCU we get splat:
+
+BUG: using smp_processor_id() in preemptible [..]
+caller is cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+CPU: 1 .. Comm: syz.3.1377 #0 PREEMPT(full)
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
+ check_preemption_disabled+0xd3/0xe0 lib/smp_processor_id.c:47
+ cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+ [..]
+
+Just use raw version instead.
+This is similar to 14d14a5d2957 ("netfilter: nft_meta: use raw_smp_processor_id()").
+
+Fixes: 0ca743a55991 ("netfilter: nf_tables: add compatibility layer for x_tables")
+Reported-by: syzbot+690d3e3ffa7335ac10eb@syzkaller.appspotmail.com
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_cpu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/xt_cpu.c b/net/netfilter/xt_cpu.c
+index 3bdc302a0f9137..9cb259902a586b 100644
+--- a/net/netfilter/xt_cpu.c
++++ b/net/netfilter/xt_cpu.c
+@@ -34,7 +34,7 @@ static bool cpu_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       const struct xt_cpu_info *info = par->matchinfo;
+-      return (info->cpu == smp_processor_id()) ^ info->invert;
++      return (info->cpu == raw_smp_processor_id()) ^ info->invert;
+ }
+ static struct xt_match cpu_mt_reg __read_mostly = {
+-- 
+2.53.0
+
diff --git a/queue-5.10/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch b/queue-5.10/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
new file mode 100644 (file)
index 0000000..51abcfa
--- /dev/null
@@ -0,0 +1,40 @@
+From 2e53644607b94bed67568d7d64845dc3525c39ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:41 +0000
+Subject: nfc: llcp: Fix use-after-free in llcp_sock_release()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit f4268b466190dae95a7585f69b4f1f8ad097632c ]
+
+llcp_sock_release() unconditionally unlinks the socket from the local
+sockets list.  However, if the socket is still in connecting state, it
+is on the connecting list.
+
+Fix this by checking the socket state and unlinking from the correct list.
+
+Fixes: b4011239a08e ("NFC: llcp: Fix non blocking sockets connections")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-1-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_sock.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index dc96d751eb278f..57dea580c02912 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -628,6 +628,8 @@ static int llcp_sock_release(struct socket *sock)
+       if (sock->type == SOCK_RAW)
+               nfc_llcp_sock_unlink(&local->raw_sockets, sk);
++      else if (sk->sk_state == LLCP_CONNECTING)
++              nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       else
+               nfc_llcp_sock_unlink(&local->sockets, sk);
+-- 
+2.53.0
+
diff --git a/queue-5.10/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch b/queue-5.10/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
new file mode 100644 (file)
index 0000000..f04dd3a
--- /dev/null
@@ -0,0 +1,67 @@
+From 22e49b9395b9e8ee28179cd4097f4c14c6bc9d1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:42 +0000
+Subject: nfc: llcp: Fix use-after-free race in nfc_llcp_recv_cc()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit b493ea2765cc17cb8aa7e7544a4b6dcb05b6ed77 ]
+
+A race condition exists in the NFC LLCP connection state machine where
+the connection acceptance packet (CC) can be processed concurrently with
+socket release.  This can lead to a use-after-free of the socket object.
+
+When nfc_llcp_recv_cc() moves the socket from the connecting_sockets
+list to the sockets list, it does so without holding the socket lock.
+If llcp_sock_release() is executing concurrently, it might have already
+unlinked the socket and dropped its references, which can result in
+nfc_llcp_recv_cc() linking a freed socket into the live list.
+
+Fix this by holding lock_sock() during the state transition and list
+movement in nfc_llcp_recv_cc().  After acquiring the lock, check if
+the socket is still hashed to ensure it hasn't already been unlinked
+and marked for destruction by the release path.  This aligns the locking
+pattern with recv_hdlc() and recv_disc().
+
+Fixes: a69f32af86e3 ("NFC: Socket linked list")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-2-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_core.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
+index e04634f22b49f4..c7de44637e0187 100644
+--- a/net/nfc/llcp_core.c
++++ b/net/nfc/llcp_core.c
+@@ -1225,6 +1225,15 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk = &llcp_sock->sk;
++      lock_sock(sk);
++
++      /* Check if socket was destroyed whilst waiting for the lock */
++      if (!sk_hashed(sk)) {
++              release_sock(sk);
++              nfc_llcp_sock_put(llcp_sock);
++              return;
++      }
++
+       /* Unlink from connecting and link to the client array */
+       nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       nfc_llcp_sock_link(&local->sockets, sk);
+@@ -1236,6 +1245,8 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk->sk_state = LLCP_CONNECTED;
+       sk->sk_state_change(sk);
++      release_sock(sk);
++
+       nfc_llcp_sock_put(llcp_sock);
+ }
+-- 
+2.53.0
+
diff --git a/queue-5.10/nfc-llcp-protect-nfc_llcp_sock_unlink-calls.patch b/queue-5.10/nfc-llcp-protect-nfc_llcp_sock_unlink-calls.patch
new file mode 100644 (file)
index 0000000..5cf14bd
--- /dev/null
@@ -0,0 +1,53 @@
+From f10f48b7faffd49b71f57136c74e78144f3c2f18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Mar 2022 20:25:22 +0100
+Subject: nfc: llcp: protect nfc_llcp_sock_unlink() calls
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+[ Upstream commit a06b8044169f6d5c3eb34772c13d2c0c1b205352 ]
+
+nfc_llcp_sock_link() is called in all paths (bind/connect) as a last
+action, still protected with lock_sock().  When cleaning up in
+llcp_sock_release(), call nfc_llcp_sock_unlink() in a mirrored way:
+earlier and still under the lock_sock().
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: f4268b466190 ("nfc: llcp: Fix use-after-free in llcp_sock_release()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_sock.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index 6e1fba2084930e..dc96d751eb278f 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -626,6 +626,11 @@ static int llcp_sock_release(struct socket *sock)
+               }
+       }
++      if (sock->type == SOCK_RAW)
++              nfc_llcp_sock_unlink(&local->raw_sockets, sk);
++      else
++              nfc_llcp_sock_unlink(&local->sockets, sk);
++
+       if (llcp_sock->reserved_ssap < LLCP_SAP_MAX)
+               nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap);
+@@ -638,11 +643,6 @@ static int llcp_sock_release(struct socket *sock)
+       if (sk->sk_state == LLCP_DISCONNECTING)
+               return err;
+-      if (sock->type == SOCK_RAW)
+-              nfc_llcp_sock_unlink(&local->raw_sockets, sk);
+-      else
+-              nfc_llcp_sock_unlink(&local->sockets, sk);
+-
+ out:
+       sock_orphan(sk);
+       sock_put(sk);
+-- 
+2.53.0
+
diff --git a/queue-5.10/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch b/queue-5.10/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
new file mode 100644 (file)
index 0000000..8df818f
--- /dev/null
@@ -0,0 +1,83 @@
+From 38f6064f86d9a5679bd76961f4f70c45327d83f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 May 2026 19:55:18 +0800
+Subject: nfc: nxp-nci: i2c: use rising-edge IRQ on ACPI systems
+
+From: Carl Lee <carl.lee@amd.com>
+
+[ Upstream commit f23bf992d65a42007c517b060ca35cebdea3525a ]
+
+Some ACPI-based platforms report incorrect IRQ trigger types (e.g.
+IRQF_TRIGGER_HIGH), which can lead to interrupt storms.
+
+Use the historically working rising-edge trigger on ACPI systems to
+avoid this regression.
+
+Device Tree-based systems continue to use the firmware-provided
+trigger type.
+
+Fixes: 57be33f85e36 ("nfc: nxp-nci: remove interrupt trigger type")
+Signed-off-by: Carl Lee <carl.lee@amd.com>
+Tested-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Luca Stefani <luca.stefani.ge1@gmail.com>
+Link: https://patch.msgid.link/20260516-nfc-nxp-nci-i2c-restore-irq-trigger-fallback-v3-1-37ba4b6e9086@amd.com
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/nxp-nci/i2c.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c
+index 237b344a30bbd8..989b4a0e5b1982 100644
+--- a/drivers/nfc/nxp-nci/i2c.c
++++ b/drivers/nfc/nxp-nci/i2c.c
+@@ -16,6 +16,7 @@
+ #include <linux/delay.h>
+ #include <linux/i2c.h>
+ #include <linux/interrupt.h>
++#include <linux/irq.h>
+ #include <linux/module.h>
+ #include <linux/nfc.h>
+ #include <linux/gpio/consumer.h>
+@@ -268,6 +269,7 @@ static int nxp_nci_i2c_probe(struct i2c_client *client,
+ {
+       struct device *dev = &client->dev;
+       struct nxp_nci_i2c_phy *phy;
++      unsigned long irqflags;
+       int r;
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+@@ -304,9 +306,26 @@ static int nxp_nci_i2c_probe(struct i2c_client *client,
+       if (r < 0)
+               return r;
++      /*
++       * ACPI platforms may report incorrect IRQ trigger types
++       * (e.g. level-high), which can lead to interrupt storms.
++       *
++       * Use the historically stable rising-edge trigger for ACPI devices.
++       *
++       * On non-ACPI systems (e.g. Device Tree), prefer the firmware-
++       * provided trigger type, falling back to rising-edge if not set.
++       */
++      if (ACPI_COMPANION(dev)) {
++              irqflags = IRQF_TRIGGER_RISING;
++      } else {
++              irqflags = irq_get_trigger_type(client->irq);
++              if (!irqflags)
++                      irqflags = IRQF_TRIGGER_RISING;
++      }
++
+       r = request_threaded_irq(client->irq, NULL,
+                                nxp_nci_i2c_irq_thread_fn,
+-                               IRQF_ONESHOT,
++                               irqflags | IRQF_ONESHOT,
+                                NXP_NCI_I2C_DRIVER_NAME, phy);
+       if (r < 0)
+               nfc_err(&client->dev, "Unable to register IRQ handler\n");
+-- 
+2.53.0
+
diff --git a/queue-5.10/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch b/queue-5.10/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
new file mode 100644 (file)
index 0000000..b7d66f9
--- /dev/null
@@ -0,0 +1,50 @@
+From 19ad278c66758b38a247e8ae918b93d14526c765 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 11:24:11 +0800
+Subject: sctp: fix race between sctp_wait_for_connect and peeloff
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit f14fe6395a8b3d961a61e138ad7b36ba3626dd4e ]
+
+sctp_wait_for_connect() drops and re-acquires the socket lock while
+waiting for the association to reach ESTABLISHED state. During this
+window, another thread can peeloff the association to a new socket via
+getsockopt(SCTP_SOCKOPT_PEELOFF), changing asoc->base.sk. After
+re-acquiring the old socket lock, sctp_wait_for_connect() returns
+success without noticing the migration â€” the caller then accesses
+the association under the wrong lock in sctp_datamsg_from_user().
+
+Add the same sk != asoc->base.sk check that sctp_wait_for_sndbuf()
+already has, returning an error if the association was migrated while
+we slept.
+
+Fixes: 668c9beb9020 ("sctp: implement assign_number for sctp_stream_interleave")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260527032411.60959-1-kipreyyy@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/socket.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 8c7bdf01e32a17..150235d861411d 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -9133,6 +9133,8 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p)
+               release_sock(sk);
+               current_timeo = schedule_timeout(current_timeo);
+               lock_sock(sk);
++              if (sk != asoc->base.sk)
++                      goto do_error;
+               *timeo_p = current_timeo;
+       }
+-- 
+2.53.0
+
index f27a9a696b554d6efd099aa92d2deacfba91ed6f..c4aa23cf6edf9ef09adf2b6ee1e6909049b275df 100644 (file)
@@ -2,3 +2,28 @@ alsa-usb-audio-fix-null-pointer-dereference-on-point.patch
 net-sched-cls_fw-fix-null-dereference-of-old-filters.patch
 phy-renesas-rcar-gen3-usb2-fix-the-use-of-msleep-dur.patch
 net-sched-sch_sfb-replace-direct-dequeue-call-with-p.patch
+nfc-llcp-protect-nfc_llcp_sock_unlink-calls.patch
+nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
+nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
+xfrm-check-for-underflow-in-xfrm_state_mtu.patch
+nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
+kernel-fork-validate-exit_signal-in-kernel_clone.patch
+netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
+netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
+netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
+tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
+net-netlink-fix-sending-unassigned-nsid-after-assign.patch
+net-netlink-don-t-set-nsid-on-local-notifications.patch
+net-smc-do-not-re-initialize-smc-hashtables.patch
+net-iucv-fix-locking-in-.getsockopt.patch
+ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
+asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
+tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
+vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
+tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
+bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
+ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
+net-sched-revert-net-sched-restrict-conditions-for-a.patch
+bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
+bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
+sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
diff --git a/queue-5.10/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch b/queue-5.10/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
new file mode 100644 (file)
index 0000000..1424eef
--- /dev/null
@@ -0,0 +1,54 @@
+From df2478f5320d5c625cdb8ee9859c75537f567e6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 09:00:21 -0700
+Subject: tun: free page on short-frame rejection in tun_xdp_one()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f4feb1e20058e407cb00f45aff47f5b7e19a6bbf ]
+
+tun_xdp_one() returns -EINVAL on a frame shorter than ETH_HLEN without
+freeing the page that vhost_net_build_xdp() allocated for it.
+tun_sendmsg() discards that -EINVAL and still returns total_len, so
+vhost_tx_batch() takes the success path and never frees the page; each
+short frame in a batch leaks one page-frag chunk.
+
+A local process that can open /dev/net/tun and /dev/vhost-net can hit
+this path: it attaches a tun/tap device as the vhost-net backend and
+feeds TX descriptors whose length minus the virtio-net header is below
+ETH_HLEN. Each kick leaks the page-frag chunks for that batch, and a
+tight submission loop exhausts host memory and triggers an OOM panic.
+Free the page before returning -EINVAL, matching the XDP-program error
+path in the same function.
+
+Fixes: 049584807f1d ("tun: add missing verification for short frame")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260520160020.375349-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 3a89f9457fa242..930086d79f97c8 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2472,8 +2472,10 @@ static int tun_xdp_one(struct tun_struct *tun,
+       bool skb_xdp = false;
+       struct page *page;
+-      if (unlikely(datasize < ETH_HLEN))
++      if (unlikely(datasize < ETH_HLEN)) {
++              put_page(virt_to_head_page(xdp->data));
+               return -EINVAL;
++      }
+       xdp_prog = rcu_dereference(tun->xdp_prog);
+       if (xdp_prog) {
+-- 
+2.53.0
+
diff --git a/queue-5.10/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch b/queue-5.10/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
new file mode 100644 (file)
index 0000000..daefb91
--- /dev/null
@@ -0,0 +1,67 @@
+From b1d31f837a05d19b580fbd4d11ad8b16c23ae3da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 11:55:12 +0000
+Subject: tunnels: do not assume transport header in
+ iptunnel_pmtud_check_icmp()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 509323077ef79a26ba0c60bb556e45c12c398b2d ]
+
+In some cases, iptunnel_pmtud_check_icmp() can be called while
+skb transport header is not set.
+
+This triggers an out-of-bound access, because
+(typeof(skb->transport_header))~0U is 65535.
+
+Access the icmp header based on IPv4 network header,
+after making sure icmp->type is present in skb linear part.
+
+Note that iptunnel_pmtud_check_icmpv6()) is fine.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Reported-by: Damiano Melotti <melotti@google.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260522115512.1519110-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index 05c7bb78fe96f0..712555c56a1836 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -262,7 +262,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct icmphdr *icmph = icmp_hdr(skb);
+       const struct iphdr *iph = ip_hdr(skb);
+       if (mtu < 576 || iph->frag_off != htons(IP_DF))
+@@ -273,9 +272,17 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+           ipv4_is_lbcast(iph->saddr)  || ipv4_is_multicast(iph->saddr))
+               return 0;
+-      if (iph->protocol == IPPROTO_ICMP && icmp_is_err(icmph->type))
+-              return 0;
++      if (iph->protocol == IPPROTO_ICMP) {
++              const struct icmphdr *icmph;
++              if (!pskb_network_may_pull(skb, iph->ihl * 4 +
++                                              offsetofend(struct icmphdr, type)))
++                      return 0;
++              iph = ip_hdr(skb);
++              icmph = (void *)iph + iph->ihl * 4;
++              if (icmp_is_err(icmph->type))
++                      return 0;
++      }
+       return iptunnel_pmtud_build_icmp(skb, mtu);
+ }
+-- 
+2.53.0
+
diff --git a/queue-5.10/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch b/queue-5.10/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
new file mode 100644 (file)
index 0000000..c8ea375
--- /dev/null
@@ -0,0 +1,87 @@
+From 104f0ec2a40c4cb7e2488e0b61727ba290002e30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:13:35 +0000
+Subject: tunnels: load network headers after skb_cow() in
+ iptunnel_pmtud_build_icmp[v6]()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b4bc94353050b1fa7b702bd4c6600710dd926cff ]
+
+Sashiko found that iptunnel_pmtud_build_icmp() and
+iptunnel_pmtud_build_icmpv6() were caching ip_hdr() and ipv6_hdr()
+before an skb_cow() call which can reallocate skb->head.
+
+Fix this possible UAF by initializing the local variables
+after the skb_cow() call.
+
+Remove skb_reset_network_header() calls which were not needed.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525201335.2361845-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index 3cdb546dbc8d71..05c7bb78fe96f0 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -194,7 +194,7 @@ EXPORT_SYMBOL_GPL(iptunnel_handle_offloads);
+  */
+ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct iphdr *iph = ip_hdr(skb);
++      const struct iphdr *iph;
+       struct icmphdr *icmph;
+       struct iphdr *niph;
+       struct ethhdr eh;
+@@ -208,7 +208,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, 576 - sizeof(*niph) - sizeof(*icmph));
+       if (err)
+@@ -218,7 +217,7 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       err = skb_cow(skb, sizeof(*niph) + sizeof(*icmph) + ETH_HLEN);
+       if (err)
+               return err;
+-
++      iph = ip_hdr(skb);
+       icmph = skb_push(skb, sizeof(*icmph));
+       *icmph = (struct icmphdr) {
+               .type                   = ICMP_DEST_UNREACH,
+@@ -290,7 +289,7 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+ {
+-      const struct ipv6hdr *ip6h = ipv6_hdr(skb);
++      const struct ipv6hdr *ip6h;
+       struct icmp6hdr *icmp6h;
+       struct ipv6hdr *nip6h;
+       struct ethhdr eh;
+@@ -305,7 +304,6 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, IPV6_MIN_MTU - sizeof(*nip6h) - sizeof(*icmp6h));
+       if (err)
+@@ -316,6 +314,7 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       if (err)
+               return err;
++      ip6h = ipv6_hdr(skb);
+       icmp6h = skb_push(skb, sizeof(*icmp6h));
+       *icmp6h = (struct icmp6hdr) {
+               .icmp6_type             = ICMPV6_PKT_TOOBIG,
+-- 
+2.53.0
+
diff --git a/queue-5.10/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch b/queue-5.10/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
new file mode 100644 (file)
index 0000000..fa838b1
--- /dev/null
@@ -0,0 +1,54 @@
+From 5d7a85504c75a4d224003957fc78eea9483778e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:36:42 +0000
+Subject: vxlan: do not reuse cached ip_hdr() value after
+ skb_tunnel_check_pmtu()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 7d9ef0cb271555d8cf39fefe6c981e1493b25ecf ]
+
+skb_tunnel_check_pmtu() can change skb->head.
+
+Reusing old_iph afer skb_tunnel_check_pmtu() can cause an UAF.
+
+Use instead ip_hdr(skb) as done in drivers/net/bareudp.c
+and drivers/net/geneve.c.
+
+Found by Sashiko.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525203642.2389723-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vxlan/vxlan_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
+index 5e5dfa9579d3aa..053cc74bd904f8 100644
+--- a/drivers/net/vxlan/vxlan_core.c
++++ b/drivers/net/vxlan/vxlan_core.c
+@@ -2752,7 +2752,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr),
+                                     vni, md, flags, udp_sum);
+@@ -2815,7 +2815,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip6_dst_hoplimit(ndst);
+               skb_scrub_packet(skb, xnet);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
+-- 
+2.53.0
+
diff --git a/queue-5.10/xfrm-check-for-underflow-in-xfrm_state_mtu.patch b/queue-5.10/xfrm-check-for-underflow-in-xfrm_state_mtu.patch
new file mode 100644 (file)
index 0000000..919142f
--- /dev/null
@@ -0,0 +1,85 @@
+From 6ca4502d79e333e839a77e9c00308b99bf3d9ba3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 10:49:14 -0600
+Subject: xfrm: Check for underflow in xfrm_state_mtu
+
+From: David Ahern <dahern@nvidia.com>
+
+[ Upstream commit 742b04d0550b0ec89dcbc99537ec88653bd1ad90 ]
+
+Leo Lin reported OOB write issue in esp component:
+
+  xfrm_state_mtu() returns u32 but performs its arithmetic in unsigned
+  modulo-2^32 space using an attacker-influenced "header_len + authsize +
+  net_adj" subtracted from a small "mtu" argument. A nobody user can
+  install an IPv4 ESP tunnel SA with a large authentication key
+  (XFRMA_ALG_AUTH_TRUNC, e.g. hmac(sha512), 64-byte key, 64-byte trunc),
+  configure a small interface MTU (68 bytes), and set XFRMA_TFCPAD to a
+  large value. When a single UDP datagram is then sent through the
+  tunnel, xfrm_state_mtu() underflows to a near-2^32 value, and
+  esp_output() consumes it as a signed int via:
+
+        padto      = min(x->tfcpad, xfrm_state_mtu(x, mtu_cached))
+        esp.tfclen = padto - skb->len   (assigned to int)
+
+  esp.tfclen ends up negative (e.g. -207). It is sign-extended to size_t
+  when passed to memset() inside esp_output_fill_trailer(), producing a
+  ~16 EB write of zeroes at skb_tail_pointer(skb). KASAN logs it as
+  "Write of size 18446744073709551537 at addr ffff888...".
+
+Check for underflow and return 1. This causes the sendmsg attempt to
+fail with ENETUNREACH.
+
+Fixes: c5c252389374 ("[XFRM]: Optimize MTU calculation")
+Reported-by: Leo Lin <leo@depthfirst.com>
+Assisted-by: Codex:26.506.31004
+Signed-off-by: David Ahern <dahern@nvidia.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 02d1d8d1fdea40..5f407f4f8eee7a 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -2549,10 +2549,14 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+       const struct xfrm_type *type = READ_ONCE(x->type);
+       struct crypto_aead *aead;
+       u32 blksize, net_adj = 0;
++      u32 overhead, payload_mtu;
+       if (x->km.state != XFRM_STATE_VALID ||
+-          !type || type->proto != IPPROTO_ESP)
++          !type || type->proto != IPPROTO_ESP) {
++              if (mtu <= x->props.header_len)
++                      return 1;
+               return mtu - x->props.header_len;
++      }
+       aead = x->data;
+       blksize = ALIGN(crypto_aead_blocksize(aead), 4);
+@@ -2572,8 +2576,17 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+               break;
+       }
+-      return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
+-               net_adj) & ~(blksize - 1)) + net_adj - 2;
++      overhead = x->props.header_len + crypto_aead_authsize(aead) + net_adj;
++      if (mtu <= overhead)
++              return 1;
++
++      payload_mtu = mtu - overhead;
++      payload_mtu &= ~(blksize - 1);
++      if (payload_mtu <= 2)
++              return 1;
++
++      return payload_mtu + net_adj - 2;
++
+ }
+ EXPORT_SYMBOL_GPL(xfrm_state_mtu);
+-- 
+2.53.0
+
diff --git a/queue-5.15/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch b/queue-5.15/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
new file mode 100644 (file)
index 0000000..ba64f28
--- /dev/null
@@ -0,0 +1,47 @@
+From 5215ae9a41b85629ca1fa2761ed7d70b5ffd1247 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 09:24:00 -0300
+Subject: ASoC: codecs: simple-mux: Fix enum control bounds check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit f63ad68e18d774a5d15cd7e405ead63f6b322679 ]
+
+simple_mux_control_put() rejects values greater than e->items, but
+enum control values are zero based. For the two-entry mux used by this
+driver, valid values are 0 and 1, so value 2 must be rejected as well.
+
+Accepting e->items can store an invalid mux state, pass it to the GPIO
+setter, and pass it on to the DAPM mux update path where it is used as
+an index into the enum text array.
+
+Use the same >= e->items check used by the ASoC enum helpers.
+
+Fixes: 342fbb7578d1 ("ASoC: add simple-mux")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260527-asoc-simple-mux-enum-bounds-v1-1-3f805b9fc671@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/simple-mux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/simple-mux.c b/sound/soc/codecs/simple-mux.c
+index e0a09dadfa7cf0..344bc61b9dc26a 100644
+--- a/sound/soc/codecs/simple-mux.c
++++ b/sound/soc/codecs/simple-mux.c
+@@ -40,7 +40,7 @@ static int simple_mux_control_put(struct snd_kcontrol *kcontrol,
+       struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
+       struct simple_mux *priv = snd_soc_component_get_drvdata(c);
+-      if (ucontrol->value.enumerated.item[0] > e->items)
++      if (ucontrol->value.enumerated.item[0] >= e->items)
+               return -EINVAL;
+       if (priv->mux == ucontrol->value.enumerated.item[0])
+-- 
+2.53.0
+
diff --git a/queue-5.15/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch b/queue-5.15/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
new file mode 100644 (file)
index 0000000..8059dd4
--- /dev/null
@@ -0,0 +1,112 @@
+From ca7ba65fe7ca81e0707eebe2bbc9c70d09349e9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 13:51:47 -0300
+Subject: ASoC: Intel: bytcht_es8316: Fix MCLK leak on init errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit afb2a3a9d8369d18122a0d7cd294eba9a98259c6 ]
+
+byt_cht_es8316_init() enables MCLK before configuring the codec sysclk
+and creating the headset jack. If either of those later steps fails, the
+function returns without disabling MCLK, leaving the clock enabled after
+card registration fails.
+
+Track whether this driver enabled MCLK and disable it on the init error
+paths. Add the matching DAI link exit callback so the same clock enable
+is also balanced when ASoC cleans up a successfully initialized link.
+
+Fixes: a03bdaa565cb ("ASoC: Intel: add machine driver for BYT/CHT + ES8316")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260519-asoc-bytcht-es8316-mclk-leak-v1-1-b4a11cdc2afd@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcht_es8316.c | 29 ++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
+index 923e69c7695c29..d54bc667175f50 100644
+--- a/sound/soc/intel/boards/bytcht_es8316.c
++++ b/sound/soc/intel/boards/bytcht_es8316.c
+@@ -39,6 +39,7 @@ struct byt_cht_es8316_private {
+       struct gpio_desc *speaker_en_gpio;
+       struct device *codec_dev;
+       bool speaker_en;
++      bool mclk_enabled;
+ };
+ enum {
+@@ -169,6 +170,15 @@ static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
+       },
+ };
++static void byt_cht_es8316_disable_mclk(struct byt_cht_es8316_private *priv)
++{
++      if (!priv->mclk_enabled)
++              return;
++
++      clk_disable_unprepare(priv->mclk);
++      priv->mclk_enabled = false;
++}
++
+ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+ {
+       struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component;
+@@ -225,12 +235,14 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+       ret = clk_prepare_enable(priv->mclk);
+       if (ret)
+               dev_err(card->dev, "unable to enable MCLK\n");
++      else
++              priv->mclk_enabled = true;
+       ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(runtime, 0), 0, 19200000,
+                                    SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               dev_err(card->dev, "can't set codec clock %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       ret = snd_soc_card_jack_new(card, "Headset",
+@@ -239,13 +251,25 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+                                   ARRAY_SIZE(byt_cht_es8316_jack_pins));
+       if (ret) {
+               dev_err(card->dev, "jack creation failed %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+       snd_soc_component_set_jack(codec, &priv->jack, NULL);
+       return 0;
++
++err_disable_mclk:
++      byt_cht_es8316_disable_mclk(priv);
++      return ret;
++}
++
++static void byt_cht_es8316_exit(struct snd_soc_pcm_runtime *runtime)
++{
++      struct snd_soc_card *card = runtime->card;
++      struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
++
++      byt_cht_es8316_disable_mclk(priv);
+ }
+ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
+@@ -355,6 +379,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
+               .dpcm_playback = 1,
+               .dpcm_capture = 1,
+               .init = byt_cht_es8316_init,
++              .exit = byt_cht_es8316_exit,
+               SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
+       },
+ };
+-- 
+2.53.0
+
diff --git a/queue-5.15/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch b/queue-5.15/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
new file mode 100644 (file)
index 0000000..b8c800b
--- /dev/null
@@ -0,0 +1,40 @@
+From dcf2ae8fc417a0f33b793bdc44d2146907b40e58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 11:21:39 +0800
+Subject: Bluetooth: 6lowpan: check skb_clone() return value in
+ send_mcast_pkt()
+
+From: Zhao Dongdong <zhaodongdong@kylinos.cn>
+
+[ Upstream commit 3c40d381ce04f9575a5d8b542898183c3b4b38dc ]
+
+The skb_clone() function can return NULL if memory allocation fails.
+send_mcast_pkt() calls skb_clone() without checking the return value, which
+can lead to a NULL pointer dereference in send_pkt() when it dereferences
+skb->data.
+Add a NULL check after skb_clone() and skip the peer if the clone fails.
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Signed-off-by: Zhao Dongdong <zhaodongdong@kylinos.cn>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index b70d3a38fdedc1..26bc594182ea08 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -485,6 +485,8 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
+                       int ret;
+                       local_skb = skb_clone(skb, GFP_ATOMIC);
++                      if (!local_skb)
++                              continue;
+                       BT_DBG("xmit %s to %pMR type %u IP %pI6c chan %p",
+                              netdev->name,
+-- 
+2.53.0
+
diff --git a/queue-5.15/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch b/queue-5.15/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
new file mode 100644 (file)
index 0000000..29e3a7c
--- /dev/null
@@ -0,0 +1,62 @@
+From 88b80890252e34db534c76091b0327a9044aa673 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 18:51:52 +0800
+Subject: Bluetooth: l2cap: clear chan->ident on ECRED reconfiguration success
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit 00e1950716c6ed67d74777b2db286b0fa23b4be9 ]
+
+l2cap_ecred_reconf_rsp() returns early on success without clearing
+chan->ident. Every other L2CAP response handler (l2cap_ecred_conn_rsp,
+l2cap_le_connect_rsp, l2cap_config_rsp) clears chan->ident after a
+successful transaction to prevent the channel from matching subsequent
+responses with the recycled ident value.
+
+A remote attacker that completed a reconfiguration as the peer can
+replay a failure response with the stale ident, causing the kernel to
+match and destroy the already-established channel via
+l2cap_chan_del(chan, ECONNRESET).
+
+Clear chan->ident for all matching channels on success, and harden the
+failure path by using l2cap_chan_hold_unless_zero() consistent with
+other L2CAP handlers (l2cap_le_command_rej, __l2cap_get_chan_by_ident).
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index a5db427c13de20..7e3825c1b10b95 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -6422,14 +6422,20 @@ static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
+       BT_DBG("result 0x%4.4x", result);
+-      if (!result)
++      if (!result) {
++              list_for_each_entry(chan, &conn->chan_l, list) {
++                      if (chan->ident == cmd->ident)
++                              chan->ident = 0;
++              }
+               return 0;
++      }
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
+               if (chan->ident != cmd->ident)
+                       continue;
+-              l2cap_chan_hold(chan);
++              if (!l2cap_chan_hold_unless_zero(chan))
++                      continue;
+               l2cap_chan_lock(chan);
+               l2cap_chan_del(chan, ECONNRESET);
+-- 
+2.53.0
+
diff --git a/queue-5.15/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch b/queue-5.15/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
new file mode 100644 (file)
index 0000000..16bc06b
--- /dev/null
@@ -0,0 +1,82 @@
+From 393ffffe6c1927eb8f839bcd3400df8ec5d105fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 May 2026 12:09:42 -0400
+Subject: Bluetooth: L2CAP: Fix possible crash on l2cap_ecred_conn_rsp
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 41c2713b204e6cb6a94587bc6bf6935107df5479 ]
+
+If dcid is received for an already-assigned destination CID the spec
+requires that both channels to be discarded, but calling l2cap_chan_del
+may invalidate the tmp cursor created by list_for_each_entry_safe and
+in fact it is the wrong procedure as the chan->dcid may be assigned
+previously it really needs to be disconnected.
+
+Calling l2cap_chan_clone directly may still lead to l2cap_chan_del so
+instead schedule l2cap_chan_timeout with delay 0 to close the channel
+asynchronously.
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 27 ++++++++++++++++++++++-----
+ 1 file changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 7e3825c1b10b95..38ac75f85144be 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -6222,6 +6222,7 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+       cmd_len -= sizeof(*rsp);
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
++              struct l2cap_chan *orig;
+               u16 dcid;
+               if (chan->ident != cmd->ident ||
+@@ -6243,8 +6244,10 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+               BT_DBG("dcid[%d] 0x%4.4x", i, dcid);
++              orig = __l2cap_get_chan_by_dcid(conn, dcid);
++
+               /* Check if dcid is already in use */
+-              if (dcid && __l2cap_get_chan_by_dcid(conn, dcid)) {
++              if (dcid && orig) {
+                       /* If a device receives a
+                        * L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an
+                        * already-assigned Destination CID, then both the
+@@ -6253,10 +6256,24 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+                        */
+                       l2cap_chan_del(chan, ECONNREFUSED);
+                       l2cap_chan_unlock(chan);
+-                      chan = __l2cap_get_chan_by_dcid(conn, dcid);
+-                      l2cap_chan_lock(chan);
+-                      l2cap_chan_del(chan, ECONNRESET);
+-                      l2cap_chan_unlock(chan);
++
++                      /* Check that the dcid channel mode is
++                       * L2CAP_MODE_EXT_FLOWCTL since this procedure is only
++                       * valid for that mode and shouldn't disconnect a dcid
++                       * in other modes.
++                       */
++                      if (orig->mode == L2CAP_MODE_EXT_FLOWCTL) {
++                              l2cap_chan_lock(orig);
++                              /* Disconnect the original channel as it may be
++                               * considered connected since dcid has already
++                               * been assigned; don't call l2cap_chan_close
++                               * directly since that could lead to
++                               * l2cap_chan_del and then removing the channel
++                               * from the list while we're iterating over it.
++                               */
++                              __set_chan_timer(orig, 0);
++                              l2cap_chan_unlock(orig);
++                      }
+                       continue;
+               }
+-- 
+2.53.0
+
diff --git a/queue-5.15/bonding-refuse-to-enslave-can-devices.patch b/queue-5.15/bonding-refuse-to-enslave-can-devices.patch
new file mode 100644 (file)
index 0000000..de8ba87
--- /dev/null
@@ -0,0 +1,74 @@
+From 8f9b352ebc74f13c003ce2ca2a71bc360c4453eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 21:33:19 +0200
+Subject: bonding: refuse to enslave CAN devices
+
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+
+[ Upstream commit 8ba68464e4787b6a7ec938826e16124df20fd23d ]
+
+syzbot reported a kernel paging request crash in
+can_rx_unregister() inside net/can/af_can.c. The crash occurs
+because a virtual CAN device (vxcan) is being enslaved to a
+bonding master.
+
+During the enslavement process, the bonding driver mutates
+and modifies the network device states to fit an Ethernet-like
+aggregation model. However, CAN devices operate on a completely
+different Layer 2 architecture, relying on the CAN mid-layer
+private data structure (can_ml_priv) instead of standard
+Ethernet structures. Since bonding does not initialize or
+maintain these CAN structures, subsequent operations on the
+half-enslaved interface (such as closing associated sockets
+via isotp_release) lead to a null-pointer dereference when
+accessing the CAN receiver lists.
+
+Bonding CAN interfaces is architecturally invalid as CAN lacks
+MAC addresses, ARP capabilities, and standard Ethernet
+link-layer mechanisms. While generic loopback devices are
+blocked globally in net/core/dev.c, virtual CAN devices
+bypass this check because they do not carry the IFF_LOOPBACK
+flag, despite acting as local software-loopbacks.
+
+Fix this by explicitly blocking network devices of type
+ARPHRD_CAN from being enslaved at the very beginning of
+bond_enslave(). This prevents illegal state mutations,
+eliminates the resulting KASAN crashes, and avoids potential
+memory leaks from incomplete socket cleanups.
+
+As the CAN support has been added a long time after bonding
+the Fixes-tag points to the introduction of ARPHRD_CAN that
+would have needed a specific handling in bonding_main.c.
+
+Fixes: cd05acfe65ed ("[CAN]: Allocate protocol numbers for PF_CAN")
+Reported-by: syzbot+8ed98cbd0161632bce95@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=8ed98cbd0161632bce95
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Link: https://patch.msgid.link/20260526-bonding-candev-v1-1-ba1df400918a@hartkopp.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 5321d9dca698a9..42ad34b308b924 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1776,6 +1776,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
+       int link_reporting;
+       int res = 0, i;
++      if (slave_dev->type == ARPHRD_CAN) {
++              BOND_NL_ERR(bond_dev, extack,
++                          "CAN devices cannot be enslaved");
++              return -EPERM;
++      }
++
+       if (slave_dev->flags & IFF_MASTER &&
+           !netif_is_bond_master(slave_dev)) {
+               BOND_NL_ERR(bond_dev, extack,
+-- 
+2.53.0
+
diff --git a/queue-5.15/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch b/queue-5.15/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
new file mode 100644 (file)
index 0000000..0ebf699
--- /dev/null
@@ -0,0 +1,62 @@
+From c6f88ca06d9276170efdf68cdf9eba8377a9fbb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:33 -0700
+Subject: ethtool: eeprom: add more safeties to EEPROM Netlink fallback
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 67cfdd9210b99f260b3e0afeb9525e0acc7be31e ]
+
+The Netlink fallback path for reading module EEPROM
+(fallback_set_params()) validates that offset < eeprom_len,
+but does not check that offset + length stays within eeprom_len.
+The ioctl equivalent (ethtool_get_any_eeprom() in ioctl.c) has
+always enforced both bounds:
+
+  if (eeprom.offset + eeprom.len > total_len)
+      return -EINVAL;
+
+This could lead to surprises in both drivers and device FW.
+Add the missing offset + length validation to fallback_set_params(),
+mirroring the ioctl.
+
+Similarly - ethtool core in general, and ethtool_get_any_eeprom()
+in particular tries to zero-init all buffers passed to the drivers
+to avoid any extra work of zeroing things out. eeprom_fallback()
+uses a plain kmalloc(), change it to zalloc.
+
+Fixes: 96d971e307cc ("ethtool: Add fallback to get_module_eeprom from netlink command")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-11-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/eeprom.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c
+index 49c0a2a77f02de..6ce40f95d8aba5 100644
+--- a/net/ethtool/eeprom.c
++++ b/net/ethtool/eeprom.c
+@@ -43,6 +43,9 @@ static int fallback_set_params(struct eeprom_req_info *request,
+       if (offset >= modinfo->eeprom_len)
+               return -EINVAL;
++      if (length > modinfo->eeprom_len - offset)
++              return -EINVAL;
++
+       eeprom->cmd = ETHTOOL_GMODULEEEPROM;
+       eeprom->len = length;
+       eeprom->offset = offset;
+@@ -69,7 +72,7 @@ static int eeprom_fallback(struct eeprom_req_info *request,
+       if (err < 0)
+               return err;
+-      data = kmalloc(eeprom.len, GFP_KERNEL);
++      data = kzalloc(eeprom.len, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+       err = ethtool_get_module_eeprom_call(dev, &eeprom, data);
+-- 
+2.53.0
+
diff --git a/queue-5.15/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch b/queue-5.15/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
new file mode 100644 (file)
index 0000000..1489bd3
--- /dev/null
@@ -0,0 +1,78 @@
+From 12476c61f034d6d453c15c5ba72225947eb33f30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:02:45 +0200
+Subject: gpio: rockchip: convert bank->clk to devm_clk_get_enabled()
+
+From: Marco Scardovi <scardracs@disroot.org>
+
+[ Upstream commit 3e46c18d5d87f063a93ae0fe7662fbf6660459d5 ]
+
+The bank->clk was previously obtained via of_clk_get() and manually
+prepared/enabled. However, it was missing a corresponding clk_put() in
+both the error paths and the remove function, leading to a reference leak.
+
+Convert the allocation to devm_clk_get_enabled(), which also properly
+propagates failures from clk_prepare_enable() that were previously ignored.
+
+The GPIO bank device uses the same OF node as the previous of_clk_get()
+call, so devm_clk_get_enabled(dev, NULL) correctly resolves the same
+clock provider entry.
+
+Fix the reference leak and simplify the code by removing the manual
+clk_disable_unprepare() calls in the probe error paths and in the
+remove function.
+
+Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
+Assisted-by: Antigravity:gemini-3.5-flash
+Signed-off-by: Marco Scardovi <scardracs@disroot.org>
+Link: https://patch.msgid.link/20260526171050.12785-2-scardracs@disroot.org
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-rockchip.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index d331745da1a3a8..df2eefc1554a01 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -649,11 +649,10 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+       if (!bank->irq)
+               return -EINVAL;
+-      bank->clk = of_clk_get(bank->of_node, 0);
++      bank->clk = devm_clk_get_enabled(bank->dev, NULL);
+       if (IS_ERR(bank->clk))
+               return PTR_ERR(bank->clk);
+-      clk_prepare_enable(bank->clk);
+       id = readl(bank->reg_base + gpio_regs_v2.version_id);
+       /* If not gpio v2, that is default to v1. */
+@@ -663,7 +662,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+               bank->db_clk = of_clk_get(bank->of_node, 1);
+               if (IS_ERR(bank->db_clk)) {
+                       dev_err(bank->dev, "cannot find debounce clk\n");
+-                      clk_disable_unprepare(bank->clk);
+                       return -EINVAL;
+               }
+       } else {
+@@ -737,7 +735,6 @@ static int rockchip_gpio_probe(struct platform_device *pdev)
+       ret = rockchip_gpiolib_register(bank);
+       if (ret) {
+-              clk_disable_unprepare(bank->clk);
+               mutex_unlock(&bank->deferred_lock);
+               return ret;
+       }
+@@ -773,7 +770,6 @@ static int rockchip_gpio_remove(struct platform_device *pdev)
+ {
+       struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);
+-      clk_disable_unprepare(bank->clk);
+       gpiochip_remove(&bank->gpio_chip);
+       return 0;
+-- 
+2.53.0
+
diff --git a/queue-5.15/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch b/queue-5.15/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
new file mode 100644 (file)
index 0000000..74351db
--- /dev/null
@@ -0,0 +1,48 @@
+From 31fe5d6f53e55b29e3de2edf56e7154850a00b43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 12:21:47 +0000
+Subject: ipv4: free net->ipv4.sysctl_local_reserved_ports after
+ unregister_net_sysctl_table()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 87a1e0fe7776da7ab411be332b4be58ac8840d10 ]
+
+ipv4_sysctl_exit_net() is currently freeing net->ipv4.sysctl_local_reserved_ports
+too soon.
+
+Only after unregister_net_sysctl_table() we can be sure no threads can possibly
+use the sysctls, including /proc/sys/net/ipv4/ip_local_reserved_ports.
+
+Fixes: 122ff243f5f1 ("ipv4: make ip_local_reserved_ports per netns")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Link: https://patch.msgid.link/20260521122147.3584624-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/sysctl_net_ipv4.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 1f22e72074fdca..a7d335ab000403 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -1415,10 +1415,10 @@ static __net_exit void ipv4_sysctl_exit_net(struct net *net)
+ {
+       struct ctl_table *table;
+-      kfree(net->ipv4.sysctl_local_reserved_ports);
+       table = net->ipv4.ipv4_hdr->ctl_table_arg;
+       unregister_net_sysctl_table(net->ipv4.ipv4_hdr);
+       kfree(table);
++      kfree(net->ipv4.sysctl_local_reserved_ports);
+ }
+ static __net_initdata struct pernet_operations ipv4_sysctl_ops = {
+-- 
+2.53.0
+
diff --git a/queue-5.15/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch b/queue-5.15/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
new file mode 100644 (file)
index 0000000..de29628
--- /dev/null
@@ -0,0 +1,62 @@
+From 6ccd6c9272c29323b347031d382d5abaff1371b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 21:10:31 +0530
+Subject: ipv6: rpl: fix hdrlen overflow in ipv6_rpl_srh_decompress()
+
+From: Rahul Chandelkar <rc@rexion.ai>
+
+[ Upstream commit 9d5e7a46a9f6d8f503b41bfefef70659845f1679 ]
+
+ipv6_rpl_srh_decompress() computes:
+
+    outhdr->hdrlen = (((n + 1) * sizeof(struct in6_addr)) >> 3);
+
+hdrlen is __u8. For n >= 127 the result exceeds 255 and silently
+truncates. With n=127 (cmpri=15, cmpre=15, pad=0, hdrlen=16):
+
+    (128 * 16) >> 3 = 256, truncated to 0 as __u8
+
+The caller in ipv6_rpl_srh_rcv() then places the compressed header
+at buf + ((ohdr->hdrlen + 1) << 3). With hdrlen=0 this is buf + 8,
+but the decompressed region occupies buf[0..2055] (8-byte header
+plus 128 full addresses). The compressed header overlaps the
+decompressed data, and ipv6_rpl_srh_compress() writes into this
+overlap, corrupting the routing header of the forwarded packet.
+
+The existing guard at exthdrs.c:546 checks (n + 1) > 255, which
+prevents n+1 from overflowing unsigned char (the segments_left
+field), but does not prevent the computed hdrlen from overflowing
+__u8. n=127 passes because 128 <= 255, yet hdrlen=256 does not
+fit.
+
+Tighten the bound to (n + 1) > 127. This caps n at 126, giving
+hdrlen = (127 * 16) >> 3 = 254, which fits in __u8. The compressed
+header then lands at buf + ((254 + 1) << 3) = buf + 2040, exactly
+past the decompressed region (buf[0..2039]). No overlap. 127
+segments is well beyond any realistic RPL deployment.
+
+Fixes: 8610c7c6e3bd ("net: ipv6: add support for rpl sr exthdr")
+Signed-off-by: Rahul Chandelkar <rc@rexion.ai>
+Link: https://patch.msgid.link/20260525154031.2290876-1-rc@rexion.ai
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index 343b957e6337ab..a25dfa59ca2196 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -557,7 +557,7 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
+        * unsigned char which is segments_left field. Should not be
+        * higher than that.
+        */
+-      if (r || (n + 1) > 255) {
++      if (r || (n + 1) > 127) {
+               kfree_skb(skb);
+               return -1;
+       }
+-- 
+2.53.0
+
diff --git a/queue-5.15/kernel-fork-validate-exit_signal-in-kernel_clone.patch b/queue-5.15/kernel-fork-validate-exit_signal-in-kernel_clone.patch
new file mode 100644 (file)
index 0000000..e376e67
--- /dev/null
@@ -0,0 +1,116 @@
+From a672b7dc40692524e3cd2127ccf43f1bb8109361 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Mar 2026 20:49:56 +0530
+Subject: kernel/fork: validate exit_signal in kernel_clone()
+
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+
+[ Upstream commit 09e7827e785729f391c8d46dc71becce70d296ab ]
+
+When a child process exits, it sends exit_signal to its parent via
+do_notify_parent().  The clone() syscall constructs exit_signal as:
+
+(lower_32_bits(clone_flags) & CSIGNAL)
+
+CSIGNAL is 0xff, so values in the range 65-255 are possible.  However,
+valid_signal() only accepts signals up to _NSIG (64 on x86_64).  A
+non-zero non-valid exit_signal acts the same as exit_signal == 0: the
+parent process is not signaled when the child terminates.
+
+The syzkaller reproducer triggers this by calling clone() with flags=0x80,
+resulting in exit_signal = (0x80 & CSIGNAL) = 128, which exceeds _NSIG and
+is not a valid signal.
+
+The v1 of this patch added the check only in the clone() syscall handler,
+which is incomplete.  kernel_clone() has other callers such as
+sys_ia32_clone() which would remain unprotected.  Move the check to
+kernel_clone() to cover all callers.
+
+Since the valid_signal() check is now in kernel_clone() and covers all
+callers including clone3(), the same check in copy_clone_args_from_user()
+becomes redundant and is removed.  The higher 32bits check for clone3() is
+kept as it is clone3() specific.
+
+Note that this is a user-visible change: previously, passing an invalid
+exit_signal to clone() was silently accepted.  The man page for clone()
+does not document any defined behavior for invalid exit_signal values, so
+rejecting them with -EINVAL is the correct behavior.  It is unlikely that
+any sane application relies on passing an invalid exit_signal.
+
+[oleg@redhat.com: the comment above kernel_clone() should be updated]
+  Link: https://lore.kernel.org/abwvgU17W8wuW2-J@redhat.com
+Link: https://lore.kernel.org/20260316151956.563558-1-kartikey406@gmail.com
+Fixes: 3f2c788a1314 ("fork: prevent accidental access to clone3 features")
+Signed-off-by: Deepanshu Kartikey <Kartikey406@gmail.com>
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Reported-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bbe6b99feefc3a0842de
+Tested-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/20260307064202.353405-1-kartikey406@gmail.com/T/ [v1]
+Link: https://lore.kernel.org/all/20260316104536.558108-1-kartikey406@gmail.com/T/ [v2]
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Ben Segall <bsegall@google.com>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Juri Lelli <juri.lelli@redhat.com>
+Cc: Kees Cook <kees@kernel.org>
+Cc: Liam Howlett <liam@infradead.org>
+Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Valentin Schneider <vschneid@redhat.com>
+Cc: Vincent Guittot <vincent.guittot@linaro.org>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/fork.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/fork.c b/kernel/fork.c
+index eb772b1e819f2f..faf9d68fae3029 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -2632,8 +2632,6 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
+  *
+  * It copies the process, and if successful kick-starts
+  * it and waits for it to finish using the VM if required.
+- *
+- * args->exit_signal is expected to be checked for sanity by the caller.
+  */
+ pid_t kernel_clone(struct kernel_clone_args *args)
+ {
+@@ -2658,6 +2656,9 @@ pid_t kernel_clone(struct kernel_clone_args *args)
+           (args->pidfd == args->parent_tid))
+               return -EINVAL;
++      if (!valid_signal(args->exit_signal))
++              return -EINVAL;
++
+       /*
+        * Determine whether and which event to report to ptracer.  When
+        * called from kernel_thread or CLONE_UNTRACED is explicitly
+@@ -2834,11 +2835,9 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
+               return -EINVAL;
+       /*
+-       * Verify that higher 32bits of exit_signal are unset and that
+-       * it is a valid signal
++       * Verify that higher 32bits of exit_signal are unset
+        */
+-      if (unlikely((args.exit_signal & ~((u64)CSIGNAL)) ||
+-                   !valid_signal(args.exit_signal)))
++      if (unlikely(args.exit_signal & ~((u64)CSIGNAL)))
+               return -EINVAL;
+       if ((args.flags & CLONE_INTO_CGROUP) &&
+-- 
+2.53.0
+
diff --git a/queue-5.15/net-iucv-fix-locking-in-.getsockopt.patch b/queue-5.15/net-iucv-fix-locking-in-.getsockopt.patch
new file mode 100644 (file)
index 0000000..498c6c7
--- /dev/null
@@ -0,0 +1,87 @@
+From b1ae81f8dddb681b2eddf3193864b1b66a2997ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 07:11:45 -0700
+Subject: net/iucv: fix locking in .getsockopt
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 3589d20a666caf30ad100c960a2de7de390fce88 ]
+
+Mirror iucv_sock_setsockopt() and wrap the whole switch in
+lock_sock()/release_sock(). The pre-existing SO_MSGLIMIT-only lock
+becomes redundant and is removed.
+
+Any AF_IUCV HIPER user can potentially crash the kernel by racing
+recvmsg() with getsockopt(SO_MSGSIZE): the SO_MSGSIZE arm dereferences
+iucv->hs_dev->mtu after iucv_sock_close() (called from the racing
+recvmsg()) has set hs_dev to NULL, producing a NULL pointer dereference
+oops.
+
+Suggested-by: Stanislav Fomichev <sdf.kernel@gmail.com>
+Fixes: 51363b8751a6 ("af_iucv: allow retrieval of maximum message size")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Tested-by: Alexandra Winter <wintera@linux.ibm.com>
+Link: https://patch.msgid.link/20260521-af_iucv_fix2-v1-1-f16b1c510aa9@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index e6cb3e1cbbf9b8..3188d719a2e42d 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -1533,7 +1533,7 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       struct sock *sk = sock->sk;
+       struct iucv_sock *iucv = iucv_sk(sk);
+       unsigned int val;
+-      int len;
++      int len, rc;
+       if (level != SOL_IUCV)
+               return -ENOPROTOOPT;
+@@ -1546,26 +1546,34 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       len = min_t(unsigned int, len, sizeof(int));
++      rc = 0;
++
++      lock_sock(sk);
+       switch (optname) {
+       case SO_IPRMDATA_MSG:
+               val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0;
+               break;
+       case SO_MSGLIMIT:
+-              lock_sock(sk);
+               val = (iucv->path != NULL) ? iucv->path->msglim /* connected */
+                                          : iucv->msglimit;    /* default */
+-              release_sock(sk);
+               break;
+       case SO_MSGSIZE:
+-              if (sk->sk_state == IUCV_OPEN)
+-                      return -EBADFD;
++              if (sk->sk_state == IUCV_OPEN) {
++                      rc = -EBADFD;
++                      break;
++              }
+               val = (iucv->hs_dev) ? iucv->hs_dev->mtu -
+                               sizeof(struct af_iucv_trans_hdr) - ETH_HLEN :
+                               0x7fffffff;
+               break;
+       default:
+-              return -ENOPROTOOPT;
++              rc = -ENOPROTOOPT;
++              break;
+       }
++      release_sock(sk);
++
++      if (rc)
++              return rc;
+       if (put_user(len, optlen))
+               return -EFAULT;
+-- 
+2.53.0
+
diff --git a/queue-5.15/net-netlink-don-t-set-nsid-on-local-notifications.patch b/queue-5.15/net-netlink-don-t-set-nsid-on-local-notifications.patch
new file mode 100644 (file)
index 0000000..2e13dd7
--- /dev/null
@@ -0,0 +1,82 @@
+From 8e997f36f06cd4000c395ddafafad1bf52c0ae8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:36 +0200
+Subject: net: netlink: don't set nsid on local notifications
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 88b126b39f9757e9debc322d4679239e9af089c7 ]
+
+In most cases, notifications on sockets with NETLINK_LISTEN_ALL_NSID
+do not contain NSID in their ancillary data in case the event is local
+to the listener.
+
+However, when a self-referential NSID is allocated for a namespace,
+every local notification starts sending this ID to the user space.
+
+This is problematic, because the listener cannot tell if those
+notifications are local or not anymore without making extra requests
+to figure out if the provided NSID is local or not.  The listener
+can also not figure out the local NSID beforehand as it can be
+allocated at any point in time by other processes, changing the
+structure of the future notifications for everyone.
+
+The value is practically not useful, since it's the namespace's own
+ID that the application has to obtain from other sources in order to
+figure out if it's the same or not.  So, for the application it's
+just an extra busy work with no benefits.  Moreover, applications
+that do not know about this quirk may be mishandling notifications
+with NSID set as notifications from remote namespaces.  This is the
+case for ovs-vswitchd and the iproute2's 'ip monitor' that stops
+printing 'current' and starts printing the nsid number mid-session.
+
+Lack of clear documentation for this behavior is also not helping.
+
+A search though open-source projects doesn't reveal any projects
+that use NETNSA_NSID_NOT_ASSIGNED and rely on metadata to contain
+self-referential NSIDs (expected, since the value is not useful).
+Quite the opposite, as already mentioned, there are few applications
+that rely on NSID to not be present in local events.
+
+Since the value is not useful and actively harmful in some cases,
+let's not report it for local events, making the notifications more
+consistent.
+
+Also adding some blank lines for readability.
+
+Fixes: 59324cf35aba ("netlink: allow to listen "all" netns")
+Reported-by: Matteo Perin <matteo.perin@canonical.com>
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-3-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 12e765fcbd747d..731c53178eb559 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1482,10 +1482,14 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++
+       NETLINK_CB(p->skb2).nsid_is_set = false;
+-      NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+-      if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+-              NETLINK_CB(p->skb2).nsid_is_set = true;
++      if (!net_eq(sock_net(sk), p->net)) {
++              NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
++              if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
++                      NETLINK_CB(p->skb2).nsid_is_set = true;
++      }
++
+       val = netlink_broadcast_deliver(sk, p->skb2);
+       if (val < 0) {
+               netlink_overrun(sk);
+-- 
+2.53.0
+
diff --git a/queue-5.15/net-netlink-fix-sending-unassigned-nsid-after-assign.patch b/queue-5.15/net-netlink-fix-sending-unassigned-nsid-after-assign.patch
new file mode 100644 (file)
index 0000000..3de140e
--- /dev/null
@@ -0,0 +1,45 @@
+From 1c2e8ff9678997ab9d9e9fafcda4a7065d1b13b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:35 +0200
+Subject: net: netlink: fix sending unassigned nsid after assigned one
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 70f8592ee90585272018a725054b6eb2ab7e99ca ]
+
+If the current skb is not shared, it is re-used directly for all the
+sockets subscribed to the notification.  If we have remote all-nsid
+socket receiving a message first, then the 'nsid_is_set' will be
+set to 'true'.  If the nsid is NOT_ASSIGNED for the next socket in
+the list, the 'nsid_is_set' will remain 'true' and the negative value
+is be delivered to the user space.  All subsequent nsid values will be
+delivered as well, since there is no code path that sets the flag
+back to 'false'.
+
+Fix that by always dropping the flag to 'false' first.
+
+Fixes: 7212462fa6fd ("netlink: don't send unknown nsid")
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-2-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 65eb164d00c40d..12e765fcbd747d 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1482,6 +1482,7 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++      NETLINK_CB(p->skb2).nsid_is_set = false;
+       NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+       if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+               NETLINK_CB(p->skb2).nsid_is_set = true;
+-- 
+2.53.0
+
diff --git a/queue-5.15/net-sched-revert-net-sched-restrict-conditions-for-a.patch b/queue-5.15/net-sched-revert-net-sched-restrict-conditions-for-a.patch
new file mode 100644 (file)
index 0000000..a320707
--- /dev/null
@@ -0,0 +1,102 @@
+From 15fbd43e1439577d25c3a1604fdc2ef8e46d0a66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:49 -0400
+Subject: net/sched: Revert "net/sched: Restrict conditions for adding
+ duplicating netems to qdisc tree"
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit eda0b7f203bb166c98d1418b204135bd566ac83b ]
+
+This reverts commit ec8e0e3d7adef940cdf9475e2352c0680189d14e.
+
+The original patch rejects any tree containing two netems when
+either has duplication set, even when they sit on unrelated classes
+of the same classful parent. That broke configurations that have
+worked since netem was introduced.
+
+The re-entrancy problem the original commit was trying to solve is
+handled by later patch using tc_depth flag.
+
+Doing this revert will (re)expose the original bug with multiple
+netem duplication. When this patch is backported make sure
+and get the full series.
+
+Fixes: ec8e0e3d7ade ("net/sched: Restrict conditions for adding duplicating netems to qdisc tree")
+Reported-by: Ji-Soo Chung <jschung2@proton.me>
+Reported-by: Gerlinde <lrGerlinde@mailfence.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220774
+Reported-by: zyc zyc <zyc199902@zohomail.cn>
+Closes: https://lore.kernel.org/all/19adda5a1e2.12410b78222774.9191120410578703463@zohomail.cn/
+Reported-by: Manas Ghandat <ghandatmanas@gmail.com>
+Closes: https://lore.kernel.org/netdev/f69b2c8f-8325-4c2e-a011-6dbc089f30e4@gmail.com/
+Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-3-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_netem.c | 40 ----------------------------------------
+ 1 file changed, 40 deletions(-)
+
+diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
+index 3e3bced82c564d..3dc6411b0a33c7 100644
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -985,41 +985,6 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
+       return 0;
+ }
+-static const struct Qdisc_class_ops netem_class_ops;
+-
+-static int check_netem_in_tree(struct Qdisc *sch, bool duplicates,
+-                             struct netlink_ext_ack *extack)
+-{
+-      struct Qdisc *root, *q;
+-      unsigned int i;
+-
+-      root = qdisc_root_sleeping(sch);
+-
+-      if (sch != root && root->ops->cl_ops == &netem_class_ops) {
+-              if (duplicates ||
+-                  ((struct netem_sched_data *)qdisc_priv(root))->duplicate)
+-                      goto err;
+-      }
+-
+-      if (!qdisc_dev(root))
+-              return 0;
+-
+-      hash_for_each(qdisc_dev(root)->qdisc_hash, i, q, hash) {
+-              if (sch != q && q->ops->cl_ops == &netem_class_ops) {
+-                      if (duplicates ||
+-                          ((struct netem_sched_data *)qdisc_priv(q))->duplicate)
+-                              goto err;
+-              }
+-      }
+-
+-      return 0;
+-
+-err:
+-      NL_SET_ERR_MSG(extack,
+-                     "netem: cannot mix duplicating netems with other netems in tree");
+-      return -EINVAL;
+-}
+-
+ /* Parse netlink message to set options */
+ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+                       struct netlink_ext_ack *extack)
+@@ -1087,11 +1052,6 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+       q->gap = qopt->gap;
+       q->counter = 0;
+       q->loss = qopt->loss;
+-
+-      ret = check_netem_in_tree(sch, qopt->duplicate, extack);
+-      if (ret)
+-              goto unlock;
+-
+       q->duplicate = qopt->duplicate;
+       /* for compatibility with earlier versions.
+-- 
+2.53.0
+
diff --git a/queue-5.15/net-smc-do-not-re-initialize-smc-hashtables.patch b/queue-5.15/net-smc-do-not-re-initialize-smc-hashtables.patch
new file mode 100644 (file)
index 0000000..f21b5ab
--- /dev/null
@@ -0,0 +1,59 @@
+From ad78b70f116d7974dfa0ebc4c03c6b86f8a79984 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 16:56:39 +0200
+Subject: net/smc: Do not re-initialize smc hashtables
+
+From: Alexandra Winter <wintera@linux.ibm.com>
+
+[ Upstream commit 9e4389b0038781f19f97895186ed941ff8ac1678 ]
+
+INIT_HLIST_HEAD(&smc_v*_hashinfo.ht) are called after smc_nl_init(),
+proto_register() and sock_register(). This can lead to smc_v*_hashinfo.ht
+being reset even though hash entries already exist and are being used,
+possibly resulting in a corrupted list.
+
+Remove unnecessary and dangerous re-initialisation of smc_v*_hashinfo.ht in
+smc_init(); it is implicitly initialised to zero anyhow. Add
+HLIST_HEAD_INIT to the definitions for clarity.
+
+Fixes: f16a7dd5cf27 ("smc: netlink interface for SMC sockets")
+Suggested-by: Halil Pasic <pasic@linux.ibm.com>
+Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
+Acked-by: Halil Pasic <pasic@linux.ibm.com>
+Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
+Link: https://patch.msgid.link/20260521145639.10317-1-wintera@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index 5425c46a2e7c71..6b60a5dd240dd1 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -123,10 +123,12 @@ static struct sock *smc_tcp_syn_recv_sock(const struct sock *sk,
+ static struct smc_hashinfo smc_v4_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v4_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ static struct smc_hashinfo smc_v6_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v6_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ int smc_hash_sk(struct sock *sk)
+@@ -2938,8 +2940,6 @@ static int __init smc_init(void)
+               pr_err("%s: sock_register fails with %d\n", __func__, rc);
+               goto out_proto6;
+       }
+-      INIT_HLIST_HEAD(&smc_v4_hashinfo.ht);
+-      INIT_HLIST_HEAD(&smc_v6_hashinfo.ht);
+       rc = smc_ib_register_client();
+       if (rc) {
+-- 
+2.53.0
+
diff --git a/queue-5.15/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch b/queue-5.15/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
new file mode 100644 (file)
index 0000000..7de0a2b
--- /dev/null
@@ -0,0 +1,107 @@
+From 2a0697060f2a0682a13e9dbc26b0cc2b9dd12ddc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 22:52:07 +0200
+Subject: netfilter: ebtables: fix OOB read in compat_mtw_from_user
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit f438d1786d657d57790c5d138d6db3fc9fdac392 ]
+
+Luxiao Xu says:
+
+ The function compat_mtw_from_user() converts ebtables extensions from
+ 32-bit user structures to kernel native structures. However, it lacks
+ proper validation of the user-supplied match_size/target_size.
+
+ When certain extensions are processed, the kernel-side translation
+ logic may perform memory accesses based on the extension's expected
+ size. If the user provides a size smaller than what the extension
+ requires, it results in an out-of-bounds read as reported by KASAN.
+
+ This fix introduces a check to ensure match_size is at least as large
+ as the extension's required compatsize. This covers matches, watchers,
+ and targets, while maintaining compatibility with standard targets.
+
+AFAIU this is relevant for matches that need to go though
+match->compat_from_user() call.  Those that use plain memcpy with the
+user-provided size are ok because the caller checks that size vs the
+start of the next rule entry offset (which itself is checked vs. total
+size copied from userspace).
+
+The ->compat_from_user() callbacks assume they can read compatsize bytes,
+so they need this extra check.
+
+Based on an earlier patch from Luxiao Xu.
+
+Fixes: 81e675c227ec ("netfilter: ebtables: add CONFIG_COMPAT support")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/netfilter/ebtables.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
+index c74efcc2b4996d..2083facfc87d9b 100644
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1951,6 +1951,25 @@ enum compat_mwt {
+       EBT_COMPAT_TARGET,
+ };
++static bool match_size_ok(const struct xt_match *match, unsigned int match_size)
++{
++      u16 csize;
++
++      if (match->matchsize == -1) /* cannot validate ebt_among */
++              return true;
++
++      csize = match->compatsize ? : match->matchsize;
++
++      return match_size >= csize;
++}
++
++static bool tgt_size_ok(const struct xt_target *tgt, unsigned int tgt_size)
++{
++      u16 csize = tgt->compatsize ? : tgt->targetsize;
++
++      return tgt_size >= csize;
++}
++
+ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                               enum compat_mwt compat_mwt,
+                               struct ebt_entries_buf_state *state,
+@@ -1976,6 +1995,11 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+               if (IS_ERR(match))
+                       return PTR_ERR(match);
++              if (!match_size_ok(match, match_size)) {
++                      module_put(match->me);
++                      return -EINVAL;
++              }
++
+               off = ebt_compat_match_offset(match, match_size);
+               if (dst) {
+                       if (match->compat_from_user)
+@@ -1995,6 +2019,12 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                                           mwt->u.revision);
+               if (IS_ERR(wt))
+                       return PTR_ERR(wt);
++
++              if (!tgt_size_ok(wt, match_size)) {
++                      module_put(wt->me);
++                      return -EINVAL;
++              }
++
+               off = xt_compat_target_offset(wt);
+               if (dst) {
+-- 
+2.53.0
+
diff --git a/queue-5.15/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch b/queue-5.15/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
new file mode 100644 (file)
index 0000000..aa958e5
--- /dev/null
@@ -0,0 +1,68 @@
+From 0899af06dcf89b63877fa69450af6847b0c75547 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 12:36:14 -0700
+Subject: netfilter: synproxy: refresh tcphdr after skb_ensure_writable
+
+From: Chris Mason <clm@meta.com>
+
+[ Upstream commit 92170e6afe927ab2792a3f71902845789c8e31b1 ]
+
+synproxy_tstamp_adjust() rewrites the TCP timestamp option in place
+and then patches the TCP checksum via inet_proto_csum_replace4() on
+the caller-supplied tcphdr pointer.  Both ipv4_synproxy_hook() and
+ipv6_synproxy_hook() obtain that pointer with skb_header_pointer()
+before calling in, so it may either alias skb->head directly or
+point at the caller's on-stack _tcph buffer.
+
+Between obtaining the pointer and using it, the function calls
+skb_ensure_writable(skb, optend), which on a cloned or non-linear
+skb invokes pskb_expand_head() and frees the old skb->head.  After
+that point the cached th is stale:
+
+    caller (ipv[46]_synproxy_hook)
+      th = skb_header_pointer(skb, ..., &_tcph)
+      synproxy_tstamp_adjust(skb, protoff, th, ...)
+        skb_ensure_writable(skb, optend)
+          pskb_expand_head()        /* kfree(old skb->head) */
+        ...
+        inet_proto_csum_replace4(&th->check, ...)
+                                    /* writes into freed head, or
+                                       into the caller's stack copy
+                                       leaving the on-wire checksum
+                                       stale */
+
+The option bytes are written through skb->data and are fine; only
+the checksum update goes through th and so lands in the wrong
+place.  The result is either a write into freed slab memory or a
+packet leaving with a checksum that does not match its payload.
+
+Fix by re-deriving th from skb->data + protoff immediately after
+skb_ensure_writable() succeeds, so the subsequent checksum update
+targets the linear, writable header.
+
+Fixes: 48b1de4c110a ("netfilter: add SYNPROXY core/target")
+Assisted-by: kres (claude-opus-4-7)
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-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_synproxy_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c
+index 049a88f0380117..cdb2c3e23af7ee 100644
+--- a/net/netfilter/nf_synproxy_core.c
++++ b/net/netfilter/nf_synproxy_core.c
+@@ -199,6 +199,8 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff,
+       if (skb_ensure_writable(skb, optend))
+               return 0;
++      th = (struct tcphdr *)(skb->data + protoff);
++
+       while (optoff < optend) {
+               unsigned char *op = skb->data + optoff;
+-- 
+2.53.0
+
diff --git a/queue-5.15/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch b/queue-5.15/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
new file mode 100644 (file)
index 0000000..6e8304b
--- /dev/null
@@ -0,0 +1,48 @@
+From 2f7ee612f3843e6f212e651de546b55665281a55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 20:10:08 +0200
+Subject: netfilter: xt_cpu: prefer raw_smp_processor_id
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit c376f07e16c02239ed44cabb97145d03f65b4d15 ]
+
+With PREEMPT_RCU we get splat:
+
+BUG: using smp_processor_id() in preemptible [..]
+caller is cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+CPU: 1 .. Comm: syz.3.1377 #0 PREEMPT(full)
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
+ check_preemption_disabled+0xd3/0xe0 lib/smp_processor_id.c:47
+ cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+ [..]
+
+Just use raw version instead.
+This is similar to 14d14a5d2957 ("netfilter: nft_meta: use raw_smp_processor_id()").
+
+Fixes: 0ca743a55991 ("netfilter: nf_tables: add compatibility layer for x_tables")
+Reported-by: syzbot+690d3e3ffa7335ac10eb@syzkaller.appspotmail.com
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_cpu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/xt_cpu.c b/net/netfilter/xt_cpu.c
+index 3bdc302a0f9137..9cb259902a586b 100644
+--- a/net/netfilter/xt_cpu.c
++++ b/net/netfilter/xt_cpu.c
+@@ -34,7 +34,7 @@ static bool cpu_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       const struct xt_cpu_info *info = par->matchinfo;
+-      return (info->cpu == smp_processor_id()) ^ info->invert;
++      return (info->cpu == raw_smp_processor_id()) ^ info->invert;
+ }
+ static struct xt_match cpu_mt_reg __read_mostly = {
+-- 
+2.53.0
+
diff --git a/queue-5.15/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch b/queue-5.15/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
new file mode 100644 (file)
index 0000000..fcaa032
--- /dev/null
@@ -0,0 +1,40 @@
+From 1da7769db462443217ed66ce6646363125c03e5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:41 +0000
+Subject: nfc: llcp: Fix use-after-free in llcp_sock_release()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit f4268b466190dae95a7585f69b4f1f8ad097632c ]
+
+llcp_sock_release() unconditionally unlinks the socket from the local
+sockets list.  However, if the socket is still in connecting state, it
+is on the connecting list.
+
+Fix this by checking the socket state and unlinking from the correct list.
+
+Fixes: b4011239a08e ("NFC: llcp: Fix non blocking sockets connections")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-1-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_sock.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index 6e1fba2084930e..54af85d939c6b9 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -640,6 +640,8 @@ static int llcp_sock_release(struct socket *sock)
+       if (sock->type == SOCK_RAW)
+               nfc_llcp_sock_unlink(&local->raw_sockets, sk);
++      else if (sk->sk_state == LLCP_CONNECTING)
++              nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       else
+               nfc_llcp_sock_unlink(&local->sockets, sk);
+-- 
+2.53.0
+
diff --git a/queue-5.15/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch b/queue-5.15/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
new file mode 100644 (file)
index 0000000..906565f
--- /dev/null
@@ -0,0 +1,67 @@
+From 652fe46e2b45d2433a29cb76584eea98e082c2f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:42 +0000
+Subject: nfc: llcp: Fix use-after-free race in nfc_llcp_recv_cc()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit b493ea2765cc17cb8aa7e7544a4b6dcb05b6ed77 ]
+
+A race condition exists in the NFC LLCP connection state machine where
+the connection acceptance packet (CC) can be processed concurrently with
+socket release.  This can lead to a use-after-free of the socket object.
+
+When nfc_llcp_recv_cc() moves the socket from the connecting_sockets
+list to the sockets list, it does so without holding the socket lock.
+If llcp_sock_release() is executing concurrently, it might have already
+unlinked the socket and dropped its references, which can result in
+nfc_llcp_recv_cc() linking a freed socket into the live list.
+
+Fix this by holding lock_sock() during the state transition and list
+movement in nfc_llcp_recv_cc().  After acquiring the lock, check if
+the socket is still hashed to ensure it hasn't already been unlinked
+and marked for destruction by the release path.  This aligns the locking
+pattern with recv_hdlc() and recv_disc().
+
+Fixes: a69f32af86e3 ("NFC: Socket linked list")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-2-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_core.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
+index e04634f22b49f4..c7de44637e0187 100644
+--- a/net/nfc/llcp_core.c
++++ b/net/nfc/llcp_core.c
+@@ -1225,6 +1225,15 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk = &llcp_sock->sk;
++      lock_sock(sk);
++
++      /* Check if socket was destroyed whilst waiting for the lock */
++      if (!sk_hashed(sk)) {
++              release_sock(sk);
++              nfc_llcp_sock_put(llcp_sock);
++              return;
++      }
++
+       /* Unlink from connecting and link to the client array */
+       nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       nfc_llcp_sock_link(&local->sockets, sk);
+@@ -1236,6 +1245,8 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk->sk_state = LLCP_CONNECTED;
+       sk->sk_state_change(sk);
++      release_sock(sk);
++
+       nfc_llcp_sock_put(llcp_sock);
+ }
+-- 
+2.53.0
+
diff --git a/queue-5.15/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch b/queue-5.15/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
new file mode 100644 (file)
index 0000000..97e6765
--- /dev/null
@@ -0,0 +1,83 @@
+From 7ce95e17969c2ef6813c3c45d94a553315dce89b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 May 2026 19:55:18 +0800
+Subject: nfc: nxp-nci: i2c: use rising-edge IRQ on ACPI systems
+
+From: Carl Lee <carl.lee@amd.com>
+
+[ Upstream commit f23bf992d65a42007c517b060ca35cebdea3525a ]
+
+Some ACPI-based platforms report incorrect IRQ trigger types (e.g.
+IRQF_TRIGGER_HIGH), which can lead to interrupt storms.
+
+Use the historically working rising-edge trigger on ACPI systems to
+avoid this regression.
+
+Device Tree-based systems continue to use the firmware-provided
+trigger type.
+
+Fixes: 57be33f85e36 ("nfc: nxp-nci: remove interrupt trigger type")
+Signed-off-by: Carl Lee <carl.lee@amd.com>
+Tested-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Luca Stefani <luca.stefani.ge1@gmail.com>
+Link: https://patch.msgid.link/20260516-nfc-nxp-nci-i2c-restore-irq-trigger-fallback-v3-1-37ba4b6e9086@amd.com
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/nxp-nci/i2c.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c
+index 22c498860c03d5..a0e665f958c4d5 100644
+--- a/drivers/nfc/nxp-nci/i2c.c
++++ b/drivers/nfc/nxp-nci/i2c.c
+@@ -16,6 +16,7 @@
+ #include <linux/delay.h>
+ #include <linux/i2c.h>
+ #include <linux/interrupt.h>
++#include <linux/irq.h>
+ #include <linux/module.h>
+ #include <linux/nfc.h>
+ #include <linux/gpio/consumer.h>
+@@ -268,6 +269,7 @@ static int nxp_nci_i2c_probe(struct i2c_client *client,
+ {
+       struct device *dev = &client->dev;
+       struct nxp_nci_i2c_phy *phy;
++      unsigned long irqflags;
+       int r;
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+@@ -304,9 +306,26 @@ static int nxp_nci_i2c_probe(struct i2c_client *client,
+       if (r < 0)
+               return r;
++      /*
++       * ACPI platforms may report incorrect IRQ trigger types
++       * (e.g. level-high), which can lead to interrupt storms.
++       *
++       * Use the historically stable rising-edge trigger for ACPI devices.
++       *
++       * On non-ACPI systems (e.g. Device Tree), prefer the firmware-
++       * provided trigger type, falling back to rising-edge if not set.
++       */
++      if (ACPI_COMPANION(dev)) {
++              irqflags = IRQF_TRIGGER_RISING;
++      } else {
++              irqflags = irq_get_trigger_type(client->irq);
++              if (!irqflags)
++                      irqflags = IRQF_TRIGGER_RISING;
++      }
++
+       r = request_threaded_irq(client->irq, NULL,
+                                nxp_nci_i2c_irq_thread_fn,
+-                               IRQF_ONESHOT,
++                               irqflags | IRQF_ONESHOT,
+                                NXP_NCI_I2C_DRIVER_NAME, phy);
+       if (r < 0)
+               nfc_err(&client->dev, "Unable to register IRQ handler\n");
+-- 
+2.53.0
+
diff --git a/queue-5.15/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch b/queue-5.15/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
new file mode 100644 (file)
index 0000000..ee6b89e
--- /dev/null
@@ -0,0 +1,50 @@
+From a27b84367bd322f2b53cd168f454ab479cb9e934 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 11:24:11 +0800
+Subject: sctp: fix race between sctp_wait_for_connect and peeloff
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit f14fe6395a8b3d961a61e138ad7b36ba3626dd4e ]
+
+sctp_wait_for_connect() drops and re-acquires the socket lock while
+waiting for the association to reach ESTABLISHED state. During this
+window, another thread can peeloff the association to a new socket via
+getsockopt(SCTP_SOCKOPT_PEELOFF), changing asoc->base.sk. After
+re-acquiring the old socket lock, sctp_wait_for_connect() returns
+success without noticing the migration â€” the caller then accesses
+the association under the wrong lock in sctp_datamsg_from_user().
+
+Add the same sk != asoc->base.sk check that sctp_wait_for_sndbuf()
+already has, returning an error if the association was migrated while
+we slept.
+
+Fixes: 668c9beb9020 ("sctp: implement assign_number for sctp_stream_interleave")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260527032411.60959-1-kipreyyy@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/socket.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 11040232ee937b..136b122d87c5a6 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -9369,6 +9369,8 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p)
+               release_sock(sk);
+               current_timeo = schedule_timeout(current_timeo);
+               lock_sock(sk);
++              if (sk != asoc->base.sk)
++                      goto do_error;
+               *timeo_p = current_timeo;
+       }
+-- 
+2.53.0
+
index b08d13ad77357bf9da23cf93b2bf927fa794dd4c..1b2dcdd1466dfaa3de4b9d0ba313f2d642215178 100644 (file)
@@ -4,3 +4,31 @@ net-sched-sch_sfb-replace-direct-dequeue-call-with-p.patch
 drm-remove-plane-hsub-vsub-alignment-requirement-for.patch
 dmaengine-idxd-fix-not-releasing-workqueue-on-.relea.patch
 net-cpsw_new-fix-potential-unregister-of-netdev-that.patch
+nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
+nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
+xfrm-check-for-underflow-in-xfrm_state_mtu.patch
+nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
+kernel-fork-validate-exit_signal-in-kernel_clone.patch
+netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
+netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
+netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
+tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
+net-netlink-fix-sending-unassigned-nsid-after-assign.patch
+net-netlink-don-t-set-nsid-on-local-notifications.patch
+net-smc-do-not-re-initialize-smc-hashtables.patch
+net-iucv-fix-locking-in-.getsockopt.patch
+ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
+asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
+tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
+vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
+tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
+asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
+bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
+bonding-refuse-to-enslave-can-devices.patch
+ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
+ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
+net-sched-revert-net-sched-restrict-conditions-for-a.patch
+bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
+bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
+gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
+sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
diff --git a/queue-5.15/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch b/queue-5.15/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
new file mode 100644 (file)
index 0000000..40a02f6
--- /dev/null
@@ -0,0 +1,54 @@
+From 5429844329f1004c49595dabfd07861f21710708 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 09:00:21 -0700
+Subject: tun: free page on short-frame rejection in tun_xdp_one()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f4feb1e20058e407cb00f45aff47f5b7e19a6bbf ]
+
+tun_xdp_one() returns -EINVAL on a frame shorter than ETH_HLEN without
+freeing the page that vhost_net_build_xdp() allocated for it.
+tun_sendmsg() discards that -EINVAL and still returns total_len, so
+vhost_tx_batch() takes the success path and never frees the page; each
+short frame in a batch leaks one page-frag chunk.
+
+A local process that can open /dev/net/tun and /dev/vhost-net can hit
+this path: it attaches a tun/tap device as the vhost-net backend and
+feeds TX descriptors whose length minus the virtio-net header is below
+ETH_HLEN. Each kick leaks the page-frag chunks for that batch, and a
+tight submission loop exhausts host memory and triggers an OOM panic.
+Free the page before returning -EINVAL, matching the XDP-program error
+path in the same function.
+
+Fixes: 049584807f1d ("tun: add missing verification for short frame")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260520160020.375349-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 5c9e7d0beffa26..803cb4722dbf4a 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2422,8 +2422,10 @@ static int tun_xdp_one(struct tun_struct *tun,
+       bool skb_xdp = false;
+       struct page *page;
+-      if (unlikely(datasize < ETH_HLEN))
++      if (unlikely(datasize < ETH_HLEN)) {
++              put_page(virt_to_head_page(xdp->data));
+               return -EINVAL;
++      }
+       xdp_prog = rcu_dereference(tun->xdp_prog);
+       if (xdp_prog) {
+-- 
+2.53.0
+
diff --git a/queue-5.15/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch b/queue-5.15/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
new file mode 100644 (file)
index 0000000..086052e
--- /dev/null
@@ -0,0 +1,67 @@
+From 8249b8fe86dec818a6318d68f03ebe8f26e89ef6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 11:55:12 +0000
+Subject: tunnels: do not assume transport header in
+ iptunnel_pmtud_check_icmp()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 509323077ef79a26ba0c60bb556e45c12c398b2d ]
+
+In some cases, iptunnel_pmtud_check_icmp() can be called while
+skb transport header is not set.
+
+This triggers an out-of-bound access, because
+(typeof(skb->transport_header))~0U is 65535.
+
+Access the icmp header based on IPv4 network header,
+after making sure icmp->type is present in skb linear part.
+
+Note that iptunnel_pmtud_check_icmpv6()) is fine.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Reported-by: Damiano Melotti <melotti@google.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260522115512.1519110-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index 4d80bbcd15d5a4..f535b875a02b88 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -262,7 +262,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct icmphdr *icmph = icmp_hdr(skb);
+       const struct iphdr *iph = ip_hdr(skb);
+       if (mtu < 576 || iph->frag_off != htons(IP_DF))
+@@ -273,9 +272,17 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+           ipv4_is_lbcast(iph->saddr)  || ipv4_is_multicast(iph->saddr))
+               return 0;
+-      if (iph->protocol == IPPROTO_ICMP && icmp_is_err(icmph->type))
+-              return 0;
++      if (iph->protocol == IPPROTO_ICMP) {
++              const struct icmphdr *icmph;
++              if (!pskb_network_may_pull(skb, iph->ihl * 4 +
++                                              offsetofend(struct icmphdr, type)))
++                      return 0;
++              iph = ip_hdr(skb);
++              icmph = (void *)iph + iph->ihl * 4;
++              if (icmp_is_err(icmph->type))
++                      return 0;
++      }
+       return iptunnel_pmtud_build_icmp(skb, mtu);
+ }
+-- 
+2.53.0
+
diff --git a/queue-5.15/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch b/queue-5.15/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
new file mode 100644 (file)
index 0000000..fd0bebb
--- /dev/null
@@ -0,0 +1,87 @@
+From ee4436d0931a8ff123078311a8193abd52e3cd76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:13:35 +0000
+Subject: tunnels: load network headers after skb_cow() in
+ iptunnel_pmtud_build_icmp[v6]()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b4bc94353050b1fa7b702bd4c6600710dd926cff ]
+
+Sashiko found that iptunnel_pmtud_build_icmp() and
+iptunnel_pmtud_build_icmpv6() were caching ip_hdr() and ipv6_hdr()
+before an skb_cow() call which can reallocate skb->head.
+
+Fix this possible UAF by initializing the local variables
+after the skb_cow() call.
+
+Remove skb_reset_network_header() calls which were not needed.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525201335.2361845-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index 3737188ba4e1e5..4d80bbcd15d5a4 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -194,7 +194,7 @@ EXPORT_SYMBOL_GPL(iptunnel_handle_offloads);
+  */
+ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct iphdr *iph = ip_hdr(skb);
++      const struct iphdr *iph;
+       struct icmphdr *icmph;
+       struct iphdr *niph;
+       struct ethhdr eh;
+@@ -208,7 +208,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, 576 - sizeof(*niph) - sizeof(*icmph));
+       if (err)
+@@ -218,7 +217,7 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       err = skb_cow(skb, sizeof(*niph) + sizeof(*icmph) + ETH_HLEN);
+       if (err)
+               return err;
+-
++      iph = ip_hdr(skb);
+       icmph = skb_push(skb, sizeof(*icmph));
+       *icmph = (struct icmphdr) {
+               .type                   = ICMP_DEST_UNREACH,
+@@ -290,7 +289,7 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+ {
+-      const struct ipv6hdr *ip6h = ipv6_hdr(skb);
++      const struct ipv6hdr *ip6h;
+       struct icmp6hdr *icmp6h;
+       struct ipv6hdr *nip6h;
+       struct ethhdr eh;
+@@ -305,7 +304,6 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, IPV6_MIN_MTU - sizeof(*nip6h) - sizeof(*icmp6h));
+       if (err)
+@@ -316,6 +314,7 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       if (err)
+               return err;
++      ip6h = ipv6_hdr(skb);
+       icmp6h = skb_push(skb, sizeof(*icmp6h));
+       *icmp6h = (struct icmp6hdr) {
+               .icmp6_type             = ICMPV6_PKT_TOOBIG,
+-- 
+2.53.0
+
diff --git a/queue-5.15/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch b/queue-5.15/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
new file mode 100644 (file)
index 0000000..fdc0a5b
--- /dev/null
@@ -0,0 +1,54 @@
+From cd0e8f185705b7c38723c084e49eebd54f644098 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:36:42 +0000
+Subject: vxlan: do not reuse cached ip_hdr() value after
+ skb_tunnel_check_pmtu()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 7d9ef0cb271555d8cf39fefe6c981e1493b25ecf ]
+
+skb_tunnel_check_pmtu() can change skb->head.
+
+Reusing old_iph afer skb_tunnel_check_pmtu() can cause an UAF.
+
+Use instead ip_hdr(skb) as done in drivers/net/bareudp.c
+and drivers/net/geneve.c.
+
+Found by Sashiko.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525203642.2389723-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vxlan/vxlan_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
+index bd2b44071781ca..7967b429dfcf5f 100644
+--- a/drivers/net/vxlan/vxlan_core.c
++++ b/drivers/net/vxlan/vxlan_core.c
+@@ -2753,7 +2753,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr),
+                                     vni, md, flags, udp_sum);
+@@ -2816,7 +2816,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip6_dst_hoplimit(ndst);
+               skb_scrub_packet(skb, xnet);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
+-- 
+2.53.0
+
diff --git a/queue-5.15/xfrm-check-for-underflow-in-xfrm_state_mtu.patch b/queue-5.15/xfrm-check-for-underflow-in-xfrm_state_mtu.patch
new file mode 100644 (file)
index 0000000..9ab1fce
--- /dev/null
@@ -0,0 +1,85 @@
+From 1c7e2d114626b6cb876e8e6707895c38d83bdaa8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 10:49:14 -0600
+Subject: xfrm: Check for underflow in xfrm_state_mtu
+
+From: David Ahern <dahern@nvidia.com>
+
+[ Upstream commit 742b04d0550b0ec89dcbc99537ec88653bd1ad90 ]
+
+Leo Lin reported OOB write issue in esp component:
+
+  xfrm_state_mtu() returns u32 but performs its arithmetic in unsigned
+  modulo-2^32 space using an attacker-influenced "header_len + authsize +
+  net_adj" subtracted from a small "mtu" argument. A nobody user can
+  install an IPv4 ESP tunnel SA with a large authentication key
+  (XFRMA_ALG_AUTH_TRUNC, e.g. hmac(sha512), 64-byte key, 64-byte trunc),
+  configure a small interface MTU (68 bytes), and set XFRMA_TFCPAD to a
+  large value. When a single UDP datagram is then sent through the
+  tunnel, xfrm_state_mtu() underflows to a near-2^32 value, and
+  esp_output() consumes it as a signed int via:
+
+        padto      = min(x->tfcpad, xfrm_state_mtu(x, mtu_cached))
+        esp.tfclen = padto - skb->len   (assigned to int)
+
+  esp.tfclen ends up negative (e.g. -207). It is sign-extended to size_t
+  when passed to memset() inside esp_output_fill_trailer(), producing a
+  ~16 EB write of zeroes at skb_tail_pointer(skb). KASAN logs it as
+  "Write of size 18446744073709551537 at addr ffff888...".
+
+Check for underflow and return 1. This causes the sendmsg attempt to
+fail with ENETUNREACH.
+
+Fixes: c5c252389374 ("[XFRM]: Optimize MTU calculation")
+Reported-by: Leo Lin <leo@depthfirst.com>
+Assisted-by: Codex:26.506.31004
+Signed-off-by: David Ahern <dahern@nvidia.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index f7f568bfb93a80..9593fcc7508c94 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -2581,10 +2581,14 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+       const struct xfrm_type *type = READ_ONCE(x->type);
+       struct crypto_aead *aead;
+       u32 blksize, net_adj = 0;
++      u32 overhead, payload_mtu;
+       if (x->km.state != XFRM_STATE_VALID ||
+-          !type || type->proto != IPPROTO_ESP)
++          !type || type->proto != IPPROTO_ESP) {
++              if (mtu <= x->props.header_len)
++                      return 1;
+               return mtu - x->props.header_len;
++      }
+       aead = x->data;
+       blksize = ALIGN(crypto_aead_blocksize(aead), 4);
+@@ -2604,8 +2608,17 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+               break;
+       }
+-      return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
+-               net_adj) & ~(blksize - 1)) + net_adj - 2;
++      overhead = x->props.header_len + crypto_aead_authsize(aead) + net_adj;
++      if (mtu <= overhead)
++              return 1;
++
++      payload_mtu = mtu - overhead;
++      payload_mtu &= ~(blksize - 1);
++      if (payload_mtu <= 2)
++              return 1;
++
++      return payload_mtu + net_adj - 2;
++
+ }
+ EXPORT_SYMBOL_GPL(xfrm_state_mtu);
+-- 
+2.53.0
+
diff --git a/queue-6.1/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch b/queue-6.1/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
new file mode 100644 (file)
index 0000000..fd4197c
--- /dev/null
@@ -0,0 +1,47 @@
+From 86f15fb7b3bcaa9307a6962b5201b5f93ea6b5b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 09:24:00 -0300
+Subject: ASoC: codecs: simple-mux: Fix enum control bounds check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit f63ad68e18d774a5d15cd7e405ead63f6b322679 ]
+
+simple_mux_control_put() rejects values greater than e->items, but
+enum control values are zero based. For the two-entry mux used by this
+driver, valid values are 0 and 1, so value 2 must be rejected as well.
+
+Accepting e->items can store an invalid mux state, pass it to the GPIO
+setter, and pass it on to the DAPM mux update path where it is used as
+an index into the enum text array.
+
+Use the same >= e->items check used by the ASoC enum helpers.
+
+Fixes: 342fbb7578d1 ("ASoC: add simple-mux")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260527-asoc-simple-mux-enum-bounds-v1-1-3f805b9fc671@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/simple-mux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/simple-mux.c b/sound/soc/codecs/simple-mux.c
+index d30c0d24d90a65..c5aa58c6e7bae6 100644
+--- a/sound/soc/codecs/simple-mux.c
++++ b/sound/soc/codecs/simple-mux.c
+@@ -40,7 +40,7 @@ static int simple_mux_control_put(struct snd_kcontrol *kcontrol,
+       struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
+       struct simple_mux *priv = snd_soc_component_get_drvdata(c);
+-      if (ucontrol->value.enumerated.item[0] > e->items)
++      if (ucontrol->value.enumerated.item[0] >= e->items)
+               return -EINVAL;
+       if (priv->mux == ucontrol->value.enumerated.item[0])
+-- 
+2.53.0
+
diff --git a/queue-6.1/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch b/queue-6.1/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
new file mode 100644 (file)
index 0000000..ce67f0b
--- /dev/null
@@ -0,0 +1,112 @@
+From 6676b3b2d8abbdf90a58f3d3e887db52017ed1ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 13:51:47 -0300
+Subject: ASoC: Intel: bytcht_es8316: Fix MCLK leak on init errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit afb2a3a9d8369d18122a0d7cd294eba9a98259c6 ]
+
+byt_cht_es8316_init() enables MCLK before configuring the codec sysclk
+and creating the headset jack. If either of those later steps fails, the
+function returns without disabling MCLK, leaving the clock enabled after
+card registration fails.
+
+Track whether this driver enabled MCLK and disable it on the init error
+paths. Add the matching DAI link exit callback so the same clock enable
+is also balanced when ASoC cleans up a successfully initialized link.
+
+Fixes: a03bdaa565cb ("ASoC: Intel: add machine driver for BYT/CHT + ES8316")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260519-asoc-bytcht-es8316-mclk-leak-v1-1-b4a11cdc2afd@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcht_es8316.c | 29 ++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
+index fa2c3981dacac9..ff3642e8c132f8 100644
+--- a/sound/soc/intel/boards/bytcht_es8316.c
++++ b/sound/soc/intel/boards/bytcht_es8316.c
+@@ -39,6 +39,7 @@ struct byt_cht_es8316_private {
+       struct gpio_desc *speaker_en_gpio;
+       struct device *codec_dev;
+       bool speaker_en;
++      bool mclk_enabled;
+ };
+ enum {
+@@ -169,6 +170,15 @@ static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
+       },
+ };
++static void byt_cht_es8316_disable_mclk(struct byt_cht_es8316_private *priv)
++{
++      if (!priv->mclk_enabled)
++              return;
++
++      clk_disable_unprepare(priv->mclk);
++      priv->mclk_enabled = false;
++}
++
+ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+ {
+       struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component;
+@@ -225,12 +235,14 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+       ret = clk_prepare_enable(priv->mclk);
+       if (ret)
+               dev_err(card->dev, "unable to enable MCLK\n");
++      else
++              priv->mclk_enabled = true;
+       ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(runtime, 0), 0, 19200000,
+                                    SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               dev_err(card->dev, "can't set codec clock %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       ret = snd_soc_card_jack_new_pins(card, "Headset",
+@@ -239,13 +251,25 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+                                        ARRAY_SIZE(byt_cht_es8316_jack_pins));
+       if (ret) {
+               dev_err(card->dev, "jack creation failed %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+       snd_soc_component_set_jack(codec, &priv->jack, NULL);
+       return 0;
++
++err_disable_mclk:
++      byt_cht_es8316_disable_mclk(priv);
++      return ret;
++}
++
++static void byt_cht_es8316_exit(struct snd_soc_pcm_runtime *runtime)
++{
++      struct snd_soc_card *card = runtime->card;
++      struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
++
++      byt_cht_es8316_disable_mclk(priv);
+ }
+ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
+@@ -355,6 +379,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
+               .dpcm_playback = 1,
+               .dpcm_capture = 1,
+               .init = byt_cht_es8316_init,
++              .exit = byt_cht_es8316_exit,
+               SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
+       },
+ };
+-- 
+2.53.0
+
diff --git a/queue-6.1/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch b/queue-6.1/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
new file mode 100644 (file)
index 0000000..bfbf375
--- /dev/null
@@ -0,0 +1,40 @@
+From d4fd1b935a27d91a39dec9c29069b4f02909647d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 11:21:39 +0800
+Subject: Bluetooth: 6lowpan: check skb_clone() return value in
+ send_mcast_pkt()
+
+From: Zhao Dongdong <zhaodongdong@kylinos.cn>
+
+[ Upstream commit 3c40d381ce04f9575a5d8b542898183c3b4b38dc ]
+
+The skb_clone() function can return NULL if memory allocation fails.
+send_mcast_pkt() calls skb_clone() without checking the return value, which
+can lead to a NULL pointer dereference in send_pkt() when it dereferences
+skb->data.
+Add a NULL check after skb_clone() and skip the peer if the clone fails.
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Signed-off-by: Zhao Dongdong <zhaodongdong@kylinos.cn>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 347361ff0cc878..dc3d1d5326e96a 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -485,6 +485,8 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
+                       int ret;
+                       local_skb = skb_clone(skb, GFP_ATOMIC);
++                      if (!local_skb)
++                              continue;
+                       BT_DBG("xmit %s to %pMR type %u IP %pI6c chan %p",
+                              netdev->name,
+-- 
+2.53.0
+
diff --git a/queue-6.1/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch b/queue-6.1/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
new file mode 100644 (file)
index 0000000..707921c
--- /dev/null
@@ -0,0 +1,62 @@
+From 04075e492b5bd67fee72be4528f851b3ead2a771 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 18:51:52 +0800
+Subject: Bluetooth: l2cap: clear chan->ident on ECRED reconfiguration success
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit 00e1950716c6ed67d74777b2db286b0fa23b4be9 ]
+
+l2cap_ecred_reconf_rsp() returns early on success without clearing
+chan->ident. Every other L2CAP response handler (l2cap_ecred_conn_rsp,
+l2cap_le_connect_rsp, l2cap_config_rsp) clears chan->ident after a
+successful transaction to prevent the channel from matching subsequent
+responses with the recycled ident value.
+
+A remote attacker that completed a reconfiguration as the peer can
+replay a failure response with the stale ident, causing the kernel to
+match and destroy the already-established channel via
+l2cap_chan_del(chan, ECONNRESET).
+
+Clear chan->ident for all matching channels on success, and harden the
+failure path by using l2cap_chan_hold_unless_zero() consistent with
+other L2CAP handlers (l2cap_le_command_rej, __l2cap_get_chan_by_ident).
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 21f63ca434e3fd..a3ee31f2fa2880 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -6454,14 +6454,20 @@ static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
+       BT_DBG("result 0x%4.4x", result);
+-      if (!result)
++      if (!result) {
++              list_for_each_entry(chan, &conn->chan_l, list) {
++                      if (chan->ident == cmd->ident)
++                              chan->ident = 0;
++              }
+               return 0;
++      }
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
+               if (chan->ident != cmd->ident)
+                       continue;
+-              l2cap_chan_hold(chan);
++              if (!l2cap_chan_hold_unless_zero(chan))
++                      continue;
+               l2cap_chan_lock(chan);
+               l2cap_chan_del(chan, ECONNRESET);
+-- 
+2.53.0
+
diff --git a/queue-6.1/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch b/queue-6.1/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
new file mode 100644 (file)
index 0000000..25de3c1
--- /dev/null
@@ -0,0 +1,82 @@
+From 093c62d66dd253d45c07ce26aa6ad7e6dfea7a2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 May 2026 12:09:42 -0400
+Subject: Bluetooth: L2CAP: Fix possible crash on l2cap_ecred_conn_rsp
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 41c2713b204e6cb6a94587bc6bf6935107df5479 ]
+
+If dcid is received for an already-assigned destination CID the spec
+requires that both channels to be discarded, but calling l2cap_chan_del
+may invalidate the tmp cursor created by list_for_each_entry_safe and
+in fact it is the wrong procedure as the chan->dcid may be assigned
+previously it really needs to be disconnected.
+
+Calling l2cap_chan_clone directly may still lead to l2cap_chan_del so
+instead schedule l2cap_chan_timeout with delay 0 to close the channel
+asynchronously.
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 27 ++++++++++++++++++++++-----
+ 1 file changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index a3ee31f2fa2880..8031f83b10832e 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -6254,6 +6254,7 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+       cmd_len -= sizeof(*rsp);
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
++              struct l2cap_chan *orig;
+               u16 dcid;
+               if (chan->ident != cmd->ident ||
+@@ -6275,8 +6276,10 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+               BT_DBG("dcid[%d] 0x%4.4x", i, dcid);
++              orig = __l2cap_get_chan_by_dcid(conn, dcid);
++
+               /* Check if dcid is already in use */
+-              if (dcid && __l2cap_get_chan_by_dcid(conn, dcid)) {
++              if (dcid && orig) {
+                       /* If a device receives a
+                        * L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an
+                        * already-assigned Destination CID, then both the
+@@ -6285,10 +6288,24 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+                        */
+                       l2cap_chan_del(chan, ECONNREFUSED);
+                       l2cap_chan_unlock(chan);
+-                      chan = __l2cap_get_chan_by_dcid(conn, dcid);
+-                      l2cap_chan_lock(chan);
+-                      l2cap_chan_del(chan, ECONNRESET);
+-                      l2cap_chan_unlock(chan);
++
++                      /* Check that the dcid channel mode is
++                       * L2CAP_MODE_EXT_FLOWCTL since this procedure is only
++                       * valid for that mode and shouldn't disconnect a dcid
++                       * in other modes.
++                       */
++                      if (orig->mode == L2CAP_MODE_EXT_FLOWCTL) {
++                              l2cap_chan_lock(orig);
++                              /* Disconnect the original channel as it may be
++                               * considered connected since dcid has already
++                               * been assigned; don't call l2cap_chan_close
++                               * directly since that could lead to
++                               * l2cap_chan_del and then removing the channel
++                               * from the list while we're iterating over it.
++                               */
++                              __set_chan_timer(orig, 0);
++                              l2cap_chan_unlock(orig);
++                      }
+                       continue;
+               }
+-- 
+2.53.0
+
diff --git a/queue-6.1/bonding-refuse-to-enslave-can-devices.patch b/queue-6.1/bonding-refuse-to-enslave-can-devices.patch
new file mode 100644 (file)
index 0000000..6cf5d8f
--- /dev/null
@@ -0,0 +1,74 @@
+From 569e72048542af72775f2bb22a0a150fe87e678f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 21:33:19 +0200
+Subject: bonding: refuse to enslave CAN devices
+
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+
+[ Upstream commit 8ba68464e4787b6a7ec938826e16124df20fd23d ]
+
+syzbot reported a kernel paging request crash in
+can_rx_unregister() inside net/can/af_can.c. The crash occurs
+because a virtual CAN device (vxcan) is being enslaved to a
+bonding master.
+
+During the enslavement process, the bonding driver mutates
+and modifies the network device states to fit an Ethernet-like
+aggregation model. However, CAN devices operate on a completely
+different Layer 2 architecture, relying on the CAN mid-layer
+private data structure (can_ml_priv) instead of standard
+Ethernet structures. Since bonding does not initialize or
+maintain these CAN structures, subsequent operations on the
+half-enslaved interface (such as closing associated sockets
+via isotp_release) lead to a null-pointer dereference when
+accessing the CAN receiver lists.
+
+Bonding CAN interfaces is architecturally invalid as CAN lacks
+MAC addresses, ARP capabilities, and standard Ethernet
+link-layer mechanisms. While generic loopback devices are
+blocked globally in net/core/dev.c, virtual CAN devices
+bypass this check because they do not carry the IFF_LOOPBACK
+flag, despite acting as local software-loopbacks.
+
+Fix this by explicitly blocking network devices of type
+ARPHRD_CAN from being enslaved at the very beginning of
+bond_enslave(). This prevents illegal state mutations,
+eliminates the resulting KASAN crashes, and avoids potential
+memory leaks from incomplete socket cleanups.
+
+As the CAN support has been added a long time after bonding
+the Fixes-tag points to the introduction of ARPHRD_CAN that
+would have needed a specific handling in bonding_main.c.
+
+Fixes: cd05acfe65ed ("[CAN]: Allocate protocol numbers for PF_CAN")
+Reported-by: syzbot+8ed98cbd0161632bce95@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=8ed98cbd0161632bce95
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Link: https://patch.msgid.link/20260526-bonding-candev-v1-1-ba1df400918a@hartkopp.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index e9e2dec1dcb131..0e078252b52a98 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1848,6 +1848,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
+       int link_reporting;
+       int res = 0, i;
++      if (slave_dev->type == ARPHRD_CAN) {
++              BOND_NL_ERR(bond_dev, extack,
++                          "CAN devices cannot be enslaved");
++              return -EPERM;
++      }
++
+       if (slave_dev->flags & IFF_MASTER &&
+           !netif_is_bond_master(slave_dev)) {
+               BOND_NL_ERR(bond_dev, extack,
+-- 
+2.53.0
+
diff --git a/queue-6.1/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch b/queue-6.1/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
new file mode 100644 (file)
index 0000000..80add78
--- /dev/null
@@ -0,0 +1,62 @@
+From 0390598b033bcf7f29952077b262ac1327599c47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:33 -0700
+Subject: ethtool: eeprom: add more safeties to EEPROM Netlink fallback
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 67cfdd9210b99f260b3e0afeb9525e0acc7be31e ]
+
+The Netlink fallback path for reading module EEPROM
+(fallback_set_params()) validates that offset < eeprom_len,
+but does not check that offset + length stays within eeprom_len.
+The ioctl equivalent (ethtool_get_any_eeprom() in ioctl.c) has
+always enforced both bounds:
+
+  if (eeprom.offset + eeprom.len > total_len)
+      return -EINVAL;
+
+This could lead to surprises in both drivers and device FW.
+Add the missing offset + length validation to fallback_set_params(),
+mirroring the ioctl.
+
+Similarly - ethtool core in general, and ethtool_get_any_eeprom()
+in particular tries to zero-init all buffers passed to the drivers
+to avoid any extra work of zeroing things out. eeprom_fallback()
+uses a plain kmalloc(), change it to zalloc.
+
+Fixes: 96d971e307cc ("ethtool: Add fallback to get_module_eeprom from netlink command")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-11-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/eeprom.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c
+index 49c0a2a77f02de..6ce40f95d8aba5 100644
+--- a/net/ethtool/eeprom.c
++++ b/net/ethtool/eeprom.c
+@@ -43,6 +43,9 @@ static int fallback_set_params(struct eeprom_req_info *request,
+       if (offset >= modinfo->eeprom_len)
+               return -EINVAL;
++      if (length > modinfo->eeprom_len - offset)
++              return -EINVAL;
++
+       eeprom->cmd = ETHTOOL_GMODULEEEPROM;
+       eeprom->len = length;
+       eeprom->offset = offset;
+@@ -69,7 +72,7 @@ static int eeprom_fallback(struct eeprom_req_info *request,
+       if (err < 0)
+               return err;
+-      data = kmalloc(eeprom.len, GFP_KERNEL);
++      data = kzalloc(eeprom.len, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+       err = ethtool_get_module_eeprom_call(dev, &eeprom, data);
+-- 
+2.53.0
+
diff --git a/queue-6.1/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch b/queue-6.1/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
new file mode 100644 (file)
index 0000000..7728a35
--- /dev/null
@@ -0,0 +1,78 @@
+From 1ffd821641663944469346fbac362cf6b6e8116f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:02:45 +0200
+Subject: gpio: rockchip: convert bank->clk to devm_clk_get_enabled()
+
+From: Marco Scardovi <scardracs@disroot.org>
+
+[ Upstream commit 3e46c18d5d87f063a93ae0fe7662fbf6660459d5 ]
+
+The bank->clk was previously obtained via of_clk_get() and manually
+prepared/enabled. However, it was missing a corresponding clk_put() in
+both the error paths and the remove function, leading to a reference leak.
+
+Convert the allocation to devm_clk_get_enabled(), which also properly
+propagates failures from clk_prepare_enable() that were previously ignored.
+
+The GPIO bank device uses the same OF node as the previous of_clk_get()
+call, so devm_clk_get_enabled(dev, NULL) correctly resolves the same
+clock provider entry.
+
+Fix the reference leak and simplify the code by removing the manual
+clk_disable_unprepare() calls in the probe error paths and in the
+remove function.
+
+Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
+Assisted-by: Antigravity:gemini-3.5-flash
+Signed-off-by: Marco Scardovi <scardracs@disroot.org>
+Link: https://patch.msgid.link/20260526171050.12785-2-scardracs@disroot.org
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-rockchip.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index bf301b2d18b8f1..147d2fda4fe120 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -647,11 +647,10 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+       if (!bank->irq)
+               return -EINVAL;
+-      bank->clk = of_clk_get(bank->of_node, 0);
++      bank->clk = devm_clk_get_enabled(bank->dev, NULL);
+       if (IS_ERR(bank->clk))
+               return PTR_ERR(bank->clk);
+-      clk_prepare_enable(bank->clk);
+       id = readl(bank->reg_base + gpio_regs_v2.version_id);
+       /* If not gpio v2, that is default to v1. */
+@@ -661,7 +660,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+               bank->db_clk = of_clk_get(bank->of_node, 1);
+               if (IS_ERR(bank->db_clk)) {
+                       dev_err(bank->dev, "cannot find debounce clk\n");
+-                      clk_disable_unprepare(bank->clk);
+                       return -EINVAL;
+               }
+       } else {
+@@ -735,7 +733,6 @@ static int rockchip_gpio_probe(struct platform_device *pdev)
+       ret = rockchip_gpiolib_register(bank);
+       if (ret) {
+-              clk_disable_unprepare(bank->clk);
+               mutex_unlock(&bank->deferred_lock);
+               return ret;
+       }
+@@ -776,7 +773,6 @@ static int rockchip_gpio_remove(struct platform_device *pdev)
+ {
+       struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);
+-      clk_disable_unprepare(bank->clk);
+       gpiochip_remove(&bank->gpio_chip);
+       return 0;
+-- 
+2.53.0
+
diff --git a/queue-6.1/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch b/queue-6.1/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
new file mode 100644 (file)
index 0000000..739c1ae
--- /dev/null
@@ -0,0 +1,48 @@
+From 63fafc9c26c6336ea6bc00bdb6ad06f7f2f371b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 12:21:47 +0000
+Subject: ipv4: free net->ipv4.sysctl_local_reserved_ports after
+ unregister_net_sysctl_table()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 87a1e0fe7776da7ab411be332b4be58ac8840d10 ]
+
+ipv4_sysctl_exit_net() is currently freeing net->ipv4.sysctl_local_reserved_ports
+too soon.
+
+Only after unregister_net_sysctl_table() we can be sure no threads can possibly
+use the sysctls, including /proc/sys/net/ipv4/ip_local_reserved_ports.
+
+Fixes: 122ff243f5f1 ("ipv4: make ip_local_reserved_ports per netns")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Link: https://patch.msgid.link/20260521122147.3584624-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/sysctl_net_ipv4.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 6b4c9b0fc9abb7..ef17d0f95a9da5 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -1449,10 +1449,10 @@ static __net_exit void ipv4_sysctl_exit_net(struct net *net)
+ {
+       struct ctl_table *table;
+-      kfree(net->ipv4.sysctl_local_reserved_ports);
+       table = net->ipv4.ipv4_hdr->ctl_table_arg;
+       unregister_net_sysctl_table(net->ipv4.ipv4_hdr);
+       kfree(table);
++      kfree(net->ipv4.sysctl_local_reserved_ports);
+ }
+ static __net_initdata struct pernet_operations ipv4_sysctl_ops = {
+-- 
+2.53.0
+
diff --git a/queue-6.1/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch b/queue-6.1/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch
new file mode 100644 (file)
index 0000000..366fc41
--- /dev/null
@@ -0,0 +1,49 @@
+From 14cd9def271cd39d43881ac55b6ef3bb8988eb82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 13:31:31 +0800
+Subject: ipv6: fix possible infinite loop in fib6_select_path()
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 9c7da87c2dc860bb17ca1ece942495d28b1ce3b9 ]
+
+Found while auditing the same pattern Sashiko reported in
+rt6_fill_node() [1]. Apply the same fix as
+commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").
+
+Writers holding tb6_lock can list_del_rcu(&first->fib6_siblings)
+without waiting for RCU readers; first->fib6_siblings.next then
+still points into the old ring and this softirq-side walker never
+reaches &first->fib6_siblings as its terminator. fib6_purge_rt()
+always WRITE_ONCE()s first->fib6_nsiblings to 0 before
+list_del_rcu(), so an inside-loop check is a reliable detach signal.
+
+[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev
+
+Fixes: d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260527053133.180695-2-jiayuan.chen@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 0e96f7cb21a297..2b861eacee30e4 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -486,6 +486,9 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
+               const struct fib6_nh *nh = sibling->fib6_nh;
+               int nh_upper_bound;
++              if (!READ_ONCE(first->fib6_nsiblings))
++                      break;
++
+               nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);
+               if (hash > nh_upper_bound)
+                       continue;
+-- 
+2.53.0
+
diff --git a/queue-6.1/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch b/queue-6.1/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch
new file mode 100644 (file)
index 0000000..32f3310
--- /dev/null
@@ -0,0 +1,47 @@
+From bc635bfda0f2d9086fd4fcf9c9fd736a9f92a20c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 13:31:30 +0800
+Subject: ipv6: fix possible infinite loop in rt6_fill_node()
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 9f72412bcf60144f252b0d6205106abf14344abc ]
+
+Sashiko reported this issue [1]. Apply the same fix as
+commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").
+
+Writers holding tb6_lock can list_del_rcu(&rt->fib6_siblings)
+without waiting for RCU readers; rt->fib6_siblings.next then still
+points into the old ring and this softirq-side walker never reaches
+&rt->fib6_siblings, causing a CPU stall. fib6_del_route() always
+WRITE_ONCE()s rt->fib6_nsiblings to 0 before list_del_rcu(), so an
+inside-loop check is a reliable detach signal.
+
+[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev
+
+Fixes: d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260527053133.180695-1-jiayuan.chen@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 987ef0954e2ea2..0e96f7cb21a297 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -5790,6 +5790,8 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
+                               goto nla_put_failure;
+                       }
++                      if (!READ_ONCE(rt->fib6_nsiblings))
++                              break;
+               }
+               rcu_read_unlock();
+-- 
+2.53.0
+
diff --git a/queue-6.1/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch b/queue-6.1/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
new file mode 100644 (file)
index 0000000..6c0c578
--- /dev/null
@@ -0,0 +1,62 @@
+From fc08ca2f450c85073a0bdb2150bf886682099420 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 21:10:31 +0530
+Subject: ipv6: rpl: fix hdrlen overflow in ipv6_rpl_srh_decompress()
+
+From: Rahul Chandelkar <rc@rexion.ai>
+
+[ Upstream commit 9d5e7a46a9f6d8f503b41bfefef70659845f1679 ]
+
+ipv6_rpl_srh_decompress() computes:
+
+    outhdr->hdrlen = (((n + 1) * sizeof(struct in6_addr)) >> 3);
+
+hdrlen is __u8. For n >= 127 the result exceeds 255 and silently
+truncates. With n=127 (cmpri=15, cmpre=15, pad=0, hdrlen=16):
+
+    (128 * 16) >> 3 = 256, truncated to 0 as __u8
+
+The caller in ipv6_rpl_srh_rcv() then places the compressed header
+at buf + ((ohdr->hdrlen + 1) << 3). With hdrlen=0 this is buf + 8,
+but the decompressed region occupies buf[0..2055] (8-byte header
+plus 128 full addresses). The compressed header overlaps the
+decompressed data, and ipv6_rpl_srh_compress() writes into this
+overlap, corrupting the routing header of the forwarded packet.
+
+The existing guard at exthdrs.c:546 checks (n + 1) > 255, which
+prevents n+1 from overflowing unsigned char (the segments_left
+field), but does not prevent the computed hdrlen from overflowing
+__u8. n=127 passes because 128 <= 255, yet hdrlen=256 does not
+fit.
+
+Tighten the bound to (n + 1) > 127. This caps n at 126, giving
+hdrlen = (127 * 16) >> 3 = 254, which fits in __u8. The compressed
+header then lands at buf + ((254 + 1) << 3) = buf + 2040, exactly
+past the decompressed region (buf[0..2039]). No overlap. 127
+segments is well beyond any realistic RPL deployment.
+
+Fixes: 8610c7c6e3bd ("net: ipv6: add support for rpl sr exthdr")
+Signed-off-by: Rahul Chandelkar <rc@rexion.ai>
+Link: https://patch.msgid.link/20260525154031.2290876-1-rc@rexion.ai
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index 826ef36aa2bcc0..13e57e3f7d7981 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -564,7 +564,7 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
+        * unsigned char which is segments_left field. Should not be
+        * higher than that.
+        */
+-      if (r || (n + 1) > 255) {
++      if (r || (n + 1) > 127) {
+               kfree_skb(skb);
+               return -1;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.1/kernel-fork-validate-exit_signal-in-kernel_clone.patch b/queue-6.1/kernel-fork-validate-exit_signal-in-kernel_clone.patch
new file mode 100644 (file)
index 0000000..8f74d4f
--- /dev/null
@@ -0,0 +1,116 @@
+From b8ed18def3adb8737a3547e5363196f58fd7c05e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Mar 2026 20:49:56 +0530
+Subject: kernel/fork: validate exit_signal in kernel_clone()
+
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+
+[ Upstream commit 09e7827e785729f391c8d46dc71becce70d296ab ]
+
+When a child process exits, it sends exit_signal to its parent via
+do_notify_parent().  The clone() syscall constructs exit_signal as:
+
+(lower_32_bits(clone_flags) & CSIGNAL)
+
+CSIGNAL is 0xff, so values in the range 65-255 are possible.  However,
+valid_signal() only accepts signals up to _NSIG (64 on x86_64).  A
+non-zero non-valid exit_signal acts the same as exit_signal == 0: the
+parent process is not signaled when the child terminates.
+
+The syzkaller reproducer triggers this by calling clone() with flags=0x80,
+resulting in exit_signal = (0x80 & CSIGNAL) = 128, which exceeds _NSIG and
+is not a valid signal.
+
+The v1 of this patch added the check only in the clone() syscall handler,
+which is incomplete.  kernel_clone() has other callers such as
+sys_ia32_clone() which would remain unprotected.  Move the check to
+kernel_clone() to cover all callers.
+
+Since the valid_signal() check is now in kernel_clone() and covers all
+callers including clone3(), the same check in copy_clone_args_from_user()
+becomes redundant and is removed.  The higher 32bits check for clone3() is
+kept as it is clone3() specific.
+
+Note that this is a user-visible change: previously, passing an invalid
+exit_signal to clone() was silently accepted.  The man page for clone()
+does not document any defined behavior for invalid exit_signal values, so
+rejecting them with -EINVAL is the correct behavior.  It is unlikely that
+any sane application relies on passing an invalid exit_signal.
+
+[oleg@redhat.com: the comment above kernel_clone() should be updated]
+  Link: https://lore.kernel.org/abwvgU17W8wuW2-J@redhat.com
+Link: https://lore.kernel.org/20260316151956.563558-1-kartikey406@gmail.com
+Fixes: 3f2c788a1314 ("fork: prevent accidental access to clone3 features")
+Signed-off-by: Deepanshu Kartikey <Kartikey406@gmail.com>
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Reported-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bbe6b99feefc3a0842de
+Tested-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/20260307064202.353405-1-kartikey406@gmail.com/T/ [v1]
+Link: https://lore.kernel.org/all/20260316104536.558108-1-kartikey406@gmail.com/T/ [v2]
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Ben Segall <bsegall@google.com>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Juri Lelli <juri.lelli@redhat.com>
+Cc: Kees Cook <kees@kernel.org>
+Cc: Liam Howlett <liam@infradead.org>
+Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Valentin Schneider <vschneid@redhat.com>
+Cc: Vincent Guittot <vincent.guittot@linaro.org>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/fork.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/fork.c b/kernel/fork.c
+index db2a9016f636f4..9931ee7e1dfa4a 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -2717,8 +2717,6 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
+  *
+  * It copies the process, and if successful kick-starts
+  * it and waits for it to finish using the VM if required.
+- *
+- * args->exit_signal is expected to be checked for sanity by the caller.
+  */
+ pid_t kernel_clone(struct kernel_clone_args *args)
+ {
+@@ -2743,6 +2741,9 @@ pid_t kernel_clone(struct kernel_clone_args *args)
+           (args->pidfd == args->parent_tid))
+               return -EINVAL;
++      if (!valid_signal(args->exit_signal))
++              return -EINVAL;
++
+       /*
+        * Determine whether and which event to report to ptracer.  When
+        * called from kernel_thread or CLONE_UNTRACED is explicitly
+@@ -2943,11 +2944,9 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
+               return -EINVAL;
+       /*
+-       * Verify that higher 32bits of exit_signal are unset and that
+-       * it is a valid signal
++       * Verify that higher 32bits of exit_signal are unset
+        */
+-      if (unlikely((args.exit_signal & ~((u64)CSIGNAL)) ||
+-                   !valid_signal(args.exit_signal)))
++      if (unlikely(args.exit_signal & ~((u64)CSIGNAL)))
+               return -EINVAL;
+       if ((args.flags & CLONE_INTO_CGROUP) &&
+-- 
+2.53.0
+
diff --git a/queue-6.1/net-hsr-fix-potential-oob-access-in-supervision-fram.patch b/queue-6.1/net-hsr-fix-potential-oob-access-in-supervision-fram.patch
new file mode 100644 (file)
index 0000000..bae0095
--- /dev/null
@@ -0,0 +1,48 @@
+From 0b29ab076e6420d94cdf71344843273ac24c035c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 May 2026 15:03:30 +0200
+Subject: net: hsr: fix potential OOB access in supervision frame handling
+
+From: Luka Gejak <luka.gejak@linux.dev>
+
+[ Upstream commit f229426072fc865654a60978bb7fda790a051ff3 ]
+
+Ensure the entire TLV header is linearized before access by adding
+sizeof(struct hsr_sup_tlv) to the pskb_may_pull() calls. Without this,
+a truncated frame could cause an out-of-bounds access.
+
+Fixes: eafaa88b3eb7 ("net: hsr: Add support for redbox supervision frames")
+Signed-off-by: Luka Gejak <luka.gejak@linux.dev>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260523130330.61880-1-luka.gejak@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_forward.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index 3852fd99509f04..7a596c4f603e2d 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -84,7 +84,7 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb)
+       /* Get next tlv */
+       total_length += hsr_sup_tag->tlv.HSR_TLV_length;
+-      if (!pskb_may_pull(skb, total_length))
++      if (!pskb_may_pull(skb, total_length + sizeof(struct hsr_sup_tlv)))
+               return false;
+       skb_pull(skb, total_length);
+       hsr_sup_tlv = (struct hsr_sup_tlv *)skb->data;
+@@ -100,7 +100,7 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb)
+               /* make sure another tlv follows */
+               total_length += sizeof(struct hsr_sup_tlv) + hsr_sup_tlv->HSR_TLV_length;
+-              if (!pskb_may_pull(skb, total_length))
++              if (!pskb_may_pull(skb, total_length + sizeof(struct hsr_sup_tlv)))
+                       return false;
+               /* get next tlv */
+-- 
+2.53.0
+
diff --git a/queue-6.1/net-iucv-fix-locking-in-.getsockopt.patch b/queue-6.1/net-iucv-fix-locking-in-.getsockopt.patch
new file mode 100644 (file)
index 0000000..91d6e9b
--- /dev/null
@@ -0,0 +1,87 @@
+From 277a6dc2ceb871eeb57e47f85f1a96b4074d627f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 07:11:45 -0700
+Subject: net/iucv: fix locking in .getsockopt
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 3589d20a666caf30ad100c960a2de7de390fce88 ]
+
+Mirror iucv_sock_setsockopt() and wrap the whole switch in
+lock_sock()/release_sock(). The pre-existing SO_MSGLIMIT-only lock
+becomes redundant and is removed.
+
+Any AF_IUCV HIPER user can potentially crash the kernel by racing
+recvmsg() with getsockopt(SO_MSGSIZE): the SO_MSGSIZE arm dereferences
+iucv->hs_dev->mtu after iucv_sock_close() (called from the racing
+recvmsg()) has set hs_dev to NULL, producing a NULL pointer dereference
+oops.
+
+Suggested-by: Stanislav Fomichev <sdf.kernel@gmail.com>
+Fixes: 51363b8751a6 ("af_iucv: allow retrieval of maximum message size")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Tested-by: Alexandra Winter <wintera@linux.ibm.com>
+Link: https://patch.msgid.link/20260521-af_iucv_fix2-v1-1-f16b1c510aa9@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index 0f660b1d3bd51c..e9a9bb0dee065a 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -1539,7 +1539,7 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       struct sock *sk = sock->sk;
+       struct iucv_sock *iucv = iucv_sk(sk);
+       unsigned int val;
+-      int len;
++      int len, rc;
+       if (level != SOL_IUCV)
+               return -ENOPROTOOPT;
+@@ -1552,26 +1552,34 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       len = min_t(unsigned int, len, sizeof(int));
++      rc = 0;
++
++      lock_sock(sk);
+       switch (optname) {
+       case SO_IPRMDATA_MSG:
+               val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0;
+               break;
+       case SO_MSGLIMIT:
+-              lock_sock(sk);
+               val = (iucv->path != NULL) ? iucv->path->msglim /* connected */
+                                          : iucv->msglimit;    /* default */
+-              release_sock(sk);
+               break;
+       case SO_MSGSIZE:
+-              if (sk->sk_state == IUCV_OPEN)
+-                      return -EBADFD;
++              if (sk->sk_state == IUCV_OPEN) {
++                      rc = -EBADFD;
++                      break;
++              }
+               val = (iucv->hs_dev) ? iucv->hs_dev->mtu -
+                               sizeof(struct af_iucv_trans_hdr) - ETH_HLEN :
+                               0x7fffffff;
+               break;
+       default:
+-              return -ENOPROTOOPT;
++              rc = -ENOPROTOOPT;
++              break;
+       }
++      release_sock(sk);
++
++      if (rc)
++              return rc;
+       if (put_user(len, optlen))
+               return -EFAULT;
+-- 
+2.53.0
+
diff --git a/queue-6.1/net-mana-add-null-guards-in-teardown-path-to-prevent.patch b/queue-6.1/net-mana-add-null-guards-in-teardown-path-to-prevent.patch
new file mode 100644 (file)
index 0000000..19f4ace
--- /dev/null
@@ -0,0 +1,148 @@
+From 887318a634db628011b9fada12068b88c78a2c19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 01:08:24 -0700
+Subject: net: mana: Add NULL guards in teardown path to prevent panic on
+ attach failure
+
+From: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+
+[ Upstream commit 17bfe0a8c014ee1d542ad352cd6a0a505361664a ]
+
+When queue allocation fails partway through, the error cleanup frees
+and NULLs apc->tx_qp and apc->rxqs. Multiple teardown paths such as
+mana_remove(), mana_change_mtu() recovery, and internal error handling
+in mana_alloc_queues() can subsequently call into functions that
+dereference these pointers without NULL checks:
+
+- mana_chn_setxdp() dereferences apc->rxqs[0], causing a NULL pointer
+  dereference panic (CR2: 0000000000000000 at mana_chn_setxdp+0x26).
+- mana_destroy_vport() iterates apc->rxqs without a NULL check.
+- mana_fence_rqs() iterates apc->rxqs without a NULL check.
+- mana_dealloc_queues() iterates apc->tx_qp without a NULL check.
+
+Add NULL guards for apc->rxqs in mana_fence_rqs(),
+mana_destroy_vport(), and before the mana_chn_setxdp() call. Add a
+NULL guard for apc->tx_qp in mana_dealloc_queues() to skip TX queue
+draining when TX queues were never allocated or already freed.
+
+Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
+Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+Link: https://patch.msgid.link/20260525081129.1230035-2-dipayanroy@linux.microsoft.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microsoft/mana/mana_en.c | 70 +++++++++++--------
+ 1 file changed, 41 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
+index 3f46a6edcee521..0f84cc4586f02e 100644
+--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
+@@ -914,6 +914,9 @@ static void mana_fence_rqs(struct mana_port_context *apc)
+       struct mana_rxq *rxq;
+       int err;
++      if (!apc->rxqs)
++              return;
++
+       for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
+               rxq = apc->rxqs[rxq_idx];
+               err = mana_fence_rq(apc, rxq);
+@@ -1815,13 +1818,16 @@ static void mana_destroy_vport(struct mana_port_context *apc)
+       struct mana_rxq *rxq;
+       u32 rxq_idx;
+-      for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
+-              rxq = apc->rxqs[rxq_idx];
+-              if (!rxq)
+-                      continue;
++      if (apc->rxqs) {
+-              mana_destroy_rxq(apc, rxq, true);
+-              apc->rxqs[rxq_idx] = NULL;
++              for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
++                      rxq = apc->rxqs[rxq_idx];
++                      if (!rxq)
++                              continue;
++
++                      mana_destroy_rxq(apc, rxq, true);
++                      apc->rxqs[rxq_idx] = NULL;
++              }
+       }
+       mana_destroy_txq(apc);
+@@ -2010,7 +2016,8 @@ static int mana_dealloc_queues(struct net_device *ndev)
+       if (apc->port_is_up)
+               return -EINVAL;
+-      mana_chn_setxdp(apc, NULL);
++      if (apc->rxqs)
++              mana_chn_setxdp(apc, NULL);
+       if (gd->gdma_context->is_pf)
+               mana_pf_deregister_filter(apc);
+@@ -2028,33 +2035,38 @@ static int mana_dealloc_queues(struct net_device *ndev)
+        * number of queues.
+        */
+-      for (i = 0; i < apc->num_queues; i++) {
+-              txq = &apc->tx_qp[i].txq;
+-              tsleep = 1000;
+-              while (atomic_read(&txq->pending_sends) > 0 &&
+-                     time_before(jiffies, timeout)) {
+-                      usleep_range(tsleep, tsleep + 1000);
+-                      tsleep <<= 1;
+-              }
+-              if (atomic_read(&txq->pending_sends)) {
+-                      err = pcie_flr(to_pci_dev(gd->gdma_context->dev));
+-                      if (err) {
+-                              netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
+-                                         err, atomic_read(&txq->pending_sends),
+-                                         txq->gdma_txq_id);
++      if (apc->tx_qp) {
++              for (i = 0; i < apc->num_queues; i++) {
++                      txq = &apc->tx_qp[i].txq;
++                      tsleep = 1000;
++                      while (atomic_read(&txq->pending_sends) > 0 &&
++                             time_before(jiffies, timeout)) {
++                              usleep_range(tsleep, tsleep + 1000);
++                              tsleep <<= 1;
++                      }
++                      if (atomic_read(&txq->pending_sends)) {
++                              err =
++                                  pcie_flr(to_pci_dev(gd->gdma_context->dev));
++                              if (err) {
++                                      netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
++                                                 err,
++                                          atomic_read(&txq->pending_sends),
++                                          txq->gdma_txq_id);
++                              }
++                              break;
+                       }
+-                      break;
+               }
+-      }
+-      for (i = 0; i < apc->num_queues; i++) {
+-              txq = &apc->tx_qp[i].txq;
+-              while ((skb = skb_dequeue(&txq->pending_skbs))) {
+-                      mana_unmap_skb(skb, apc);
+-                      dev_kfree_skb_any(skb);
++              for (i = 0; i < apc->num_queues; i++) {
++                      txq = &apc->tx_qp[i].txq;
++                      while ((skb = skb_dequeue(&txq->pending_skbs))) {
++                              mana_unmap_skb(skb, apc);
++                              dev_kfree_skb_any(skb);
++                      }
++                      atomic_set(&txq->pending_sends, 0);
+               }
+-              atomic_set(&txq->pending_sends, 0);
+       }
++
+       /* We're 100% sure the queues can no longer be woken up, because
+        * we're sure now mana_poll_tx_cq() can't be running.
+        */
+-- 
+2.53.0
+
diff --git a/queue-6.1/net-netlink-don-t-set-nsid-on-local-notifications.patch b/queue-6.1/net-netlink-don-t-set-nsid-on-local-notifications.patch
new file mode 100644 (file)
index 0000000..19f53a3
--- /dev/null
@@ -0,0 +1,82 @@
+From 87583f214a963aadfd305bd6e219b3164ca2a4f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:36 +0200
+Subject: net: netlink: don't set nsid on local notifications
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 88b126b39f9757e9debc322d4679239e9af089c7 ]
+
+In most cases, notifications on sockets with NETLINK_LISTEN_ALL_NSID
+do not contain NSID in their ancillary data in case the event is local
+to the listener.
+
+However, when a self-referential NSID is allocated for a namespace,
+every local notification starts sending this ID to the user space.
+
+This is problematic, because the listener cannot tell if those
+notifications are local or not anymore without making extra requests
+to figure out if the provided NSID is local or not.  The listener
+can also not figure out the local NSID beforehand as it can be
+allocated at any point in time by other processes, changing the
+structure of the future notifications for everyone.
+
+The value is practically not useful, since it's the namespace's own
+ID that the application has to obtain from other sources in order to
+figure out if it's the same or not.  So, for the application it's
+just an extra busy work with no benefits.  Moreover, applications
+that do not know about this quirk may be mishandling notifications
+with NSID set as notifications from remote namespaces.  This is the
+case for ovs-vswitchd and the iproute2's 'ip monitor' that stops
+printing 'current' and starts printing the nsid number mid-session.
+
+Lack of clear documentation for this behavior is also not helping.
+
+A search though open-source projects doesn't reveal any projects
+that use NETNSA_NSID_NOT_ASSIGNED and rely on metadata to contain
+self-referential NSIDs (expected, since the value is not useful).
+Quite the opposite, as already mentioned, there are few applications
+that rely on NSID to not be present in local events.
+
+Since the value is not useful and actively harmful in some cases,
+let's not report it for local events, making the notifications more
+consistent.
+
+Also adding some blank lines for readability.
+
+Fixes: 59324cf35aba ("netlink: allow to listen "all" netns")
+Reported-by: Matteo Perin <matteo.perin@canonical.com>
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-3-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index f502a57ad5470e..f5d4eba785d03c 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1473,10 +1473,14 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++
+       NETLINK_CB(p->skb2).nsid_is_set = false;
+-      NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+-      if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+-              NETLINK_CB(p->skb2).nsid_is_set = true;
++      if (!net_eq(sock_net(sk), p->net)) {
++              NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
++              if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
++                      NETLINK_CB(p->skb2).nsid_is_set = true;
++      }
++
+       val = netlink_broadcast_deliver(sk, p->skb2);
+       if (val < 0) {
+               netlink_overrun(sk);
+-- 
+2.53.0
+
diff --git a/queue-6.1/net-netlink-fix-sending-unassigned-nsid-after-assign.patch b/queue-6.1/net-netlink-fix-sending-unassigned-nsid-after-assign.patch
new file mode 100644 (file)
index 0000000..67f7b27
--- /dev/null
@@ -0,0 +1,45 @@
+From 7b8fa930fb47141bf44e3402249e442349265a97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:35 +0200
+Subject: net: netlink: fix sending unassigned nsid after assigned one
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 70f8592ee90585272018a725054b6eb2ab7e99ca ]
+
+If the current skb is not shared, it is re-used directly for all the
+sockets subscribed to the notification.  If we have remote all-nsid
+socket receiving a message first, then the 'nsid_is_set' will be
+set to 'true'.  If the nsid is NOT_ASSIGNED for the next socket in
+the list, the 'nsid_is_set' will remain 'true' and the negative value
+is be delivered to the user space.  All subsequent nsid values will be
+delivered as well, since there is no code path that sets the flag
+back to 'false'.
+
+Fix that by always dropping the flag to 'false' first.
+
+Fixes: 7212462fa6fd ("netlink: don't send unknown nsid")
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-2-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 8c441c98ba5630..f502a57ad5470e 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1473,6 +1473,7 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++      NETLINK_CB(p->skb2).nsid_is_set = false;
+       NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+       if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+               NETLINK_CB(p->skb2).nsid_is_set = true;
+-- 
+2.53.0
+
diff --git a/queue-6.1/net-sched-revert-net-sched-restrict-conditions-for-a.patch b/queue-6.1/net-sched-revert-net-sched-restrict-conditions-for-a.patch
new file mode 100644 (file)
index 0000000..9983b8d
--- /dev/null
@@ -0,0 +1,102 @@
+From f0782e00e36a05e61adcdd37cb84129da8466d7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:49 -0400
+Subject: net/sched: Revert "net/sched: Restrict conditions for adding
+ duplicating netems to qdisc tree"
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit eda0b7f203bb166c98d1418b204135bd566ac83b ]
+
+This reverts commit ec8e0e3d7adef940cdf9475e2352c0680189d14e.
+
+The original patch rejects any tree containing two netems when
+either has duplication set, even when they sit on unrelated classes
+of the same classful parent. That broke configurations that have
+worked since netem was introduced.
+
+The re-entrancy problem the original commit was trying to solve is
+handled by later patch using tc_depth flag.
+
+Doing this revert will (re)expose the original bug with multiple
+netem duplication. When this patch is backported make sure
+and get the full series.
+
+Fixes: ec8e0e3d7ade ("net/sched: Restrict conditions for adding duplicating netems to qdisc tree")
+Reported-by: Ji-Soo Chung <jschung2@proton.me>
+Reported-by: Gerlinde <lrGerlinde@mailfence.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220774
+Reported-by: zyc zyc <zyc199902@zohomail.cn>
+Closes: https://lore.kernel.org/all/19adda5a1e2.12410b78222774.9191120410578703463@zohomail.cn/
+Reported-by: Manas Ghandat <ghandatmanas@gmail.com>
+Closes: https://lore.kernel.org/netdev/f69b2c8f-8325-4c2e-a011-6dbc089f30e4@gmail.com/
+Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-3-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_netem.c | 40 ----------------------------------------
+ 1 file changed, 40 deletions(-)
+
+diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
+index 2c47bd8dba6478..3bebe8043cfaf5 100644
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -984,41 +984,6 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
+       return 0;
+ }
+-static const struct Qdisc_class_ops netem_class_ops;
+-
+-static int check_netem_in_tree(struct Qdisc *sch, bool duplicates,
+-                             struct netlink_ext_ack *extack)
+-{
+-      struct Qdisc *root, *q;
+-      unsigned int i;
+-
+-      root = qdisc_root_sleeping(sch);
+-
+-      if (sch != root && root->ops->cl_ops == &netem_class_ops) {
+-              if (duplicates ||
+-                  ((struct netem_sched_data *)qdisc_priv(root))->duplicate)
+-                      goto err;
+-      }
+-
+-      if (!qdisc_dev(root))
+-              return 0;
+-
+-      hash_for_each(qdisc_dev(root)->qdisc_hash, i, q, hash) {
+-              if (sch != q && q->ops->cl_ops == &netem_class_ops) {
+-                      if (duplicates ||
+-                          ((struct netem_sched_data *)qdisc_priv(q))->duplicate)
+-                              goto err;
+-              }
+-      }
+-
+-      return 0;
+-
+-err:
+-      NL_SET_ERR_MSG(extack,
+-                     "netem: cannot mix duplicating netems with other netems in tree");
+-      return -EINVAL;
+-}
+-
+ /* Parse netlink message to set options */
+ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+                       struct netlink_ext_ack *extack)
+@@ -1083,11 +1048,6 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+       q->gap = qopt->gap;
+       q->counter = 0;
+       q->loss = qopt->loss;
+-
+-      ret = check_netem_in_tree(sch, qopt->duplicate, extack);
+-      if (ret)
+-              goto unlock;
+-
+       q->duplicate = qopt->duplicate;
+       /* for compatibility with earlier versions.
+-- 
+2.53.0
+
diff --git a/queue-6.1/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch b/queue-6.1/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch
new file mode 100644 (file)
index 0000000..1e868be
--- /dev/null
@@ -0,0 +1,64 @@
+From 38bf0156ae6705225351535aa395c6dd24a7f70c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 May 2026 19:43:53 +0100
+Subject: net: skbuff: fix pskb_carve leaking zcopy pages
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit ff6e798c2eac3ebd0501ad7e796f583fab928de8 ]
+
+When SKBFL_MANAGED_FRAG_REFS is set, frag pages are not refcounted but
+their lifetime is controlled by the attached ubuf_info. To make a copy
+of the skb_shared_info, we either should clear the flag and reference
+the frags, or keep the flag and have frags unreferenced.
+
+pskb_carve_inside_header() and pskb_carve_inside_nonlinear() don't
+follow the rule and thus can leak page references. Let's clear
+SKBFL_MANAGED_FRAG_REFS from the original skb to fix it. It's the
+simplest way to address it, but there are more performant ways to do
+that if it ever becomes a problem.
+
+Link: https://lore.kernel.org/all/20260523085809.26331-1-nvminh232@clc.fitus.edu.vn/
+Fixes: 753f1ca4e1e50 ("net: introduce managed frags infrastructure")
+Reported-by: Minh Nguyen <minhnguyen.080505@gmail.com>
+Reported-by: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/1e2086aa69217d7f9c8da3d38f5be7160f1b4cd1.1779993185.git.asml.silence@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 8bc4b26de5e538..41b2aaed7a14aa 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -6232,6 +6232,11 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
+       skb_copy_from_linear_data_offset(skb, off, data, new_hlen);
+       skb->len -= off;
++      /* Remove SKBFL_MANAGED_FRAG_REFS instead of trying to honour it
++       * while refcounting frags below.
++       */
++      skb_zcopy_downgrade_managed(skb);
++
+       memcpy((struct skb_shared_info *)(data + size),
+              skb_shinfo(skb),
+              offsetof(struct skb_shared_info,
+@@ -6344,6 +6349,11 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,
+               return -ENOMEM;
+       size = SKB_WITH_OVERHEAD(size);
++      /* Remove SKBFL_MANAGED_FRAG_REFS instead of trying to honour it
++       * while refcounting frags below.
++       */
++      skb_zcopy_downgrade_managed(skb);
++
+       memcpy((struct skb_shared_info *)(data + size),
+              skb_shinfo(skb), offsetof(struct skb_shared_info, frags[0]));
+       if (skb_orphan_frags(skb, gfp_mask)) {
+-- 
+2.53.0
+
diff --git a/queue-6.1/net-smc-do-not-re-initialize-smc-hashtables.patch b/queue-6.1/net-smc-do-not-re-initialize-smc-hashtables.patch
new file mode 100644 (file)
index 0000000..bee0c31
--- /dev/null
@@ -0,0 +1,59 @@
+From 2a6427b72ba9dcb901fec45dc4de27ea66c17565 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 16:56:39 +0200
+Subject: net/smc: Do not re-initialize smc hashtables
+
+From: Alexandra Winter <wintera@linux.ibm.com>
+
+[ Upstream commit 9e4389b0038781f19f97895186ed941ff8ac1678 ]
+
+INIT_HLIST_HEAD(&smc_v*_hashinfo.ht) are called after smc_nl_init(),
+proto_register() and sock_register(). This can lead to smc_v*_hashinfo.ht
+being reset even though hash entries already exist and are being used,
+possibly resulting in a corrupted list.
+
+Remove unnecessary and dangerous re-initialisation of smc_v*_hashinfo.ht in
+smc_init(); it is implicitly initialised to zero anyhow. Add
+HLIST_HEAD_INIT to the definitions for clarity.
+
+Fixes: f16a7dd5cf27 ("smc: netlink interface for SMC sockets")
+Suggested-by: Halil Pasic <pasic@linux.ibm.com>
+Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
+Acked-by: Halil Pasic <pasic@linux.ibm.com>
+Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
+Link: https://patch.msgid.link/20260521145639.10317-1-wintera@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index b0f8eca077b893..012a7da967441d 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -180,10 +180,12 @@ static bool smc_hs_congested(const struct sock *sk)
+ static struct smc_hashinfo smc_v4_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v4_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ static struct smc_hashinfo smc_v6_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v6_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ int smc_hash_sk(struct sock *sk)
+@@ -3495,8 +3497,6 @@ static int __init smc_init(void)
+               pr_err("%s: sock_register fails with %d\n", __func__, rc);
+               goto out_proto6;
+       }
+-      INIT_HLIST_HEAD(&smc_v4_hashinfo.ht);
+-      INIT_HLIST_HEAD(&smc_v6_hashinfo.ht);
+       rc = smc_ib_register_client();
+       if (rc) {
+-- 
+2.53.0
+
diff --git a/queue-6.1/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch b/queue-6.1/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
new file mode 100644 (file)
index 0000000..f8c3483
--- /dev/null
@@ -0,0 +1,107 @@
+From 3dfaa74871b35bb24db1992f864ad737da52a802 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 22:52:07 +0200
+Subject: netfilter: ebtables: fix OOB read in compat_mtw_from_user
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit f438d1786d657d57790c5d138d6db3fc9fdac392 ]
+
+Luxiao Xu says:
+
+ The function compat_mtw_from_user() converts ebtables extensions from
+ 32-bit user structures to kernel native structures. However, it lacks
+ proper validation of the user-supplied match_size/target_size.
+
+ When certain extensions are processed, the kernel-side translation
+ logic may perform memory accesses based on the extension's expected
+ size. If the user provides a size smaller than what the extension
+ requires, it results in an out-of-bounds read as reported by KASAN.
+
+ This fix introduces a check to ensure match_size is at least as large
+ as the extension's required compatsize. This covers matches, watchers,
+ and targets, while maintaining compatibility with standard targets.
+
+AFAIU this is relevant for matches that need to go though
+match->compat_from_user() call.  Those that use plain memcpy with the
+user-provided size are ok because the caller checks that size vs the
+start of the next rule entry offset (which itself is checked vs. total
+size copied from userspace).
+
+The ->compat_from_user() callbacks assume they can read compatsize bytes,
+so they need this extra check.
+
+Based on an earlier patch from Luxiao Xu.
+
+Fixes: 81e675c227ec ("netfilter: ebtables: add CONFIG_COMPAT support")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/netfilter/ebtables.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
+index f99e348c8f37fa..bc69406d103df6 100644
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1952,6 +1952,25 @@ enum compat_mwt {
+       EBT_COMPAT_TARGET,
+ };
++static bool match_size_ok(const struct xt_match *match, unsigned int match_size)
++{
++      u16 csize;
++
++      if (match->matchsize == -1) /* cannot validate ebt_among */
++              return true;
++
++      csize = match->compatsize ? : match->matchsize;
++
++      return match_size >= csize;
++}
++
++static bool tgt_size_ok(const struct xt_target *tgt, unsigned int tgt_size)
++{
++      u16 csize = tgt->compatsize ? : tgt->targetsize;
++
++      return tgt_size >= csize;
++}
++
+ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                               enum compat_mwt compat_mwt,
+                               struct ebt_entries_buf_state *state,
+@@ -1977,6 +1996,11 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+               if (IS_ERR(match))
+                       return PTR_ERR(match);
++              if (!match_size_ok(match, match_size)) {
++                      module_put(match->me);
++                      return -EINVAL;
++              }
++
+               off = ebt_compat_match_offset(match, match_size);
+               if (dst) {
+                       if (match->compat_from_user)
+@@ -1996,6 +2020,12 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                                           mwt->u.revision);
+               if (IS_ERR(wt))
+                       return PTR_ERR(wt);
++
++              if (!tgt_size_ok(wt, match_size)) {
++                      module_put(wt->me);
++                      return -EINVAL;
++              }
++
+               off = xt_compat_target_offset(wt);
+               if (dst) {
+-- 
+2.53.0
+
diff --git a/queue-6.1/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch b/queue-6.1/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
new file mode 100644 (file)
index 0000000..ba02a3a
--- /dev/null
@@ -0,0 +1,68 @@
+From ab8e73dd82db0bae81cac0f2b54f4cb37bc6849d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 12:36:14 -0700
+Subject: netfilter: synproxy: refresh tcphdr after skb_ensure_writable
+
+From: Chris Mason <clm@meta.com>
+
+[ Upstream commit 92170e6afe927ab2792a3f71902845789c8e31b1 ]
+
+synproxy_tstamp_adjust() rewrites the TCP timestamp option in place
+and then patches the TCP checksum via inet_proto_csum_replace4() on
+the caller-supplied tcphdr pointer.  Both ipv4_synproxy_hook() and
+ipv6_synproxy_hook() obtain that pointer with skb_header_pointer()
+before calling in, so it may either alias skb->head directly or
+point at the caller's on-stack _tcph buffer.
+
+Between obtaining the pointer and using it, the function calls
+skb_ensure_writable(skb, optend), which on a cloned or non-linear
+skb invokes pskb_expand_head() and frees the old skb->head.  After
+that point the cached th is stale:
+
+    caller (ipv[46]_synproxy_hook)
+      th = skb_header_pointer(skb, ..., &_tcph)
+      synproxy_tstamp_adjust(skb, protoff, th, ...)
+        skb_ensure_writable(skb, optend)
+          pskb_expand_head()        /* kfree(old skb->head) */
+        ...
+        inet_proto_csum_replace4(&th->check, ...)
+                                    /* writes into freed head, or
+                                       into the caller's stack copy
+                                       leaving the on-wire checksum
+                                       stale */
+
+The option bytes are written through skb->data and are fine; only
+the checksum update goes through th and so lands in the wrong
+place.  The result is either a write into freed slab memory or a
+packet leaving with a checksum that does not match its payload.
+
+Fix by re-deriving th from skb->data + protoff immediately after
+skb_ensure_writable() succeeds, so the subsequent checksum update
+targets the linear, writable header.
+
+Fixes: 48b1de4c110a ("netfilter: add SYNPROXY core/target")
+Assisted-by: kres (claude-opus-4-7)
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-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_synproxy_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c
+index 16915f8eef2b16..f5a52075691faa 100644
+--- a/net/netfilter/nf_synproxy_core.c
++++ b/net/netfilter/nf_synproxy_core.c
+@@ -199,6 +199,8 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff,
+       if (skb_ensure_writable(skb, optend))
+               return 0;
++      th = (struct tcphdr *)(skb->data + protoff);
++
+       while (optoff < optend) {
+               unsigned char *op = skb->data + optoff;
+-- 
+2.53.0
+
diff --git a/queue-6.1/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch b/queue-6.1/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
new file mode 100644 (file)
index 0000000..297e217
--- /dev/null
@@ -0,0 +1,48 @@
+From ac92733db8b1e88939556d09b9dc735b73ae25eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 20:10:08 +0200
+Subject: netfilter: xt_cpu: prefer raw_smp_processor_id
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit c376f07e16c02239ed44cabb97145d03f65b4d15 ]
+
+With PREEMPT_RCU we get splat:
+
+BUG: using smp_processor_id() in preemptible [..]
+caller is cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+CPU: 1 .. Comm: syz.3.1377 #0 PREEMPT(full)
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
+ check_preemption_disabled+0xd3/0xe0 lib/smp_processor_id.c:47
+ cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+ [..]
+
+Just use raw version instead.
+This is similar to 14d14a5d2957 ("netfilter: nft_meta: use raw_smp_processor_id()").
+
+Fixes: 0ca743a55991 ("netfilter: nf_tables: add compatibility layer for x_tables")
+Reported-by: syzbot+690d3e3ffa7335ac10eb@syzkaller.appspotmail.com
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_cpu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/xt_cpu.c b/net/netfilter/xt_cpu.c
+index 3bdc302a0f9137..9cb259902a586b 100644
+--- a/net/netfilter/xt_cpu.c
++++ b/net/netfilter/xt_cpu.c
+@@ -34,7 +34,7 @@ static bool cpu_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       const struct xt_cpu_info *info = par->matchinfo;
+-      return (info->cpu == smp_processor_id()) ^ info->invert;
++      return (info->cpu == raw_smp_processor_id()) ^ info->invert;
+ }
+ static struct xt_match cpu_mt_reg __read_mostly = {
+-- 
+2.53.0
+
diff --git a/queue-6.1/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch b/queue-6.1/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
new file mode 100644 (file)
index 0000000..1df779b
--- /dev/null
@@ -0,0 +1,40 @@
+From c32c38996dfd259ee827a46098b263a72fd3261c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:41 +0000
+Subject: nfc: llcp: Fix use-after-free in llcp_sock_release()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit f4268b466190dae95a7585f69b4f1f8ad097632c ]
+
+llcp_sock_release() unconditionally unlinks the socket from the local
+sockets list.  However, if the socket is still in connecting state, it
+is on the connecting list.
+
+Fix this by checking the socket state and unlinking from the correct list.
+
+Fixes: b4011239a08e ("NFC: llcp: Fix non blocking sockets connections")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-1-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_sock.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index cd0fd26196b8b6..6cdcc49a58bcd5 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -633,6 +633,8 @@ static int llcp_sock_release(struct socket *sock)
+       if (sock->type == SOCK_RAW)
+               nfc_llcp_sock_unlink(&local->raw_sockets, sk);
++      else if (sk->sk_state == LLCP_CONNECTING)
++              nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       else
+               nfc_llcp_sock_unlink(&local->sockets, sk);
+-- 
+2.53.0
+
diff --git a/queue-6.1/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch b/queue-6.1/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
new file mode 100644 (file)
index 0000000..d093f73
--- /dev/null
@@ -0,0 +1,67 @@
+From d4e4ff599f7d61e66989494fc457d98a740ca2cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:42 +0000
+Subject: nfc: llcp: Fix use-after-free race in nfc_llcp_recv_cc()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit b493ea2765cc17cb8aa7e7544a4b6dcb05b6ed77 ]
+
+A race condition exists in the NFC LLCP connection state machine where
+the connection acceptance packet (CC) can be processed concurrently with
+socket release.  This can lead to a use-after-free of the socket object.
+
+When nfc_llcp_recv_cc() moves the socket from the connecting_sockets
+list to the sockets list, it does so without holding the socket lock.
+If llcp_sock_release() is executing concurrently, it might have already
+unlinked the socket and dropped its references, which can result in
+nfc_llcp_recv_cc() linking a freed socket into the live list.
+
+Fix this by holding lock_sock() during the state transition and list
+movement in nfc_llcp_recv_cc().  After acquiring the lock, check if
+the socket is still hashed to ensure it hasn't already been unlinked
+and marked for destruction by the release path.  This aligns the locking
+pattern with recv_hdlc() and recv_disc().
+
+Fixes: a69f32af86e3 ("NFC: Socket linked list")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-2-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_core.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
+index d9562840fa180b..62b0f2d6686eb8 100644
+--- a/net/nfc/llcp_core.c
++++ b/net/nfc/llcp_core.c
+@@ -1216,6 +1216,15 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk = &llcp_sock->sk;
++      lock_sock(sk);
++
++      /* Check if socket was destroyed whilst waiting for the lock */
++      if (!sk_hashed(sk)) {
++              release_sock(sk);
++              nfc_llcp_sock_put(llcp_sock);
++              return;
++      }
++
+       /* Unlink from connecting and link to the client array */
+       nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       nfc_llcp_sock_link(&local->sockets, sk);
+@@ -1227,6 +1236,8 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk->sk_state = LLCP_CONNECTED;
+       sk->sk_state_change(sk);
++      release_sock(sk);
++
+       nfc_llcp_sock_put(llcp_sock);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.1/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch b/queue-6.1/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
new file mode 100644 (file)
index 0000000..fb8b1bf
--- /dev/null
@@ -0,0 +1,83 @@
+From f0d02dec96b3c85b336ad9ff6d259d0688281009 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 May 2026 19:55:18 +0800
+Subject: nfc: nxp-nci: i2c: use rising-edge IRQ on ACPI systems
+
+From: Carl Lee <carl.lee@amd.com>
+
+[ Upstream commit f23bf992d65a42007c517b060ca35cebdea3525a ]
+
+Some ACPI-based platforms report incorrect IRQ trigger types (e.g.
+IRQF_TRIGGER_HIGH), which can lead to interrupt storms.
+
+Use the historically working rising-edge trigger on ACPI systems to
+avoid this regression.
+
+Device Tree-based systems continue to use the firmware-provided
+trigger type.
+
+Fixes: 57be33f85e36 ("nfc: nxp-nci: remove interrupt trigger type")
+Signed-off-by: Carl Lee <carl.lee@amd.com>
+Tested-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Luca Stefani <luca.stefani.ge1@gmail.com>
+Link: https://patch.msgid.link/20260516-nfc-nxp-nci-i2c-restore-irq-trigger-fallback-v3-1-37ba4b6e9086@amd.com
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/nxp-nci/i2c.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c
+index f256c85888229a..9b9ca3ced856b4 100644
+--- a/drivers/nfc/nxp-nci/i2c.c
++++ b/drivers/nfc/nxp-nci/i2c.c
+@@ -16,6 +16,7 @@
+ #include <linux/delay.h>
+ #include <linux/i2c.h>
+ #include <linux/interrupt.h>
++#include <linux/irq.h>
+ #include <linux/module.h>
+ #include <linux/nfc.h>
+ #include <linux/gpio/consumer.h>
+@@ -268,6 +269,7 @@ static int nxp_nci_i2c_probe(struct i2c_client *client,
+ {
+       struct device *dev = &client->dev;
+       struct nxp_nci_i2c_phy *phy;
++      unsigned long irqflags;
+       int r;
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+@@ -304,9 +306,26 @@ static int nxp_nci_i2c_probe(struct i2c_client *client,
+       if (r < 0)
+               return r;
++      /*
++       * ACPI platforms may report incorrect IRQ trigger types
++       * (e.g. level-high), which can lead to interrupt storms.
++       *
++       * Use the historically stable rising-edge trigger for ACPI devices.
++       *
++       * On non-ACPI systems (e.g. Device Tree), prefer the firmware-
++       * provided trigger type, falling back to rising-edge if not set.
++       */
++      if (ACPI_COMPANION(dev)) {
++              irqflags = IRQF_TRIGGER_RISING;
++      } else {
++              irqflags = irq_get_trigger_type(client->irq);
++              if (!irqflags)
++                      irqflags = IRQF_TRIGGER_RISING;
++      }
++
+       r = request_threaded_irq(client->irq, NULL,
+                                nxp_nci_i2c_irq_thread_fn,
+-                               IRQF_ONESHOT,
++                               irqflags | IRQF_ONESHOT,
+                                NXP_NCI_I2C_DRIVER_NAME, phy);
+       if (r < 0)
+               nfc_err(&client->dev, "Unable to register IRQ handler\n");
+-- 
+2.53.0
+
diff --git a/queue-6.1/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch b/queue-6.1/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
new file mode 100644 (file)
index 0000000..90f3e9e
--- /dev/null
@@ -0,0 +1,50 @@
+From 87a75459a2341fcf236e5a31f9cddef2f14f909f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 11:24:11 +0800
+Subject: sctp: fix race between sctp_wait_for_connect and peeloff
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit f14fe6395a8b3d961a61e138ad7b36ba3626dd4e ]
+
+sctp_wait_for_connect() drops and re-acquires the socket lock while
+waiting for the association to reach ESTABLISHED state. During this
+window, another thread can peeloff the association to a new socket via
+getsockopt(SCTP_SOCKOPT_PEELOFF), changing asoc->base.sk. After
+re-acquiring the old socket lock, sctp_wait_for_connect() returns
+success without noticing the migration â€” the caller then accesses
+the association under the wrong lock in sctp_datamsg_from_user().
+
+Add the same sk != asoc->base.sk check that sctp_wait_for_sndbuf()
+already has, returning an error if the association was migrated while
+we slept.
+
+Fixes: 668c9beb9020 ("sctp: implement assign_number for sctp_stream_interleave")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260527032411.60959-1-kipreyyy@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/socket.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index b544f403f7ca8f..867a426867a7d1 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -9364,6 +9364,8 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p)
+               release_sock(sk);
+               current_timeo = schedule_timeout(current_timeo);
+               lock_sock(sk);
++              if (sk != asoc->base.sk)
++                      goto do_error;
+               *timeo_p = current_timeo;
+       }
+-- 
+2.53.0
+
index 55f8f58b1d3e086205737d7d7a77fa5dfc265298..460625468f09e9718044f627c6edb5b27073bf64 100644 (file)
@@ -3,3 +3,39 @@ net-mctp-ensure-our-nlmsg-responses-are-initialised.patch
 net-sched-sch_sfb-replace-direct-dequeue-call-with-p.patch
 drm-remove-plane-hsub-vsub-alignment-requirement-for.patch
 net-cpsw_new-fix-potential-unregister-of-netdev-that.patch
+nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
+nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
+xfrm-check-for-underflow-in-xfrm_state_mtu.patch
+nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
+tools-bootconfig-cleanup-bootconfig-footer-size-calc.patch
+tools-bootconfig-fix-buf-leaks-in-apply_xbc.patch
+kernel-fork-validate-exit_signal-in-kernel_clone.patch
+netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
+netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
+netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
+tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
+tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch
+net-netlink-fix-sending-unassigned-nsid-after-assign.patch
+net-netlink-don-t-set-nsid-on-local-notifications.patch
+net-smc-do-not-re-initialize-smc-hashtables.patch
+net-iucv-fix-locking-in-.getsockopt.patch
+ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
+asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
+net-hsr-fix-potential-oob-access-in-supervision-fram.patch
+tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
+vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
+tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
+asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
+bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
+bonding-refuse-to-enslave-can-devices.patch
+ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
+ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
+net-sched-revert-net-sched-restrict-conditions-for-a.patch
+bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
+bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
+gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
+net-mana-add-null-guards-in-teardown-path-to-prevent.patch
+sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
+ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch
+ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch
+net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch
diff --git a/queue-6.1/tools-bootconfig-cleanup-bootconfig-footer-size-calc.patch b/queue-6.1/tools-bootconfig-cleanup-bootconfig-footer-size-calc.patch
new file mode 100644 (file)
index 0000000..1cabe88
--- /dev/null
@@ -0,0 +1,101 @@
+From ac0eebf10a72887064f430ccaeb21d016f6fefb4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Jul 2025 11:24:17 +0900
+Subject: tools/bootconfig: Cleanup bootconfig footer size calculations
+
+From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+
+[ Upstream commit 26dda57695090e05c1a99c3e8f802f862d1ac474 ]
+
+There are many same pattern of 8 + BOOTCONFIG_MAGIC_LEN for calculating
+the size of bootconfig footer. Use BOOTCONFIG_FOOTER_SIZE macro to
+clean up those magic numbers.
+
+Link: https://lore.kernel.org/all/175211425693.2591046.16029516706923643510.stgit@mhiramat.tok.corp.google.com/
+
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Stable-dep-of: f42d01aadced ("tools/bootconfig: Fix buf leaks in apply_xbc")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bootconfig/main.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
+index 32cf48f2da9a1d..d302235f6b9743 100644
+--- a/tools/bootconfig/main.c
++++ b/tools/bootconfig/main.c
+@@ -16,6 +16,10 @@
+ #define pr_err(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
++/* Bootconfig footer is [size][csum][BOOTCONFIG_MAGIC]. */
++#define BOOTCONFIG_FOOTER_SIZE        \
++      (sizeof(uint32_t) * 2 + BOOTCONFIG_MAGIC_LEN)
++
+ static int xbc_show_value(struct xbc_node *node, bool semicolon)
+ {
+       const char *val, *eol;
+@@ -188,7 +192,7 @@ static int load_xbc_from_initrd(int fd, char **buf)
+       if (ret < 0)
+               return -errno;
+-      if (stat.st_size < 8 + BOOTCONFIG_MAGIC_LEN)
++      if (stat.st_size < BOOTCONFIG_FOOTER_SIZE)
+               return 0;
+       if (lseek(fd, -BOOTCONFIG_MAGIC_LEN, SEEK_END) < 0)
+@@ -201,7 +205,7 @@ static int load_xbc_from_initrd(int fd, char **buf)
+       if (memcmp(magic, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN) != 0)
+               return 0;
+-      if (lseek(fd, -(8 + BOOTCONFIG_MAGIC_LEN), SEEK_END) < 0)
++      if (lseek(fd, -BOOTCONFIG_FOOTER_SIZE, SEEK_END) < 0)
+               return pr_errno("Failed to lseek for size", -errno);
+       if (read(fd, &size, sizeof(uint32_t)) < 0)
+@@ -213,12 +217,12 @@ static int load_xbc_from_initrd(int fd, char **buf)
+       csum = le32toh(csum);
+       /* Wrong size error  */
+-      if (stat.st_size < size + 8 + BOOTCONFIG_MAGIC_LEN) {
++      if (stat.st_size < size + BOOTCONFIG_FOOTER_SIZE) {
+               pr_err("bootconfig size is too big\n");
+               return -E2BIG;
+       }
+-      if (lseek(fd, stat.st_size - (size + 8 + BOOTCONFIG_MAGIC_LEN),
++      if (lseek(fd, stat.st_size - (size + BOOTCONFIG_FOOTER_SIZE),
+                 SEEK_SET) < 0)
+               return pr_errno("Failed to lseek", -errno);
+@@ -349,7 +353,7 @@ static int delete_xbc(const char *path)
+               ret = fstat(fd, &stat);
+               if (!ret)
+                       ret = ftruncate(fd, stat.st_size
+-                                      - size - 8 - BOOTCONFIG_MAGIC_LEN);
++                                      - size - BOOTCONFIG_FOOTER_SIZE);
+               if (ret)
+                       ret = -errno;
+       } /* Ignore if there is no boot config in initrd */
+@@ -379,8 +383,7 @@ static int apply_xbc(const char *path, const char *xbc_path)
+       csum = xbc_calc_checksum(buf, size);
+       /* Backup the bootconfig data */
+-      data = calloc(size + BOOTCONFIG_ALIGN +
+-                    sizeof(uint32_t) + sizeof(uint32_t) + BOOTCONFIG_MAGIC_LEN, 1);
++      data = calloc(size + BOOTCONFIG_ALIGN + BOOTCONFIG_FOOTER_SIZE, 1);
+       if (!data)
+               return -ENOMEM;
+       memcpy(data, buf, size);
+@@ -428,7 +431,7 @@ static int apply_xbc(const char *path, const char *xbc_path)
+       }
+       /* To align up the total size to BOOTCONFIG_ALIGN, get padding size */
+-      total_size = stat.st_size + size + sizeof(uint32_t) * 2 + BOOTCONFIG_MAGIC_LEN;
++      total_size = stat.st_size + size + BOOTCONFIG_FOOTER_SIZE;
+       pad = ((total_size + BOOTCONFIG_ALIGN - 1) & (~BOOTCONFIG_ALIGN_MASK)) - total_size;
+       size += pad;
+-- 
+2.53.0
+
diff --git a/queue-6.1/tools-bootconfig-fix-buf-leaks-in-apply_xbc.patch b/queue-6.1/tools-bootconfig-fix-buf-leaks-in-apply_xbc.patch
new file mode 100644 (file)
index 0000000..1eb49df
--- /dev/null
@@ -0,0 +1,40 @@
+From 5d57c3fbd9d27d7268cda74dca1bc7cf324a97b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 11:01:26 +0800
+Subject: tools/bootconfig: Fix buf leaks in apply_xbc
+
+From: Hongtao Lee <lihongtao@kylinos.cn>
+
+[ Upstream commit f42d01aadcedd7bbf4f9a466cabe25c1781dedad ]
+
+If data calloc failed, free the buf before return.
+
+Link: https://lore.kernel.org/all/20260520030126.147782-1-lihongtao@kylinos.cn/
+
+Fixes: 950313ebf79c ("tools: bootconfig: Add bootconfig command")
+Signed-off-by: Hongtao Lee <lihongtao@kylinos.cn>
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bootconfig/main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
+index d302235f6b9743..49573044e93a58 100644
+--- a/tools/bootconfig/main.c
++++ b/tools/bootconfig/main.c
+@@ -384,8 +384,10 @@ static int apply_xbc(const char *path, const char *xbc_path)
+       /* Backup the bootconfig data */
+       data = calloc(size + BOOTCONFIG_ALIGN + BOOTCONFIG_FOOTER_SIZE, 1);
+-      if (!data)
++      if (!data) {
++              free(buf);
+               return -ENOMEM;
++      }
+       memcpy(data, buf, size);
+       /* Check the data format */
+-- 
+2.53.0
+
diff --git a/queue-6.1/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch b/queue-6.1/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch
new file mode 100644 (file)
index 0000000..b8454bd
--- /dev/null
@@ -0,0 +1,47 @@
+From bb188f576f0edabc4130f514c78a24e7688ab500 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 09:33:13 -0700
+Subject: tun: free page on build_skb failure in tun_xdp_one()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit aa8963fdce667a42fb7f0bdd2909fadcab02f9a8 ]
+
+When build_skb() fails in tun_xdp_one(), the function sets ret to
+-ENOMEM and jumps to the out label, which returns without freeing the
+page that vhost_net_build_xdp() allocated for the frame. As with the
+short-frame rejection path, tun_sendmsg() discards the per-buffer error
+and still returns total_len, so vhost_tx_batch() takes the success path
+and never frees the page. Each build_skb() failure in a batch leaks one
+page-frag chunk.
+
+Free the page before taking the error path, matching the put_page() the
+other error exits of tun_xdp_one() already perform.
+
+Fixes: 043d222f93ab ("tuntap: accept an array of XDP buffs through sendmsg()")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260521163312.1479805-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 1ad6af74de7c3f..e8f8c7d5df29ec 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2494,6 +2494,7 @@ static int tun_xdp_one(struct tun_struct *tun,
+ build:
+       skb = build_skb(xdp->data_hard_start, buflen);
+       if (!skb) {
++              put_page(virt_to_head_page(xdp->data));
+               ret = -ENOMEM;
+               goto out;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.1/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch b/queue-6.1/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
new file mode 100644 (file)
index 0000000..05d8a97
--- /dev/null
@@ -0,0 +1,54 @@
+From 5c440911e85062918a527b28e9134ebfe175ca0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 09:00:21 -0700
+Subject: tun: free page on short-frame rejection in tun_xdp_one()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f4feb1e20058e407cb00f45aff47f5b7e19a6bbf ]
+
+tun_xdp_one() returns -EINVAL on a frame shorter than ETH_HLEN without
+freeing the page that vhost_net_build_xdp() allocated for it.
+tun_sendmsg() discards that -EINVAL and still returns total_len, so
+vhost_tx_batch() takes the success path and never frees the page; each
+short frame in a batch leaks one page-frag chunk.
+
+A local process that can open /dev/net/tun and /dev/vhost-net can hit
+this path: it attaches a tun/tap device as the vhost-net backend and
+feeds TX descriptors whose length minus the virtio-net header is below
+ETH_HLEN. Each kick leaks the page-frag chunks for that batch, and a
+tight submission loop exhausts host memory and triggers an OOM panic.
+Free the page before returning -EINVAL, matching the XDP-program error
+path in the same function.
+
+Fixes: 049584807f1d ("tun: add missing verification for short frame")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260520160020.375349-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 03478ae3ff2448..1ad6af74de7c3f 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2448,8 +2448,10 @@ static int tun_xdp_one(struct tun_struct *tun,
+       bool skb_xdp = false;
+       struct page *page;
+-      if (unlikely(datasize < ETH_HLEN))
++      if (unlikely(datasize < ETH_HLEN)) {
++              put_page(virt_to_head_page(xdp->data));
+               return -EINVAL;
++      }
+       xdp_prog = rcu_dereference(tun->xdp_prog);
+       if (xdp_prog) {
+-- 
+2.53.0
+
diff --git a/queue-6.1/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch b/queue-6.1/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
new file mode 100644 (file)
index 0000000..9070de6
--- /dev/null
@@ -0,0 +1,67 @@
+From c2d1652243c2106030b888d049b0723b0595a461 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 11:55:12 +0000
+Subject: tunnels: do not assume transport header in
+ iptunnel_pmtud_check_icmp()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 509323077ef79a26ba0c60bb556e45c12c398b2d ]
+
+In some cases, iptunnel_pmtud_check_icmp() can be called while
+skb transport header is not set.
+
+This triggers an out-of-bound access, because
+(typeof(skb->transport_header))~0U is 65535.
+
+Access the icmp header based on IPv4 network header,
+after making sure icmp->type is present in skb linear part.
+
+Note that iptunnel_pmtud_check_icmpv6()) is fine.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Reported-by: Damiano Melotti <melotti@google.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260522115512.1519110-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index 5fb437f040ace7..9f6f1b435d8d72 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -262,7 +262,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct icmphdr *icmph = icmp_hdr(skb);
+       const struct iphdr *iph = ip_hdr(skb);
+       if (mtu < 576 || iph->frag_off != htons(IP_DF))
+@@ -273,9 +272,17 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+           ipv4_is_lbcast(iph->saddr)  || ipv4_is_multicast(iph->saddr))
+               return 0;
+-      if (iph->protocol == IPPROTO_ICMP && icmp_is_err(icmph->type))
+-              return 0;
++      if (iph->protocol == IPPROTO_ICMP) {
++              const struct icmphdr *icmph;
++              if (!pskb_network_may_pull(skb, iph->ihl * 4 +
++                                              offsetofend(struct icmphdr, type)))
++                      return 0;
++              iph = ip_hdr(skb);
++              icmph = (void *)iph + iph->ihl * 4;
++              if (icmp_is_err(icmph->type))
++                      return 0;
++      }
+       return iptunnel_pmtud_build_icmp(skb, mtu);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.1/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch b/queue-6.1/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
new file mode 100644 (file)
index 0000000..8330e6b
--- /dev/null
@@ -0,0 +1,87 @@
+From 631f31b7f9b3d6112d874c23a3166f4d820f43d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:13:35 +0000
+Subject: tunnels: load network headers after skb_cow() in
+ iptunnel_pmtud_build_icmp[v6]()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b4bc94353050b1fa7b702bd4c6600710dd926cff ]
+
+Sashiko found that iptunnel_pmtud_build_icmp() and
+iptunnel_pmtud_build_icmpv6() were caching ip_hdr() and ipv6_hdr()
+before an skb_cow() call which can reallocate skb->head.
+
+Fix this possible UAF by initializing the local variables
+after the skb_cow() call.
+
+Remove skb_reset_network_header() calls which were not needed.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525201335.2361845-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index 75e3d7501752df..5fb437f040ace7 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -194,7 +194,7 @@ EXPORT_SYMBOL_GPL(iptunnel_handle_offloads);
+  */
+ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct iphdr *iph = ip_hdr(skb);
++      const struct iphdr *iph;
+       struct icmphdr *icmph;
+       struct iphdr *niph;
+       struct ethhdr eh;
+@@ -208,7 +208,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, 576 - sizeof(*niph) - sizeof(*icmph));
+       if (err)
+@@ -218,7 +217,7 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       err = skb_cow(skb, sizeof(*niph) + sizeof(*icmph) + ETH_HLEN);
+       if (err)
+               return err;
+-
++      iph = ip_hdr(skb);
+       icmph = skb_push(skb, sizeof(*icmph));
+       *icmph = (struct icmphdr) {
+               .type                   = ICMP_DEST_UNREACH,
+@@ -290,7 +289,7 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+ {
+-      const struct ipv6hdr *ip6h = ipv6_hdr(skb);
++      const struct ipv6hdr *ip6h;
+       struct icmp6hdr *icmp6h;
+       struct ipv6hdr *nip6h;
+       struct ethhdr eh;
+@@ -305,7 +304,6 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, IPV6_MIN_MTU - sizeof(*nip6h) - sizeof(*icmp6h));
+       if (err)
+@@ -316,6 +314,7 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       if (err)
+               return err;
++      ip6h = ipv6_hdr(skb);
+       icmp6h = skb_push(skb, sizeof(*icmp6h));
+       *icmp6h = (struct icmp6hdr) {
+               .icmp6_type             = ICMPV6_PKT_TOOBIG,
+-- 
+2.53.0
+
diff --git a/queue-6.1/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch b/queue-6.1/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
new file mode 100644 (file)
index 0000000..07fd35b
--- /dev/null
@@ -0,0 +1,54 @@
+From a7a6e641fe6fc96f9df30d1a1d9f9746487e304d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:36:42 +0000
+Subject: vxlan: do not reuse cached ip_hdr() value after
+ skb_tunnel_check_pmtu()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 7d9ef0cb271555d8cf39fefe6c981e1493b25ecf ]
+
+skb_tunnel_check_pmtu() can change skb->head.
+
+Reusing old_iph afer skb_tunnel_check_pmtu() can cause an UAF.
+
+Use instead ip_hdr(skb) as done in drivers/net/bareudp.c
+and drivers/net/geneve.c.
+
+Found by Sashiko.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525203642.2389723-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vxlan/vxlan_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
+index 6ad59c8afdcfc1..9d7ebf8aa79f66 100644
+--- a/drivers/net/vxlan/vxlan_core.c
++++ b/drivers/net/vxlan/vxlan_core.c
+@@ -2682,7 +2682,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr),
+                                     vni, md, flags, udp_sum);
+@@ -2745,7 +2745,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip6_dst_hoplimit(ndst);
+               skb_scrub_packet(skb, xnet);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
+-- 
+2.53.0
+
diff --git a/queue-6.1/xfrm-check-for-underflow-in-xfrm_state_mtu.patch b/queue-6.1/xfrm-check-for-underflow-in-xfrm_state_mtu.patch
new file mode 100644 (file)
index 0000000..be68ad0
--- /dev/null
@@ -0,0 +1,85 @@
+From 79e34564ad0557d657a7f43b3bf7be9cf7ee3c9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 10:49:14 -0600
+Subject: xfrm: Check for underflow in xfrm_state_mtu
+
+From: David Ahern <dahern@nvidia.com>
+
+[ Upstream commit 742b04d0550b0ec89dcbc99537ec88653bd1ad90 ]
+
+Leo Lin reported OOB write issue in esp component:
+
+  xfrm_state_mtu() returns u32 but performs its arithmetic in unsigned
+  modulo-2^32 space using an attacker-influenced "header_len + authsize +
+  net_adj" subtracted from a small "mtu" argument. A nobody user can
+  install an IPv4 ESP tunnel SA with a large authentication key
+  (XFRMA_ALG_AUTH_TRUNC, e.g. hmac(sha512), 64-byte key, 64-byte trunc),
+  configure a small interface MTU (68 bytes), and set XFRMA_TFCPAD to a
+  large value. When a single UDP datagram is then sent through the
+  tunnel, xfrm_state_mtu() underflows to a near-2^32 value, and
+  esp_output() consumes it as a signed int via:
+
+        padto      = min(x->tfcpad, xfrm_state_mtu(x, mtu_cached))
+        esp.tfclen = padto - skb->len   (assigned to int)
+
+  esp.tfclen ends up negative (e.g. -207). It is sign-extended to size_t
+  when passed to memset() inside esp_output_fill_trailer(), producing a
+  ~16 EB write of zeroes at skb_tail_pointer(skb). KASAN logs it as
+  "Write of size 18446744073709551537 at addr ffff888...".
+
+Check for underflow and return 1. This causes the sendmsg attempt to
+fail with ENETUNREACH.
+
+Fixes: c5c252389374 ("[XFRM]: Optimize MTU calculation")
+Reported-by: Leo Lin <leo@depthfirst.com>
+Assisted-by: Codex:26.506.31004
+Signed-off-by: David Ahern <dahern@nvidia.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 7dd536d5f43f3a..f3661d2946e6ef 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -2577,10 +2577,14 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+       const struct xfrm_type *type = READ_ONCE(x->type);
+       struct crypto_aead *aead;
+       u32 blksize, net_adj = 0;
++      u32 overhead, payload_mtu;
+       if (x->km.state != XFRM_STATE_VALID ||
+-          !type || type->proto != IPPROTO_ESP)
++          !type || type->proto != IPPROTO_ESP) {
++              if (mtu <= x->props.header_len)
++                      return 1;
+               return mtu - x->props.header_len;
++      }
+       aead = x->data;
+       blksize = ALIGN(crypto_aead_blocksize(aead), 4);
+@@ -2600,8 +2604,17 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+               break;
+       }
+-      return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
+-               net_adj) & ~(blksize - 1)) + net_adj - 2;
++      overhead = x->props.header_len + crypto_aead_authsize(aead) + net_adj;
++      if (mtu <= overhead)
++              return 1;
++
++      payload_mtu = mtu - overhead;
++      payload_mtu &= ~(blksize - 1);
++      if (payload_mtu <= 2)
++              return 1;
++
++      return payload_mtu + net_adj - 2;
++
+ }
+ EXPORT_SYMBOL_GPL(xfrm_state_mtu);
+-- 
+2.53.0
+
diff --git a/queue-6.12/accel-ivpu-prevent-uninitialized-data-bug-in-debugfs.patch b/queue-6.12/accel-ivpu-prevent-uninitialized-data-bug-in-debugfs.patch
new file mode 100644 (file)
index 0000000..c593596
--- /dev/null
@@ -0,0 +1,40 @@
+From 4c9ad76d387005dffad998dac23b2459ec145dc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 10:14:42 +0300
+Subject: accel/ivpu: prevent uninitialized data bug in debugfs
+
+From: Dan Carpenter <error27@gmail.com>
+
+[ Upstream commit 44e151be23deb788d9f6124de93823faf6e04e99 ]
+
+The simple_write_to_buffer() will only initialize data starting from
+the *pos offset so if it's non-zero then the first part of the buffer
+uninitialized.  Really, if *pos is non-zero then this code won't work
+so just check for that at the start of the function.
+
+Fixes: 320323d2e545 ("accel/ivpu: Add debugfs interface for setting HWS priority bands")
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Reviewed-by: Karol Wachowski <karol.wachowski@linux.intel.com>
+Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
+Link: https://patch.msgid.link/ahP24m6Mii9EDL7Q@stanley.mountain
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/ivpu/ivpu_debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c
+index df89c1c0da6dd7..1da4ce6a99cd9b 100644
+--- a/drivers/accel/ivpu/ivpu_debugfs.c
++++ b/drivers/accel/ivpu/ivpu_debugfs.c
+@@ -447,7 +447,7 @@ priority_bands_fops_write(struct file *file, const char __user *user_buf, size_t
+       u32 band;
+       int ret;
+-      if (size >= sizeof(buf))
++      if (*pos != 0 || size >= sizeof(buf))
+               return -EINVAL;
+       ret = simple_write_to_buffer(buf, sizeof(buf) - 1, pos, user_buf, size);
+-- 
+2.53.0
+
diff --git a/queue-6.12/alsa-pcm-oss-fix-setup-list-uaf-on-proc-write-error.patch b/queue-6.12/alsa-pcm-oss-fix-setup-list-uaf-on-proc-write-error.patch
new file mode 100644 (file)
index 0000000..9662962
--- /dev/null
@@ -0,0 +1,84 @@
+From e2bfb6d6bb3939d07c524c14d0bbbacb36dc8c36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 22:09:40 -0300
+Subject: ALSA: pcm: oss: Fix setup list UAF on proc write error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit 4cc54bdd54b337e77115be5b55577d1c58608eae ]
+
+snd_pcm_oss_proc_write() links a newly allocated setup entry into the
+OSS setup list before duplicating the task name. If the task-name
+allocation fails, the error path frees the already linked entry and
+leaves setup_list pointing at freed memory.
+
+A later OSS device open can then walk the stale list entry in
+snd_pcm_oss_look_for_setup() and dereference freed memory.
+
+Allocate the task name and initialize the setup entry before publishing
+the entry on setup_list. Also fetch the initial proc read iterator only
+after taking setup_mutex, so all setup_list traversal follows the same
+list lifetime rules.
+
+Reported-by: syzbot+8e498074a794999eb41c@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/6a1062b7.170a0220.35b2b7.0003.GAE@google.com
+Closes: https://syzkaller.appspot.com/bug?extid=8e498074a794999eb41c
+Fixes: 060d77b9c04a ("[ALSA] Fix / clean up PCM-OSS setup hooks")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260522-alsa-pcm-oss-setup-uaf-v1-1-40bdcc4d17e8@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/oss/pcm_oss.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
+index daa7cda98ae6f6..a65a3b8d04b8cb 100644
+--- a/sound/core/oss/pcm_oss.c
++++ b/sound/core/oss/pcm_oss.c
+@@ -2966,8 +2966,10 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
+                                 struct snd_info_buffer *buffer)
+ {
+       struct snd_pcm_str *pstr = entry->private_data;
+-      struct snd_pcm_oss_setup *setup = pstr->oss.setup_list;
++      struct snd_pcm_oss_setup *setup;
++
+       guard(mutex)(&pstr->oss.setup_mutex);
++      setup = pstr->oss.setup_list;
+       while (setup) {
+               snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n",
+                           setup->task_name,
+@@ -3052,6 +3054,13 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
+                               buffer->error = -ENOMEM;
+                               return;
+                       }
++                      template.task_name = kstrdup(task_name, GFP_KERNEL);
++                      if (!template.task_name) {
++                              kfree(setup);
++                              buffer->error = -ENOMEM;
++                              return;
++                      }
++                      *setup = template;
+                       if (pstr->oss.setup_list == NULL)
+                               pstr->oss.setup_list = setup;
+                       else {
+@@ -3059,12 +3068,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
+                                    setup1->next; setup1 = setup1->next);
+                               setup1->next = setup;
+                       }
+-                      template.task_name = kstrdup(task_name, GFP_KERNEL);
+-                      if (! template.task_name) {
+-                              kfree(setup);
+-                              buffer->error = -ENOMEM;
+-                              return;
+-                      }
++                      continue;
+               }
+               *setup = template;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.12/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch b/queue-6.12/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
new file mode 100644 (file)
index 0000000..732c7cb
--- /dev/null
@@ -0,0 +1,47 @@
+From 9722d73d4801f84157614d8954bec2c2b9bdc203 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 09:24:00 -0300
+Subject: ASoC: codecs: simple-mux: Fix enum control bounds check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit f63ad68e18d774a5d15cd7e405ead63f6b322679 ]
+
+simple_mux_control_put() rejects values greater than e->items, but
+enum control values are zero based. For the two-entry mux used by this
+driver, valid values are 0 and 1, so value 2 must be rejected as well.
+
+Accepting e->items can store an invalid mux state, pass it to the GPIO
+setter, and pass it on to the DAPM mux update path where it is used as
+an index into the enum text array.
+
+Use the same >= e->items check used by the ASoC enum helpers.
+
+Fixes: 342fbb7578d1 ("ASoC: add simple-mux")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260527-asoc-simple-mux-enum-bounds-v1-1-3f805b9fc671@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/simple-mux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/simple-mux.c b/sound/soc/codecs/simple-mux.c
+index 240af0563283e5..4c94087a246e16 100644
+--- a/sound/soc/codecs/simple-mux.c
++++ b/sound/soc/codecs/simple-mux.c
+@@ -49,7 +49,7 @@ static int simple_mux_control_put(struct snd_kcontrol *kcontrol,
+       struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
+       struct simple_mux *priv = snd_soc_component_get_drvdata(c);
+-      if (ucontrol->value.enumerated.item[0] > e->items)
++      if (ucontrol->value.enumerated.item[0] >= e->items)
+               return -EINVAL;
+       if (priv->mux == ucontrol->value.enumerated.item[0])
+-- 
+2.53.0
+
diff --git a/queue-6.12/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch b/queue-6.12/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
new file mode 100644 (file)
index 0000000..a6cccea
--- /dev/null
@@ -0,0 +1,112 @@
+From 5e5c472d24ad493061f66fe89eb7267232ccc545 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 13:51:47 -0300
+Subject: ASoC: Intel: bytcht_es8316: Fix MCLK leak on init errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit afb2a3a9d8369d18122a0d7cd294eba9a98259c6 ]
+
+byt_cht_es8316_init() enables MCLK before configuring the codec sysclk
+and creating the headset jack. If either of those later steps fails, the
+function returns without disabling MCLK, leaving the clock enabled after
+card registration fails.
+
+Track whether this driver enabled MCLK and disable it on the init error
+paths. Add the matching DAI link exit callback so the same clock enable
+is also balanced when ASoC cleans up a successfully initialized link.
+
+Fixes: a03bdaa565cb ("ASoC: Intel: add machine driver for BYT/CHT + ES8316")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260519-asoc-bytcht-es8316-mclk-leak-v1-1-b4a11cdc2afd@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcht_es8316.c | 29 ++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
+index 7975dc0ceb3518..676c08247cfcb9 100644
+--- a/sound/soc/intel/boards/bytcht_es8316.c
++++ b/sound/soc/intel/boards/bytcht_es8316.c
+@@ -40,6 +40,7 @@ struct byt_cht_es8316_private {
+       struct gpio_desc *speaker_en_gpio;
+       struct device *codec_dev;
+       bool speaker_en;
++      bool mclk_enabled;
+ };
+ enum {
+@@ -170,6 +171,15 @@ static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
+       },
+ };
++static void byt_cht_es8316_disable_mclk(struct byt_cht_es8316_private *priv)
++{
++      if (!priv->mclk_enabled)
++              return;
++
++      clk_disable_unprepare(priv->mclk);
++      priv->mclk_enabled = false;
++}
++
+ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+ {
+       struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component;
+@@ -226,12 +236,14 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+       ret = clk_prepare_enable(priv->mclk);
+       if (ret)
+               dev_err(card->dev, "unable to enable MCLK\n");
++      else
++              priv->mclk_enabled = true;
+       ret = snd_soc_dai_set_sysclk(snd_soc_rtd_to_codec(runtime, 0), 0, 19200000,
+                                    SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               dev_err(card->dev, "can't set codec clock %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       ret = snd_soc_card_jack_new_pins(card, "Headset",
+@@ -240,13 +252,25 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+                                        ARRAY_SIZE(byt_cht_es8316_jack_pins));
+       if (ret) {
+               dev_err(card->dev, "jack creation failed %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+       snd_soc_component_set_jack(codec, &priv->jack, NULL);
+       return 0;
++
++err_disable_mclk:
++      byt_cht_es8316_disable_mclk(priv);
++      return ret;
++}
++
++static void byt_cht_es8316_exit(struct snd_soc_pcm_runtime *runtime)
++{
++      struct snd_soc_card *card = runtime->card;
++      struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
++
++      byt_cht_es8316_disable_mclk(priv);
+ }
+ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
+@@ -356,6 +380,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
+               .dpcm_playback = 1,
+               .dpcm_capture = 1,
+               .init = byt_cht_es8316_init,
++              .exit = byt_cht_es8316_exit,
+               SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
+       },
+ };
+-- 
+2.53.0
+
diff --git a/queue-6.12/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch b/queue-6.12/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
new file mode 100644 (file)
index 0000000..057ab3b
--- /dev/null
@@ -0,0 +1,40 @@
+From 847aa47b30c596764ef8708a2a20ce10ca5f3f42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 11:21:39 +0800
+Subject: Bluetooth: 6lowpan: check skb_clone() return value in
+ send_mcast_pkt()
+
+From: Zhao Dongdong <zhaodongdong@kylinos.cn>
+
+[ Upstream commit 3c40d381ce04f9575a5d8b542898183c3b4b38dc ]
+
+The skb_clone() function can return NULL if memory allocation fails.
+send_mcast_pkt() calls skb_clone() without checking the return value, which
+can lead to a NULL pointer dereference in send_pkt() when it dereferences
+skb->data.
+Add a NULL check after skb_clone() and skip the peer if the clone fails.
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Signed-off-by: Zhao Dongdong <zhaodongdong@kylinos.cn>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index e5186a438290ae..03f0b5d27b60d3 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -485,6 +485,8 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
+                       int ret;
+                       local_skb = skb_clone(skb, GFP_ATOMIC);
++                      if (!local_skb)
++                              continue;
+                       BT_DBG("xmit %s to %pMR type %u IP %pI6c chan %p",
+                              netdev->name,
+-- 
+2.53.0
+
diff --git a/queue-6.12/bluetooth-hci_sync-set-hci_cmd_drain_workqueue-durin.patch b/queue-6.12/bluetooth-hci_sync-set-hci_cmd_drain_workqueue-durin.patch
new file mode 100644 (file)
index 0000000..d14f5e7
--- /dev/null
@@ -0,0 +1,57 @@
+From c03e703dbdffb14ce5981c3217312da176b23f7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 10:50:58 -0300
+Subject: Bluetooth: hci_sync: Set HCI_CMD_DRAIN_WORKQUEUE during device close
+
+From: Heitor Alves de Siqueira <halves@igalia.com>
+
+[ Upstream commit 525daaea459fc215f432de1b8debbd9144bf97b0 ]
+
+Since hci_dev_close_sync() can now be called during the reset path, we
+should also set HCI_CMD_DRAIN_WORKQUEUE. This avoids queuing timeouts
+while the hdev workqueue is being drained.
+
+Fixes: 877afadad2dc ("Bluetooth: When HCI work queue is drained, only queue chained work")
+Signed-off-by: Heitor Alves de Siqueira <halves@igalia.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index fbcb3bbfef4fde..f6e133756bd9ba 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -5223,6 +5223,12 @@ int hci_dev_close_sync(struct hci_dev *hdev)
+       bt_dev_dbg(hdev, "");
++      /* Set HCI_DRAIN_WORKQUEUE flag to prevent queuing work during
++       * reset/close. See hci_cmd_work() and handle_cmd_cnt_and_timer().
++       */
++      hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
++      synchronize_rcu();
++
+       if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
+               disable_delayed_work(&hdev->power_off);
+               disable_delayed_work(&hdev->ncmd_timer);
+@@ -5246,6 +5252,7 @@ int hci_dev_close_sync(struct hci_dev *hdev)
+       if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
+               cancel_delayed_work_sync(&hdev->cmd_timer);
++              hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
+               return err;
+       }
+@@ -5345,6 +5352,7 @@ int hci_dev_close_sync(struct hci_dev *hdev)
+       /* Clear flags */
+       hdev->flags &= BIT(HCI_RAW);
+       hci_dev_clear_volatile_flags(hdev);
++      hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
+       memset(hdev->eir, 0, sizeof(hdev->eir));
+       memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
+-- 
+2.53.0
+
diff --git a/queue-6.12/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch b/queue-6.12/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
new file mode 100644 (file)
index 0000000..4093bae
--- /dev/null
@@ -0,0 +1,62 @@
+From 02ad67cbd0668dcb120eee25ed7f55b3e99520a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 18:51:52 +0800
+Subject: Bluetooth: l2cap: clear chan->ident on ECRED reconfiguration success
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit 00e1950716c6ed67d74777b2db286b0fa23b4be9 ]
+
+l2cap_ecred_reconf_rsp() returns early on success without clearing
+chan->ident. Every other L2CAP response handler (l2cap_ecred_conn_rsp,
+l2cap_le_connect_rsp, l2cap_config_rsp) clears chan->ident after a
+successful transaction to prevent the channel from matching subsequent
+responses with the recycled ident value.
+
+A remote attacker that completed a reconfiguration as the peer can
+replay a failure response with the stale ident, causing the kernel to
+match and destroy the already-established channel via
+l2cap_chan_del(chan, ECONNRESET).
+
+Clear chan->ident for all matching channels on success, and harden the
+failure path by using l2cap_chan_hold_unless_zero() consistent with
+other L2CAP handlers (l2cap_le_command_rej, __l2cap_get_chan_by_ident).
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index b24e4d8130ddb1..9de5d545966d60 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -5392,14 +5392,20 @@ static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
+       BT_DBG("result 0x%4.4x", result);
+-      if (!result)
++      if (!result) {
++              list_for_each_entry(chan, &conn->chan_l, list) {
++                      if (chan->ident == cmd->ident)
++                              chan->ident = 0;
++              }
+               return 0;
++      }
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
+               if (chan->ident != cmd->ident)
+                       continue;
+-              l2cap_chan_hold(chan);
++              if (!l2cap_chan_hold_unless_zero(chan))
++                      continue;
+               l2cap_chan_lock(chan);
+               l2cap_chan_del(chan, ECONNRESET);
+-- 
+2.53.0
+
diff --git a/queue-6.12/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch b/queue-6.12/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
new file mode 100644 (file)
index 0000000..862561e
--- /dev/null
@@ -0,0 +1,82 @@
+From c1acc8473ff9e3ae3fd224360f8981462a6a97c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 May 2026 12:09:42 -0400
+Subject: Bluetooth: L2CAP: Fix possible crash on l2cap_ecred_conn_rsp
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 41c2713b204e6cb6a94587bc6bf6935107df5479 ]
+
+If dcid is received for an already-assigned destination CID the spec
+requires that both channels to be discarded, but calling l2cap_chan_del
+may invalidate the tmp cursor created by list_for_each_entry_safe and
+in fact it is the wrong procedure as the chan->dcid may be assigned
+previously it really needs to be disconnected.
+
+Calling l2cap_chan_clone directly may still lead to l2cap_chan_del so
+instead schedule l2cap_chan_timeout with delay 0 to close the channel
+asynchronously.
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 27 ++++++++++++++++++++++-----
+ 1 file changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 9de5d545966d60..f0b0f347ebc10a 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -5194,6 +5194,7 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+       cmd_len -= sizeof(*rsp);
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
++              struct l2cap_chan *orig;
+               u16 dcid;
+               if (chan->ident != cmd->ident ||
+@@ -5215,8 +5216,10 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+               BT_DBG("dcid[%d] 0x%4.4x", i, dcid);
++              orig = __l2cap_get_chan_by_dcid(conn, dcid);
++
+               /* Check if dcid is already in use */
+-              if (dcid && __l2cap_get_chan_by_dcid(conn, dcid)) {
++              if (dcid && orig) {
+                       /* If a device receives a
+                        * L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an
+                        * already-assigned Destination CID, then both the
+@@ -5225,10 +5228,24 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+                        */
+                       l2cap_chan_del(chan, ECONNREFUSED);
+                       l2cap_chan_unlock(chan);
+-                      chan = __l2cap_get_chan_by_dcid(conn, dcid);
+-                      l2cap_chan_lock(chan);
+-                      l2cap_chan_del(chan, ECONNRESET);
+-                      l2cap_chan_unlock(chan);
++
++                      /* Check that the dcid channel mode is
++                       * L2CAP_MODE_EXT_FLOWCTL since this procedure is only
++                       * valid for that mode and shouldn't disconnect a dcid
++                       * in other modes.
++                       */
++                      if (orig->mode == L2CAP_MODE_EXT_FLOWCTL) {
++                              l2cap_chan_lock(orig);
++                              /* Disconnect the original channel as it may be
++                               * considered connected since dcid has already
++                               * been assigned; don't call l2cap_chan_close
++                               * directly since that could lead to
++                               * l2cap_chan_del and then removing the channel
++                               * from the list while we're iterating over it.
++                               */
++                              __set_chan_timer(orig, 0);
++                              l2cap_chan_unlock(orig);
++                      }
+                       continue;
+               }
+-- 
+2.53.0
+
diff --git a/queue-6.12/bonding-refuse-to-enslave-can-devices.patch b/queue-6.12/bonding-refuse-to-enslave-can-devices.patch
new file mode 100644 (file)
index 0000000..bd487bd
--- /dev/null
@@ -0,0 +1,74 @@
+From b54fbe3c1b9b0b52f9b4cee559d51a479d4e18e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 21:33:19 +0200
+Subject: bonding: refuse to enslave CAN devices
+
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+
+[ Upstream commit 8ba68464e4787b6a7ec938826e16124df20fd23d ]
+
+syzbot reported a kernel paging request crash in
+can_rx_unregister() inside net/can/af_can.c. The crash occurs
+because a virtual CAN device (vxcan) is being enslaved to a
+bonding master.
+
+During the enslavement process, the bonding driver mutates
+and modifies the network device states to fit an Ethernet-like
+aggregation model. However, CAN devices operate on a completely
+different Layer 2 architecture, relying on the CAN mid-layer
+private data structure (can_ml_priv) instead of standard
+Ethernet structures. Since bonding does not initialize or
+maintain these CAN structures, subsequent operations on the
+half-enslaved interface (such as closing associated sockets
+via isotp_release) lead to a null-pointer dereference when
+accessing the CAN receiver lists.
+
+Bonding CAN interfaces is architecturally invalid as CAN lacks
+MAC addresses, ARP capabilities, and standard Ethernet
+link-layer mechanisms. While generic loopback devices are
+blocked globally in net/core/dev.c, virtual CAN devices
+bypass this check because they do not carry the IFF_LOOPBACK
+flag, despite acting as local software-loopbacks.
+
+Fix this by explicitly blocking network devices of type
+ARPHRD_CAN from being enslaved at the very beginning of
+bond_enslave(). This prevents illegal state mutations,
+eliminates the resulting KASAN crashes, and avoids potential
+memory leaks from incomplete socket cleanups.
+
+As the CAN support has been added a long time after bonding
+the Fixes-tag points to the introduction of ARPHRD_CAN that
+would have needed a specific handling in bonding_main.c.
+
+Fixes: cd05acfe65ed ("[CAN]: Allocate protocol numbers for PF_CAN")
+Reported-by: syzbot+8ed98cbd0161632bce95@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=8ed98cbd0161632bce95
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Link: https://patch.msgid.link/20260526-bonding-candev-v1-1-ba1df400918a@hartkopp.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 1b2cd7f870353c..c6b114946d9a5a 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1927,6 +1927,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
+       int link_reporting;
+       int res = 0, i;
++      if (slave_dev->type == ARPHRD_CAN) {
++              BOND_NL_ERR(bond_dev, extack,
++                          "CAN devices cannot be enslaved");
++              return -EPERM;
++      }
++
+       if (slave_dev->flags & IFF_MASTER &&
+           !netif_is_bond_master(slave_dev)) {
+               BOND_NL_ERR(bond_dev, extack,
+-- 
+2.53.0
+
diff --git a/queue-6.12/cxl-test-update-mock-dev-array-before-calling-platfo.patch b/queue-6.12/cxl-test-update-mock-dev-array-before-calling-platfo.patch
new file mode 100644 (file)
index 0000000..e0cf811
--- /dev/null
@@ -0,0 +1,272 @@
+From acdb4ee2828f711306d28baa05e6e3605db0dc70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 20:14:57 +0800
+Subject: cxl/test: Update mock dev array before calling platform_device_add()
+
+From: Li Ming <ming.li@zohomail.com>
+
+[ Upstream commit d90f236f8b9e354848bd226f581db27755ab901d ]
+
+CXL test environment hits the following error sometimes.
+
+ cxl_mem mem9: endpoint7 failed probe
+
+All mock memdevs are platform firmware devices added by cxl_test module,
+and cxl_test module also provides a platform device driver for them to
+create a memdev device to CXL subsystem. cxl_test module uses
+cxl_rcd/mem_single/mem arrays to store different types of mock memdevs.
+CXL drivers calls registered mock functions for a mock memdev by
+checking if a given memdev is in these arrays.
+
+When cxl_test module adds these mock memdevs, it always calls
+platform_device_add() before adding them to a suitable mock memdev
+array. However, there is a small window where CXL drivers calls mock
+function for a added memdev before it added to a mock memdev array. In
+above case, cxl endpoint driver considers a added memdev was not a mock
+memdev, then calling devm_cxl_endpoint_decoders_setup() for it rather
+than mock_endpoint_decoders_setup().
+
+An appropriate solution is that adding a new mock device to a mock
+device array before calling platform_device_add() for it. It can
+guarantee the new mock device is visible to CXL subsystem.
+
+This patch introduces a new helped called cxl_mock_platform_device_add()
+to handle the issue, and uses the function for all mock devices addition.
+
+Fixes: 3a2b97b3210b ("cxl/test: Improve init-order fidelity relative to real-world systems")
+Signed-off-by: Li Ming <ming.li@zohomail.com>
+Tested-by: Alison Schofield <alison.schofield@intel.com>
+Reviewed-by: Alison Schofield <alison.schofield@intel.com>
+Link: https://patch.msgid.link/20260520121457.234404-1-ming.li@zohomail.com
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/cxl/test/cxl.c | 105 ++++++++++++++---------------------
+ 1 file changed, 43 insertions(+), 62 deletions(-)
+
+diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
+index 050725afa45d16..0d0c434426e7bf 100644
+--- a/tools/testing/cxl/test/cxl.c
++++ b/tools/testing/cxl/test/cxl.c
+@@ -1058,6 +1058,23 @@ static void mock_companion(struct acpi_device *adev, struct device *dev)
+ #define SZ_64G (SZ_32G * 2)
+ #endif
++static int cxl_mock_platform_device_add(struct platform_device *pdev,
++                                      struct platform_device **ppdev)
++{
++      int rc;
++
++      if (ppdev)
++              *ppdev = pdev;
++      rc = platform_device_add(pdev);
++      if (rc) {
++              platform_device_put(pdev);
++              if (ppdev)
++                      *ppdev = NULL;
++      }
++
++      return rc;
++}
++
+ static __init int cxl_rch_topo_init(void)
+ {
+       int rc, i;
+@@ -1072,13 +1089,10 @@ static __init int cxl_rch_topo_init(void)
+                       goto err_bridge;
+               mock_companion(adev, &pdev->dev);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_rch[i]);
++              if (rc)
+                       goto err_bridge;
+-              }
+-              cxl_rch[i] = pdev;
+               mock_pci_bus[idx].bridge = &pdev->dev;
+               rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
+                                      "firmware_node");
+@@ -1130,13 +1144,10 @@ static __init int cxl_single_topo_init(void)
+                       goto err_bridge;
+               mock_companion(adev, &pdev->dev);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_hb_single[i]);
++              if (rc)
+                       goto err_bridge;
+-              }
+-              cxl_hb_single[i] = pdev;
+               mock_pci_bus[i + NR_CXL_HOST_BRIDGES].bridge = &pdev->dev;
+               rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
+                                      "physical_node");
+@@ -1155,12 +1166,9 @@ static __init int cxl_single_topo_init(void)
+                       goto err_port;
+               pdev->dev.parent = &bridge->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_root_single[i]);
++              if (rc)
+                       goto err_port;
+-              }
+-              cxl_root_single[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_swu_single); i++) {
+@@ -1173,12 +1181,9 @@ static __init int cxl_single_topo_init(void)
+                       goto err_uport;
+               pdev->dev.parent = &root_port->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_swu_single[i]);
++              if (rc)
+                       goto err_uport;
+-              }
+-              cxl_swu_single[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_swd_single); i++) {
+@@ -1192,12 +1197,9 @@ static __init int cxl_single_topo_init(void)
+                       goto err_dport;
+               pdev->dev.parent = &uport->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_swd_single[i]);
++              if (rc)
+                       goto err_dport;
+-              }
+-              cxl_swd_single[i] = pdev;
+       }
+       return 0;
+@@ -1270,12 +1272,9 @@ static int cxl_mem_init(void)
+               pdev->dev.parent = &dport->dev;
+               set_dev_node(&pdev->dev, i % 2);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_mem[i]);
++              if (rc)
+                       goto err_mem;
+-              }
+-              cxl_mem[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_mem_single); i++) {
+@@ -1288,12 +1287,9 @@ static int cxl_mem_init(void)
+               pdev->dev.parent = &dport->dev;
+               set_dev_node(&pdev->dev, i % 2);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_mem_single[i]);
++              if (rc)
+                       goto err_single;
+-              }
+-              cxl_mem_single[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_rcd); i++) {
+@@ -1307,12 +1303,9 @@ static int cxl_mem_init(void)
+               pdev->dev.parent = &rch->dev;
+               set_dev_node(&pdev->dev, i % 2);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_rcd[i]);
++              if (rc)
+                       goto err_rcd;
+-              }
+-              cxl_rcd[i] = pdev;
+       }
+       return 0;
+@@ -1373,13 +1366,10 @@ static __init int cxl_test_init(void)
+                       goto err_bridge;
+               mock_companion(adev, &pdev->dev);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_host_bridge[i]);
++              if (rc)
+                       goto err_bridge;
+-              }
+-              cxl_host_bridge[i] = pdev;
+               mock_pci_bus[i].bridge = &pdev->dev;
+               rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
+                                      "physical_node");
+@@ -1397,12 +1387,9 @@ static __init int cxl_test_init(void)
+                       goto err_port;
+               pdev->dev.parent = &bridge->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_root_port[i]);
++              if (rc)
+                       goto err_port;
+-              }
+-              cxl_root_port[i] = pdev;
+       }
+       BUILD_BUG_ON(ARRAY_SIZE(cxl_switch_uport) != ARRAY_SIZE(cxl_root_port));
+@@ -1415,12 +1402,9 @@ static __init int cxl_test_init(void)
+                       goto err_uport;
+               pdev->dev.parent = &root_port->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_switch_uport[i]);
++              if (rc)
+                       goto err_uport;
+-              }
+-              cxl_switch_uport[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_switch_dport); i++) {
+@@ -1433,12 +1417,9 @@ static __init int cxl_test_init(void)
+                       goto err_dport;
+               pdev->dev.parent = &uport->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_switch_dport[i]);
++              if (rc)
+                       goto err_dport;
+-              }
+-              cxl_switch_dport[i] = pdev;
+       }
+       rc = cxl_single_topo_init();
+@@ -1456,9 +1437,9 @@ static __init int cxl_test_init(void)
+       mock_companion(&acpi0017_mock, &cxl_acpi->dev);
+       acpi0017_mock.dev.bus = &platform_bus_type;
+-      rc = platform_device_add(cxl_acpi);
++      rc = cxl_mock_platform_device_add(cxl_acpi, NULL);
+       if (rc)
+-              goto err_root;
++              goto err_rch;
+       rc = cxl_mem_init();
+       if (rc)
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-cmis-fix-u16-to-u8-truncation-of-msleep_pre_.patch b/queue-6.12/ethtool-cmis-fix-u16-to-u8-truncation-of-msleep_pre_.patch
new file mode 100644 (file)
index 0000000..65cd72a
--- /dev/null
@@ -0,0 +1,52 @@
+From 648671bc8093e3ce79abced8f849bce032120898 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:10 -0700
+Subject: ethtool: cmis: fix u16-to-u8 truncation of msleep_pre_rpl
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 3e8c3d464c36bb342fe377b026577c7ec27fdbb4 ]
+
+ethtool_cmis_cdb_compose_args() accepts msleep_pre_rpl as u16 but stores
+it into the u8 field ethtool_cmis_cdb_cmd_args::msleep_pre_rpl, silently
+truncating values >= 256. Seven of the nine call sites pass 1000 ms
+(it's the third argument from the end).
+
+Fixes: a39c84d79625 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-8-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
+index 3e7c293af78c4d..aa32a675b8f8d2 100644
+--- a/net/ethtool/cmis.h
++++ b/net/ethtool/cmis.h
+@@ -59,9 +59,9 @@ struct ethtool_cmis_cdb_request {
+  * struct ethtool_cmis_cdb_cmd_args - CDB commands execution arguments
+  * @req: CDB command fields as described in the CMIS standard.
+  * @max_duration: Maximum duration time for command completion in msec.
++ * @msleep_pre_rpl: Waiting time before checking reply in msec.
+  * @read_write_len_ext: Allowable additional number of byte octets to the LPL
+  *                    in a READ or a WRITE commands.
+- * @msleep_pre_rpl: Waiting time before checking reply in msec.
+  * @rpl_exp_len: Expected reply length in bytes.
+  * @flags: Validation flags for CDB commands.
+  * @err_msg: Error message to be sent to user space.
+@@ -69,8 +69,8 @@ struct ethtool_cmis_cdb_request {
+ struct ethtool_cmis_cdb_cmd_args {
+       struct ethtool_cmis_cdb_request req;
+       u16                             max_duration;
++      u16                             msleep_pre_rpl;
+       u8                              read_write_len_ext;
+-      u8                              msleep_pre_rpl;
+       u8                              rpl_exp_len;
+       u8                              flags;
+       char                            *err_msg;
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-cmis-require-exact-cdb-reply-length.patch b/queue-6.12/ethtool-cmis-require-exact-cdb-reply-length.patch
new file mode 100644 (file)
index 0000000..f96549f
--- /dev/null
@@ -0,0 +1,70 @@
+From 3a4007ec8ec1e03a9ff89f57f73ee84e04c25d89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:09 -0700
+Subject: ethtool: cmis: require exact CDB reply length
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 6c3f999a9d1338c6c89a9ff4549eafe72bc2e7b1 ]
+
+Malicious SFP module could respond with rpl_len longer than
+what cmis_cdb_process_reply() expected, leading to OOB writes.
+Malicious HW is a bit theoretical but some modules may just
+be buggy and/or the reads may occasionally get corrupted,
+so let's protect the kernel.
+
+The existing check protects from short replies. We need to
+protect from long ones, too. All callers that pass a non-zero
+rpl_exp_len cast the reply payload to a fixed-layout struct
+and read fields at fixed offsets, with no version negotiation
+or short-reply handling:
+
+  - cmis_cdb_validate_password()
+  - cmis_cdb_module_features_get()
+  - cmis_fw_update_fw_mng_features_get()
+
+so let's assume that responses longer than expected do not
+have to be handled gracefully here. Add a warning message
+to make the debug easier in case my understanding is wrong...
+
+Note that page_data->length (argument of kmalloc) comes from
+last arg to ethtool_cmis_page_init() which is rpl_exp_len.
+
+Note2 that AIs also like to point out overflows in args->req.payload
+itself (which is a fixed-size 120 B buffer, on the stack),
+but callers should be reading structs defined by the standard,
+so protecting from requests for more data than max seem like
+defensive programming.
+
+Fixes: a39c84d79625 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands")
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-7-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis_cdb.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
+index 8bf99295bfbe96..690002366d965a 100644
+--- a/net/ethtool/cmis_cdb.c
++++ b/net/ethtool/cmis_cdb.c
+@@ -508,8 +508,13 @@ static int cmis_cdb_process_reply(struct net_device *dev,
+       }
+       rpl = (struct ethtool_cmis_cdb_rpl *)page_data->data;
+-      if ((args->rpl_exp_len > rpl->hdr.rpl_len + rpl_hdr_len) ||
+-          !rpl->hdr.rpl_chk_code) {
++      if (rpl->hdr.rpl_len != args->rpl_exp_len) {
++              netdev_warn(dev, "CDB reply length mismatch, expected %u got %u\n",
++                          args->rpl_exp_len, rpl->hdr.rpl_len);
++              err = -EIO;
++              goto out;
++      }
++      if (!rpl->hdr.rpl_chk_code) {
+               err = -EIO;
+               goto out;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-cmis-validate-fw-size-against-start_cmd_payl.patch b/queue-6.12/ethtool-cmis-validate-fw-size-against-start_cmd_payl.patch
new file mode 100644 (file)
index 0000000..2626435
--- /dev/null
@@ -0,0 +1,48 @@
+From fcc4acaaba061fd1a5f467a29e8275b8fa2e553d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:12 -0700
+Subject: ethtool: cmis: validate fw->size against start_cmd_payload_size
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit d5551f4c1800dc714cec86647bdd651ae0de923e ]
+
+cmis_fw_update_start_download() copies start_cmd_payload_size bytes
+from the firmware blob into the CDB LPL vendor_data[] payload without
+validating that the FW has enough data.
+
+Since the start_cmd_payload_size can only be ~120B an image too short
+is most likely corrupted, so reject it.
+
+Fixes: c4f78134d45c ("ethtool: cmis_fw_update: add a layer for supporting firmware update using CDB")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-10-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis_fw_update.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/ethtool/cmis_fw_update.c b/net/ethtool/cmis_fw_update.c
+index 560bafd4d16864..9c6d9571cf24db 100644
+--- a/net/ethtool/cmis_fw_update.c
++++ b/net/ethtool/cmis_fw_update.c
+@@ -129,6 +129,14 @@ cmis_fw_update_start_download(struct ethtool_cmis_cdb *cdb,
+       u8 lpl_len;
+       int err;
++      if (fw_update->fw->size < vendor_data_size) {
++              ethnl_module_fw_flash_ntf_err(fw_update->dev,
++                                            &fw_update->ntf_params,
++                                            "Firmware image too small for module's start payload",
++                                            NULL);
++              return -EINVAL;
++      }
++
+       pl.image_size = cpu_to_be32(fw_update->fw->size);
+       memcpy(pl.vendor_data, fw_update->fw->data, vendor_data_size);
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-cmis-validate-start_cmd_payload_size-from-mo.patch b/queue-6.12/ethtool-cmis-validate-start_cmd_payload_size-from-mo.patch
new file mode 100644 (file)
index 0000000..5a679e0
--- /dev/null
@@ -0,0 +1,96 @@
+From d367668456b5ef08aa2d63a9210126855a598733 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:11 -0700
+Subject: ethtool: cmis: validate start_cmd_payload_size from module
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 12c2496a71f82f63617971ca9b730dffa05cf58b ]
+
+The CMIS firmware update code reads start_cmd_payload_size from
+the module's FW Management Features CDB reply and uses it directly
+as the byte count for memcpy. The destination buffer is 112 bytes
+(ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH - 8). So a malicious
+module (or corrupted response) can cause a OOB write later on in
+cmis_fw_update_start_download().
+
+Let's error out. If modules that expect longer LPL writes actually
+exist we should revisit.
+
+struct cmis_cdb_start_fw_download_pl's definition has to move,
+no change there.
+
+Fixes: c4f78134d45c ("ethtool: cmis_fw_update: add a layer for supporting firmware update using CDB")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-9-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis_fw_update.c | 36 ++++++++++++++++++++++--------------
+ 1 file changed, 22 insertions(+), 14 deletions(-)
+
+diff --git a/net/ethtool/cmis_fw_update.c b/net/ethtool/cmis_fw_update.c
+index 48aef6220f0094..560bafd4d16864 100644
+--- a/net/ethtool/cmis_fw_update.c
++++ b/net/ethtool/cmis_fw_update.c
+@@ -43,6 +43,20 @@ enum cmis_cdb_fw_write_mechanism {
+       CMIS_CDB_FW_WRITE_MECHANISM_BOTH        = 0x11,
+ };
++/* See section 9.7.2 "CMD 0101h: Start Firmware Download" in CMIS standard
++ * revision 5.2.
++ * struct cmis_cdb_start_fw_download_pl is a structured layout of the
++ * flat array, ethtool_cmis_cdb_request::payload.
++ */
++struct cmis_cdb_start_fw_download_pl {
++      __struct_group(cmis_cdb_start_fw_download_pl_h, head, /* no attrs */,
++                      __be32  image_size;
++                      __be32  resv1;
++      );
++      u8 vendor_data[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH -
++              sizeof(struct cmis_cdb_start_fw_download_pl_h)];
++};
++
+ static int
+ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
+                                  struct net_device *dev,
+@@ -85,6 +99,14 @@ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
+        */
+       cdb->read_write_len_ext = rpl->read_write_len_ext;
+       fw_mng->start_cmd_payload_size = rpl->start_cmd_payload_size;
++      if (fw_mng->start_cmd_payload_size >
++          sizeof_field(struct cmis_cdb_start_fw_download_pl, vendor_data)) {
++              ethnl_module_fw_flash_ntf_err(dev, ntf_params,
++                                            "Start cmd payload size exceeds max LPL payload",
++                                            NULL);
++              return -EINVAL;
++      }
++
+       fw_mng->write_mechanism =
+               rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_LPL ?
+               CMIS_CDB_FW_WRITE_MECHANISM_LPL :
+@@ -96,20 +118,6 @@ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
+       return 0;
+ }
+-/* See section 9.7.2 "CMD 0101h: Start Firmware Download" in CMIS standard
+- * revision 5.2.
+- * struct cmis_cdb_start_fw_download_pl is a structured layout of the
+- * flat array, ethtool_cmis_cdb_request::payload.
+- */
+-struct cmis_cdb_start_fw_download_pl {
+-      __struct_group(cmis_cdb_start_fw_download_pl_h, head, /* no attrs */,
+-                      __be32  image_size;
+-                      __be32  resv1;
+-      );
+-      u8 vendor_data[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH -
+-              sizeof(struct cmis_cdb_start_fw_download_pl_h)];
+-};
+-
+ static int
+ cmis_fw_update_start_download(struct ethtool_cmis_cdb *cdb,
+                             struct ethtool_cmis_fw_update_params *fw_update,
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-coalesce-cap-profile-updates-at-net_dim_para.patch b/queue-6.12/ethtool-coalesce-cap-profile-updates-at-net_dim_para.patch
new file mode 100644 (file)
index 0000000..415e4ff
--- /dev/null
@@ -0,0 +1,45 @@
+From 6ebe6f5cd207f3de29da77f0f70dc68965c22876 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:24 -0700
+Subject: ethtool: coalesce: cap profile updates at NET_DIM_PARAMS_NUM_PROFILES
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 7281b096b072f6c6e30420e3467d738f2e4c4b57 ]
+
+ethnl_update_profile() walks the ETHTOOL_A_PROFILE_IRQ_MODERATION
+nest list with an index 'i' and writes new_profile[i++] without
+bounding i. The destination is kmemdup()'d at NET_DIM_PARAMS_NUM_PROFILES
+entries (5), but the Netlink nest count is entirely user-controlled.
+Netlink policies do not have support for constraining the number
+of nested entries (or number of multi-attr entries).
+
+Fixes: f750dfe825b9 ("ethtool: provide customized dim profile management")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-2-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/coalesce.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/ethtool/coalesce.c b/net/ethtool/coalesce.c
+index 3e18ca1ccc5ef6..cace02d964cb21 100644
+--- a/net/ethtool/coalesce.c
++++ b/net/ethtool/coalesce.c
+@@ -463,6 +463,12 @@ static int ethnl_update_profile(struct net_device *dev,
+       nla_for_each_nested_type(nest, ETHTOOL_A_PROFILE_IRQ_MODERATION,
+                                nests, rem) {
++              if (i >= NET_DIM_PARAMS_NUM_PROFILES) {
++                      NL_SET_BAD_ATTR(extack, nest);
++                      ret = -E2BIG;
++                      goto err_out;
++              }
++
+               ret = nla_parse_nested(tb, len_irq_moder - 1, nest,
+                                      coalesce_irq_moderation_policy,
+                                      extack);
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch b/queue-6.12/ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch
new file mode 100644 (file)
index 0000000..3fba19b
--- /dev/null
@@ -0,0 +1,48 @@
+From a13b6bf690bfd0087cc339710797feaef6f6d5b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:32 -0700
+Subject: ethtool: eeprom: add missing ethnl_ops_begin() / _complete() during
+ fallback
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 2376586f85f972fefe701f095bb37dcfe7405d21 ]
+
+All ethtool driver op calls should be sandwiched between
+ethnl_ops_begin() / ethnl_ops_complete(). In Netlink eeprom code,
+if the paged access failed we fall back to old API, but we
+first call _complete() and the fallback never does its own
+ethnl_ops_begin(). Move the fallback into the _begin() / _complete()
+section.
+
+Fixes: 96d971e307cc ("ethtool: Add fallback to get_module_eeprom from netlink command")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-10-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/eeprom.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c
+index 3b8209e930fd3a..03cb418a15823b 100644
+--- a/net/ethtool/eeprom.c
++++ b/net/ethtool/eeprom.c
+@@ -140,12 +140,11 @@ static int eeprom_prepare_data(const struct ethnl_req_info *req_base,
+       return 0;
+ err_ops:
++      if (ret == -EOPNOTSUPP)
++              ret = eeprom_fallback(request, reply);
+       ethnl_ops_complete(dev);
+ err_free:
+       kfree(page_data.data);
+-
+-      if (ret == -EOPNOTSUPP)
+-              return eeprom_fallback(request, reply);
+       return ret;
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch b/queue-6.12/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
new file mode 100644 (file)
index 0000000..9dee1be
--- /dev/null
@@ -0,0 +1,62 @@
+From eace429d42bbff2aa2557fa49842b196eb23a680 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:33 -0700
+Subject: ethtool: eeprom: add more safeties to EEPROM Netlink fallback
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 67cfdd9210b99f260b3e0afeb9525e0acc7be31e ]
+
+The Netlink fallback path for reading module EEPROM
+(fallback_set_params()) validates that offset < eeprom_len,
+but does not check that offset + length stays within eeprom_len.
+The ioctl equivalent (ethtool_get_any_eeprom() in ioctl.c) has
+always enforced both bounds:
+
+  if (eeprom.offset + eeprom.len > total_len)
+      return -EINVAL;
+
+This could lead to surprises in both drivers and device FW.
+Add the missing offset + length validation to fallback_set_params(),
+mirroring the ioctl.
+
+Similarly - ethtool core in general, and ethtool_get_any_eeprom()
+in particular tries to zero-init all buffers passed to the drivers
+to avoid any extra work of zeroing things out. eeprom_fallback()
+uses a plain kmalloc(), change it to zalloc.
+
+Fixes: 96d971e307cc ("ethtool: Add fallback to get_module_eeprom from netlink command")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-11-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/eeprom.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c
+index 03cb418a15823b..80af38a6c76acf 100644
+--- a/net/ethtool/eeprom.c
++++ b/net/ethtool/eeprom.c
+@@ -43,6 +43,9 @@ static int fallback_set_params(struct eeprom_req_info *request,
+       if (offset >= modinfo->eeprom_len)
+               return -EINVAL;
++      if (length > modinfo->eeprom_len - offset)
++              return -EINVAL;
++
+       eeprom->cmd = ETHTOOL_GMODULEEEPROM;
+       eeprom->len = length;
+       eeprom->offset = offset;
+@@ -68,7 +71,7 @@ static int eeprom_fallback(struct eeprom_req_info *request,
+       if (err < 0)
+               return err;
+-      data = kmalloc(eeprom.len, GFP_KERNEL);
++      data = kzalloc(eeprom.len, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+       err = ethtool_get_module_eeprom_call(dev, &eeprom, data);
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-linkstate-fix-unbalanced-ethnl_ops_complete-.patch b/queue-6.12/ethtool-linkstate-fix-unbalanced-ethnl_ops_complete-.patch
new file mode 100644 (file)
index 0000000..a592edc
--- /dev/null
@@ -0,0 +1,43 @@
+From c9c55cdbc9d68d28c4942b316acd0c34051b286f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:26 -0700
+Subject: ethtool: linkstate: fix unbalanced ethnl_ops_complete() on PHY lookup
+ error
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 596c51ed9e125b12c4d85b4530dfd4c7847634b7 ]
+
+linkstate_prepare_data() calls ethnl_req_get_phydev() before
+ethnl_ops_begin(), but routes its error path through "goto out"
+which calls ethnl_ops_complete().
+
+Fixes: fe55b1d401c6 ("ethtool: linkstate: migrate linkstate functions to support multi-PHY setups")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-4-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/linkstate.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/net/ethtool/linkstate.c b/net/ethtool/linkstate.c
+index 05a5f72c99fab1..3dc52a39d34525 100644
+--- a/net/ethtool/linkstate.c
++++ b/net/ethtool/linkstate.c
+@@ -105,10 +105,8 @@ static int linkstate_prepare_data(const struct ethnl_req_info *req_base,
+       phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_LINKSTATE_HEADER,
+                                     info->extack);
+-      if (IS_ERR(phydev)) {
+-              ret = PTR_ERR(phydev);
+-              goto out;
+-      }
++      if (IS_ERR(phydev))
++              return PTR_ERR(phydev);
+       ret = ethnl_ops_begin(dev);
+       if (ret < 0)
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-module-avoid-leaking-a-netdev-ref-on-module-.patch b/queue-6.12/ethtool-module-avoid-leaking-a-netdev-ref-on-module-.patch
new file mode 100644 (file)
index 0000000..5b4838f
--- /dev/null
@@ -0,0 +1,50 @@
+From ecce56fee8e68bba693ca2a51c13cb0a8d90ae9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:05 -0700
+Subject: ethtool: module: avoid leaking a netdev ref on module flash errors
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit fb7f511d62692661846c47f199e0afe25c2982db ]
+
+module_flash_fw_schedule() is missing undo for setting
+the "in_progress" flag and taking the netdev reference.
+Delay taking these, the device can't disappear while
+we are holding rtnl_lock.
+
+Fixes: 32b4c8b53ee7 ("ethtool: Add ability to flash transceiver modules' firmware")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-3-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/module.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/module.c b/net/ethtool/module.c
+index 6988e07bdcd6d4..76d13ef4ba0427 100644
+--- a/net/ethtool/module.c
++++ b/net/ethtool/module.c
+@@ -318,8 +318,6 @@ module_flash_fw_schedule(struct net_device *dev, const char *file_name,
+       if (err < 0)
+               goto err_release_firmware;
+-      dev->ethtool->module_fw_flash_in_progress = true;
+-      netdev_hold(dev, &module_fw->dev_tracker, GFP_KERNEL);
+       fw_update->dev = dev;
+       fw_update->ntf_params.portid = info->snd_portid;
+       fw_update->ntf_params.seq = info->snd_seq;
+@@ -334,6 +332,9 @@ module_flash_fw_schedule(struct net_device *dev, const char *file_name,
+       if (err < 0)
+               goto err_release_firmware;
++      dev->ethtool->module_fw_flash_in_progress = true;
++      netdev_hold(dev, &module_fw->dev_tracker, GFP_KERNEL);
++
+       schedule_work(&module_fw->work);
+       return 0;
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-module-check-fw_flash_in_progress-under-rtnl.patch b/queue-6.12/ethtool-module-check-fw_flash_in_progress-under-rtnl.patch
new file mode 100644 (file)
index 0000000..be67e2d
--- /dev/null
@@ -0,0 +1,56 @@
+From 97b374a40553467f255faf43f38484155f16857f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:07 -0700
+Subject: ethtool: module: check fw_flash_in_progress under rtnl_lock
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 504eaefa44c8dec50f7499edcb36d24f3aefab2a ]
+
+ethnl_set_module_validate() inspects module_fw_flash_in_progress
+but validate is meant for _input_ validation, not state validation.
+rtnl_lock is not held, yet. Move the check into ethnl_set_module().
+
+Fixes: 32b4c8b53ee7 ("ethtool: Add ability to flash transceiver modules' firmware")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-5-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/module.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/net/ethtool/module.c b/net/ethtool/module.c
+index 76d13ef4ba0427..ab1e8a83acd0b1 100644
+--- a/net/ethtool/module.c
++++ b/net/ethtool/module.c
+@@ -119,12 +119,6 @@ ethnl_set_module_validate(struct ethnl_req_info *req_info,
+       if (!tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY])
+               return 0;
+-      if (req_info->dev->ethtool->module_fw_flash_in_progress) {
+-              NL_SET_ERR_MSG(info->extack,
+-                             "Module firmware flashing is in progress");
+-              return -EBUSY;
+-      }
+-
+       if (!ops->get_module_power_mode || !ops->set_module_power_mode) {
+               NL_SET_ERR_MSG_ATTR(info->extack,
+                                   tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY],
+@@ -147,6 +141,12 @@ ethnl_set_module(struct ethnl_req_info *req_info, struct genl_info *info)
+       ops = dev->ethtool_ops;
++      if (dev->ethtool->module_fw_flash_in_progress) {
++              NL_SET_ERR_MSG(info->extack,
++                             "Module firmware flashing is in progress");
++              return -EBUSY;
++      }
++
+       power_new.policy = nla_get_u8(tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY]);
+       ret = ops->get_module_power_mode(dev, &power, info->extack);
+       if (ret < 0)
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-module-fix-cleanup-if-socket-used-for-flashi.patch b/queue-6.12/ethtool-module-fix-cleanup-if-socket-used-for-flashi.patch
new file mode 100644 (file)
index 0000000..0b0971a
--- /dev/null
@@ -0,0 +1,105 @@
+From e1fa51ed09dcfa83fcecf69b928831a72149f740 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:08 -0700
+Subject: ethtool: module: fix cleanup if socket used for flashing multiple
+ devices
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 760d04ebad5c4304f22c0d2251c9623b87a117c8 ]
+
+When a single Netlink socket issues MODULE_FW_FLASH_ACT against multiple
+devices, ethnl_sock_priv_set() overwrites sk_priv->dev on each call,
+retaining only the last one. The socket priv is used on socket close,
+to walk the global work list and mark the uncompleted flashing work
+as "orphaned". Otherwise if another socket reuses the PID it will
+unexpectedly receive the flashing notifications.
+
+Don't record the device, record net pointer instead. The purpose of
+the dev is to scope the work to a netns, anyway. If we store netns
+the overrides are safe/a nop since all flashed devices must be in
+the same netns as the socket.
+
+Fixes: 32b4c8b53ee7 ("ethtool: Add ability to flash transceiver modules' firmware")
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-6-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/module.c  | 9 ++++-----
+ net/ethtool/netlink.c | 4 ++--
+ net/ethtool/netlink.h | 4 ++--
+ 3 files changed, 8 insertions(+), 9 deletions(-)
+
+diff --git a/net/ethtool/module.c b/net/ethtool/module.c
+index ab1e8a83acd0b1..5a08c320b4660d 100644
+--- a/net/ethtool/module.c
++++ b/net/ethtool/module.c
+@@ -282,11 +282,9 @@ void ethnl_module_fw_flash_sock_destroy(struct ethnl_sock_priv *sk_priv)
+       spin_lock(&module_fw_flash_work_list_lock);
+       list_for_each_entry(work, &module_fw_flash_work_list, list) {
+-              if (work->fw_update.dev == sk_priv->dev &&
+-                  work->fw_update.ntf_params.portid == sk_priv->portid) {
++              if (work->fw_update.ntf_params.portid == sk_priv->portid &&
++                  dev_net(work->fw_update.dev) == sk_priv->net)
+                       work->fw_update.ntf_params.closed_sock = true;
+-                      break;
+-              }
+       }
+       spin_unlock(&module_fw_flash_work_list_lock);
+ }
+@@ -323,7 +321,8 @@ module_flash_fw_schedule(struct net_device *dev, const char *file_name,
+       fw_update->ntf_params.seq = info->snd_seq;
+       fw_update->ntf_params.closed_sock = false;
+-      err = ethnl_sock_priv_set(skb, dev, fw_update->ntf_params.portid,
++      err = ethnl_sock_priv_set(skb, dev_net(dev),
++                                fw_update->ntf_params.portid,
+                                 ETHTOOL_SOCK_TYPE_MODULE_FW_FLASH);
+       if (err < 0)
+               goto err_release_firmware;
+diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
+index a52be67139d0ac..409b4109940b7c 100644
+--- a/net/ethtool/netlink.c
++++ b/net/ethtool/netlink.c
+@@ -50,7 +50,7 @@ const struct nla_policy ethnl_header_policy_phy_stats[] = {
+       [ETHTOOL_A_HEADER_PHY_INDEX]            = NLA_POLICY_MIN(NLA_U32, 1),
+ };
+-int ethnl_sock_priv_set(struct sk_buff *skb, struct net_device *dev, u32 portid,
++int ethnl_sock_priv_set(struct sk_buff *skb, struct net *net, u32 portid,
+                       enum ethnl_sock_type type)
+ {
+       struct ethnl_sock_priv *sk_priv;
+@@ -59,7 +59,7 @@ int ethnl_sock_priv_set(struct sk_buff *skb, struct net_device *dev, u32 portid,
+       if (IS_ERR(sk_priv))
+               return PTR_ERR(sk_priv);
+-      sk_priv->dev = dev;
++      sk_priv->net = net;
+       sk_priv->portid = portid;
+       sk_priv->type = type;
+diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h
+index 5e176938d6d228..11843bd10bcade 100644
+--- a/net/ethtool/netlink.h
++++ b/net/ethtool/netlink.h
+@@ -315,12 +315,12 @@ enum ethnl_sock_type {
+ };
+ struct ethnl_sock_priv {
+-      struct net_device *dev;
++      struct net *net;
+       u32 portid;
+       enum ethnl_sock_type type;
+ };
+-int ethnl_sock_priv_set(struct sk_buff *skb, struct net_device *dev, u32 portid,
++int ethnl_sock_priv_set(struct sk_buff *skb, struct net *net, u32 portid,
+                       enum ethnl_sock_type type);
+ /**
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-pse-pd-fix-missing-ethnl_ops_complete.patch b/queue-6.12/ethtool-pse-pd-fix-missing-ethnl_ops_complete.patch
new file mode 100644 (file)
index 0000000..4f3ebe8
--- /dev/null
@@ -0,0 +1,59 @@
+From d87e38cb504e75d198e622156e79c9804c30b718 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:27 -0700
+Subject: ethtool: pse-pd: fix missing ethnl_ops_complete()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit ab5bf428fb6bd361163c7247b92750d1d24ca2ed ]
+
+pse_prepare_data() is missing ethnl_ops_complete() if
+ethnl_req_get_phydev() returned an error. Move getting
+phydev up so that we don't have to worry about this
+(similar order to linkstate_prepare_data()).
+
+Note that phydev may still be NULL (this is checked in
+pse_get_pse_attributes()), the goal isn't really to avoid
+the _begin() / _complete() calls, only to simplify the error
+handling.
+
+While at it propagate the original error. Why this code
+overrides the error with -ENODEV but !phydev generates
+-EOPNOTSUPP is unclear to me...
+
+Fixes: 31748765bed3 ("net: ethtool: pse-pd: Target the command to the requested PHY")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-5-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/pse-pd.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
+index 71843de832cca7..01517c53113def 100644
+--- a/net/ethtool/pse-pd.c
++++ b/net/ethtool/pse-pd.c
+@@ -60,14 +60,14 @@ static int pse_prepare_data(const struct ethnl_req_info *req_base,
+       struct phy_device *phydev;
+       int ret;
+-      ret = ethnl_ops_begin(dev);
+-      if (ret < 0)
+-              return ret;
+-
+       phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_PSE_HEADER,
+                                     info->extack);
+       if (IS_ERR(phydev))
+-              return -ENODEV;
++              return PTR_ERR(phydev);
++
++      ret = ethnl_ops_begin(dev);
++      if (ret < 0)
++              return ret;
+       ret = pse_get_pse_attributes(phydev, info->extack, data);
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-rss-fix-hkey-leak-when-indir_size-is-0.patch b/queue-6.12/ethtool-rss-fix-hkey-leak-when-indir_size-is-0.patch
new file mode 100644 (file)
index 0000000..ec00a0c
--- /dev/null
@@ -0,0 +1,47 @@
+From cc79b6df73ae96027b1531931f0e6aa6c979ca41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:06:46 -0700
+Subject: ethtool: rss: fix hkey leak when indir_size is 0
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 78ccf1a70c6378e1f5073a8c2209b5129067b925 ]
+
+rss_get_data_alloc() allocates a single buffer that backs both the
+indirection table and the hash key, but only assigned data->indir_table
+when indir_size was nonzero. The expectation was that no driver
+implements RSS without supporting indirection table but apparently
+enic does just that (it's the only such in-tree driver).
+enic has get_rxfh_key_size but no get_rxfh_indir_size.
+data->indir_table stays as NULL, hkey gets set but rss_get_data_free()
+kfree(data->indir_table) is a nop and the allocation leaks.
+
+Always store the allocation base in data->indir_table so the free path
+is unambiguous. No caller treats indir_table as a sentinel; everything
+keys off indir_size.
+
+Fixes: 7112a04664bf ("ethtool: add netlink based get rss support")
+Link: https://patch.msgid.link/20260522230647.1705600-6-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/rss.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
+index 8aa45f3fdfdf08..3570d58c5cca6d 100644
+--- a/net/ethtool/rss.c
++++ b/net/ethtool/rss.c
+@@ -78,8 +78,7 @@ rss_prepare_get(const struct rss_req_info *request, struct net_device *dev,
+               goto out_ops;
+       }
+-      if (data->indir_size)
+-              data->indir_table = (u32 *)rss_config;
++      data->indir_table = (u32 *)rss_config;
+       if (data->hkey_size)
+               data->hkey = rss_config + indir_bytes;
+-- 
+2.53.0
+
diff --git a/queue-6.12/ethtool-strset-fix-header-attribute-index-in-ethnl_r.patch b/queue-6.12/ethtool-strset-fix-header-attribute-index-in-ethnl_r.patch
new file mode 100644 (file)
index 0000000..aa9f0b4
--- /dev/null
@@ -0,0 +1,42 @@
+From 2f5ec54271a0eada7e7c8c5e819d0923c0b17ce8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:31 -0700
+Subject: ethtool: strset: fix header attribute index in ethnl_req_get_phydev()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit a8d8bef6b45bf7cc0b1f6110c5cd8d0160a9bad7 ]
+
+strset_prepare_data() passes ETHTOOL_A_HEADER_FLAGS (3) as the header
+attribute to ethnl_req_get_phydev(). This is incorrect, in the main
+attr space 3 is ETHTOOL_A_STRSET_COUNTS_ONLY, not the request
+header attr. The correct constant is ETHTOOL_A_STRSET_HEADER (1).
+
+ethnl_req_get_phydev() only uses this value for the extack,
+so this is not a "functionally visible"(?) bug.
+
+Fixes: e96c93aa4be9 ("net: ethtool: strset: Allow querying phy stats by index")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-9-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/strset.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ethtool/strset.c b/net/ethtool/strset.c
+index b9400d18f01d58..73597f0bc923a3 100644
+--- a/net/ethtool/strset.c
++++ b/net/ethtool/strset.c
+@@ -299,7 +299,7 @@ static int strset_prepare_data(const struct ethnl_req_info *req_base,
+               return 0;
+       }
+-      phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_HEADER_FLAGS,
++      phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_STRSET_HEADER,
+                                     info->extack);
+       /* phydev can be NULL, check for errors only */
+-- 
+2.53.0
+
diff --git a/queue-6.12/gpio-mxc-fix-irq_high-handling.patch b/queue-6.12/gpio-mxc-fix-irq_high-handling.patch
new file mode 100644 (file)
index 0000000..8a413ba
--- /dev/null
@@ -0,0 +1,38 @@
+From d06b6fb2d6a16285e12b133c9a3e2efd9f1e060f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:01 +0200
+Subject: gpio: mxc: fix irq_high handling
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit dac917ed5aead741004db8d0d5151dd577802df8 ]
+
+If port->irq_high is -1 (fsl,imx21-gpio compatible) and gpio_idx is >= 16
+enable_irq_wake() is called with -1 which is wrong.
+
+Fixes: 5f6d1998adeb ("gpio: mxc: release the parent IRQ in runtime suspend")
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260526063504.25916-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-mxc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
+index 3cdc2b218a86af..a8ab78ae7fa30c 100644
+--- a/drivers/gpio/gpio-mxc.c
++++ b/drivers/gpio/gpio-mxc.c
+@@ -473,7 +473,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
+                * the handler is needed only once, but doing it for every port
+                * is more robust and easier.
+                */
+-              port->irq_high = -1;
++              port->irq_high = 0;
+               port->mx_irq_handler = mx2_gpio_irq_handler;
+       } else
+               port->mx_irq_handler = mx3_gpio_irq_handler;
+-- 
+2.53.0
+
diff --git a/queue-6.12/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch b/queue-6.12/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
new file mode 100644 (file)
index 0000000..65d6125
--- /dev/null
@@ -0,0 +1,78 @@
+From d1aae623768e071f3095ecc7b4a0b90aa914e851 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:02:45 +0200
+Subject: gpio: rockchip: convert bank->clk to devm_clk_get_enabled()
+
+From: Marco Scardovi <scardracs@disroot.org>
+
+[ Upstream commit 3e46c18d5d87f063a93ae0fe7662fbf6660459d5 ]
+
+The bank->clk was previously obtained via of_clk_get() and manually
+prepared/enabled. However, it was missing a corresponding clk_put() in
+both the error paths and the remove function, leading to a reference leak.
+
+Convert the allocation to devm_clk_get_enabled(), which also properly
+propagates failures from clk_prepare_enable() that were previously ignored.
+
+The GPIO bank device uses the same OF node as the previous of_clk_get()
+call, so devm_clk_get_enabled(dev, NULL) correctly resolves the same
+clock provider entry.
+
+Fix the reference leak and simplify the code by removing the manual
+clk_disable_unprepare() calls in the probe error paths and in the
+remove function.
+
+Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
+Assisted-by: Antigravity:gemini-3.5-flash
+Signed-off-by: Marco Scardovi <scardracs@disroot.org>
+Link: https://patch.msgid.link/20260526171050.12785-2-scardracs@disroot.org
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-rockchip.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index 4e2132c80be32a..052713bd8d07a9 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -647,11 +647,10 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+       if (!bank->irq)
+               return -EINVAL;
+-      bank->clk = of_clk_get(bank->of_node, 0);
++      bank->clk = devm_clk_get_enabled(bank->dev, NULL);
+       if (IS_ERR(bank->clk))
+               return PTR_ERR(bank->clk);
+-      clk_prepare_enable(bank->clk);
+       id = readl(bank->reg_base + gpio_regs_v2.version_id);
+       /* If not gpio v2, that is default to v1. */
+@@ -661,7 +660,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+               bank->db_clk = of_clk_get(bank->of_node, 1);
+               if (IS_ERR(bank->db_clk)) {
+                       dev_err(bank->dev, "cannot find debounce clk\n");
+-                      clk_disable_unprepare(bank->clk);
+                       return -EINVAL;
+               }
+       } else {
+@@ -735,7 +733,6 @@ static int rockchip_gpio_probe(struct platform_device *pdev)
+       ret = rockchip_gpiolib_register(bank);
+       if (ret) {
+-              clk_disable_unprepare(bank->clk);
+               mutex_unlock(&bank->deferred_lock);
+               return ret;
+       }
+@@ -776,7 +773,6 @@ static void rockchip_gpio_remove(struct platform_device *pdev)
+ {
+       struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);
+-      clk_disable_unprepare(bank->clk);
+       gpiochip_remove(&bank->gpio_chip);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.12/gpio-virtuser-fix-uninitialized-data-bug-in-gpio_vir.patch b/queue-6.12/gpio-virtuser-fix-uninitialized-data-bug-in-gpio_vir.patch
new file mode 100644 (file)
index 0000000..0c97a02
--- /dev/null
@@ -0,0 +1,49 @@
+From e8a0ef3e4d01ecf7c6b89f1ef4a52b96e3fc1fc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 10:15:16 +0300
+Subject: gpio: virtuser: Fix uninitialized data bug in
+ gpio_virtuser_direction_do_write()
+
+From: Dan Carpenter <error27@gmail.com>
+
+[ Upstream commit 8a122b5e72cc0043705f0d524bcd15f0c0b3ec15 ]
+
+If *ppos is non-zero (user-space write split over multiple calls to
+write()) then simple_write_to_buffer() won't initialize the start of the
+buffer. Really, non-zero values for *ppos aren't going to work at all.
+Check for that and return -EINVAL at the start of the function.
+
+Fixes: 91581c4b3f29 ("gpio: virtuser: new virtual testing driver for the GPIO API")
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Link: https://patch.msgid.link/ahP3BJWWy-m_qI0X@stanley.mountain
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-virtuser.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpio/gpio-virtuser.c b/drivers/gpio/gpio-virtuser.c
+index 8a313dd624c26e..ff1977b2699144 100644
+--- a/drivers/gpio/gpio-virtuser.c
++++ b/drivers/gpio/gpio-virtuser.c
+@@ -400,7 +400,7 @@ static ssize_t gpio_virtuser_direction_do_write(struct file *file,
+       char buf[32], *trimmed;
+       int ret, dir, val = 0;
+-      if (count >= sizeof(buf))
++      if (*ppos != 0 || count >= sizeof(buf))
+               return -EINVAL;
+       ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
+@@ -627,7 +627,7 @@ static ssize_t gpio_virtuser_consumer_write(struct file *file,
+       char buf[GPIO_VIRTUSER_NAME_BUF_LEN + 2];
+       int ret;
+-      if (count >= sizeof(buf))
++      if (*ppos != 0 || count >= sizeof(buf))
+               return -EINVAL;
+       ret = simple_write_to_buffer(buf, GPIO_VIRTUSER_NAME_BUF_LEN, ppos,
+-- 
+2.53.0
+
diff --git a/queue-6.12/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch b/queue-6.12/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
new file mode 100644 (file)
index 0000000..90f577c
--- /dev/null
@@ -0,0 +1,48 @@
+From b85bcdd734c195cd86e91ea415c8cb2b48d20683 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 12:21:47 +0000
+Subject: ipv4: free net->ipv4.sysctl_local_reserved_ports after
+ unregister_net_sysctl_table()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 87a1e0fe7776da7ab411be332b4be58ac8840d10 ]
+
+ipv4_sysctl_exit_net() is currently freeing net->ipv4.sysctl_local_reserved_ports
+too soon.
+
+Only after unregister_net_sysctl_table() we can be sure no threads can possibly
+use the sysctls, including /proc/sys/net/ipv4/ip_local_reserved_ports.
+
+Fixes: 122ff243f5f1 ("ipv4: make ip_local_reserved_ports per netns")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Link: https://patch.msgid.link/20260521122147.3584624-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/sysctl_net_ipv4.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 8d411cce0aedc1..35a6e7d8f52f7e 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -1630,10 +1630,10 @@ static __net_exit void ipv4_sysctl_exit_net(struct net *net)
+ {
+       const struct ctl_table *table;
+-      kfree(net->ipv4.sysctl_local_reserved_ports);
+       table = net->ipv4.ipv4_hdr->ctl_table_arg;
+       unregister_net_sysctl_table(net->ipv4.ipv4_hdr);
+       kfree(table);
++      kfree(net->ipv4.sysctl_local_reserved_ports);
+ }
+ static __net_initdata struct pernet_operations ipv4_sysctl_ops = {
+-- 
+2.53.0
+
diff --git a/queue-6.12/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch b/queue-6.12/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch
new file mode 100644 (file)
index 0000000..1987652
--- /dev/null
@@ -0,0 +1,49 @@
+From 0c667bf1831d8bd1afb0b20048bae0657bc19b0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 13:31:31 +0800
+Subject: ipv6: fix possible infinite loop in fib6_select_path()
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 9c7da87c2dc860bb17ca1ece942495d28b1ce3b9 ]
+
+Found while auditing the same pattern Sashiko reported in
+rt6_fill_node() [1]. Apply the same fix as
+commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").
+
+Writers holding tb6_lock can list_del_rcu(&first->fib6_siblings)
+without waiting for RCU readers; first->fib6_siblings.next then
+still points into the old ring and this softirq-side walker never
+reaches &first->fib6_siblings as its terminator. fib6_purge_rt()
+always WRITE_ONCE()s first->fib6_nsiblings to 0 before
+list_del_rcu(), so an inside-loop check is a reliable detach signal.
+
+[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev
+
+Fixes: d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260527053133.180695-2-jiayuan.chen@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index c73218fd82c615..9e7470e8154429 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -482,6 +482,9 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
+               const struct fib6_nh *nh = sibling->fib6_nh;
+               int nh_upper_bound;
++              if (!READ_ONCE(first->fib6_nsiblings))
++                      break;
++
+               nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);
+               if (hash > nh_upper_bound)
+                       continue;
+-- 
+2.53.0
+
diff --git a/queue-6.12/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch b/queue-6.12/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch
new file mode 100644 (file)
index 0000000..929a968
--- /dev/null
@@ -0,0 +1,47 @@
+From eadfc481d6f6a107bce2837ee1f4423d95b0730a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 13:31:30 +0800
+Subject: ipv6: fix possible infinite loop in rt6_fill_node()
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 9f72412bcf60144f252b0d6205106abf14344abc ]
+
+Sashiko reported this issue [1]. Apply the same fix as
+commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").
+
+Writers holding tb6_lock can list_del_rcu(&rt->fib6_siblings)
+without waiting for RCU readers; rt->fib6_siblings.next then still
+points into the old ring and this softirq-side walker never reaches
+&rt->fib6_siblings, causing a CPU stall. fib6_del_route() always
+WRITE_ONCE()s rt->fib6_nsiblings to 0 before list_del_rcu(), so an
+inside-loop check is a reliable detach signal.
+
+[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev
+
+Fixes: d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260527053133.180695-1-jiayuan.chen@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 31c9e3b73f2da1..c73218fd82c615 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -5812,6 +5812,8 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
+                               goto nla_put_failure;
+                       }
++                      if (!READ_ONCE(rt->fib6_nsiblings))
++                              break;
+               }
+               rcu_read_unlock();
+-- 
+2.53.0
+
diff --git a/queue-6.12/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch b/queue-6.12/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
new file mode 100644 (file)
index 0000000..e40e571
--- /dev/null
@@ -0,0 +1,62 @@
+From 5fe5a7749f8348b1f29eecadcf936692b1efc613 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 21:10:31 +0530
+Subject: ipv6: rpl: fix hdrlen overflow in ipv6_rpl_srh_decompress()
+
+From: Rahul Chandelkar <rc@rexion.ai>
+
+[ Upstream commit 9d5e7a46a9f6d8f503b41bfefef70659845f1679 ]
+
+ipv6_rpl_srh_decompress() computes:
+
+    outhdr->hdrlen = (((n + 1) * sizeof(struct in6_addr)) >> 3);
+
+hdrlen is __u8. For n >= 127 the result exceeds 255 and silently
+truncates. With n=127 (cmpri=15, cmpre=15, pad=0, hdrlen=16):
+
+    (128 * 16) >> 3 = 256, truncated to 0 as __u8
+
+The caller in ipv6_rpl_srh_rcv() then places the compressed header
+at buf + ((ohdr->hdrlen + 1) << 3). With hdrlen=0 this is buf + 8,
+but the decompressed region occupies buf[0..2055] (8-byte header
+plus 128 full addresses). The compressed header overlaps the
+decompressed data, and ipv6_rpl_srh_compress() writes into this
+overlap, corrupting the routing header of the forwarded packet.
+
+The existing guard at exthdrs.c:546 checks (n + 1) > 255, which
+prevents n+1 from overflowing unsigned char (the segments_left
+field), but does not prevent the computed hdrlen from overflowing
+__u8. n=127 passes because 128 <= 255, yet hdrlen=256 does not
+fit.
+
+Tighten the bound to (n + 1) > 127. This caps n at 126, giving
+hdrlen = (127 * 16) >> 3 = 254, which fits in __u8. The compressed
+header then lands at buf + ((254 + 1) << 3) = buf + 2040, exactly
+past the decompressed region (buf[0..2039]). No overlap. 127
+segments is well beyond any realistic RPL deployment.
+
+Fixes: 8610c7c6e3bd ("net: ipv6: add support for rpl sr exthdr")
+Signed-off-by: Rahul Chandelkar <rc@rexion.ai>
+Link: https://patch.msgid.link/20260525154031.2290876-1-rc@rexion.ai
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index 5ef6fbc66beb11..43e34fe448ffe5 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -546,7 +546,7 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
+        * unsigned char which is segments_left field. Should not be
+        * higher than that.
+        */
+-      if (r || (n + 1) > 255) {
++      if (r || (n + 1) > 127) {
+               kfree_skb(skb);
+               return -1;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.12/kernel-fork-validate-exit_signal-in-kernel_clone.patch b/queue-6.12/kernel-fork-validate-exit_signal-in-kernel_clone.patch
new file mode 100644 (file)
index 0000000..92079d7
--- /dev/null
@@ -0,0 +1,116 @@
+From a82d548757479b3ca17d9a83621823a9b630a9c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Mar 2026 20:49:56 +0530
+Subject: kernel/fork: validate exit_signal in kernel_clone()
+
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+
+[ Upstream commit 09e7827e785729f391c8d46dc71becce70d296ab ]
+
+When a child process exits, it sends exit_signal to its parent via
+do_notify_parent().  The clone() syscall constructs exit_signal as:
+
+(lower_32_bits(clone_flags) & CSIGNAL)
+
+CSIGNAL is 0xff, so values in the range 65-255 are possible.  However,
+valid_signal() only accepts signals up to _NSIG (64 on x86_64).  A
+non-zero non-valid exit_signal acts the same as exit_signal == 0: the
+parent process is not signaled when the child terminates.
+
+The syzkaller reproducer triggers this by calling clone() with flags=0x80,
+resulting in exit_signal = (0x80 & CSIGNAL) = 128, which exceeds _NSIG and
+is not a valid signal.
+
+The v1 of this patch added the check only in the clone() syscall handler,
+which is incomplete.  kernel_clone() has other callers such as
+sys_ia32_clone() which would remain unprotected.  Move the check to
+kernel_clone() to cover all callers.
+
+Since the valid_signal() check is now in kernel_clone() and covers all
+callers including clone3(), the same check in copy_clone_args_from_user()
+becomes redundant and is removed.  The higher 32bits check for clone3() is
+kept as it is clone3() specific.
+
+Note that this is a user-visible change: previously, passing an invalid
+exit_signal to clone() was silently accepted.  The man page for clone()
+does not document any defined behavior for invalid exit_signal values, so
+rejecting them with -EINVAL is the correct behavior.  It is unlikely that
+any sane application relies on passing an invalid exit_signal.
+
+[oleg@redhat.com: the comment above kernel_clone() should be updated]
+  Link: https://lore.kernel.org/abwvgU17W8wuW2-J@redhat.com
+Link: https://lore.kernel.org/20260316151956.563558-1-kartikey406@gmail.com
+Fixes: 3f2c788a1314 ("fork: prevent accidental access to clone3 features")
+Signed-off-by: Deepanshu Kartikey <Kartikey406@gmail.com>
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Reported-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bbe6b99feefc3a0842de
+Tested-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/20260307064202.353405-1-kartikey406@gmail.com/T/ [v1]
+Link: https://lore.kernel.org/all/20260316104536.558108-1-kartikey406@gmail.com/T/ [v2]
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Ben Segall <bsegall@google.com>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Juri Lelli <juri.lelli@redhat.com>
+Cc: Kees Cook <kees@kernel.org>
+Cc: Liam Howlett <liam@infradead.org>
+Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Valentin Schneider <vschneid@redhat.com>
+Cc: Vincent Guittot <vincent.guittot@linaro.org>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/fork.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/fork.c b/kernel/fork.c
+index c4955cffcb6f4e..1f306743832b3e 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -2773,8 +2773,6 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
+  *
+  * It copies the process, and if successful kick-starts
+  * it and waits for it to finish using the VM if required.
+- *
+- * args->exit_signal is expected to be checked for sanity by the caller.
+  */
+ pid_t kernel_clone(struct kernel_clone_args *args)
+ {
+@@ -2799,6 +2797,9 @@ pid_t kernel_clone(struct kernel_clone_args *args)
+           (args->pidfd == args->parent_tid))
+               return -EINVAL;
++      if (!valid_signal(args->exit_signal))
++              return -EINVAL;
++
+       /*
+        * Determine whether and which event to report to ptracer.  When
+        * called from kernel_thread or CLONE_UNTRACED is explicitly
+@@ -2999,11 +3000,9 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
+               return -EINVAL;
+       /*
+-       * Verify that higher 32bits of exit_signal are unset and that
+-       * it is a valid signal
++       * Verify that higher 32bits of exit_signal are unset
+        */
+-      if (unlikely((args.exit_signal & ~((u64)CSIGNAL)) ||
+-                   !valid_signal(args.exit_signal)))
++      if (unlikely(args.exit_signal & ~((u64)CSIGNAL)))
+               return -EINVAL;
+       if ((args.flags & CLONE_INTO_CGROUP) &&
+-- 
+2.53.0
+
diff --git a/queue-6.12/kunit-fix-use-after-free-in-debugfs-when-using-kunit.patch b/queue-6.12/kunit-fix-use-after-free-in-debugfs-when-using-kunit.patch
new file mode 100644 (file)
index 0000000..1bfd76f
--- /dev/null
@@ -0,0 +1,110 @@
+From da3f684ae417a67b4727c5f4f7fd96d3860085bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 10:48:54 +0200
+Subject: kunit: fix use-after-free in debugfs when using kunit.filter
+
+From: Florian Schmaus <florian.schmaus@codasip.com>
+
+[ Upstream commit fb6988b83b4cafe8db63999c1ddff1b7c66d2ff5 ]
+
+When the kernel is booted with a kunit filter (e.g.,
+kunit.filter="speed!=slow"), the kunit executor dynamically allocates
+copies of the filtered test suites using kmalloc/kmemdup.
+
+During the initial boot execution, kunit_debugfs_create_suite() creates
+debugfs files (such as /sys/kernel/debug/kunit/<suite>/run) and
+permanently stores a pointer to the dynamically allocated suite in the
+inode's i_private field.
+
+Previously, the executor freed this dynamically allocated suite_set
+immediately after executing the boot-time tests. Because the debugfs
+nodes were not destroyed, any subsequent interaction with the debugfs
+`run` file from userspace triggered a use-after-free (UAF). On systems
+with architectural capabilities, like CHERI RISC-V, this resulted in
+an immediate fatal hardware exception due to the invalidation of the
+capability tags on the reclaimed memory. On other architectures, it
+resulted in silent memory corruption.
+
+Fix this UAF by properly coupling the lifetime of the filtered suite
+memory allocation to the lifetime of the kunit subsystem and its
+associated VFS nodes. Ownership of the boot-time suite_set is now
+transferred to a global tracker ('kunit_boot_suites'), and the memory
+is cleanly released in kunit_exit() during module teardown.
+
+Link: https://lore.kernel.org/r/20260507084854.233984-1-florian.schmaus@codasip.com
+Fixes: e2219db280e3 ("kunit: add debugfs /sys/kernel/debug/kunit/<suite>/results display")
+Signed-off-by: Florian Schmaus <florian.schmaus@codasip.com>
+Reviewed-by: Martin Kaiser <martin@kaiser.cx>
+Reviewed-by: David Gow <david@davidgow.net>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/kunit/test.h |  1 +
+ lib/kunit/executor.c | 19 ++++++++++++++++---
+ lib/kunit/test.c     |  1 +
+ 3 files changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/include/kunit/test.h b/include/kunit/test.h
+index 34b71e42fb107c..6132faa314fcb8 100644
+--- a/include/kunit/test.h
++++ b/include/kunit/test.h
+@@ -547,6 +547,7 @@ unsigned long kunit_vm_mmap(struct kunit *test, struct file *file,
+                           unsigned long offset);
+ void kunit_cleanup(struct kunit *test);
++void kunit_free_boot_suites(void);
+ void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt, ...);
+diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c
+index 34b7b6833df3d5..7cd1c87eb2edfb 100644
+--- a/lib/kunit/executor.c
++++ b/lib/kunit/executor.c
+@@ -15,6 +15,16 @@ extern struct kunit_suite * const __kunit_suites_end[];
+ extern struct kunit_suite * const __kunit_init_suites_start[];
+ extern struct kunit_suite * const __kunit_init_suites_end[];
++static struct kunit_suite_set kunit_boot_suites;
++
++void kunit_free_boot_suites(void)
++{
++      if (kunit_boot_suites.start) {
++              kunit_free_suite_set(kunit_boot_suites);
++              kunit_boot_suites = (struct kunit_suite_set){ NULL, NULL };
++      }
++}
++
+ static char *action_param;
+ module_param_named(action, action_param, charp, 0400);
+@@ -392,9 +402,12 @@ int kunit_run_all_tests(void)
+               pr_err("kunit executor: unknown action '%s'\n", action_param);
+ free_out:
+-      if (filter_glob_param || filter_param)
+-              kunit_free_suite_set(suite_set);
+-      else if (init_num_suites > 0)
++      if (filter_glob_param || filter_param) {
++              if (err)
++                      kunit_free_suite_set(suite_set);
++              else
++                      kunit_boot_suites = suite_set;
++      } else if (init_num_suites > 0)
+               /* Don't use kunit_free_suite_set because suites aren't individually allocated */
+               kfree(suite_set.start);
+diff --git a/lib/kunit/test.c b/lib/kunit/test.c
+index 089c832e3cdbd5..b808826e6de2cf 100644
+--- a/lib/kunit/test.c
++++ b/lib/kunit/test.c
+@@ -954,6 +954,7 @@ static void __exit kunit_exit(void)
+       kunit_bus_shutdown();
+       kunit_debugfs_cleanup();
++      kunit_free_boot_suites();
+ }
+ module_exit(kunit_exit);
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-avoid-checksumming-unreadable-skb-tail-on-trim.patch b/queue-6.12/net-avoid-checksumming-unreadable-skb-tail-on-trim.patch
new file mode 100644 (file)
index 0000000..88de68c
--- /dev/null
@@ -0,0 +1,102 @@
+From 4f491a1ffae73fe0d638ea5ee51e151c69b23ab5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 14:06:40 +0200
+Subject: net: Avoid checksumming unreadable skb tail on trim
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Björn Töpel <bjorn@kernel.org>
+
+[ Upstream commit 2e357f002c61fd76fd8f12468744a06a5ec48eaa ]
+
+pskb_trim_rcsum_slow() keeps CHECKSUM_COMPLETE valid by subtracting
+the checksum of the bytes removed from the skb tail. That assumes the
+removed bytes can be read.
+
+io_uring zcrx skbs may contain unreadable net_iov frags. With fbnic
+header/data split, small TCP/IPv4 packets can carry Ethernet padding
+in such a frag. ip_rcv_core() trims the skb to iph->tot_len before TCP
+sees it, and the CHECKSUM_COMPLETE adjustment then calls
+skb_checksum() on the padding.
+
+This is exposed by IPv4 because small TCP/IPv4 frames can be shorter
+than the Ethernet minimum payload. TCP/IPv6 frames are large enough in
+the normal zcrx path, so they do not hit the same padding trim.
+
+Keep the existing checksum adjustment for readable skbs. If the
+remaining packet is fully linear, drop CHECKSUM_COMPLETE and let the
+stack validate the packet after trimming. If unreadable payload would
+remain, fail the trim; the checksum cannot be adjusted without reading
+the trimmed tail.
+
+Also clear skb->unreadable when trimming removes all frags.
+
+Fixes: 65249feb6b3d ("net: add support for skbs with unreadable frags")
+Signed-off-by: Björn Töpel <bjorn@kernel.org>
+Reviewed-by: Breno Leitao <leitao@debian.org>
+Link: https://patch.msgid.link/20260522120643.242974-1-bjorn@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 31 +++++++++++++++++++++++++++----
+ 1 file changed, 27 insertions(+), 4 deletions(-)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index aa9e9148847363..8c9f026182a6f0 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -2765,6 +2765,8 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len)
+               skb->data_len  = 0;
+               skb_set_tail_pointer(skb, len);
+       }
++      if (!skb_shinfo(skb)->nr_frags && !skb_has_frag_list(skb))
++              skb->unreadable = 0;
+       if (!skb->sk || skb->destructor == sock_edemux)
+               skb_condense(skb);
+@@ -2772,16 +2774,37 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len)
+ }
+ EXPORT_SYMBOL(___pskb_trim);
++static int pskb_trim_rcsum_complete(struct sk_buff *skb, unsigned int len)
++{
++      int delta = skb->len - len;
++
++      if (skb_frags_readable(skb)) {
++              skb->csum = csum_block_sub(skb->csum,
++                                         skb_checksum(skb, len, delta, 0),
++                                         len);
++              return 0;
++      }
++
++      if (len > skb_headlen(skb))
++              return -EFAULT;
++
++      /* The trimmed bytes are unreadable, but the remaining packet can be
++       * checksummed by software after trimming.
++       */
++      skb->ip_summed = CHECKSUM_NONE;
++      return 0;
++}
++
+ /* Note : use pskb_trim_rcsum() instead of calling this directly
+  */
+ int pskb_trim_rcsum_slow(struct sk_buff *skb, unsigned int len)
+ {
+       if (skb->ip_summed == CHECKSUM_COMPLETE) {
+-              int delta = skb->len - len;
++              int err;
+-              skb->csum = csum_block_sub(skb->csum,
+-                                         skb_checksum(skb, len, delta, 0),
+-                                         len);
++              err = pskb_trim_rcsum_complete(skb, len);
++              if (err)
++                      return err;
+       } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               int hdlen = (len > skb_headlen(skb)) ? skb_headlen(skb) : len;
+               int offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-ethtool-add-new-parameters-and-a-function-to-sup.patch b/queue-6.12/net-ethtool-add-new-parameters-and-a-function-to-sup.patch
new file mode 100644 (file)
index 0000000..7ad55f8
--- /dev/null
@@ -0,0 +1,203 @@
+From ef3d0abad78355d2c1d9a1832b2540b666451d9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Oct 2024 13:53:46 +0300
+Subject: net: ethtool: Add new parameters and a function to support EPL
+
+From: Danielle Ratson <danieller@nvidia.com>
+
+[ Upstream commit edc344568922eb9588e77ba49de1ef0cb9a2ff1c ]
+
+In the CMIS specification for pluggable modules, LPL (Local Payload) and
+EPL (Extended Payload) are two types of data payloads used for managing
+various functions and features of the module.
+
+EPL payloads are used for more complex and extensive management
+functions that require a larger amount of data, so writing firmware
+blocks using EPL is much more efficient.
+
+Currently, only LPL payload is supported for writing firmware blocks to
+the module.
+
+Add EPL related parameters to the function ethtool_cmis_cdb_compose_args()
+and add a specific function for calculating the maximum allowable length
+extension for EPL. Both will be used in the next patch to add support for
+writing firmware blocks using EPL.
+
+Signed-off-by: Danielle Ratson <danieller@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 12c2496a71f8 ("ethtool: cmis: validate start_cmd_payload_size from module")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis.h           | 12 +++++++-----
+ net/ethtool/cmis_cdb.c       | 32 +++++++++++++++++++++-----------
+ net/ethtool/cmis_fw_update.c | 17 ++++++++++-------
+ 3 files changed, 38 insertions(+), 23 deletions(-)
+
+diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
+index aa32a675b8f8d2..e11e47b3f2fc8f 100644
+--- a/net/ethtool/cmis.h
++++ b/net/ethtool/cmis.h
+@@ -96,13 +96,15 @@ struct ethtool_cmis_cdb_rpl {
+       u8 payload[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH];
+ };
+-u32 ethtool_cmis_get_max_payload_size(u8 num_of_byte_octs);
++u32 ethtool_cmis_get_max_lpl_size(u8 num_of_byte_octs);
++u32 ethtool_cmis_get_max_epl_size(u8 num_of_byte_octs);
+ void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
+-                                 enum ethtool_cmis_cdb_cmd_id cmd, u8 *pl,
+-                                 u8 lpl_len, u16 max_duration,
+-                                 u8 read_write_len_ext, u16 msleep_pre_rpl,
+-                                 u8 rpl_exp_len, u8 flags);
++                                 enum ethtool_cmis_cdb_cmd_id cmd, u8 *lpl,
++                                 u8 lpl_len, u8 *epl, u16 epl_len,
++                                 u16 max_duration, u8 read_write_len_ext,
++                                 u16 msleep_pre_rpl, u8 rpl_exp_len,
++                                 u8 flags);
+ void ethtool_cmis_cdb_check_completion_flag(u8 cmis_rev, u8 *flags);
+diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
+index 690002366d965a..31142e239cf6b2 100644
+--- a/net/ethtool/cmis_cdb.c
++++ b/net/ethtool/cmis_cdb.c
+@@ -11,25 +11,34 @@
+  * min(i, 15) byte octets where i specifies the allowable additional number of
+  * byte octets in a READ or a WRITE.
+  */
+-u32 ethtool_cmis_get_max_payload_size(u8 num_of_byte_octs)
++u32 ethtool_cmis_get_max_lpl_size(u8 num_of_byte_octs)
+ {
+       return 8 * (1 + min_t(u8, num_of_byte_octs, 15));
+ }
++/* For accessing the EPL field on page 9Fh, the allowable length extension is
++ * min(i, 255) byte octets where i specifies the allowable additional number of
++ * byte octets in a READ or a WRITE.
++ */
++u32 ethtool_cmis_get_max_epl_size(u8 num_of_byte_octs)
++{
++      return 8 * (1 + min_t(u8, num_of_byte_octs, 255));
++}
++
+ void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
+-                                 enum ethtool_cmis_cdb_cmd_id cmd, u8 *pl,
+-                                 u8 lpl_len, u16 max_duration,
+-                                 u8 read_write_len_ext, u16 msleep_pre_rpl,
+-                                 u8 rpl_exp_len, u8 flags)
++                                 enum ethtool_cmis_cdb_cmd_id cmd, u8 *lpl,
++                                 u8 lpl_len, u8 *epl, u16 epl_len,
++                                 u16 max_duration, u8 read_write_len_ext,
++                                 u16 msleep_pre_rpl, u8 rpl_exp_len, u8 flags)
+ {
+       args->req.id = cpu_to_be16(cmd);
+       args->req.lpl_len = lpl_len;
+-      if (pl)
+-              memcpy(args->req.payload, pl, args->req.lpl_len);
++      if (lpl)
++              memcpy(args->req.payload, lpl, args->req.lpl_len);
+       args->max_duration = max_duration;
+       args->read_write_len_ext =
+-              ethtool_cmis_get_max_payload_size(read_write_len_ext);
++              ethtool_cmis_get_max_lpl_size(read_write_len_ext);
+       args->msleep_pre_rpl = msleep_pre_rpl;
+       args->rpl_exp_len = rpl_exp_len;
+       args->flags = flags;
+@@ -183,7 +192,7 @@ cmis_cdb_validate_password(struct ethtool_cmis_cdb *cdb,
+       }
+       ethtool_cmis_cdb_compose_args(&args, ETHTOOL_CMIS_CDB_CMD_QUERY_STATUS,
+-                                    (u8 *)&qs_pl, sizeof(qs_pl), 0,
++                                    (u8 *)&qs_pl, sizeof(qs_pl), NULL, 0, 0,
+                                     cdb->read_write_len_ext, 1000,
+                                     sizeof(*rpl),
+                                     CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);
+@@ -245,8 +254,9 @@ static int cmis_cdb_module_features_get(struct ethtool_cmis_cdb *cdb,
+       ethtool_cmis_cdb_check_completion_flag(cdb->cmis_rev, &flags);
+       ethtool_cmis_cdb_compose_args(&args,
+                                     ETHTOOL_CMIS_CDB_CMD_MODULE_FEATURES,
+-                                    NULL, 0, 0, cdb->read_write_len_ext,
+-                                    1000, sizeof(*rpl), flags);
++                                    NULL, 0, NULL, 0, 0,
++                                    cdb->read_write_len_ext, 1000,
++                                    sizeof(*rpl), flags);
+       err = ethtool_cmis_cdb_execute_cmd(dev, &args);
+       if (err < 0) {
+diff --git a/net/ethtool/cmis_fw_update.c b/net/ethtool/cmis_fw_update.c
+index 655ff5224ffa30..a514127985d44e 100644
+--- a/net/ethtool/cmis_fw_update.c
++++ b/net/ethtool/cmis_fw_update.c
+@@ -54,7 +54,8 @@ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
+       ethtool_cmis_cdb_check_completion_flag(cdb->cmis_rev, &flags);
+       ethtool_cmis_cdb_compose_args(&args,
+                                     ETHTOOL_CMIS_CDB_CMD_FW_MANAGMENT_FEATURES,
+-                                    NULL, 0, cdb->max_completion_time,
++                                    NULL, 0, NULL, 0,
++                                    cdb->max_completion_time,
+                                     cdb->read_write_len_ext, 1000,
+                                     sizeof(*rpl), flags);
+@@ -122,7 +123,7 @@ cmis_fw_update_start_download(struct ethtool_cmis_cdb *cdb,
+       ethtool_cmis_cdb_compose_args(&args,
+                                     ETHTOOL_CMIS_CDB_CMD_START_FW_DOWNLOAD,
+-                                    (u8 *)&pl, lpl_len,
++                                    (u8 *)&pl, lpl_len, NULL, 0,
+                                     fw_mng->max_duration_start,
+                                     cdb->read_write_len_ext, 1000, 0,
+                                     CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);
+@@ -158,7 +159,7 @@ cmis_fw_update_write_image(struct ethtool_cmis_cdb *cdb,
+       int err;
+       max_lpl_len = min_t(u32,
+-                          ethtool_cmis_get_max_payload_size(cdb->read_write_len_ext),
++                          ethtool_cmis_get_max_lpl_size(cdb->read_write_len_ext),
+                           ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH);
+       max_block_size =
+               max_lpl_len - sizeof_field(struct cmis_cdb_write_fw_block_lpl_pl,
+@@ -183,7 +184,7 @@ cmis_fw_update_write_image(struct ethtool_cmis_cdb *cdb,
+               ethtool_cmis_cdb_compose_args(&args,
+                                             ETHTOOL_CMIS_CDB_CMD_WRITE_FW_BLOCK_LPL,
+-                                            (u8 *)&pl, lpl_len,
++                                            (u8 *)&pl, lpl_len, NULL, 0,
+                                             fw_mng->max_duration_write,
+                                             cdb->read_write_len_ext, 1, 0,
+                                             CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);
+@@ -212,7 +213,8 @@ cmis_fw_update_complete_download(struct ethtool_cmis_cdb *cdb,
+       ethtool_cmis_cdb_compose_args(&args,
+                                     ETHTOOL_CMIS_CDB_CMD_COMPLETE_FW_DOWNLOAD,
+-                                    NULL, 0, fw_mng->max_duration_complete,
++                                    NULL, 0, NULL, 0,
++                                    fw_mng->max_duration_complete,
+                                     cdb->read_write_len_ext, 1000, 0,
+                                     CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);
+@@ -294,7 +296,7 @@ cmis_fw_update_run_image(struct ethtool_cmis_cdb *cdb, struct net_device *dev,
+       int err;
+       ethtool_cmis_cdb_compose_args(&args, ETHTOOL_CMIS_CDB_CMD_RUN_FW_IMAGE,
+-                                    (u8 *)&pl, sizeof(pl),
++                                    (u8 *)&pl, sizeof(pl), NULL, 0,
+                                     cdb->max_completion_time,
+                                     cdb->read_write_len_ext, 1000, 0,
+                                     CDB_F_MODULE_STATE_VALID);
+@@ -326,7 +328,8 @@ cmis_fw_update_commit_image(struct ethtool_cmis_cdb *cdb,
+       ethtool_cmis_cdb_compose_args(&args,
+                                     ETHTOOL_CMIS_CDB_CMD_COMMIT_FW_IMAGE,
+-                                    NULL, 0, cdb->max_completion_time,
++                                    NULL, 0, NULL, 0,
++                                    cdb->max_completion_time,
+                                     cdb->read_write_len_ext, 1000, 0,
+                                     CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-ethtool-add-support-for-writing-firmware-blocks-.patch b/queue-6.12/net-ethtool-add-support-for-writing-firmware-blocks-.patch
new file mode 100644 (file)
index 0000000..8c64c86
--- /dev/null
@@ -0,0 +1,323 @@
+From 72b43e32aa56e2172e3d7423bf34884e809aea85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Oct 2024 13:53:47 +0300
+Subject: net: ethtool: Add support for writing firmware blocks using EPL
+ payload
+
+From: Danielle Ratson <danieller@nvidia.com>
+
+[ Upstream commit 9a3b0d078bd825613c0821bf7bf5a2e1d8d60057 ]
+
+In the CMIS specification for pluggable modules, LPL (Local Payload) and
+EPL (Extended Payload) are two types of data payloads used for managing
+various functions and features of the module.
+
+EPL payloads are used for more complex and extensive management
+functions that require a larger amount of data, so writing firmware
+blocks using EPL is much more efficient.
+
+Currently, only LPL payload is supported for writing firmware blocks to
+the module.
+
+Add support for writing firmware block using EPL payload, both to
+support modules that supports only EPL write mechanism, and to optimize
+the flashing process of modules that support LPL and EPL.
+
+Signed-off-by: Danielle Ratson <danieller@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 12c2496a71f8 ("ethtool: cmis: validate start_cmd_payload_size from module")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis.h           |  4 ++
+ net/ethtool/cmis_cdb.c       | 66 ++++++++++++++++++++++++--
+ net/ethtool/cmis_fw_update.c | 91 ++++++++++++++++++++++++++++++++----
+ 3 files changed, 148 insertions(+), 13 deletions(-)
+
+diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
+index e11e47b3f2fc8f..1ab96bdd2c6f92 100644
+--- a/net/ethtool/cmis.h
++++ b/net/ethtool/cmis.h
+@@ -1,6 +1,7 @@
+ /* SPDX-License-Identifier: GPL-2.0-only */
+ #define ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH            120
++#define ETHTOOL_CMIS_CDB_EPL_MAX_PL_LENGTH            2048
+ #define ETHTOOL_CMIS_CDB_CMD_PAGE                     0x9F
+ #define ETHTOOL_CMIS_CDB_PAGE_I2C_ADDR                        0x50
+@@ -23,6 +24,7 @@ enum ethtool_cmis_cdb_cmd_id {
+       ETHTOOL_CMIS_CDB_CMD_FW_MANAGMENT_FEATURES      = 0x0041,
+       ETHTOOL_CMIS_CDB_CMD_START_FW_DOWNLOAD          = 0x0101,
+       ETHTOOL_CMIS_CDB_CMD_WRITE_FW_BLOCK_LPL         = 0x0103,
++      ETHTOOL_CMIS_CDB_CMD_WRITE_FW_BLOCK_EPL         = 0x0104,
+       ETHTOOL_CMIS_CDB_CMD_COMPLETE_FW_DOWNLOAD       = 0x0107,
+       ETHTOOL_CMIS_CDB_CMD_RUN_FW_IMAGE               = 0x0109,
+       ETHTOOL_CMIS_CDB_CMD_COMMIT_FW_IMAGE            = 0x010A,
+@@ -38,6 +40,7 @@ enum ethtool_cmis_cdb_cmd_id {
+  * @resv1: Added to match the CMIS standard request continuity.
+  * @resv2: Added to match the CMIS standard request continuity.
+  * @payload: Payload for the CDB commands.
++ * @epl: Extended payload for the CDB commands.
+  */
+ struct ethtool_cmis_cdb_request {
+       __be16 id;
+@@ -49,6 +52,7 @@ struct ethtool_cmis_cdb_request {
+               u8 resv2;
+               u8 payload[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH];
+       );
++      u8 *epl;        /* Everything above this field checksummed. */
+ };
+ #define CDB_F_COMPLETION_VALID                BIT(0)
+diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
+index 31142e239cf6b2..606d88df31f235 100644
+--- a/net/ethtool/cmis_cdb.c
++++ b/net/ethtool/cmis_cdb.c
+@@ -33,12 +33,19 @@ void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
+ {
+       args->req.id = cpu_to_be16(cmd);
+       args->req.lpl_len = lpl_len;
+-      if (lpl)
++      if (lpl) {
+               memcpy(args->req.payload, lpl, args->req.lpl_len);
++              args->read_write_len_ext =
++                      ethtool_cmis_get_max_lpl_size(read_write_len_ext);
++      }
++      if (epl) {
++              args->req.epl_len = cpu_to_be16(epl_len);
++              args->req.epl = epl;
++              args->read_write_len_ext =
++                      ethtool_cmis_get_max_epl_size(read_write_len_ext);
++      }
+       args->max_duration = max_duration;
+-      args->read_write_len_ext =
+-              ethtool_cmis_get_max_lpl_size(read_write_len_ext);
+       args->msleep_pre_rpl = msleep_pre_rpl;
+       args->rpl_exp_len = rpl_exp_len;
+       args->flags = flags;
+@@ -561,6 +568,49 @@ __ethtool_cmis_cdb_execute_cmd(struct net_device *dev,
+       return err;
+ }
++#define CMIS_CDB_EPL_PAGE_START                       0xA0
++#define CMIS_CDB_EPL_PAGE_END                 0xAF
++#define CMIS_CDB_EPL_FW_BLOCK_OFFSET_START    128
++#define CMIS_CDB_EPL_FW_BLOCK_OFFSET_END      255
++
++static int
++ethtool_cmis_cdb_execute_epl_cmd(struct net_device *dev,
++                               struct ethtool_cmis_cdb_cmd_args *args,
++                               struct ethtool_module_eeprom *page_data)
++{
++      u16 epl_len = be16_to_cpu(args->req.epl_len);
++      u32 bytes_written = 0;
++      u8 page;
++      int err;
++
++      for (page = CMIS_CDB_EPL_PAGE_START;
++           page <= CMIS_CDB_EPL_PAGE_END && bytes_written < epl_len; page++) {
++              u16 offset = CMIS_CDB_EPL_FW_BLOCK_OFFSET_START;
++
++              while (offset <= CMIS_CDB_EPL_FW_BLOCK_OFFSET_END &&
++                     bytes_written < epl_len) {
++                      u32 bytes_left = epl_len - bytes_written;
++                      u16 space_left, bytes_to_write;
++
++                      space_left = CMIS_CDB_EPL_FW_BLOCK_OFFSET_END - offset + 1;
++                      bytes_to_write = min_t(u16, bytes_left,
++                                             min_t(u16, space_left,
++                                                   args->read_write_len_ext));
++
++                      err = __ethtool_cmis_cdb_execute_cmd(dev, page_data,
++                                                           page, offset,
++                                                           bytes_to_write,
++                                                           args->req.epl + bytes_written);
++                      if (err < 0)
++                              return err;
++
++                      offset += bytes_to_write;
++                      bytes_written += bytes_to_write;
++              }
++      }
++      return 0;
++}
++
+ static u8 cmis_cdb_calc_checksum(const void *data, size_t size)
+ {
+       const u8 *bytes = (const u8 *)data;
+@@ -582,7 +632,9 @@ int ethtool_cmis_cdb_execute_cmd(struct net_device *dev,
+       int err;
+       args->req.chk_code =
+-              cmis_cdb_calc_checksum(&args->req, sizeof(args->req));
++              cmis_cdb_calc_checksum(&args->req,
++                                     offsetof(struct ethtool_cmis_cdb_request,
++                                              epl));
+       if (args->req.lpl_len > args->read_write_len_ext) {
+               args->err_msg = "LPL length is longer than CDB read write length extension allows";
+@@ -604,6 +656,12 @@ int ethtool_cmis_cdb_execute_cmd(struct net_device *dev,
+       if (err < 0)
+               return err;
++      if (args->req.epl_len) {
++              err = ethtool_cmis_cdb_execute_epl_cmd(dev, args, &page_data);
++              if (err < 0)
++                      return err;
++      }
++
+       offset = CMIS_CDB_CMD_ID_OFFSET +
+               offsetof(struct ethtool_cmis_cdb_request, id);
+       err = __ethtool_cmis_cdb_execute_cmd(dev, &page_data,
+diff --git a/net/ethtool/cmis_fw_update.c b/net/ethtool/cmis_fw_update.c
+index a514127985d44e..48aef6220f0094 100644
+--- a/net/ethtool/cmis_fw_update.c
++++ b/net/ethtool/cmis_fw_update.c
+@@ -9,6 +9,7 @@
+ struct cmis_fw_update_fw_mng_features {
+       u8      start_cmd_payload_size;
++      u8      write_mechanism;
+       u16     max_duration_start;
+       u16     max_duration_write;
+       u16     max_duration_complete;
+@@ -36,7 +37,9 @@ struct cmis_cdb_fw_mng_features_rpl {
+ };
+ enum cmis_cdb_fw_write_mechanism {
++      CMIS_CDB_FW_WRITE_MECHANISM_NONE        = 0x00,
+       CMIS_CDB_FW_WRITE_MECHANISM_LPL         = 0x01,
++      CMIS_CDB_FW_WRITE_MECHANISM_EPL         = 0x10,
+       CMIS_CDB_FW_WRITE_MECHANISM_BOTH        = 0x11,
+ };
+@@ -68,10 +71,9 @@ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
+       }
+       rpl = (struct cmis_cdb_fw_mng_features_rpl *)args.req.payload;
+-      if (!(rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_LPL ||
+-            rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_BOTH)) {
++      if (rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_NONE) {
+               ethnl_module_fw_flash_ntf_err(dev, ntf_params,
+-                                            "Write LPL is not supported",
++                                            "CDB write mechanism is not supported",
+                                             NULL);
+               return  -EOPNOTSUPP;
+       }
+@@ -83,6 +85,10 @@ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
+        */
+       cdb->read_write_len_ext = rpl->read_write_len_ext;
+       fw_mng->start_cmd_payload_size = rpl->start_cmd_payload_size;
++      fw_mng->write_mechanism =
++              rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_LPL ?
++              CMIS_CDB_FW_WRITE_MECHANISM_LPL :
++              CMIS_CDB_FW_WRITE_MECHANISM_EPL;
+       fw_mng->max_duration_start = be16_to_cpu(rpl->max_duration_start);
+       fw_mng->max_duration_write = be16_to_cpu(rpl->max_duration_write);
+       fw_mng->max_duration_complete = be16_to_cpu(rpl->max_duration_complete);
+@@ -149,9 +155,9 @@ struct cmis_cdb_write_fw_block_lpl_pl {
+ };
+ static int
+-cmis_fw_update_write_image(struct ethtool_cmis_cdb *cdb,
+-                         struct ethtool_cmis_fw_update_params *fw_update,
+-                         struct cmis_fw_update_fw_mng_features *fw_mng)
++cmis_fw_update_write_image_lpl(struct ethtool_cmis_cdb *cdb,
++                             struct ethtool_cmis_fw_update_params *fw_update,
++                             struct cmis_fw_update_fw_mng_features *fw_mng)
+ {
+       u8 start = fw_mng->start_cmd_payload_size;
+       u32 offset, max_block_size, max_lpl_len;
+@@ -202,6 +208,67 @@ cmis_fw_update_write_image(struct ethtool_cmis_cdb *cdb,
+       return 0;
+ }
++struct cmis_cdb_write_fw_block_epl_pl {
++      u8 fw_block[ETHTOOL_CMIS_CDB_EPL_MAX_PL_LENGTH];
++};
++
++static int
++cmis_fw_update_write_image_epl(struct ethtool_cmis_cdb *cdb,
++                             struct ethtool_cmis_fw_update_params *fw_update,
++                             struct cmis_fw_update_fw_mng_features *fw_mng)
++{
++      u8 start = fw_mng->start_cmd_payload_size;
++      u32 image_size = fw_update->fw->size;
++      u32 offset, lpl_len;
++      int err;
++
++      lpl_len = sizeof_field(struct cmis_cdb_write_fw_block_lpl_pl,
++                             block_address);
++
++      for (offset = start; offset < image_size;
++           offset += ETHTOOL_CMIS_CDB_EPL_MAX_PL_LENGTH) {
++              struct cmis_cdb_write_fw_block_lpl_pl lpl = {
++                      .block_address = cpu_to_be32(offset - start),
++              };
++              struct cmis_cdb_write_fw_block_epl_pl *epl;
++              struct ethtool_cmis_cdb_cmd_args args = {};
++              u32 epl_len;
++
++              ethnl_module_fw_flash_ntf_in_progress(fw_update->dev,
++                                                    &fw_update->ntf_params,
++                                                    offset - start,
++                                                    image_size);
++
++              epl_len = min_t(u32, ETHTOOL_CMIS_CDB_EPL_MAX_PL_LENGTH,
++                              image_size - offset);
++              epl = kmalloc_array(epl_len, sizeof(u8), GFP_KERNEL);
++              if (!epl)
++                      return -ENOMEM;
++
++              memcpy(epl->fw_block, &fw_update->fw->data[offset], epl_len);
++
++              ethtool_cmis_cdb_compose_args(&args,
++                                            ETHTOOL_CMIS_CDB_CMD_WRITE_FW_BLOCK_EPL,
++                                            (u8 *)&lpl, lpl_len, (u8 *)epl,
++                                            epl_len,
++                                            fw_mng->max_duration_write,
++                                            cdb->read_write_len_ext, 1, 0,
++                                            CDB_F_COMPLETION_VALID | CDB_F_STATUS_VALID);
++
++              err = ethtool_cmis_cdb_execute_cmd(fw_update->dev, &args);
++              kfree(epl);
++              if (err < 0) {
++                      ethnl_module_fw_flash_ntf_err(fw_update->dev,
++                                                    &fw_update->ntf_params,
++                                                    "Write FW block EPL command failed",
++                                                    args.err_msg);
++                      return err;
++              }
++      }
++
++      return 0;
++}
++
+ static int
+ cmis_fw_update_complete_download(struct ethtool_cmis_cdb *cdb,
+                                struct net_device *dev,
+@@ -238,9 +305,15 @@ cmis_fw_update_download_image(struct ethtool_cmis_cdb *cdb,
+       if (err < 0)
+               return err;
+-      err = cmis_fw_update_write_image(cdb, fw_update, fw_mng);
+-      if (err < 0)
+-              return err;
++      if (fw_mng->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_LPL) {
++              err = cmis_fw_update_write_image_lpl(cdb, fw_update, fw_mng);
++              if (err < 0)
++                      return err;
++      } else {
++              err = cmis_fw_update_write_image_epl(cdb, fw_update, fw_mng);
++              if (err < 0)
++                      return err;
++      }
+       err = cmis_fw_update_complete_download(cdb, fw_update->dev, fw_mng,
+                                              &fw_update->ntf_params);
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-handshake-drain-pending-requests-at-net-namespac.patch b/queue-6.12/net-handshake-drain-pending-requests-at-net-namespac.patch
new file mode 100644 (file)
index 0000000..518c8da
--- /dev/null
@@ -0,0 +1,112 @@
+From b31d1fc4e428f49c68f4bf59c55cd6c35c252205 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:22 -0400
+Subject: net/handshake: Drain pending requests at net namespace exit
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit ea5fe6a73ca57e5150b8a38b341aef2636eb72f0 ]
+
+The arguments to list_splice_init() in handshake_net_exit() are
+reversed. The call moves the local empty "requests" list onto
+hn->hn_requests, leaving the local list empty, so the subsequent
+drain loop runs zero iterations. Pending handshake requests that
+had not yet been accepted are not torn down when the net namespace
+is destroyed; each one keeps a reference on a socket file and on
+the handshake_req allocation.
+
+Pass the source and destination in the documented order
+(list_splice_init(list, head) moves list onto head) so the pending
+list is transferred to the local scratch list and drained through
+handshake_complete().
+
+Fixing the splice direction exposes a list-corruption race. After
+the splice each req->hr_list still has non-empty link pointers,
+threading the stack-local scratch list rather than hn_requests.
+A concurrent handshake_req_cancel() -- for example, from sunrpc's
+TLS timeout on a kernel socket whose netns reference was not
+taken -- finds the request through the rhashtable, calls
+remove_pending(), and sees !list_empty(&req->hr_list).
+__remove_pending_locked() then list_del_init()s an entry off the
+scratch list while the drain iterates, corrupting it. The same
+call arriving after the drain loop has run list_del() on an
+entry hits LIST_POISON instead.
+
+Have remove_pending() check HANDSHAKE_F_NET_DRAINING under
+hn_lock and report not-found when drain is in progress. The
+drain has already taken ownership; handshake_complete()'s existing
+test_and_set on HANDSHAKE_F_REQ_COMPLETED still arbitrates
+between drain and cancel for who calls the consumer's hp_done. Use
+list_del_init() rather than list_del() in the drain so req->hr_list
+does not carry LIST_POISON after drain releases the entry.
+
+The DRAINING guard in remove_pending() makes cancel return false,
+but cancel still falls through to test_and_set_bit on
+HANDSHAKE_F_REQ_COMPLETED and drops the request's hr_file reference.
+Without another pin, if that is the last reference, sk_destruct frees
+the request while it is still linked on the drain loop's local list.
+Pin each request's hr_file under hn_lock before releasing the list,
+and drop that drain pin after the loop finishes with the request.
+
+Fixes: 3b3009ea8abb ("net/handshake: Create a NETLINK service for handling handshake requests")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-8-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/netlink.c | 10 ++++++++--
+ net/handshake/request.c |  5 ++++-
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/net/handshake/netlink.c b/net/handshake/netlink.c
+index 86a12c9125d403..e49041cc0f9d70 100644
+--- a/net/handshake/netlink.c
++++ b/net/handshake/netlink.c
+@@ -205,13 +205,19 @@ static void __net_exit handshake_net_exit(struct net *net)
+        */
+       spin_lock_bh(&hn->hn_lock);
+       set_bit(HANDSHAKE_F_NET_DRAINING, &hn->hn_flags);
+-      list_splice_init(&requests, &hn->hn_requests);
++      list_splice_init(&hn->hn_requests, &requests);
++      list_for_each_entry(req, &requests, hr_list)
++              get_file(req->hr_file);
+       spin_unlock_bh(&hn->hn_lock);
+       while (!list_empty(&requests)) {
++              struct file *file;
++
+               req = list_first_entry(&requests, struct handshake_req, hr_list);
+-              list_del(&req->hr_list);
++              file = req->hr_file;
++              list_del_init(&req->hr_list);
+               handshake_complete(req, -ETIMEDOUT, NULL);
++              fput(file);
+       }
+ }
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 35bc6290e12033..96f80e0df67b50 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -163,13 +163,16 @@ static void __remove_pending_locked(struct handshake_net *hn,
+  * otherwise %false.
+  *
+  * If @req was on a pending list, it has not yet been accepted.
++ * Returns %false when the net namespace is draining; the drain
++ * loop has taken ownership of the pending list.
+  */
+ static bool remove_pending(struct handshake_net *hn, struct handshake_req *req)
+ {
+       bool ret = false;
+       spin_lock_bh(&hn->hn_lock);
+-      if (!list_empty(&req->hr_list)) {
++      if (!test_bit(HANDSHAKE_F_NET_DRAINING, &hn->hn_flags) &&
++          !list_empty(&req->hr_list)) {
+               __remove_pending_locked(hn, req);
+               ret = true;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-handshake-pass-negative-errno-through-handshake_.patch b/queue-6.12/net-handshake-pass-negative-errno-through-handshake_.patch
new file mode 100644 (file)
index 0000000..b538c19
--- /dev/null
@@ -0,0 +1,212 @@
+From 1616ec410d95511eda4e449b2797c511fb5f7bf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:17 -0400
+Subject: net/handshake: Pass negative errno through handshake_complete()
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 6b22d433aa13f68e3cd9534ca9a5f4277bfa01c2 ]
+
+handshake_complete() declares status as unsigned int and
+tls_handshake_done() negates that value (-status) before handing
+it to the TLS consumer. Consumers match on negative errno
+constants -- xs_tls_handshake_done() has
+
+       switch (status) {
+       case 0:
+       case -EACCES:
+       case -ETIMEDOUT:
+               lower_transport->xprt_err = status;
+               break;
+       default:
+               lower_transport->xprt_err = -EACCES;
+       }
+
+so the API as designed expects callers to pass positive errno
+values that the tlshd shim then negates.
+
+Three internal callers in handshake_nl_accept_doit(), the
+net-exit drain, and a kunit test follow kernel convention and
+pass negative errnos -- -EIO, -ETIMEDOUT, -ETIMEDOUT. The
+implicit conversion to unsigned int turns -ETIMEDOUT into
+0xFFFFFF92; the subsequent -status in tls_handshake_done()
+wraps back to 110, the consumer's switch falls through, and
+the xprt reports -EACCES on what should be -ETIMEDOUT or -EIO.
+
+Fix the API rather than the call sites. The natural kernel
+convention is negative errno in, negative errno out. Change
+handshake_complete() and hp_done to take int status, drop the
+negation in tls_handshake_done(), and negate once in
+handshake_nl_done_doit() where status arrives from the wire
+as an unsigned netlink attribute. The three internal callers
+were already correct under that convention and need no change.
+
+At the same wire boundary, declare MAX_ERRNO as the netlink
+policy upper bound for HANDSHAKE_A_DONE_STATUS. Attribute
+validation rejects out-of-range values before
+handshake_nl_done_doit() runs, and negating a bounded u32 there
+stays within int range -- closing the UBSAN-visible signed-
+integer overflow that an unconstrained u32 would invoke.
+
+Fixes: 3b3009ea8abb ("net/handshake: Create a NETLINK service for handling handshake requests")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-3-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/netlink/specs/handshake.yaml | 8 ++++++++
+ net/handshake/genl.c                       | 3 ++-
+ net/handshake/genl.h                       | 1 +
+ net/handshake/handshake-test.c             | 2 +-
+ net/handshake/handshake.h                  | 4 ++--
+ net/handshake/netlink.c                    | 2 +-
+ net/handshake/request.c                    | 2 +-
+ net/handshake/tlshd.c                      | 4 ++--
+ 8 files changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/Documentation/netlink/specs/handshake.yaml b/Documentation/netlink/specs/handshake.yaml
+index b934cc513e3d6f..090fc11da4604a 100644
+--- a/Documentation/netlink/specs/handshake.yaml
++++ b/Documentation/netlink/specs/handshake.yaml
+@@ -12,6 +12,12 @@ protocol: genetlink
+ doc: Netlink protocol to request a transport layer security handshake.
+ definitions:
++  -
++    type: const
++    name: max-errno
++    value: 4095
++    header: linux/err.h
++    scope: kernel
+   -
+     type: enum
+     name: handler-class
+@@ -77,6 +83,8 @@ attribute-sets:
+       -
+         name: status
+         type: u32
++        checks:
++          max: max-errno
+       -
+         name: sockfd
+         type: s32
+diff --git a/net/handshake/genl.c b/net/handshake/genl.c
+index f55d14d7b7269d..a5fa8b27f22423 100644
+--- a/net/handshake/genl.c
++++ b/net/handshake/genl.c
+@@ -9,6 +9,7 @@
+ #include "genl.h"
+ #include <uapi/linux/handshake.h>
++#include <linux/err.h>
+ /* HANDSHAKE_CMD_ACCEPT - do */
+ static const struct nla_policy handshake_accept_nl_policy[HANDSHAKE_A_ACCEPT_HANDLER_CLASS + 1] = {
+@@ -17,7 +18,7 @@ static const struct nla_policy handshake_accept_nl_policy[HANDSHAKE_A_ACCEPT_HAN
+ /* HANDSHAKE_CMD_DONE - do */
+ static const struct nla_policy handshake_done_nl_policy[HANDSHAKE_A_DONE_REMOTE_AUTH + 1] = {
+-      [HANDSHAKE_A_DONE_STATUS] = { .type = NLA_U32, },
++      [HANDSHAKE_A_DONE_STATUS] = NLA_POLICY_MAX(NLA_U32, MAX_ERRNO),
+       [HANDSHAKE_A_DONE_SOCKFD] = { .type = NLA_S32, },
+       [HANDSHAKE_A_DONE_REMOTE_AUTH] = { .type = NLA_U32, },
+ };
+diff --git a/net/handshake/genl.h b/net/handshake/genl.h
+index ae72a596f6cc3e..684e5fd684481b 100644
+--- a/net/handshake/genl.h
++++ b/net/handshake/genl.h
+@@ -10,6 +10,7 @@
+ #include <net/genetlink.h>
+ #include <uapi/linux/handshake.h>
++#include <linux/err.h>
+ int handshake_nl_accept_doit(struct sk_buff *skb, struct genl_info *info);
+ int handshake_nl_done_doit(struct sk_buff *skb, struct genl_info *info);
+diff --git a/net/handshake/handshake-test.c b/net/handshake/handshake-test.c
+index 34fd1d9b2db861..a331b308aaa240 100644
+--- a/net/handshake/handshake-test.c
++++ b/net/handshake/handshake-test.c
+@@ -25,7 +25,7 @@ static int test_accept_func(struct handshake_req *req, struct genl_info *info,
+       return 0;
+ }
+-static void test_done_func(struct handshake_req *req, unsigned int status,
++static void test_done_func(struct handshake_req *req, int status,
+                          struct genl_info *info)
+ {
+ }
+diff --git a/net/handshake/handshake.h b/net/handshake/handshake.h
+index a48163765a7a1d..2289b0e274f40a 100644
+--- a/net/handshake/handshake.h
++++ b/net/handshake/handshake.h
+@@ -57,7 +57,7 @@ struct handshake_proto {
+       int                     (*hp_accept)(struct handshake_req *req,
+                                            struct genl_info *info, int fd);
+       void                    (*hp_done)(struct handshake_req *req,
+-                                         unsigned int status,
++                                         int status,
+                                          struct genl_info *info);
+       void                    (*hp_destroy)(struct handshake_req *req);
+ };
+@@ -86,7 +86,7 @@ struct handshake_req *handshake_req_hash_lookup(struct sock *sk);
+ struct handshake_req *handshake_req_next(struct handshake_net *hn, int class);
+ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+                        gfp_t flags);
+-void handshake_complete(struct handshake_req *req, unsigned int status,
++void handshake_complete(struct handshake_req *req, int status,
+                       struct genl_info *info);
+ bool handshake_req_cancel(struct sock *sk);
+diff --git a/net/handshake/netlink.c b/net/handshake/netlink.c
+index 394e270cc505cb..d8211e0ba75c69 100644
+--- a/net/handshake/netlink.c
++++ b/net/handshake/netlink.c
+@@ -161,7 +161,7 @@ int handshake_nl_done_doit(struct sk_buff *skb, struct genl_info *info)
+       status = -EIO;
+       if (info->attrs[HANDSHAKE_A_DONE_STATUS])
+-              status = nla_get_u32(info->attrs[HANDSHAKE_A_DONE_STATUS]);
++              status = -(int)nla_get_u32(info->attrs[HANDSHAKE_A_DONE_STATUS]);
+       handshake_complete(req, status, info);
+       sockfd_put(sock);
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 75562f6629e050..2f58d74f16554b 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -285,7 +285,7 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+ }
+ EXPORT_SYMBOL(handshake_req_submit);
+-void handshake_complete(struct handshake_req *req, unsigned int status,
++void handshake_complete(struct handshake_req *req, int status,
+                       struct genl_info *info)
+ {
+       struct sock *sk = req->hr_sk;
+diff --git a/net/handshake/tlshd.c b/net/handshake/tlshd.c
+index fd71ef2d18ceb2..5464e57c347b9c 100644
+--- a/net/handshake/tlshd.c
++++ b/net/handshake/tlshd.c
+@@ -93,7 +93,7 @@ static void tls_handshake_remote_peerids(struct tls_handshake_req *treq,
+  *
+  */
+ static void tls_handshake_done(struct handshake_req *req,
+-                             unsigned int status, struct genl_info *info)
++                             int status, struct genl_info *info)
+ {
+       struct tls_handshake_req *treq = handshake_req_private(req);
+@@ -104,7 +104,7 @@ static void tls_handshake_done(struct handshake_req *req,
+       if (!status)
+               set_bit(HANDSHAKE_F_REQ_SESSION, &req->hr_flags);
+-      treq->th_consumer_done(treq->th_consumer_data, -status,
++      treq->th_consumer_done(treq->th_consumer_data, status,
+                              treq->th_peerid[0]);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-handshake-take-a-long-lived-file-reference-at-su.patch b/queue-6.12/net-handshake-take-a-long-lived-file-reference-at-su.patch
new file mode 100644 (file)
index 0000000..4ce3a51
--- /dev/null
@@ -0,0 +1,187 @@
+From 3285d576d858e0fd808c19cd043f6dc5649577fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:18 -0400
+Subject: net/handshake: Take a long-lived file reference at submit
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 09dba37eee70d0596e26645015f1aa95a9848e9d ]
+
+handshake_nl_accept_doit() needs the file pointer backing
+req->hr_sk->sk_socket to survive the window between
+handshake_req_next() and the subsequent FD_PREPARE() and get_file().
+The submit-side sock_hold() does not provide that.  sk_refcnt keeps
+struct sock alive, but struct socket is owned by sock->file: when
+the consumer fputs the last file reference, sock_release() tears
+the socket down regardless of any sock_hold.
+
+Add an hr_file pointer to struct handshake_req and acquire an
+explicit reference on sock->file during handshake_req_submit().
+handshake_complete() and handshake_req_cancel() release the
+reference on the completion-bit-winning path.
+
+The submit error path must also release the file reference, but
+after rhashtable insertion a concurrent handshake_req_cancel() can
+discover the request and race the error path.  Gate the error-path
+cleanup -- sk_destruct restoration, fput, and request destruction
+-- with test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED), the same
+serialization handshake_complete() and handshake_req_cancel()
+already use.  When cancel has already claimed ownership, the submit
+error path returns without touching the request; socket teardown
+handles final destruction.
+
+The accept-side dereferences are not yet retargeted; that change
+comes in the next patch.
+
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-4-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: ea5fe6a73ca5 ("net/handshake: Drain pending requests at net namespace exit")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/handshake.h |  2 ++
+ net/handshake/netlink.c   |  6 ------
+ net/handshake/request.c   | 42 ++++++++++++++++++++++++++++++++-------
+ 3 files changed, 37 insertions(+), 13 deletions(-)
+
+diff --git a/net/handshake/handshake.h b/net/handshake/handshake.h
+index 2289b0e274f40a..da61cadd1ad3e7 100644
+--- a/net/handshake/handshake.h
++++ b/net/handshake/handshake.h
+@@ -24,6 +24,7 @@ enum hn_flags_bits {
+       HANDSHAKE_F_NET_DRAINING,
+ };
++struct file;
+ struct handshake_proto;
+ /* One handshake request */
+@@ -32,6 +33,7 @@ struct handshake_req {
+       struct rhash_head               hr_rhash;
+       unsigned long                   hr_flags;
+       const struct handshake_proto    *hr_proto;
++      struct file                     *hr_file;
+       struct sock                     *hr_sk;
+       void                            (*hr_odestruct)(struct sock *sk);
+diff --git a/net/handshake/netlink.c b/net/handshake/netlink.c
+index d8211e0ba75c69..86a12c9125d403 100644
+--- a/net/handshake/netlink.c
++++ b/net/handshake/netlink.c
+@@ -211,12 +211,6 @@ static void __net_exit handshake_net_exit(struct net *net)
+       while (!list_empty(&requests)) {
+               req = list_first_entry(&requests, struct handshake_req, hr_list);
+               list_del(&req->hr_list);
+-
+-              /*
+-               * Requests on this list have not yet been
+-               * accepted, so they do not have an fd to put.
+-               */
+-
+               handshake_complete(req, -ETIMEDOUT, NULL);
+       }
+ }
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 62efb7e32730ea..35bc6290e12033 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -13,6 +13,7 @@
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/inet.h>
++#include <linux/file.h>
+ #include <linux/rhashtable.h>
+ #include <net/sock.h>
+@@ -215,9 +216,16 @@ EXPORT_SYMBOL_IF_KUNIT(handshake_req_next);
+  * A zero return value from handshake_req_submit() means that
+  * exactly one subsequent completion callback is guaranteed.
+  *
+- * A negative return value from handshake_req_submit() means that
+- * no completion callback will be done and that @req has been
+- * destroyed.
++ * A negative return value from handshake_req_submit() guarantees that
++ * no completion callback will occur and that @req is no longer owned by
++ * the caller. If cancellation wins the completion race after the request
++ * has been published, final destruction is deferred until socket teardown.
++ *
++ * The caller must hold a reference on @sock->file for the duration
++ * of this call. Once the request is published to the accept side, a
++ * concurrent completion or cancellation may release the request's pin on
++ * @sock->file; the caller's reference is what keeps @sock->sk valid until
++ * handshake_req_submit() returns.
+  */
+ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+                        gfp_t flags)
+@@ -236,6 +244,14 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+               kfree(req);
+               return -EINVAL;
+       }
++
++      /*
++       * Pin sock->file for the lifetime of the request so the
++       * accept side does not race a consumer that releases the
++       * socket while a handshake is pending.
++       */
++      req->hr_file = get_file(sock->file);
++
+       req->hr_odestruct = req->hr_sk->sk_destruct;
+       req->hr_sk->sk_destruct = handshake_sk_destruct;
+@@ -267,7 +283,11 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+                       goto out_err;
+       }
+-      /* Prevent socket release while a handshake request is pending */
++      /*
++       * Pin struct sock so sk_destruct does not run until the
++       * handshake completion path releases it; struct socket is
++       * held separately via hr_file above.
++       */
+       sock_hold(req->hr_sk);
+       trace_handshake_submit(net, req, req->hr_sk);
+@@ -276,10 +296,13 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+ out_unlock:
+       spin_unlock_bh(&hn->hn_lock);
+ out_err:
+-      /* Restore original destructor so socket teardown still runs on failure */
+-      req->hr_sk->sk_destruct = req->hr_odestruct;
+       trace_handshake_submit_err(net, req, req->hr_sk, ret);
+-      handshake_req_destroy(req);
++      if (!test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) {
++              /* Restore original destructor so socket teardown still runs. */
++              req->hr_sk->sk_destruct = req->hr_odestruct;
++              fput(req->hr_file);
++              handshake_req_destroy(req);
++      }
+       return ret;
+ }
+ EXPORT_SYMBOL(handshake_req_submit);
+@@ -291,11 +314,15 @@ void handshake_complete(struct handshake_req *req, int status,
+       struct net *net = sock_net(sk);
+       if (!test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) {
++              struct file *file = req->hr_file;
++
+               trace_handshake_complete(net, req, sk, status);
+               req->hr_proto->hp_done(req, status, info);
+               /* Handshake request is no longer pending */
+               sock_put(sk);
++
++              fput(file);
+       }
+ }
+ EXPORT_SYMBOL_IF_KUNIT(handshake_complete);
+@@ -344,6 +371,7 @@ bool handshake_req_cancel(struct sock *sk)
+       /* Handshake request is no longer pending */
+       sock_put(sk);
++      fput(req->hr_file);
+       return true;
+ }
+ EXPORT_SYMBOL(handshake_req_cancel);
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-handshake-use-spin_lock_bh-for-hn_lock.patch b/queue-6.12/net-handshake-use-spin_lock_bh-for-hn_lock.patch
new file mode 100644 (file)
index 0000000..e35ed91
--- /dev/null
@@ -0,0 +1,138 @@
+From 5c0599665b076e2fc881cd31a2fcefc2561a6b45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:15 -0400
+Subject: net/handshake: Use spin_lock_bh for hn_lock
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit cc993e0927ec8bd98ea33377ada03295fcda0f24 ]
+
+nvmet_tcp_state_change(), a socket callback that runs in BH context,
+can reach handshake_req_cancel() via nvmet_tcp_schedule_release_queue()
+and tls_handshake_cancel().  handshake_req_cancel() acquires
+hn->hn_lock with plain spin_lock().  If a process-context thread on
+the same CPU holds hn->hn_lock when a softirq invokes the cancel path,
+the lock attempt deadlocks.  This is the only caller that invokes
+tls_handshake_cancel() from BH context; every other consumer calls it
+from process context.
+
+Deferring the cancel to process context in the NVMe target is not
+straightforward: nvmet_tcp_schedule_release_queue() must call
+tls_handshake_cancel() atomically with its state transition to
+DISCONNECTING.  If the cancel were deferred, the handshake completion
+callback could fire in the window before the cancel runs, observe the
+unexpected state, and return without dropping its kref on the queue.
+Reworking that interlock is considerably more invasive than hardening
+the handshake lock.  Convert all hn->hn_lock acquisitions from
+spin_lock/spin_unlock to spin_lock_bh/spin_unlock_bh so the lock is
+never taken with softirqs enabled.
+
+Fixes: 675b453e0241 ("nvmet-tcp: enable TLS handshake upcall")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-1-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/netlink.c |  4 ++--
+ net/handshake/request.c | 14 +++++++-------
+ net/handshake/tlshd.c   |  2 ++
+ 3 files changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/net/handshake/netlink.c b/net/handshake/netlink.c
+index 7e46d130dce2cd..394e270cc505cb 100644
+--- a/net/handshake/netlink.c
++++ b/net/handshake/netlink.c
+@@ -203,10 +203,10 @@ static void __net_exit handshake_net_exit(struct net *net)
+        * accepted and are in progress will be destroyed when
+        * the socket is closed.
+        */
+-      spin_lock(&hn->hn_lock);
++      spin_lock_bh(&hn->hn_lock);
+       set_bit(HANDSHAKE_F_NET_DRAINING, &hn->hn_flags);
+       list_splice_init(&requests, &hn->hn_requests);
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+       while (!list_empty(&requests)) {
+               req = list_first_entry(&requests, struct handshake_req, hr_list);
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 5df102534a596f..75562f6629e050 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -168,12 +168,12 @@ static bool remove_pending(struct handshake_net *hn, struct handshake_req *req)
+ {
+       bool ret = false;
+-      spin_lock(&hn->hn_lock);
++      spin_lock_bh(&hn->hn_lock);
+       if (!list_empty(&req->hr_list)) {
+               __remove_pending_locked(hn, req);
+               ret = true;
+       }
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+       return ret;
+ }
+@@ -183,7 +183,7 @@ struct handshake_req *handshake_req_next(struct handshake_net *hn, int class)
+       struct handshake_req *req, *pos;
+       req = NULL;
+-      spin_lock(&hn->hn_lock);
++      spin_lock_bh(&hn->hn_lock);
+       list_for_each_entry(pos, &hn->hn_requests, hr_list) {
+               if (pos->hr_proto->hp_handler_class != class)
+                       continue;
+@@ -191,7 +191,7 @@ struct handshake_req *handshake_req_next(struct handshake_net *hn, int class)
+               req = pos;
+               break;
+       }
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+       return req;
+ }
+@@ -250,7 +250,7 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+       if (READ_ONCE(hn->hn_pending) >= hn->hn_pending_max)
+               goto out_err;
+-      spin_lock(&hn->hn_lock);
++      spin_lock_bh(&hn->hn_lock);
+       ret = -EOPNOTSUPP;
+       if (test_bit(HANDSHAKE_F_NET_DRAINING, &hn->hn_flags))
+               goto out_unlock;
+@@ -259,7 +259,7 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+               goto out_unlock;
+       if (!__add_pending_locked(hn, req))
+               goto out_unlock;
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+       ret = handshake_genl_notify(net, req->hr_proto, flags);
+       if (ret) {
+@@ -275,7 +275,7 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+       return 0;
+ out_unlock:
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+ out_err:
+       /* Restore original destructor so socket teardown still runs on failure */
+       req->hr_sk->sk_destruct = req->hr_odestruct;
+diff --git a/net/handshake/tlshd.c b/net/handshake/tlshd.c
+index 822507b87447c0..fd71ef2d18ceb2 100644
+--- a/net/handshake/tlshd.c
++++ b/net/handshake/tlshd.c
+@@ -419,6 +419,8 @@ EXPORT_SYMBOL(tls_server_hello_psk);
+  * Request cancellation races with request completion. To determine
+  * who won, callers examine the return value from this function.
+  *
++ * Context: May be called from process or softirq context.
++ *
+  * Return values:
+  *   %true - Uncompleted handshake request was canceled
+  *   %false - Handshake request already completed or not found
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-hsr-fix-potential-oob-access-in-supervision-fram.patch b/queue-6.12/net-hsr-fix-potential-oob-access-in-supervision-fram.patch
new file mode 100644 (file)
index 0000000..9d950a6
--- /dev/null
@@ -0,0 +1,48 @@
+From 4453632aeb4955287c7963dcadf7e21ab15260db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 May 2026 15:03:30 +0200
+Subject: net: hsr: fix potential OOB access in supervision frame handling
+
+From: Luka Gejak <luka.gejak@linux.dev>
+
+[ Upstream commit f229426072fc865654a60978bb7fda790a051ff3 ]
+
+Ensure the entire TLV header is linearized before access by adding
+sizeof(struct hsr_sup_tlv) to the pskb_may_pull() calls. Without this,
+a truncated frame could cause an out-of-bounds access.
+
+Fixes: eafaa88b3eb7 ("net: hsr: Add support for redbox supervision frames")
+Signed-off-by: Luka Gejak <luka.gejak@linux.dev>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260523130330.61880-1-luka.gejak@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_forward.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index fa97405c517c70..e3037741a74895 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -84,7 +84,7 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb)
+       /* Get next tlv */
+       total_length += hsr_sup_tag->tlv.HSR_TLV_length;
+-      if (!pskb_may_pull(skb, total_length))
++      if (!pskb_may_pull(skb, total_length + sizeof(struct hsr_sup_tlv)))
+               return false;
+       skb_pull(skb, total_length);
+       hsr_sup_tlv = (struct hsr_sup_tlv *)skb->data;
+@@ -100,7 +100,7 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb)
+               /* make sure another tlv follows */
+               total_length += sizeof(struct hsr_sup_tlv) + hsr_sup_tlv->HSR_TLV_length;
+-              if (!pskb_may_pull(skb, total_length))
++              if (!pskb_may_pull(skb, total_length + sizeof(struct hsr_sup_tlv)))
+                       return false;
+               /* get next tlv */
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-introduce-skb-tc-depth-field-to-track-packet-loo.patch b/queue-6.12/net-introduce-skb-tc-depth-field-to-track-packet-loo.patch
new file mode 100644 (file)
index 0000000..7e7567a
--- /dev/null
@@ -0,0 +1,95 @@
+From 90e38873af8af2d4ba92f811b83ad66bc4b1a203 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:48 -0400
+Subject: net: Introduce skb tc depth field to track packet loops
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit 98b34f3e8c3492cfc89ff943c9d92b4d52863d1d ]
+
+Add a 2-bit per-skb tc depth field to track packet loops across the stack.
+
+The previous per-CPU loop counters like MIRRED_NEST_LIMIT
+assume a single call stack and lose state in two cases:
+1) When a packet is queued and reprocessed later (e.g., egress->ingress
+   via backlog), the per-cpu state is gone by the time it is dequeued.
+2) With XPS/RPS a packet may arrive on one CPU and be processed on
+   another.
+
+A per-skb field solves both by travelling with the packet itself.
+
+The field fits in existing padding, using 2 bits that were previously a
+hole:
+
+pahole before(-) and after (+) diff looks like:
+   __u8       slow_gro:1;           /*   132: 3  1 */
+   __u8       csum_not_inet:1;      /*   132: 4  1 */
+   __u8       unreadable:1;         /*   132: 5  1 */
+ + __u8       tc_depth:2;           /*   132: 6  1 */
+
+ - /* XXX 2 bits hole, try to pack */
+   /* XXX 1 byte hole, try to pack */
+
+   __u16      tc_index;             /*   134     2 */
+
+There used to be a ttl field which was removed as part of tc_verd in commit
+aec745e2c520 ("net-tc: remove unused tc_verd fields").  It was already
+unused by that time, due to remove earlier in commit c19ae86a510c ("tc: remove
+unused redirect ttl").
+
+The first user of this field is netem, which increments tc_depth on
+duplicated packets before re-enqueueing them at the root qdisc.  On
+re-entry, netem skips duplication for any skb with tc_depth already set,
+bounding recursion to a single level regardless of tree topology.
+
+The other user is mirred which increments it on each pass
+and limits to depth to MIRRED_DEFER_LIMIT (3).
+
+The new field was called ttl in earlier versions of this patch
+but renamed to tc_depth to avoid confusion with IP ttl.
+
+Note (looking at you Sashiko! Dont ignore me and continue bringing this up):
+1. Since both mirred and netem utilize the same 2-bit tc_depth field it is
+   possible when netem and mirred are used together that netem qdisc to skip
+   the duplication step. This is a known trade-off, as a 2-bit field cannot
+   independently track both features' recursion depths and it is not considered
+   sane to have a setup that addresses both features on at the same time.
+
+2. skb_scrub_packet does not clear tc_depth. This means a packet's loop history
+  is preserved even across namespaces. While this might be restrictive for
+  some topologies, it is also design intent to provide robustness against loops
+  across namespaces.
+
+Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-2-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: e80ad525fc7e ("net/sched: act_mirred: Fix return code in early mirred redirect error paths")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/skbuff.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 4344724a978212..107a8c3ff07fa2 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -802,6 +802,7 @@ enum skb_tstamp_type {
+  *    @_sk_redir: socket redirection information for skmsg
+  *    @_nfct: Associated connection, if any (with nfctinfo bits)
+  *    @skb_iif: ifindex of device we arrived on
++ *    @tc_depth: counter for packet duplication
+  *    @tc_index: Traffic control index
+  *    @hash: the packet hash
+  *    @queue_mapping: Queue mapping for multiqueue devices
+@@ -1011,6 +1012,7 @@ struct sk_buff {
+       __u8                    csum_not_inet:1;
+ #endif
+       __u8                    unreadable:1;
++      __u8                    tc_depth:2;
+ #if defined(CONFIG_NET_SCHED) || defined(CONFIG_NET_XGRESS)
+       __u16                   tc_index;       /* traffic control index */
+ #endif
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-iucv-fix-locking-in-.getsockopt.patch b/queue-6.12/net-iucv-fix-locking-in-.getsockopt.patch
new file mode 100644 (file)
index 0000000..0ba5202
--- /dev/null
@@ -0,0 +1,87 @@
+From e2a2f772df0da114de96941796e67fd0b4ad4059 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 07:11:45 -0700
+Subject: net/iucv: fix locking in .getsockopt
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 3589d20a666caf30ad100c960a2de7de390fce88 ]
+
+Mirror iucv_sock_setsockopt() and wrap the whole switch in
+lock_sock()/release_sock(). The pre-existing SO_MSGLIMIT-only lock
+becomes redundant and is removed.
+
+Any AF_IUCV HIPER user can potentially crash the kernel by racing
+recvmsg() with getsockopt(SO_MSGSIZE): the SO_MSGSIZE arm dereferences
+iucv->hs_dev->mtu after iucv_sock_close() (called from the racing
+recvmsg()) has set hs_dev to NULL, producing a NULL pointer dereference
+oops.
+
+Suggested-by: Stanislav Fomichev <sdf.kernel@gmail.com>
+Fixes: 51363b8751a6 ("af_iucv: allow retrieval of maximum message size")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Tested-by: Alexandra Winter <wintera@linux.ibm.com>
+Link: https://patch.msgid.link/20260521-af_iucv_fix2-v1-1-f16b1c510aa9@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index 7929df08d4e023..1a0b41fcea8131 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -1537,7 +1537,7 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       struct sock *sk = sock->sk;
+       struct iucv_sock *iucv = iucv_sk(sk);
+       unsigned int val;
+-      int len;
++      int len, rc;
+       if (level != SOL_IUCV)
+               return -ENOPROTOOPT;
+@@ -1550,26 +1550,34 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       len = min_t(unsigned int, len, sizeof(int));
++      rc = 0;
++
++      lock_sock(sk);
+       switch (optname) {
+       case SO_IPRMDATA_MSG:
+               val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0;
+               break;
+       case SO_MSGLIMIT:
+-              lock_sock(sk);
+               val = (iucv->path != NULL) ? iucv->path->msglim /* connected */
+                                          : iucv->msglimit;    /* default */
+-              release_sock(sk);
+               break;
+       case SO_MSGSIZE:
+-              if (sk->sk_state == IUCV_OPEN)
+-                      return -EBADFD;
++              if (sk->sk_state == IUCV_OPEN) {
++                      rc = -EBADFD;
++                      break;
++              }
+               val = (iucv->hs_dev) ? iucv->hs_dev->mtu -
+                               sizeof(struct af_iucv_trans_hdr) - ETH_HLEN :
+                               0x7fffffff;
+               break;
+       default:
+-              return -ENOPROTOOPT;
++              rc = -ENOPROTOOPT;
++              break;
+       }
++      release_sock(sk);
++
++      if (rc)
++              return rc;
+       if (put_user(len, optlen))
+               return -EFAULT;
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-mana-add-null-guards-in-teardown-path-to-prevent.patch b/queue-6.12/net-mana-add-null-guards-in-teardown-path-to-prevent.patch
new file mode 100644 (file)
index 0000000..fe676c4
--- /dev/null
@@ -0,0 +1,148 @@
+From 2b3bd98e4234b3cfbc959a8502ffa7f5525f648b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 01:08:24 -0700
+Subject: net: mana: Add NULL guards in teardown path to prevent panic on
+ attach failure
+
+From: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+
+[ Upstream commit 17bfe0a8c014ee1d542ad352cd6a0a505361664a ]
+
+When queue allocation fails partway through, the error cleanup frees
+and NULLs apc->tx_qp and apc->rxqs. Multiple teardown paths such as
+mana_remove(), mana_change_mtu() recovery, and internal error handling
+in mana_alloc_queues() can subsequently call into functions that
+dereference these pointers without NULL checks:
+
+- mana_chn_setxdp() dereferences apc->rxqs[0], causing a NULL pointer
+  dereference panic (CR2: 0000000000000000 at mana_chn_setxdp+0x26).
+- mana_destroy_vport() iterates apc->rxqs without a NULL check.
+- mana_fence_rqs() iterates apc->rxqs without a NULL check.
+- mana_dealloc_queues() iterates apc->tx_qp without a NULL check.
+
+Add NULL guards for apc->rxqs in mana_fence_rqs(),
+mana_destroy_vport(), and before the mana_chn_setxdp() call. Add a
+NULL guard for apc->tx_qp in mana_dealloc_queues() to skip TX queue
+draining when TX queues were never allocated or already freed.
+
+Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
+Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+Link: https://patch.msgid.link/20260525081129.1230035-2-dipayanroy@linux.microsoft.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microsoft/mana/mana_en.c | 70 +++++++++++--------
+ 1 file changed, 41 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
+index e527139936dee4..0e4b0ac4acf86b 100644
+--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
+@@ -1304,6 +1304,9 @@ static void mana_fence_rqs(struct mana_port_context *apc)
+       struct mana_rxq *rxq;
+       int err;
++      if (!apc->rxqs)
++              return;
++
+       for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
+               rxq = apc->rxqs[rxq_idx];
+               err = mana_fence_rq(apc, rxq);
+@@ -2324,13 +2327,16 @@ static void mana_destroy_vport(struct mana_port_context *apc)
+       struct mana_rxq *rxq;
+       u32 rxq_idx;
+-      for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
+-              rxq = apc->rxqs[rxq_idx];
+-              if (!rxq)
+-                      continue;
++      if (apc->rxqs) {
+-              mana_destroy_rxq(apc, rxq, true);
+-              apc->rxqs[rxq_idx] = NULL;
++              for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
++                      rxq = apc->rxqs[rxq_idx];
++                      if (!rxq)
++                              continue;
++
++                      mana_destroy_rxq(apc, rxq, true);
++                      apc->rxqs[rxq_idx] = NULL;
++              }
+       }
+       mana_destroy_txq(apc);
+@@ -2633,7 +2639,8 @@ static int mana_dealloc_queues(struct net_device *ndev)
+       if (apc->port_is_up)
+               return -EINVAL;
+-      mana_chn_setxdp(apc, NULL);
++      if (apc->rxqs)
++              mana_chn_setxdp(apc, NULL);
+       if (gd->gdma_context->is_pf)
+               mana_pf_deregister_filter(apc);
+@@ -2651,33 +2658,38 @@ static int mana_dealloc_queues(struct net_device *ndev)
+        * number of queues.
+        */
+-      for (i = 0; i < apc->num_queues; i++) {
+-              txq = &apc->tx_qp[i].txq;
+-              tsleep = 1000;
+-              while (atomic_read(&txq->pending_sends) > 0 &&
+-                     time_before(jiffies, timeout)) {
+-                      usleep_range(tsleep, tsleep + 1000);
+-                      tsleep <<= 1;
+-              }
+-              if (atomic_read(&txq->pending_sends)) {
+-                      err = pcie_flr(to_pci_dev(gd->gdma_context->dev));
+-                      if (err) {
+-                              netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
+-                                         err, atomic_read(&txq->pending_sends),
+-                                         txq->gdma_txq_id);
++      if (apc->tx_qp) {
++              for (i = 0; i < apc->num_queues; i++) {
++                      txq = &apc->tx_qp[i].txq;
++                      tsleep = 1000;
++                      while (atomic_read(&txq->pending_sends) > 0 &&
++                             time_before(jiffies, timeout)) {
++                              usleep_range(tsleep, tsleep + 1000);
++                              tsleep <<= 1;
++                      }
++                      if (atomic_read(&txq->pending_sends)) {
++                              err =
++                                  pcie_flr(to_pci_dev(gd->gdma_context->dev));
++                              if (err) {
++                                      netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
++                                                 err,
++                                          atomic_read(&txq->pending_sends),
++                                          txq->gdma_txq_id);
++                              }
++                              break;
+                       }
+-                      break;
+               }
+-      }
+-      for (i = 0; i < apc->num_queues; i++) {
+-              txq = &apc->tx_qp[i].txq;
+-              while ((skb = skb_dequeue(&txq->pending_skbs))) {
+-                      mana_unmap_skb(skb, apc);
+-                      dev_kfree_skb_any(skb);
++              for (i = 0; i < apc->num_queues; i++) {
++                      txq = &apc->tx_qp[i].txq;
++                      while ((skb = skb_dequeue(&txq->pending_skbs))) {
++                              mana_unmap_skb(skb, apc);
++                              dev_kfree_skb_any(skb);
++                      }
++                      atomic_set(&txq->pending_sends, 0);
+               }
+-              atomic_set(&txq->pending_sends, 0);
+       }
++
+       /* We're 100% sure the queues can no longer be woken up, because
+        * we're sure now mana_poll_tx_cq() can't be running.
+        */
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-netlink-don-t-set-nsid-on-local-notifications.patch b/queue-6.12/net-netlink-don-t-set-nsid-on-local-notifications.patch
new file mode 100644 (file)
index 0000000..c3fcfd0
--- /dev/null
@@ -0,0 +1,82 @@
+From 840c55ccee1c046b863d71aec99dbb4728047aed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:36 +0200
+Subject: net: netlink: don't set nsid on local notifications
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 88b126b39f9757e9debc322d4679239e9af089c7 ]
+
+In most cases, notifications on sockets with NETLINK_LISTEN_ALL_NSID
+do not contain NSID in their ancillary data in case the event is local
+to the listener.
+
+However, when a self-referential NSID is allocated for a namespace,
+every local notification starts sending this ID to the user space.
+
+This is problematic, because the listener cannot tell if those
+notifications are local or not anymore without making extra requests
+to figure out if the provided NSID is local or not.  The listener
+can also not figure out the local NSID beforehand as it can be
+allocated at any point in time by other processes, changing the
+structure of the future notifications for everyone.
+
+The value is practically not useful, since it's the namespace's own
+ID that the application has to obtain from other sources in order to
+figure out if it's the same or not.  So, for the application it's
+just an extra busy work with no benefits.  Moreover, applications
+that do not know about this quirk may be mishandling notifications
+with NSID set as notifications from remote namespaces.  This is the
+case for ovs-vswitchd and the iproute2's 'ip monitor' that stops
+printing 'current' and starts printing the nsid number mid-session.
+
+Lack of clear documentation for this behavior is also not helping.
+
+A search though open-source projects doesn't reveal any projects
+that use NETNSA_NSID_NOT_ASSIGNED and rely on metadata to contain
+self-referential NSIDs (expected, since the value is not useful).
+Quite the opposite, as already mentioned, there are few applications
+that rely on NSID to not be present in local events.
+
+Since the value is not useful and actively harmful in some cases,
+let's not report it for local events, making the notifications more
+consistent.
+
+Also adding some blank lines for readability.
+
+Fixes: 59324cf35aba ("netlink: allow to listen "all" netns")
+Reported-by: Matteo Perin <matteo.perin@canonical.com>
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-3-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 287b4f921c607e..e250d4a3d03097 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1477,10 +1477,14 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++
+       NETLINK_CB(p->skb2).nsid_is_set = false;
+-      NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+-      if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+-              NETLINK_CB(p->skb2).nsid_is_set = true;
++      if (!net_eq(sock_net(sk), p->net)) {
++              NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
++              if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
++                      NETLINK_CB(p->skb2).nsid_is_set = true;
++      }
++
+       val = netlink_broadcast_deliver(sk, p->skb2);
+       if (val < 0) {
+               netlink_overrun(sk);
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-netlink-fix-sending-unassigned-nsid-after-assign.patch b/queue-6.12/net-netlink-fix-sending-unassigned-nsid-after-assign.patch
new file mode 100644 (file)
index 0000000..12ec1c3
--- /dev/null
@@ -0,0 +1,45 @@
+From 87ccc21623c7194078b291a9a5397cb505f4703d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:35 +0200
+Subject: net: netlink: fix sending unassigned nsid after assigned one
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 70f8592ee90585272018a725054b6eb2ab7e99ca ]
+
+If the current skb is not shared, it is re-used directly for all the
+sockets subscribed to the notification.  If we have remote all-nsid
+socket receiving a message first, then the 'nsid_is_set' will be
+set to 'true'.  If the nsid is NOT_ASSIGNED for the next socket in
+the list, the 'nsid_is_set' will remain 'true' and the negative value
+is be delivered to the user space.  All subsequent nsid values will be
+delivered as well, since there is no code path that sets the flag
+back to 'false'.
+
+Fix that by always dropping the flag to 'false' first.
+
+Fixes: 7212462fa6fd ("netlink: don't send unknown nsid")
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-2-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 8b060465a2be1a..287b4f921c607e 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1477,6 +1477,7 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++      NETLINK_CB(p->skb2).nsid_is_set = false;
+       NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+       if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+               NETLINK_CB(p->skb2).nsid_is_set = true;
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-sched-act_mirred-add-loop-detection.patch b/queue-6.12/net-sched-act_mirred-add-loop-detection.patch
new file mode 100644 (file)
index 0000000..4d27030
--- /dev/null
@@ -0,0 +1,170 @@
+From 05b0fe4883ca44e8dae070151229f3ada6ff0ba6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Oct 2025 17:19:04 +0000
+Subject: net/sched: act_mirred: add loop detection
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit fe946a751d9b52b7c45ca34899723b314b79b249 ]
+
+Commit 0f022d32c3ec ("net/sched: Fix mirred deadlock on device recursion")
+added code in the fast path, even when act_mirred is not used.
+
+Prepare its revert by implementing loop detection in act_mirred.
+
+Adds an array of device pointers in struct netdev_xmit.
+
+tcf_mirred_is_act_redirect() can detect if the array
+already contains the target device.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Tested-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20251014171907.3554413-4-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: e80ad525fc7e ("net/sched: act_mirred: Fix return code in early mirred redirect error paths")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netdevice_xmit.h |  9 ++++-
+ net/sched/act_mirred.c         | 62 +++++++++++++---------------------
+ 2 files changed, 31 insertions(+), 40 deletions(-)
+
+diff --git a/include/linux/netdevice_xmit.h b/include/linux/netdevice_xmit.h
+index 848735b3a7c02d..59726e6cd2cc67 100644
+--- a/include/linux/netdevice_xmit.h
++++ b/include/linux/netdevice_xmit.h
+@@ -2,6 +2,12 @@
+ #ifndef _LINUX_NETDEVICE_XMIT_H
+ #define _LINUX_NETDEVICE_XMIT_H
++#if IS_ENABLED(CONFIG_NET_ACT_MIRRED)
++#define MIRRED_NEST_LIMIT     4
++#endif
++
++struct net_device;
++
+ struct netdev_xmit {
+       u16 recursion;
+       u8  more;
+@@ -9,7 +15,8 @@ struct netdev_xmit {
+       u8  skip_txqueue;
+ #endif
+ #if IS_ENABLED(CONFIG_NET_ACT_MIRRED)
+-      u8 sched_mirred_nest;
++      u8                      sched_mirred_nest;
++      struct net_device       *sched_mirred_dev[MIRRED_NEST_LIMIT];
+ #endif
+ };
+diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
+index 18d9378a9c1134..35812b6808e0a8 100644
+--- a/net/sched/act_mirred.c
++++ b/net/sched/act_mirred.c
+@@ -29,31 +29,6 @@
+ static LIST_HEAD(mirred_list);
+ static DEFINE_SPINLOCK(mirred_list_lock);
+-#define MIRRED_NEST_LIMIT    4
+-
+-#ifndef CONFIG_PREEMPT_RT
+-static u8 tcf_mirred_nest_level_inc_return(void)
+-{
+-      return __this_cpu_inc_return(softnet_data.xmit.sched_mirred_nest);
+-}
+-
+-static void tcf_mirred_nest_level_dec(void)
+-{
+-      __this_cpu_dec(softnet_data.xmit.sched_mirred_nest);
+-}
+-
+-#else
+-static u8 tcf_mirred_nest_level_inc_return(void)
+-{
+-      return current->net_xmit.sched_mirred_nest++;
+-}
+-
+-static void tcf_mirred_nest_level_dec(void)
+-{
+-      current->net_xmit.sched_mirred_nest--;
+-}
+-#endif
+-
+ static bool tcf_mirred_is_act_redirect(int action)
+ {
+       return action == TCA_EGRESS_REDIR || action == TCA_INGRESS_REDIR;
+@@ -439,44 +414,53 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+ {
+       struct tcf_mirred *m = to_mirred(a);
+       int retval = READ_ONCE(m->tcf_action);
+-      unsigned int nest_level;
++      struct netdev_xmit *xmit;
+       bool m_mac_header_xmit;
+       struct net_device *dev;
+-      int m_eaction;
++      int i, m_eaction;
+       u32 blockid;
+-      nest_level = tcf_mirred_nest_level_inc_return();
+-      if (unlikely(nest_level > MIRRED_NEST_LIMIT)) {
++#ifdef CONFIG_PREEMPT_RT
++      xmit = &current->net_xmit;
++#else
++      xmit = this_cpu_ptr(&softnet_data.xmit);
++#endif
++      if (unlikely(xmit->sched_mirred_nest >= MIRRED_NEST_LIMIT)) {
+               net_warn_ratelimited("Packet exceeded mirred recursion limit on dev %s\n",
+                                    netdev_name(skb->dev));
+-              retval = TC_ACT_SHOT;
+-              goto dec_nest_level;
++              return TC_ACT_SHOT;
+       }
+       tcf_lastuse_update(&m->tcf_tm);
+       tcf_action_update_bstats(&m->common, skb);
+       blockid = READ_ONCE(m->tcfm_blockid);
+-      if (blockid) {
+-              retval = tcf_blockcast(skb, m, blockid, res, retval);
+-              goto dec_nest_level;
+-      }
++      if (blockid)
++              return tcf_blockcast(skb, m, blockid, res, retval);
+       dev = rcu_dereference_bh(m->tcfm_dev);
+       if (unlikely(!dev)) {
+               pr_notice_once("tc mirred: target device is gone\n");
+               tcf_action_inc_overlimit_qstats(&m->common);
+-              goto dec_nest_level;
++              return retval;
+       }
++      for (i = 0; i < xmit->sched_mirred_nest; i++) {
++              if (xmit->sched_mirred_dev[i] != dev)
++                      continue;
++              pr_notice_once("tc mirred: loop on device %s\n",
++                             netdev_name(dev));
++              tcf_action_inc_overlimit_qstats(&m->common);
++              return retval;
++      }
++
++      xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = dev;
+       m_mac_header_xmit = READ_ONCE(m->tcfm_mac_header_xmit);
+       m_eaction = READ_ONCE(m->tcfm_eaction);
+       retval = tcf_mirred_to_dev(skb, m, dev, m_mac_header_xmit, m_eaction,
+                                  retval);
+-
+-dec_nest_level:
+-      tcf_mirred_nest_level_dec();
++      xmit->sched_mirred_nest--;
+       return retval;
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-sched-act_mirred-fix-return-code-in-early-mirred.patch b/queue-6.12/net-sched-act_mirred-fix-return-code-in-early-mirred.patch
new file mode 100644 (file)
index 0000000..072145e
--- /dev/null
@@ -0,0 +1,99 @@
+From 0dbbbc2ab2ba3d6976cc0d0913a7e17b77f2ec3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:54 -0400
+Subject: net/sched: act_mirred: Fix return code in early mirred redirect error
+ paths
+
+From: Victor Nogueira <victor@mojatatu.com>
+
+[ Upstream commit e80ad525fc7e8c933ad78478c5dda286cfd55c60 ]
+
+Since retval is set as TC_ACT_STOLEN in the mirred redirect case, returning
+retval in cases where redirect failed will make the callers not register
+the skb as being dropped.
+
+Fix this by returning TC_ACT_SHOT instead in such scenarios.
+
+Fixes: 16085e48cb48 ("net/sched: act_mirred: Create function tcf_mirred_to_dev and improve readability")
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Closes: https://sashiko.dev/#/patchset/20260413082027.2244884-1-hxzene%40gmail.com
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-8-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_mirred.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
+index ae9b307ad66e0d..41b731176dfe77 100644
+--- a/net/sched/act_mirred.c
++++ b/net/sched/act_mirred.c
+@@ -363,7 +363,8 @@ static int tcf_blockcast_redir(struct sk_buff *skb, struct tcf_mirred *m,
+                                        dev_is_mac_header_xmit(dev_prev),
+                                        m_eaction, retval);
+-      return retval;
++      /* If the packet wasn't redirected, we have to register as a drop */
++      return TC_ACT_SHOT;
+ }
+ static int tcf_blockcast_mirror(struct sk_buff *skb, struct tcf_mirred *m,
+@@ -403,7 +404,7 @@ static int tcf_blockcast(struct sk_buff *skb, struct tcf_mirred *m,
+       block = tcf_block_lookup(dev_net(skb->dev), blockid);
+       if (!block || xa_empty(&block->ports)) {
+               tcf_action_inc_overlimit_qstats(&m->common);
+-              return retval;
++              return is_redirect ? TC_ACT_SHOT : retval;
+       }
+       if (is_redirect)
+@@ -421,8 +422,8 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+ {
+       struct tcf_mirred *m = to_mirred(a);
+       int retval = READ_ONCE(m->tcf_action);
++      bool m_mac_header_xmit, is_redirect;
+       struct netdev_xmit *xmit;
+-      bool m_mac_header_xmit;
+       struct net_device *dev;
+       bool want_ingress;
+       int i, m_eaction;
+@@ -447,11 +448,13 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+       if (blockid)
+               return tcf_blockcast(skb, m, blockid, res, retval);
++      is_redirect = tcf_mirred_is_act_redirect(m_eaction);
++
+       dev = rcu_dereference_bh(m->tcfm_dev);
+       if (unlikely(!dev)) {
+               pr_notice_once("tc mirred: target device is gone\n");
+               tcf_action_inc_overlimit_qstats(&m->common);
+-              return retval;
++              goto err_out;
+       }
+       m_eaction = READ_ONCE(m->tcfm_eaction);
+@@ -463,7 +466,7 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+                       pr_notice_once("tc mirred: loop on device %s\n",
+                                      netdev_name(dev));
+                       tcf_action_inc_overlimit_qstats(&m->common);
+-                      return retval;
++                      goto err_out;
+               }
+               xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = dev;
+       }
+@@ -476,6 +479,11 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+               xmit->sched_mirred_nest--;
+       return retval;
++
++err_out:
++      if (is_redirect)
++              retval = TC_ACT_SHOT;
++      return retval;
+ }
+ static void tcf_stats_update(struct tc_action *a, u64 bytes, u64 packets,
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-sched-act_mirred-move-the-recursion-counter-stru.patch b/queue-6.12/net-sched-act_mirred-move-the-recursion-counter-stru.patch
new file mode 100644 (file)
index 0000000..0dd38f5
--- /dev/null
@@ -0,0 +1,99 @@
+From e1bd679da06931529a67c291b565cee93887021a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 May 2025 11:27:31 +0200
+Subject: net/sched: act_mirred: Move the recursion counter struct netdev_xmit
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit 7fe70c06a182a140be9996b02256d907e114479a ]
+
+mirred_nest_level is a per-CPU variable and relies on disabled BH for its
+locking. Without per-CPU locking in local_bh_disable() on PREEMPT_RT
+this data structure requires explicit locking.
+
+Move mirred_nest_level to struct netdev_xmit as u8, provide wrappers.
+
+Cc: Jamal Hadi Salim <jhs@mojatatu.com>
+Cc: Cong Wang <xiyou.wangcong@gmail.com>
+Cc: Jiri Pirko <jiri@resnulli.us>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Reviewed-by: Juri Lelli <juri.lelli@redhat.com>
+Link: https://patch.msgid.link/20250512092736.229935-11-bigeasy@linutronix.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: e80ad525fc7e ("net/sched: act_mirred: Fix return code in early mirred redirect error paths")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netdevice_xmit.h |  3 +++
+ net/sched/act_mirred.c         | 28 +++++++++++++++++++++++++---
+ 2 files changed, 28 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/netdevice_xmit.h b/include/linux/netdevice_xmit.h
+index 38325e07029685..848735b3a7c02d 100644
+--- a/include/linux/netdevice_xmit.h
++++ b/include/linux/netdevice_xmit.h
+@@ -8,6 +8,9 @@ struct netdev_xmit {
+ #ifdef CONFIG_NET_EGRESS
+       u8  skip_txqueue;
+ #endif
++#if IS_ENABLED(CONFIG_NET_ACT_MIRRED)
++      u8 sched_mirred_nest;
++#endif
+ };
+ #endif
+diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
+index b1b0049d7a0e9d..18d9378a9c1134 100644
+--- a/net/sched/act_mirred.c
++++ b/net/sched/act_mirred.c
+@@ -30,7 +30,29 @@ static LIST_HEAD(mirred_list);
+ static DEFINE_SPINLOCK(mirred_list_lock);
+ #define MIRRED_NEST_LIMIT    4
+-static DEFINE_PER_CPU(unsigned int, mirred_nest_level);
++
++#ifndef CONFIG_PREEMPT_RT
++static u8 tcf_mirred_nest_level_inc_return(void)
++{
++      return __this_cpu_inc_return(softnet_data.xmit.sched_mirred_nest);
++}
++
++static void tcf_mirred_nest_level_dec(void)
++{
++      __this_cpu_dec(softnet_data.xmit.sched_mirred_nest);
++}
++
++#else
++static u8 tcf_mirred_nest_level_inc_return(void)
++{
++      return current->net_xmit.sched_mirred_nest++;
++}
++
++static void tcf_mirred_nest_level_dec(void)
++{
++      current->net_xmit.sched_mirred_nest--;
++}
++#endif
+ static bool tcf_mirred_is_act_redirect(int action)
+ {
+@@ -423,7 +445,7 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+       int m_eaction;
+       u32 blockid;
+-      nest_level = __this_cpu_inc_return(mirred_nest_level);
++      nest_level = tcf_mirred_nest_level_inc_return();
+       if (unlikely(nest_level > MIRRED_NEST_LIMIT)) {
+               net_warn_ratelimited("Packet exceeded mirred recursion limit on dev %s\n",
+                                    netdev_name(skb->dev));
+@@ -454,7 +476,7 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+                                  retval);
+ dec_nest_level:
+-      __this_cpu_dec(mirred_nest_level);
++      tcf_mirred_nest_level_dec();
+       return retval;
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-sched-fix-ethx-ingress-ethy-egress-ethx-ingress-.patch b/queue-6.12/net-sched-fix-ethx-ingress-ethy-egress-ethx-ingress-.patch
new file mode 100644 (file)
index 0000000..4a9b5db
--- /dev/null
@@ -0,0 +1,136 @@
+From 3baa1fb4063a7688344267fcbce344fced937bc5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:52 -0400
+Subject: net/sched: Fix ethx:ingress -> ethy:egress -> ethx:ingress mirred
+ loop
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit db875221ab08d213a83bf30196ae8b64d55a3403 ]
+
+When mirred redirects to ingress (from either ingress or egress) the loop
+state from sched_mirred_dev array dev is lost because of 1) the packet
+deferral into the backlog and 2) the fact the sched_mirred_dev array is
+cleared. In such cases, if there was a loop we won't discover it.
+
+Here's a simple test to reproduce:
+ip a add dev port0 10.10.10.11/24
+
+tc qdisc add dev port0 clsact
+tc filter add dev port0 egress protocol ip \
+   prio 10 matchall action mirred ingress redirect dev port1
+
+tc qdisc add dev port1 clsact
+tc filter add dev port1 ingress protocol ip \
+   prio 10 matchall action mirred egress redirect dev port0
+
+ping -c 1 -W0.01 10.10.10.10
+
+Fixes: fe946a751d9b ("net/sched: act_mirred: add loop detection")
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-6-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: e80ad525fc7e ("net/sched: act_mirred: Fix return code in early mirred redirect error paths")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_mirred.c | 47 +++++++++++++++++++++++++++---------------
+ 1 file changed, 30 insertions(+), 17 deletions(-)
+
+diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
+index 35812b6808e0a8..ae9b307ad66e0d 100644
+--- a/net/sched/act_mirred.c
++++ b/net/sched/act_mirred.c
+@@ -26,6 +26,10 @@
+ #include <net/tc_act/tc_mirred.h>
+ #include <net/tc_wrapper.h>
++#define MIRRED_DEFER_LIMIT 3
++_Static_assert(MIRRED_DEFER_LIMIT <= 3,
++             "MIRRED_DEFER_LIMIT exceeds tc_depth bitfield width");
++
+ static LIST_HEAD(mirred_list);
+ static DEFINE_SPINLOCK(mirred_list_lock);
+@@ -234,12 +238,15 @@ tcf_mirred_forward(bool at_ingress, bool want_ingress, struct sk_buff *skb)
+ {
+       int err;
+-      if (!want_ingress)
++      if (!want_ingress) {
+               err = tcf_dev_queue_xmit(skb, dev_queue_xmit);
+-      else if (!at_ingress)
+-              err = netif_rx(skb);
+-      else
+-              err = netif_receive_skb(skb);
++      } else {
++              skb->tc_depth++;
++              if (!at_ingress)
++                      err = netif_rx(skb);
++              else
++                      err = netif_receive_skb(skb);
++      }
+       return err;
+ }
+@@ -417,6 +424,7 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+       struct netdev_xmit *xmit;
+       bool m_mac_header_xmit;
+       struct net_device *dev;
++      bool want_ingress;
+       int i, m_eaction;
+       u32 blockid;
+@@ -425,7 +433,8 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+ #else
+       xmit = this_cpu_ptr(&softnet_data.xmit);
+ #endif
+-      if (unlikely(xmit->sched_mirred_nest >= MIRRED_NEST_LIMIT)) {
++      if (unlikely(xmit->sched_mirred_nest >= MIRRED_NEST_LIMIT ||
++                   skb->tc_depth >= MIRRED_DEFER_LIMIT)) {
+               net_warn_ratelimited("Packet exceeded mirred recursion limit on dev %s\n",
+                                    netdev_name(skb->dev));
+               return TC_ACT_SHOT;
+@@ -444,23 +453,27 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+               tcf_action_inc_overlimit_qstats(&m->common);
+               return retval;
+       }
+-      for (i = 0; i < xmit->sched_mirred_nest; i++) {
+-              if (xmit->sched_mirred_dev[i] != dev)
+-                      continue;
+-              pr_notice_once("tc mirred: loop on device %s\n",
+-                             netdev_name(dev));
+-              tcf_action_inc_overlimit_qstats(&m->common);
+-              return retval;
+-      }
+-      xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = dev;
++      m_eaction = READ_ONCE(m->tcfm_eaction);
++      want_ingress = tcf_mirred_act_wants_ingress(m_eaction);
++      if (!want_ingress) {
++              for (i = 0; i < xmit->sched_mirred_nest; i++) {
++                      if (xmit->sched_mirred_dev[i] != dev)
++                              continue;
++                      pr_notice_once("tc mirred: loop on device %s\n",
++                                     netdev_name(dev));
++                      tcf_action_inc_overlimit_qstats(&m->common);
++                      return retval;
++              }
++              xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = dev;
++      }
+       m_mac_header_xmit = READ_ONCE(m->tcfm_mac_header_xmit);
+-      m_eaction = READ_ONCE(m->tcfm_eaction);
+       retval = tcf_mirred_to_dev(skb, m, dev, m_mac_header_xmit, m_eaction,
+                                  retval);
+-      xmit->sched_mirred_nest--;
++      if (!want_ingress)
++              xmit->sched_mirred_nest--;
+       return retval;
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-sched-fix-packet-loop-on-netem-when-duplicate-is.patch b/queue-6.12/net-sched-fix-packet-loop-on-netem-when-duplicate-is.patch
new file mode 100644 (file)
index 0000000..554070d
--- /dev/null
@@ -0,0 +1,71 @@
+From 17b4e7dc1eb95443953d4bd2d4fea853e48dc36a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:51 -0400
+Subject: net/sched: fix packet loop on netem when duplicate is on
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit 9552b11e3edabc97cfcd9f29103d5afbce7ae183 ]
+
+When netem duplicates a packet it re-enqueues the copy at the root qdisc.
+If another netem sits in the tree the copy can be duplicated
+again, recursing until the stack or memory is exhausted.
+
+The original duplication guard temporarily zeroed q->duplicate around
+the re-enqueue, but that does not cover all cases because it is
+per-qdisc state shared across all concurrent enqueue paths
+and is not safe without additional locking.
+
+Use the skb tc_depth field introduced in an earlier patch:
+ - increment it on the duplicate before re-enqueue
+ - skip duplication for any skb whose tc_depth is already non-zero.
+
+This marks the packet itself rather than mutating qdisc state,
+therefore it is safe regardless of tree topology or concurrency.
+
+Fixes: 0afb51e72855 ("[PKT_SCHED]: netem: reinsert for duplication")
+Reported-by: William Liu <will@willsroot.io>
+Reported-by: Savino Dicanosa <savy@syst3mfailure.io>
+Closes: https://lore.kernel.org/netdev/8DuRWwfqjoRDLDmBMlIfbrsZg9Gx50DHJc1ilxsEBNe2D6NMoigR_eIRIG0LOjMc3r10nUUZtArXx4oZBIdUfZQrwjcQhdinnMis_0G7VEk=@willsroot.io/
+Co-developed-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Reviewed-by: William Liu <will@willsroot.io>
+Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-5-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_netem.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
+index 1fdebf2ab7ee46..136b7d81296eff 100644
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -459,7 +459,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+       skb->prev = NULL;
+       /* Random duplication */
+-      if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor, &q->prng))
++      if (q->duplicate && skb->tc_depth == 0 &&
++          q->duplicate >= get_crandom(&q->dup_cor, &q->prng))
+               ++count;
+       /* Drop packet? */
+@@ -538,11 +539,9 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+        */
+       if (skb2) {
+               struct Qdisc *rootq = qdisc_root_bh(sch);
+-              u32 dupsave = q->duplicate; /* prevent duplicating a dup... */
+-              q->duplicate = 0;
++              skb2->tc_depth++; /* prevent duplicating a dup... */
+               rootq->enqueue(skb2, rootq, to_free);
+-              q->duplicate = dupsave;
+               skb2 = NULL;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-sched-revert-net-sched-restrict-conditions-for-a.patch b/queue-6.12/net-sched-revert-net-sched-restrict-conditions-for-a.patch
new file mode 100644 (file)
index 0000000..9081d56
--- /dev/null
@@ -0,0 +1,102 @@
+From 73f565fe71ea2136ff92eb2bac6514e173d7debc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:49 -0400
+Subject: net/sched: Revert "net/sched: Restrict conditions for adding
+ duplicating netems to qdisc tree"
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit eda0b7f203bb166c98d1418b204135bd566ac83b ]
+
+This reverts commit ec8e0e3d7adef940cdf9475e2352c0680189d14e.
+
+The original patch rejects any tree containing two netems when
+either has duplication set, even when they sit on unrelated classes
+of the same classful parent. That broke configurations that have
+worked since netem was introduced.
+
+The re-entrancy problem the original commit was trying to solve is
+handled by later patch using tc_depth flag.
+
+Doing this revert will (re)expose the original bug with multiple
+netem duplication. When this patch is backported make sure
+and get the full series.
+
+Fixes: ec8e0e3d7ade ("net/sched: Restrict conditions for adding duplicating netems to qdisc tree")
+Reported-by: Ji-Soo Chung <jschung2@proton.me>
+Reported-by: Gerlinde <lrGerlinde@mailfence.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220774
+Reported-by: zyc zyc <zyc199902@zohomail.cn>
+Closes: https://lore.kernel.org/all/19adda5a1e2.12410b78222774.9191120410578703463@zohomail.cn/
+Reported-by: Manas Ghandat <ghandatmanas@gmail.com>
+Closes: https://lore.kernel.org/netdev/f69b2c8f-8325-4c2e-a011-6dbc089f30e4@gmail.com/
+Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-3-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_netem.c | 40 ----------------------------------------
+ 1 file changed, 40 deletions(-)
+
+diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
+index 498c18d7d9c39b..1fdebf2ab7ee46 100644
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -1005,41 +1005,6 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
+       return 0;
+ }
+-static const struct Qdisc_class_ops netem_class_ops;
+-
+-static int check_netem_in_tree(struct Qdisc *sch, bool duplicates,
+-                             struct netlink_ext_ack *extack)
+-{
+-      struct Qdisc *root, *q;
+-      unsigned int i;
+-
+-      root = qdisc_root_sleeping(sch);
+-
+-      if (sch != root && root->ops->cl_ops == &netem_class_ops) {
+-              if (duplicates ||
+-                  ((struct netem_sched_data *)qdisc_priv(root))->duplicate)
+-                      goto err;
+-      }
+-
+-      if (!qdisc_dev(root))
+-              return 0;
+-
+-      hash_for_each(qdisc_dev(root)->qdisc_hash, i, q, hash) {
+-              if (sch != q && q->ops->cl_ops == &netem_class_ops) {
+-                      if (duplicates ||
+-                          ((struct netem_sched_data *)qdisc_priv(q))->duplicate)
+-                              goto err;
+-              }
+-      }
+-
+-      return 0;
+-
+-err:
+-      NL_SET_ERR_MSG(extack,
+-                     "netem: cannot mix duplicating netems with other netems in tree");
+-      return -EINVAL;
+-}
+-
+ /* Parse netlink message to set options */
+ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+                       struct netlink_ext_ack *extack)
+@@ -1116,11 +1081,6 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+       q->gap = qopt->gap;
+       q->counter = 0;
+       q->loss = qopt->loss;
+-
+-      ret = check_netem_in_tree(sch, qopt->duplicate, extack);
+-      if (ret)
+-              goto unlock;
+-
+       q->duplicate = qopt->duplicate;
+       /* for compatibility with earlier versions.
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch b/queue-6.12/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch
new file mode 100644 (file)
index 0000000..1011920
--- /dev/null
@@ -0,0 +1,64 @@
+From bd33ff9a6462c8f47edb5a624bede3a0f5cab6dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 May 2026 19:43:53 +0100
+Subject: net: skbuff: fix pskb_carve leaking zcopy pages
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit ff6e798c2eac3ebd0501ad7e796f583fab928de8 ]
+
+When SKBFL_MANAGED_FRAG_REFS is set, frag pages are not refcounted but
+their lifetime is controlled by the attached ubuf_info. To make a copy
+of the skb_shared_info, we either should clear the flag and reference
+the frags, or keep the flag and have frags unreferenced.
+
+pskb_carve_inside_header() and pskb_carve_inside_nonlinear() don't
+follow the rule and thus can leak page references. Let's clear
+SKBFL_MANAGED_FRAG_REFS from the original skb to fix it. It's the
+simplest way to address it, but there are more performant ways to do
+that if it ever becomes a problem.
+
+Link: https://lore.kernel.org/all/20260523085809.26331-1-nvminh232@clc.fitus.edu.vn/
+Fixes: 753f1ca4e1e50 ("net: introduce managed frags infrastructure")
+Reported-by: Minh Nguyen <minhnguyen.080505@gmail.com>
+Reported-by: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/1e2086aa69217d7f9c8da3d38f5be7160f1b4cd1.1779993185.git.asml.silence@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 8c9f026182a6f0..c8653ed1991ae0 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -6689,6 +6689,11 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
+       skb_copy_from_linear_data_offset(skb, off, data, new_hlen);
+       skb->len -= off;
++      /* Remove SKBFL_MANAGED_FRAG_REFS instead of trying to honour it
++       * while refcounting frags below.
++       */
++      skb_zcopy_downgrade_managed(skb);
++
+       memcpy((struct skb_shared_info *)(data + size),
+              skb_shinfo(skb),
+              offsetof(struct skb_shared_info,
+@@ -6801,6 +6806,11 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,
+               return -ENOMEM;
+       size = SKB_WITH_OVERHEAD(size);
++      /* Remove SKBFL_MANAGED_FRAG_REFS instead of trying to honour it
++       * while refcounting frags below.
++       */
++      skb_zcopy_downgrade_managed(skb);
++
+       memcpy((struct skb_shared_info *)(data + size),
+              skb_shinfo(skb), offsetof(struct skb_shared_info, frags[0]));
+       if (skb_orphan_frags(skb, gfp_mask)) {
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-smc-do-not-re-initialize-smc-hashtables.patch b/queue-6.12/net-smc-do-not-re-initialize-smc-hashtables.patch
new file mode 100644 (file)
index 0000000..e04e490
--- /dev/null
@@ -0,0 +1,59 @@
+From 6f8d315da8edbeca5a96360e65f25bbe546c3bde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 16:56:39 +0200
+Subject: net/smc: Do not re-initialize smc hashtables
+
+From: Alexandra Winter <wintera@linux.ibm.com>
+
+[ Upstream commit 9e4389b0038781f19f97895186ed941ff8ac1678 ]
+
+INIT_HLIST_HEAD(&smc_v*_hashinfo.ht) are called after smc_nl_init(),
+proto_register() and sock_register(). This can lead to smc_v*_hashinfo.ht
+being reset even though hash entries already exist and are being used,
+possibly resulting in a corrupted list.
+
+Remove unnecessary and dangerous re-initialisation of smc_v*_hashinfo.ht in
+smc_init(); it is implicitly initialised to zero anyhow. Add
+HLIST_HEAD_INIT to the definitions for clarity.
+
+Fixes: f16a7dd5cf27 ("smc: netlink interface for SMC sockets")
+Suggested-by: Halil Pasic <pasic@linux.ibm.com>
+Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
+Acked-by: Halil Pasic <pasic@linux.ibm.com>
+Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
+Link: https://patch.msgid.link/20260521145639.10317-1-wintera@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index c96abb1386be4b..6f3469ad54a165 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -187,10 +187,12 @@ static bool smc_hs_congested(const struct sock *sk)
+ struct smc_hashinfo smc_v4_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v4_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ struct smc_hashinfo smc_v6_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v6_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ int smc_hash_sk(struct sock *sk)
+@@ -3594,8 +3596,6 @@ static int __init smc_init(void)
+               pr_err("%s: sock_register fails with %d\n", __func__, rc);
+               goto out_proto6;
+       }
+-      INIT_HLIST_HEAD(&smc_v4_hashinfo.ht);
+-      INIT_HLIST_HEAD(&smc_v6_hashinfo.ht);
+       rc = smc_ib_register_client();
+       if (rc) {
+-- 
+2.53.0
+
diff --git a/queue-6.12/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch b/queue-6.12/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
new file mode 100644 (file)
index 0000000..8af1234
--- /dev/null
@@ -0,0 +1,107 @@
+From 93d5aa2ceb11b27e7ae2c6ea1e0f2865c1cb4667 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 22:52:07 +0200
+Subject: netfilter: ebtables: fix OOB read in compat_mtw_from_user
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit f438d1786d657d57790c5d138d6db3fc9fdac392 ]
+
+Luxiao Xu says:
+
+ The function compat_mtw_from_user() converts ebtables extensions from
+ 32-bit user structures to kernel native structures. However, it lacks
+ proper validation of the user-supplied match_size/target_size.
+
+ When certain extensions are processed, the kernel-side translation
+ logic may perform memory accesses based on the extension's expected
+ size. If the user provides a size smaller than what the extension
+ requires, it results in an out-of-bounds read as reported by KASAN.
+
+ This fix introduces a check to ensure match_size is at least as large
+ as the extension's required compatsize. This covers matches, watchers,
+ and targets, while maintaining compatibility with standard targets.
+
+AFAIU this is relevant for matches that need to go though
+match->compat_from_user() call.  Those that use plain memcpy with the
+user-provided size are ok because the caller checks that size vs the
+start of the next rule entry offset (which itself is checked vs. total
+size copied from userspace).
+
+The ->compat_from_user() callbacks assume they can read compatsize bytes,
+so they need this extra check.
+
+Based on an earlier patch from Luxiao Xu.
+
+Fixes: 81e675c227ec ("netfilter: ebtables: add CONFIG_COMPAT support")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/netfilter/ebtables.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
+index a461c59ad28595..1bc7b5d8f76d7a 100644
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1952,6 +1952,25 @@ enum compat_mwt {
+       EBT_COMPAT_TARGET,
+ };
++static bool match_size_ok(const struct xt_match *match, unsigned int match_size)
++{
++      u16 csize;
++
++      if (match->matchsize == -1) /* cannot validate ebt_among */
++              return true;
++
++      csize = match->compatsize ? : match->matchsize;
++
++      return match_size >= csize;
++}
++
++static bool tgt_size_ok(const struct xt_target *tgt, unsigned int tgt_size)
++{
++      u16 csize = tgt->compatsize ? : tgt->targetsize;
++
++      return tgt_size >= csize;
++}
++
+ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                               enum compat_mwt compat_mwt,
+                               struct ebt_entries_buf_state *state,
+@@ -1977,6 +1996,11 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+               if (IS_ERR(match))
+                       return PTR_ERR(match);
++              if (!match_size_ok(match, match_size)) {
++                      module_put(match->me);
++                      return -EINVAL;
++              }
++
+               off = ebt_compat_match_offset(match, match_size);
+               if (dst) {
+                       if (match->compat_from_user)
+@@ -1996,6 +2020,12 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                                           mwt->u.revision);
+               if (IS_ERR(wt))
+                       return PTR_ERR(wt);
++
++              if (!tgt_size_ok(wt, match_size)) {
++                      module_put(wt->me);
++                      return -EINVAL;
++              }
++
+               off = xt_compat_target_offset(wt);
+               if (dst) {
+-- 
+2.53.0
+
diff --git a/queue-6.12/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch b/queue-6.12/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
new file mode 100644 (file)
index 0000000..bbffcf6
--- /dev/null
@@ -0,0 +1,68 @@
+From a3f3f69a35f27105f687f284f50ac318b03783e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 12:36:14 -0700
+Subject: netfilter: synproxy: refresh tcphdr after skb_ensure_writable
+
+From: Chris Mason <clm@meta.com>
+
+[ Upstream commit 92170e6afe927ab2792a3f71902845789c8e31b1 ]
+
+synproxy_tstamp_adjust() rewrites the TCP timestamp option in place
+and then patches the TCP checksum via inet_proto_csum_replace4() on
+the caller-supplied tcphdr pointer.  Both ipv4_synproxy_hook() and
+ipv6_synproxy_hook() obtain that pointer with skb_header_pointer()
+before calling in, so it may either alias skb->head directly or
+point at the caller's on-stack _tcph buffer.
+
+Between obtaining the pointer and using it, the function calls
+skb_ensure_writable(skb, optend), which on a cloned or non-linear
+skb invokes pskb_expand_head() and frees the old skb->head.  After
+that point the cached th is stale:
+
+    caller (ipv[46]_synproxy_hook)
+      th = skb_header_pointer(skb, ..., &_tcph)
+      synproxy_tstamp_adjust(skb, protoff, th, ...)
+        skb_ensure_writable(skb, optend)
+          pskb_expand_head()        /* kfree(old skb->head) */
+        ...
+        inet_proto_csum_replace4(&th->check, ...)
+                                    /* writes into freed head, or
+                                       into the caller's stack copy
+                                       leaving the on-wire checksum
+                                       stale */
+
+The option bytes are written through skb->data and are fine; only
+the checksum update goes through th and so lands in the wrong
+place.  The result is either a write into freed slab memory or a
+packet leaving with a checksum that does not match its payload.
+
+Fix by re-deriving th from skb->data + protoff immediately after
+skb_ensure_writable() succeeds, so the subsequent checksum update
+targets the linear, writable header.
+
+Fixes: 48b1de4c110a ("netfilter: add SYNPROXY core/target")
+Assisted-by: kres (claude-opus-4-7)
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-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_synproxy_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c
+index 3fa3f5dfb26444..6a851ac4dd048f 100644
+--- a/net/netfilter/nf_synproxy_core.c
++++ b/net/netfilter/nf_synproxy_core.c
+@@ -199,6 +199,8 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff,
+       if (skb_ensure_writable(skb, optend))
+               return 0;
++      th = (struct tcphdr *)(skb->data + protoff);
++
+       while (optoff < optend) {
+               unsigned char *op = skb->data + optoff;
+-- 
+2.53.0
+
diff --git a/queue-6.12/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch b/queue-6.12/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
new file mode 100644 (file)
index 0000000..1f8c2d9
--- /dev/null
@@ -0,0 +1,48 @@
+From 474ca2dd9fd541b704fc995088c7265004a9d169 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 20:10:08 +0200
+Subject: netfilter: xt_cpu: prefer raw_smp_processor_id
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit c376f07e16c02239ed44cabb97145d03f65b4d15 ]
+
+With PREEMPT_RCU we get splat:
+
+BUG: using smp_processor_id() in preemptible [..]
+caller is cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+CPU: 1 .. Comm: syz.3.1377 #0 PREEMPT(full)
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
+ check_preemption_disabled+0xd3/0xe0 lib/smp_processor_id.c:47
+ cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+ [..]
+
+Just use raw version instead.
+This is similar to 14d14a5d2957 ("netfilter: nft_meta: use raw_smp_processor_id()").
+
+Fixes: 0ca743a55991 ("netfilter: nf_tables: add compatibility layer for x_tables")
+Reported-by: syzbot+690d3e3ffa7335ac10eb@syzkaller.appspotmail.com
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_cpu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/xt_cpu.c b/net/netfilter/xt_cpu.c
+index 3bdc302a0f9137..9cb259902a586b 100644
+--- a/net/netfilter/xt_cpu.c
++++ b/net/netfilter/xt_cpu.c
+@@ -34,7 +34,7 @@ static bool cpu_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       const struct xt_cpu_info *info = par->matchinfo;
+-      return (info->cpu == smp_processor_id()) ^ info->invert;
++      return (info->cpu == raw_smp_processor_id()) ^ info->invert;
+ }
+ static struct xt_match cpu_mt_reg __read_mostly = {
+-- 
+2.53.0
+
diff --git a/queue-6.12/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch b/queue-6.12/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
new file mode 100644 (file)
index 0000000..c072d44
--- /dev/null
@@ -0,0 +1,40 @@
+From e32f9da0e5e8c98559a32bdd7f4bfb97ef8472b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:41 +0000
+Subject: nfc: llcp: Fix use-after-free in llcp_sock_release()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit f4268b466190dae95a7585f69b4f1f8ad097632c ]
+
+llcp_sock_release() unconditionally unlinks the socket from the local
+sockets list.  However, if the socket is still in connecting state, it
+is on the connecting list.
+
+Fix this by checking the socket state and unlinking from the correct list.
+
+Fixes: b4011239a08e ("NFC: llcp: Fix non blocking sockets connections")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-1-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_sock.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index 57a2f97004e172..915929cd724f90 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -633,6 +633,8 @@ static int llcp_sock_release(struct socket *sock)
+       if (sock->type == SOCK_RAW)
+               nfc_llcp_sock_unlink(&local->raw_sockets, sk);
++      else if (sk->sk_state == LLCP_CONNECTING)
++              nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       else
+               nfc_llcp_sock_unlink(&local->sockets, sk);
+-- 
+2.53.0
+
diff --git a/queue-6.12/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch b/queue-6.12/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
new file mode 100644 (file)
index 0000000..c382968
--- /dev/null
@@ -0,0 +1,67 @@
+From bca7cd838c840b754401ac406e03bd90bd1ba27e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:42 +0000
+Subject: nfc: llcp: Fix use-after-free race in nfc_llcp_recv_cc()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit b493ea2765cc17cb8aa7e7544a4b6dcb05b6ed77 ]
+
+A race condition exists in the NFC LLCP connection state machine where
+the connection acceptance packet (CC) can be processed concurrently with
+socket release.  This can lead to a use-after-free of the socket object.
+
+When nfc_llcp_recv_cc() moves the socket from the connecting_sockets
+list to the sockets list, it does so without holding the socket lock.
+If llcp_sock_release() is executing concurrently, it might have already
+unlinked the socket and dropped its references, which can result in
+nfc_llcp_recv_cc() linking a freed socket into the live list.
+
+Fix this by holding lock_sock() during the state transition and list
+movement in nfc_llcp_recv_cc().  After acquiring the lock, check if
+the socket is still hashed to ensure it hasn't already been unlinked
+and marked for destruction by the release path.  This aligns the locking
+pattern with recv_hdlc() and recv_disc().
+
+Fixes: a69f32af86e3 ("NFC: Socket linked list")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-2-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_core.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
+index d9562840fa180b..62b0f2d6686eb8 100644
+--- a/net/nfc/llcp_core.c
++++ b/net/nfc/llcp_core.c
+@@ -1216,6 +1216,15 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk = &llcp_sock->sk;
++      lock_sock(sk);
++
++      /* Check if socket was destroyed whilst waiting for the lock */
++      if (!sk_hashed(sk)) {
++              release_sock(sk);
++              nfc_llcp_sock_put(llcp_sock);
++              return;
++      }
++
+       /* Unlink from connecting and link to the client array */
+       nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       nfc_llcp_sock_link(&local->sockets, sk);
+@@ -1227,6 +1236,8 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk->sk_state = LLCP_CONNECTED;
+       sk->sk_state_change(sk);
++      release_sock(sk);
++
+       nfc_llcp_sock_put(llcp_sock);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.12/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch b/queue-6.12/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
new file mode 100644 (file)
index 0000000..c12e272
--- /dev/null
@@ -0,0 +1,83 @@
+From b693df0a9400e622e7eb02304badec065ed62734 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 May 2026 19:55:18 +0800
+Subject: nfc: nxp-nci: i2c: use rising-edge IRQ on ACPI systems
+
+From: Carl Lee <carl.lee@amd.com>
+
+[ Upstream commit f23bf992d65a42007c517b060ca35cebdea3525a ]
+
+Some ACPI-based platforms report incorrect IRQ trigger types (e.g.
+IRQF_TRIGGER_HIGH), which can lead to interrupt storms.
+
+Use the historically working rising-edge trigger on ACPI systems to
+avoid this regression.
+
+Device Tree-based systems continue to use the firmware-provided
+trigger type.
+
+Fixes: 57be33f85e36 ("nfc: nxp-nci: remove interrupt trigger type")
+Signed-off-by: Carl Lee <carl.lee@amd.com>
+Tested-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Luca Stefani <luca.stefani.ge1@gmail.com>
+Link: https://patch.msgid.link/20260516-nfc-nxp-nci-i2c-restore-irq-trigger-fallback-v3-1-37ba4b6e9086@amd.com
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/nxp-nci/i2c.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c
+index b3d34433bd14a0..a6c08175d9dd93 100644
+--- a/drivers/nfc/nxp-nci/i2c.c
++++ b/drivers/nfc/nxp-nci/i2c.c
+@@ -16,6 +16,7 @@
+ #include <linux/delay.h>
+ #include <linux/i2c.h>
+ #include <linux/interrupt.h>
++#include <linux/irq.h>
+ #include <linux/module.h>
+ #include <linux/nfc.h>
+ #include <linux/gpio/consumer.h>
+@@ -267,6 +268,7 @@ static int nxp_nci_i2c_probe(struct i2c_client *client)
+ {
+       struct device *dev = &client->dev;
+       struct nxp_nci_i2c_phy *phy;
++      unsigned long irqflags;
+       int r;
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+@@ -303,9 +305,26 @@ static int nxp_nci_i2c_probe(struct i2c_client *client)
+       if (r < 0)
+               return r;
++      /*
++       * ACPI platforms may report incorrect IRQ trigger types
++       * (e.g. level-high), which can lead to interrupt storms.
++       *
++       * Use the historically stable rising-edge trigger for ACPI devices.
++       *
++       * On non-ACPI systems (e.g. Device Tree), prefer the firmware-
++       * provided trigger type, falling back to rising-edge if not set.
++       */
++      if (ACPI_COMPANION(dev)) {
++              irqflags = IRQF_TRIGGER_RISING;
++      } else {
++              irqflags = irq_get_trigger_type(client->irq);
++              if (!irqflags)
++                      irqflags = IRQF_TRIGGER_RISING;
++      }
++
+       r = request_threaded_irq(client->irq, NULL,
+                                nxp_nci_i2c_irq_thread_fn,
+-                               IRQF_ONESHOT,
++                               irqflags | IRQF_ONESHOT,
+                                NXP_NCI_I2C_DRIVER_NAME, phy);
+       if (r < 0)
+               nfc_err(&client->dev, "Unable to register IRQ handler\n");
+-- 
+2.53.0
+
diff --git a/queue-6.12/nvme-tcp-store-negative-errno-in-queue-tls_err.patch b/queue-6.12/nvme-tcp-store-negative-errno-in-queue-tls_err.patch
new file mode 100644 (file)
index 0000000..52e063a
--- /dev/null
@@ -0,0 +1,52 @@
+From 3e8c69447edbddd4321f2494b202a2fdacc9cd1f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:16 -0400
+Subject: nvme-tcp: store negative errno in queue->tls_err
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 9015985b5eb1a90eb86caf5bce1dfcf1aa38f8ad ]
+
+nvme_tcp_tls_done() assigns queue->tls_err in three branches.  The
+ENOKEY lookup failure and the EOPNOTSUPP initializer both store
+negative errnos.  The third branch, reached when the handshake
+layer reports a non-zero status, stores -status.
+
+The handshake layer delivers status to the consumer callback as a
+negative errno; the other in-tree consumers --
+xs_tls_handshake_done() and the nvmet target callback -- treat
+their status argument that way.  The extra negation in
+nvme_tcp_tls_done() flips the sign, leaving tls_err as a positive
+value (for instance, +EIO), which nvme_tcp_start_tls() then
+returns to its caller.
+
+Drop the extra negation so queue->tls_err uniformly carries a
+negative errno on failure.
+
+Fixes: be8e82caa685 ("nvme-tcp: enable TLS handshake upcall")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-2-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/tcp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
+index 77df3432dfb78e..31406438e3ff2d 100644
+--- a/drivers/nvme/host/tcp.c
++++ b/drivers/nvme/host/tcp.c
+@@ -1719,7 +1719,7 @@ static void nvme_tcp_tls_done(void *data, int status, key_serial_t pskid)
+               qid, pskid, status);
+       if (status) {
+-              queue->tls_err = -status;
++              queue->tls_err = status;
+               goto out_complete;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.12/remove-pointless-includes-of-linux-fdtable.h.patch b/queue-6.12/remove-pointless-includes-of-linux-fdtable.h.patch
new file mode 100644 (file)
index 0000000..a13dbc4
--- /dev/null
@@ -0,0 +1,228 @@
+From 6e90a97da649cd482a91d91e149892fe6ebc14d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Jun 2024 23:58:44 -0400
+Subject: remove pointless includes of <linux/fdtable.h>
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit be5498cac2ddb112c5bd7433d5e834a1a2493427 ]
+
+some of those used to be needed, some had been cargo-culted for
+no reason...
+
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Stable-dep-of: ea5fe6a73ca5 ("net/handshake: Drain pending requests at net namespace exit")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fcntl.c                         | 1 -
+ fs/file_table.c                    | 1 -
+ fs/notify/fanotify/fanotify.c      | 1 -
+ fs/notify/fanotify/fanotify_user.c | 1 -
+ fs/overlayfs/copy_up.c             | 1 -
+ fs/proc/base.c                     | 1 -
+ io_uring/io_uring.c                | 1 -
+ kernel/bpf/bpf_inode_storage.c     | 1 -
+ kernel/bpf/bpf_task_storage.c      | 1 -
+ kernel/bpf/token.c                 | 1 -
+ kernel/exit.c                      | 1 -
+ kernel/module/dups.c               | 1 -
+ kernel/module/kmod.c               | 1 -
+ kernel/umh.c                       | 1 -
+ net/handshake/request.c            | 1 -
+ security/apparmor/domain.c         | 1 -
+ 16 files changed, 16 deletions(-)
+
+diff --git a/fs/fcntl.c b/fs/fcntl.c
+index 3d89de31066ae0..a7947a615db6b4 100644
+--- a/fs/fcntl.c
++++ b/fs/fcntl.c
+@@ -12,7 +12,6 @@
+ #include <linux/fs.h>
+ #include <linux/filelock.h>
+ #include <linux/file.h>
+-#include <linux/fdtable.h>
+ #include <linux/capability.h>
+ #include <linux/dnotify.h>
+ #include <linux/slab.h>
+diff --git a/fs/file_table.c b/fs/file_table.c
+index f7661a70874640..2a08bc93b0b9c1 100644
+--- a/fs/file_table.c
++++ b/fs/file_table.c
+@@ -9,7 +9,6 @@
+ #include <linux/string.h>
+ #include <linux/slab.h>
+ #include <linux/file.h>
+-#include <linux/fdtable.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/fs.h>
+diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
+index bb00e1e1683838..4d86a05258b970 100644
+--- a/fs/notify/fanotify/fanotify.c
++++ b/fs/notify/fanotify/fanotify.c
+@@ -1,6 +1,5 @@
+ // SPDX-License-Identifier: GPL-2.0
+ #include <linux/fanotify.h>
+-#include <linux/fdtable.h>
+ #include <linux/fsnotify_backend.h>
+ #include <linux/init.h>
+ #include <linux/jiffies.h>
+diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
+index 93c1619cdad659..b89ad128bf09cf 100644
+--- a/fs/notify/fanotify/fanotify_user.c
++++ b/fs/notify/fanotify/fanotify_user.c
+@@ -1,7 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0
+ #include <linux/fanotify.h>
+ #include <linux/fcntl.h>
+-#include <linux/fdtable.h>
+ #include <linux/file.h>
+ #include <linux/fs.h>
+ #include <linux/anon_inodes.h>
+diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
+index 57f635d050eb5a..75e804bc152ccf 100644
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -16,7 +16,6 @@
+ #include <linux/sched/signal.h>
+ #include <linux/cred.h>
+ #include <linux/namei.h>
+-#include <linux/fdtable.h>
+ #include <linux/ratelimit.h>
+ #include <linux/exportfs.h>
+ #include "overlayfs.h"
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index d060af34a6e837..704cf6a0612ede 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -58,7 +58,6 @@
+ #include <linux/init.h>
+ #include <linux/capability.h>
+ #include <linux/file.h>
+-#include <linux/fdtable.h>
+ #include <linux/generic-radix-tree.h>
+ #include <linux/string.h>
+ #include <linux/seq_file.h>
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index eef59b9eccfab1..e515aeafa87813 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -51,7 +51,6 @@
+ #include <linux/sched/signal.h>
+ #include <linux/fs.h>
+ #include <linux/file.h>
+-#include <linux/fdtable.h>
+ #include <linux/mm.h>
+ #include <linux/mman.h>
+ #include <linux/percpu.h>
+diff --git a/kernel/bpf/bpf_inode_storage.c b/kernel/bpf/bpf_inode_storage.c
+index 29da6d3838f678..e16e79f8cd6dc3 100644
+--- a/kernel/bpf/bpf_inode_storage.c
++++ b/kernel/bpf/bpf_inode_storage.c
+@@ -16,7 +16,6 @@
+ #include <uapi/linux/btf.h>
+ #include <linux/bpf_lsm.h>
+ #include <linux/btf_ids.h>
+-#include <linux/fdtable.h>
+ #include <linux/rcupdate_trace.h>
+ DEFINE_BPF_STORAGE_CACHE(inode_cache);
+diff --git a/kernel/bpf/bpf_task_storage.c b/kernel/bpf/bpf_task_storage.c
+index adf6dfe0ba68a4..1eb9852a9f8ebb 100644
+--- a/kernel/bpf/bpf_task_storage.c
++++ b/kernel/bpf/bpf_task_storage.c
+@@ -16,7 +16,6 @@
+ #include <linux/filter.h>
+ #include <uapi/linux/btf.h>
+ #include <linux/btf_ids.h>
+-#include <linux/fdtable.h>
+ #include <linux/rcupdate_trace.h>
+ DEFINE_BPF_STORAGE_CACHE(task_cache);
+diff --git a/kernel/bpf/token.c b/kernel/bpf/token.c
+index dcbec1a0dfb33f..26057aa1350398 100644
+--- a/kernel/bpf/token.c
++++ b/kernel/bpf/token.c
+@@ -1,6 +1,5 @@
+ #include <linux/bpf.h>
+ #include <linux/vmalloc.h>
+-#include <linux/fdtable.h>
+ #include <linux/file.h>
+ #include <linux/fs.h>
+ #include <linux/kernel.h>
+diff --git a/kernel/exit.c b/kernel/exit.c
+index b91124b2d334ee..e798078f958c89 100644
+--- a/kernel/exit.c
++++ b/kernel/exit.c
+@@ -25,7 +25,6 @@
+ #include <linux/acct.h>
+ #include <linux/tsacct_kern.h>
+ #include <linux/file.h>
+-#include <linux/fdtable.h>
+ #include <linux/freezer.h>
+ #include <linux/binfmts.h>
+ #include <linux/nsproxy.h>
+diff --git a/kernel/module/dups.c b/kernel/module/dups.c
+index 9a92f2f8c9d382..bd2149fbe11738 100644
+--- a/kernel/module/dups.c
++++ b/kernel/module/dups.c
+@@ -18,7 +18,6 @@
+ #include <linux/completion.h>
+ #include <linux/cred.h>
+ #include <linux/file.h>
+-#include <linux/fdtable.h>
+ #include <linux/workqueue.h>
+ #include <linux/security.h>
+ #include <linux/mount.h>
+diff --git a/kernel/module/kmod.c b/kernel/module/kmod.c
+index 0800d989169219..25f25381251281 100644
+--- a/kernel/module/kmod.c
++++ b/kernel/module/kmod.c
+@@ -15,7 +15,6 @@
+ #include <linux/completion.h>
+ #include <linux/cred.h>
+ #include <linux/file.h>
+-#include <linux/fdtable.h>
+ #include <linux/workqueue.h>
+ #include <linux/security.h>
+ #include <linux/mount.h>
+diff --git a/kernel/umh.c b/kernel/umh.c
+index ff1f13a27d29fd..be923427077731 100644
+--- a/kernel/umh.c
++++ b/kernel/umh.c
+@@ -13,7 +13,6 @@
+ #include <linux/completion.h>
+ #include <linux/cred.h>
+ #include <linux/file.h>
+-#include <linux/fdtable.h>
+ #include <linux/fs_struct.h>
+ #include <linux/workqueue.h>
+ #include <linux/security.h>
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 2f58d74f16554b..62efb7e32730ea 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -13,7 +13,6 @@
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/inet.h>
+-#include <linux/fdtable.h>
+ #include <linux/rhashtable.h>
+ #include <net/sock.h>
+diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
+index cccd61cca509ce..fbfb1d48dc88f2 100644
+--- a/security/apparmor/domain.c
++++ b/security/apparmor/domain.c
+@@ -9,7 +9,6 @@
+  */
+ #include <linux/errno.h>
+-#include <linux/fdtable.h>
+ #include <linux/fs.h>
+ #include <linux/file.h>
+ #include <linux/mount.h>
+-- 
+2.53.0
+
diff --git a/queue-6.12/scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch b/queue-6.12/scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch
new file mode 100644 (file)
index 0000000..337f139
--- /dev/null
@@ -0,0 +1,80 @@
+From 9049be25251be93e9fc5e207468e8262b9c5dd80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 14:09:41 -0400
+Subject: scsi: core: Run queues for all non-SDEV_DEL devices from
+ scsi_run_host_queues
+
+From: David Jeffery <djeffery@redhat.com>
+
+[ Upstream commit 7205b58702273baf21d6ba7992e6ba15852325f7 ]
+
+While a SCSI host is in a recovery state, scsi_mq_requeue_cmd() will not
+set the requeue list for a requeued command to be kicked in the future.
+The expectation is a call to scsi_run_host_queues() will kick all SCSI
+devices once the recovery state is cleared.
+
+However, scsi_run_host_queues() uses shost_for_each_device() which uses
+scsi_device_get() and so will ignore devices in a partially removed
+state like SDEV_CANCEL. But these devices may also have requeued
+requests, leaving their requests stuck from not being kicked and causing
+the removal process of the device to hang.
+
+scsi_run_host_queues() needs to run against more devices than the macro
+shost_for_each_device() allows. Instead of using the too limiting
+scsi_device_get() state checks, only ignore devices in SDEV_DEL state or
+when unable to acquire a reference. Attempt to run the queues for all
+other devices when scsi_run_host_queues() is called.
+
+Fixes: 8b566edbdbfb ("scsi: core: Only kick the requeue list if necessary")
+Signed-off-by: David Jeffery <djeffery@redhat.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://patch.msgid.link/20260515180941.9698-1-djeffery@redhat.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_lib.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index 55717fd3234be2..d63d10d53a2aad 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -569,10 +569,33 @@ void scsi_requeue_run_queue(struct work_struct *work)
+ void scsi_run_host_queues(struct Scsi_Host *shost)
+ {
+-      struct scsi_device *sdev;
++      struct scsi_device *sdev, *prev = NULL;
++      unsigned long flags;
+-      shost_for_each_device(sdev, shost)
++      spin_lock_irqsave(shost->host_lock, flags);
++      __shost_for_each_device(sdev, shost) {
++              /*
++               * Only skip devices so deep into removal they will never need
++               * another kick to their queues. Thus scsi_device_get() cannot
++               * be used as it would skip devices in SDEV_CANCEL state which
++               * may need a queue kick.
++               */
++              if (sdev->sdev_state == SDEV_DEL ||
++                  !get_device(&sdev->sdev_gendev))
++                      continue;
++              spin_unlock_irqrestore(shost->host_lock, flags);
++
++              if (prev)
++                      put_device(&prev->sdev_gendev);
+               scsi_run_queue(sdev->request_queue);
++
++              prev = sdev;
++
++              spin_lock_irqsave(shost->host_lock, flags);
++      }
++      spin_unlock_irqrestore(shost->host_lock, flags);
++      if (prev)
++              put_device(&prev->sdev_gendev);
+ }
+ static void scsi_uninit_cmd(struct scsi_cmnd *cmd)
+-- 
+2.53.0
+
diff --git a/queue-6.12/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch b/queue-6.12/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
new file mode 100644 (file)
index 0000000..d1fd241
--- /dev/null
@@ -0,0 +1,50 @@
+From 42356ccefc100500180c57c828a8ec882d195912 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 11:24:11 +0800
+Subject: sctp: fix race between sctp_wait_for_connect and peeloff
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit f14fe6395a8b3d961a61e138ad7b36ba3626dd4e ]
+
+sctp_wait_for_connect() drops and re-acquires the socket lock while
+waiting for the association to reach ESTABLISHED state. During this
+window, another thread can peeloff the association to a new socket via
+getsockopt(SCTP_SOCKOPT_PEELOFF), changing asoc->base.sk. After
+re-acquiring the old socket lock, sctp_wait_for_connect() returns
+success without noticing the migration â€” the caller then accesses
+the association under the wrong lock in sctp_datamsg_from_user().
+
+Add the same sk != asoc->base.sk check that sctp_wait_for_sndbuf()
+already has, returning an error if the association was migrated while
+we slept.
+
+Fixes: 668c9beb9020 ("sctp: implement assign_number for sctp_stream_interleave")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260527032411.60959-1-kipreyyy@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/socket.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 6b562dd1aae110..3e80cf4e63ff00 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -9377,6 +9377,8 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p)
+               release_sock(sk);
+               current_timeo = schedule_timeout(current_timeo);
+               lock_sock(sk);
++              if (sk != asoc->base.sk)
++                      goto do_error;
+               *timeo_p = current_timeo;
+       }
+-- 
+2.53.0
+
index b5232c9bf7fe198a6a712828f680a041f26fc9e2..b5c21368e93955fb24372535e623ff108b1c62b9 100644 (file)
@@ -21,3 +21,74 @@ arm64-debug-split-brk64-exception-entry.patch
 arm64-debug-split-bkpt32-exception-entry.patch
 arm64-debug-remove-debug-exception-registration-infr.patch
 arm64-debug-always-unmask-interrupts-in-el0_softstp.patch
+nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
+nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
+xfrm-check-for-underflow-in-xfrm_state_mtu.patch
+nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
+kunit-fix-use-after-free-in-debugfs-when-using-kunit.patch
+kernel-fork-validate-exit_signal-in-kernel_clone.patch
+netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
+netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
+netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
+tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
+tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch
+vsock-keep-poll-shutdown-state-consistent.patch
+net-netlink-fix-sending-unassigned-nsid-after-assign.patch
+net-netlink-don-t-set-nsid-on-local-notifications.patch
+net-smc-do-not-re-initialize-smc-hashtables.patch
+net-iucv-fix-locking-in-.getsockopt.patch
+scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch
+ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
+alsa-pcm-oss-fix-setup-list-uaf-on-proc-write-error.patch
+asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
+net-hsr-fix-potential-oob-access-in-supervision-fram.patch
+accel-ivpu-prevent-uninitialized-data-bug-in-debugfs.patch
+gpio-mxc-fix-irq_high-handling.patch
+net-avoid-checksumming-unreadable-skb-tail-on-trim.patch
+ethtool-rss-fix-hkey-leak-when-indir_size-is-0.patch
+ethtool-module-avoid-leaking-a-netdev-ref-on-module-.patch
+ethtool-module-check-fw_flash_in_progress-under-rtnl.patch
+ethtool-module-fix-cleanup-if-socket-used-for-flashi.patch
+ethtool-cmis-require-exact-cdb-reply-length.patch
+ethtool-cmis-fix-u16-to-u8-truncation-of-msleep_pre_.patch
+net-ethtool-add-new-parameters-and-a-function-to-sup.patch
+net-ethtool-add-support-for-writing-firmware-blocks-.patch
+ethtool-cmis-validate-start_cmd_payload_size-from-mo.patch
+ethtool-cmis-validate-fw-size-against-start_cmd_payl.patch
+cxl-test-update-mock-dev-array-before-calling-platfo.patch
+tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
+vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
+tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
+asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
+bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
+bonding-refuse-to-enslave-can-devices.patch
+ethtool-coalesce-cap-profile-updates-at-net_dim_para.patch
+ethtool-linkstate-fix-unbalanced-ethnl_ops_complete-.patch
+ethtool-pse-pd-fix-missing-ethnl_ops_complete.patch
+ethtool-strset-fix-header-attribute-index-in-ethnl_r.patch
+ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch
+ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
+ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
+net-sched-revert-net-sched-restrict-conditions-for-a.patch
+net-sched-fix-packet-loop-on-netem-when-duplicate-is.patch
+net-sched-act_mirred-move-the-recursion-counter-stru.patch
+net-sched-act_mirred-add-loop-detection.patch
+net-introduce-skb-tc-depth-field-to-track-packet-loo.patch
+net-sched-fix-ethx-ingress-ethy-egress-ethx-ingress-.patch
+net-sched-act_mirred-fix-return-code-in-early-mirred.patch
+net-handshake-use-spin_lock_bh-for-hn_lock.patch
+nvme-tcp-store-negative-errno-in-queue-tls_err.patch
+net-handshake-pass-negative-errno-through-handshake_.patch
+remove-pointless-includes-of-linux-fdtable.h.patch
+net-handshake-take-a-long-lived-file-reference-at-su.patch
+net-handshake-drain-pending-requests-at-net-namespac.patch
+bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
+bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
+bluetooth-hci_sync-set-hci_cmd_drain_workqueue-durin.patch
+gpio-virtuser-fix-uninitialized-data-bug-in-gpio_vir.patch
+gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
+net-mana-add-null-guards-in-teardown-path-to-prevent.patch
+sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
+ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch
+ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch
+net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch
diff --git a/queue-6.12/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch b/queue-6.12/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch
new file mode 100644 (file)
index 0000000..19b0413
--- /dev/null
@@ -0,0 +1,47 @@
+From 534fe6142d2aef1ed2d9b9c49b1bc163fc996bc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 09:33:13 -0700
+Subject: tun: free page on build_skb failure in tun_xdp_one()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit aa8963fdce667a42fb7f0bdd2909fadcab02f9a8 ]
+
+When build_skb() fails in tun_xdp_one(), the function sets ret to
+-ENOMEM and jumps to the out label, which returns without freeing the
+page that vhost_net_build_xdp() allocated for the frame. As with the
+short-frame rejection path, tun_sendmsg() discards the per-buffer error
+and still returns total_len, so vhost_tx_batch() takes the success path
+and never frees the page. Each build_skb() failure in a batch leaks one
+page-frag chunk.
+
+Free the page before taking the error path, matching the put_page() the
+other error exits of tun_xdp_one() already perform.
+
+Fixes: 043d222f93ab ("tuntap: accept an array of XDP buffs through sendmsg()")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260521163312.1479805-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 19c33d21bab947..d53e60823bf1bb 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2505,6 +2505,7 @@ static int tun_xdp_one(struct tun_struct *tun,
+ build:
+       skb = build_skb(xdp->data_hard_start, buflen);
+       if (!skb) {
++              put_page(virt_to_head_page(xdp->data));
+               ret = -ENOMEM;
+               goto out;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.12/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch b/queue-6.12/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
new file mode 100644 (file)
index 0000000..05fd716
--- /dev/null
@@ -0,0 +1,54 @@
+From a94901bacf88feabd0a93461d058b8ff3054afdc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 09:00:21 -0700
+Subject: tun: free page on short-frame rejection in tun_xdp_one()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f4feb1e20058e407cb00f45aff47f5b7e19a6bbf ]
+
+tun_xdp_one() returns -EINVAL on a frame shorter than ETH_HLEN without
+freeing the page that vhost_net_build_xdp() allocated for it.
+tun_sendmsg() discards that -EINVAL and still returns total_len, so
+vhost_tx_batch() takes the success path and never frees the page; each
+short frame in a batch leaks one page-frag chunk.
+
+A local process that can open /dev/net/tun and /dev/vhost-net can hit
+this path: it attaches a tun/tap device as the vhost-net backend and
+feeds TX descriptors whose length minus the virtio-net header is below
+ETH_HLEN. Each kick leaks the page-frag chunks for that batch, and a
+tight submission loop exhausts host memory and triggers an OOM panic.
+Free the page before returning -EINVAL, matching the XDP-program error
+path in the same function.
+
+Fixes: 049584807f1d ("tun: add missing verification for short frame")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260520160020.375349-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index fb9d425eff8c1b..19c33d21bab947 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2459,8 +2459,10 @@ static int tun_xdp_one(struct tun_struct *tun,
+       bool skb_xdp = false;
+       struct page *page;
+-      if (unlikely(datasize < ETH_HLEN))
++      if (unlikely(datasize < ETH_HLEN)) {
++              put_page(virt_to_head_page(xdp->data));
+               return -EINVAL;
++      }
+       xdp_prog = rcu_dereference(tun->xdp_prog);
+       if (xdp_prog) {
+-- 
+2.53.0
+
diff --git a/queue-6.12/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch b/queue-6.12/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
new file mode 100644 (file)
index 0000000..8cb5b4a
--- /dev/null
@@ -0,0 +1,67 @@
+From ca4fa88756439e4c7f039038925258b39133573d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 11:55:12 +0000
+Subject: tunnels: do not assume transport header in
+ iptunnel_pmtud_check_icmp()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 509323077ef79a26ba0c60bb556e45c12c398b2d ]
+
+In some cases, iptunnel_pmtud_check_icmp() can be called while
+skb transport header is not set.
+
+This triggers an out-of-bound access, because
+(typeof(skb->transport_header))~0U is 65535.
+
+Access the icmp header based on IPv4 network header,
+after making sure icmp->type is present in skb linear part.
+
+Note that iptunnel_pmtud_check_icmpv6()) is fine.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Reported-by: Damiano Melotti <melotti@google.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260522115512.1519110-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index cf496644d3df6c..d0ceb86e1687a7 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -278,7 +278,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct icmphdr *icmph = icmp_hdr(skb);
+       const struct iphdr *iph = ip_hdr(skb);
+       if (mtu < 576 || iph->frag_off != htons(IP_DF))
+@@ -289,9 +288,17 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+           ipv4_is_lbcast(iph->saddr)  || ipv4_is_multicast(iph->saddr))
+               return 0;
+-      if (iph->protocol == IPPROTO_ICMP && icmp_is_err(icmph->type))
+-              return 0;
++      if (iph->protocol == IPPROTO_ICMP) {
++              const struct icmphdr *icmph;
++              if (!pskb_network_may_pull(skb, iph->ihl * 4 +
++                                              offsetofend(struct icmphdr, type)))
++                      return 0;
++              iph = ip_hdr(skb);
++              icmph = (void *)iph + iph->ihl * 4;
++              if (icmp_is_err(icmph->type))
++                      return 0;
++      }
+       return iptunnel_pmtud_build_icmp(skb, mtu);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.12/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch b/queue-6.12/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
new file mode 100644 (file)
index 0000000..bca22cb
--- /dev/null
@@ -0,0 +1,87 @@
+From 05efa6e70f6d6d1eac6923e85881c5fa1d20e3c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:13:35 +0000
+Subject: tunnels: load network headers after skb_cow() in
+ iptunnel_pmtud_build_icmp[v6]()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b4bc94353050b1fa7b702bd4c6600710dd926cff ]
+
+Sashiko found that iptunnel_pmtud_build_icmp() and
+iptunnel_pmtud_build_icmpv6() were caching ip_hdr() and ipv6_hdr()
+before an skb_cow() call which can reallocate skb->head.
+
+Fix this possible UAF by initializing the local variables
+after the skb_cow() call.
+
+Remove skb_reset_network_header() calls which were not needed.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525201335.2361845-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index 507f2f9ec400ce..cf496644d3df6c 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -210,7 +210,7 @@ EXPORT_SYMBOL_GPL(iptunnel_handle_offloads);
+  */
+ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct iphdr *iph = ip_hdr(skb);
++      const struct iphdr *iph;
+       struct icmphdr *icmph;
+       struct iphdr *niph;
+       struct ethhdr eh;
+@@ -224,7 +224,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, 576 - sizeof(*niph) - sizeof(*icmph));
+       if (err)
+@@ -234,7 +233,7 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       err = skb_cow(skb, sizeof(*niph) + sizeof(*icmph) + ETH_HLEN);
+       if (err)
+               return err;
+-
++      iph = ip_hdr(skb);
+       icmph = skb_push(skb, sizeof(*icmph));
+       *icmph = (struct icmphdr) {
+               .type                   = ICMP_DEST_UNREACH,
+@@ -306,7 +305,7 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+ {
+-      const struct ipv6hdr *ip6h = ipv6_hdr(skb);
++      const struct ipv6hdr *ip6h;
+       struct icmp6hdr *icmp6h;
+       struct ipv6hdr *nip6h;
+       struct ethhdr eh;
+@@ -321,7 +320,6 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, IPV6_MIN_MTU - sizeof(*nip6h) - sizeof(*icmp6h));
+       if (err)
+@@ -332,6 +330,7 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       if (err)
+               return err;
++      ip6h = ipv6_hdr(skb);
+       icmp6h = skb_push(skb, sizeof(*icmp6h));
+       *icmp6h = (struct icmp6hdr) {
+               .icmp6_type             = ICMPV6_PKT_TOOBIG,
+-- 
+2.53.0
+
diff --git a/queue-6.12/vsock-keep-poll-shutdown-state-consistent.patch b/queue-6.12/vsock-keep-poll-shutdown-state-consistent.patch
new file mode 100644 (file)
index 0000000..a6fd3bd
--- /dev/null
@@ -0,0 +1,247 @@
+From 5ba4d0d23a92c610446fe70f0cdf079e429f86f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 00:56:36 +0800
+Subject: vsock: keep poll shutdown state consistent
+
+From: Ziyu Zhang <ziyuzhang201@gmail.com>
+
+[ Upstream commit aae9d8a5528b8ee9ff8dc5d3558b8a9f852a724a ]
+
+vsock_poll() reads vsk->peer_shutdown before taking the socket lock
+to set EPOLLHUP and EPOLLRDHUP, then reads it again after taking
+the lock to report EOF readability. A shutdown packet can update
+peer_shutdown while poll is waiting for the lock, so one poll invocation
+can report EOF readability without the corresponding HUP/RDHUP bits.
+
+For connectible sockets, take one peer_shutdown snapshot after
+lock_sock() and use it for all peer-shutdown-derived poll bits. For
+datagram sockets, which do not take lock_sock() in poll(), take one
+lockless READ_ONCE() snapshot and pair it with WRITE_ONCE() on the
+writer side.
+
+This keeps the peer-shutdown-derived bits internally consistent for each
+poll pass.
+
+Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
+Signed-off-by: Ziyu Zhang <ziyuzhang201@gmail.com>
+Link: https://patch.msgid.link/20260519165636.62542-1-ziyuzhang201@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/vmw_vsock/af_vsock.c                | 49 ++++++++++++++++---------
+ net/vmw_vsock/hyperv_transport.c        |  9 +++--
+ net/vmw_vsock/virtio_transport_common.c | 14 ++++---
+ net/vmw_vsock/vmci_transport.c          |  8 ++--
+ 4 files changed, 52 insertions(+), 28 deletions(-)
+
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index 1db7a1f8e55f6d..f03e00cae028a5 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -523,7 +523,7 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
+                */
+               sock_reset_flag(sk, SOCK_DONE);
+               sk->sk_state = TCP_CLOSE;
+-              vsk->peer_shutdown = 0;
++              WRITE_ONCE(vsk->peer_shutdown, 0);
+       }
+       if (sk->sk_type == SOCK_SEQPACKET) {
+@@ -814,7 +814,7 @@ static struct sock *__vsock_create(struct net *net,
+       vsk->rejected = false;
+       vsk->sent_request = false;
+       vsk->ignore_connecting_rst = false;
+-      vsk->peer_shutdown = 0;
++      WRITE_ONCE(vsk->peer_shutdown, 0);
+       INIT_DELAYED_WORK(&vsk->connect_work, vsock_connect_timeout);
+       INIT_DELAYED_WORK(&vsk->pending_work, vsock_pending_work);
+@@ -1099,6 +1099,25 @@ static int vsock_shutdown(struct socket *sock, int mode)
+       return err;
+ }
++static __poll_t vsock_poll_shutdown(struct sock *sk, u32 peer_shutdown)
++{
++      __poll_t mask = 0;
++
++      /* INET sockets treat local write shutdown and peer write shutdown as a
++       * case of EPOLLHUP set.
++       */
++      if (sk->sk_shutdown == SHUTDOWN_MASK ||
++          ((sk->sk_shutdown & SEND_SHUTDOWN) &&
++           (peer_shutdown & SEND_SHUTDOWN)))
++              mask |= EPOLLHUP;
++
++      if (sk->sk_shutdown & RCV_SHUTDOWN ||
++          peer_shutdown & SEND_SHUTDOWN)
++              mask |= EPOLLRDHUP;
++
++      return mask;
++}
++
+ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+                              poll_table *wait)
+ {
+@@ -1116,24 +1135,17 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+               /* Signify that there has been an error on this socket. */
+               mask |= EPOLLERR;
+-      /* INET sockets treat local write shutdown and peer write shutdown as a
+-       * case of EPOLLHUP set.
+-       */
+-      if ((sk->sk_shutdown == SHUTDOWN_MASK) ||
+-          ((sk->sk_shutdown & SEND_SHUTDOWN) &&
+-           (vsk->peer_shutdown & SEND_SHUTDOWN))) {
+-              mask |= EPOLLHUP;
+-      }
+-
+-      if (sk->sk_shutdown & RCV_SHUTDOWN ||
+-          vsk->peer_shutdown & SEND_SHUTDOWN) {
+-              mask |= EPOLLRDHUP;
+-      }
+-
+       if (sk_is_readable(sk))
+               mask |= EPOLLIN | EPOLLRDNORM;
+       if (sock->type == SOCK_DGRAM) {
++              u32 peer_shutdown = READ_ONCE(vsk->peer_shutdown);
++
++              /* DGRAM sockets do not take lock_sock() in poll(), so use one
++               * lockless snapshot for all shutdown-derived mask bits.
++               */
++              mask |= vsock_poll_shutdown(sk, peer_shutdown);
++
+               /* For datagram sockets we can read if there is something in
+                * the queue and write as long as the socket isn't shutdown for
+                * sending.
+@@ -1148,6 +1160,7 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+       } else if (sock_type_connectible(sk->sk_type)) {
+               const struct vsock_transport *transport;
++              u32 peer_shutdown;
+               lock_sock(sk);
+@@ -1180,8 +1193,10 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+                * terminated should also be considered read, and we check the
+                * shutdown flag for that.
+                */
++              peer_shutdown = READ_ONCE(vsk->peer_shutdown);
++              mask |= vsock_poll_shutdown(sk, peer_shutdown);
+               if (sk->sk_shutdown & RCV_SHUTDOWN ||
+-                  vsk->peer_shutdown & SEND_SHUTDOWN) {
++                  peer_shutdown & SEND_SHUTDOWN) {
+                       mask |= EPOLLIN | EPOLLRDNORM;
+               }
+diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
+index 34871ed1a099c6..865e004ee286f2 100644
+--- a/net/vmw_vsock/hyperv_transport.c
++++ b/net/vmw_vsock/hyperv_transport.c
+@@ -264,7 +264,7 @@ static void hvs_do_close_lock_held(struct vsock_sock *vsk,
+       struct sock *sk = sk_vsock(vsk);
+       sock_set_flag(sk, SOCK_DONE);
+-      vsk->peer_shutdown = SHUTDOWN_MASK;
++      WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+       if (vsock_stream_has_data(vsk) <= 0)
+               sk->sk_state = TCP_CLOSING;
+       sk->sk_state_change(sk);
+@@ -593,7 +593,9 @@ static int hvs_update_recv_data(struct hvsock *hvs)
+               return -EIO;
+       if (payload_len == 0)
+-              hvs->vsk->peer_shutdown |= SEND_SHUTDOWN;
++              WRITE_ONCE(hvs->vsk->peer_shutdown,
++                         READ_ONCE(hvs->vsk->peer_shutdown) |
++                         SEND_SHUTDOWN);
+       hvs->recv_data_len = payload_len;
+       hvs->recv_data_off = 0;
+@@ -704,7 +706,8 @@ static s64 hvs_stream_has_data(struct vsock_sock *vsk)
+               ret = 1;
+               break;
+       case 0:
+-              vsk->peer_shutdown |= SEND_SHUTDOWN;
++              WRITE_ONCE(vsk->peer_shutdown,
++                         READ_ONCE(vsk->peer_shutdown) | SEND_SHUTDOWN);
+               ret = 0;
+               break;
+       default: /* -1 */
+diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
+index c182886136b445..b588ccd133eaa7 100644
+--- a/net/vmw_vsock/virtio_transport_common.c
++++ b/net/vmw_vsock/virtio_transport_common.c
+@@ -1234,7 +1234,7 @@ static void virtio_transport_do_close(struct vsock_sock *vsk,
+       struct sock *sk = sk_vsock(vsk);
+       sock_set_flag(sk, SOCK_DONE);
+-      vsk->peer_shutdown = SHUTDOWN_MASK;
++      WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+       if (vsock_stream_has_data(vsk) <= 0)
+               sk->sk_state = TCP_CLOSING;
+       sk->sk_state_change(sk);
+@@ -1437,12 +1437,15 @@ virtio_transport_recv_connected(struct sock *sk,
+       case VIRTIO_VSOCK_OP_CREDIT_UPDATE:
+               sk->sk_write_space(sk);
+               break;
+-      case VIRTIO_VSOCK_OP_SHUTDOWN:
++      case VIRTIO_VSOCK_OP_SHUTDOWN: {
++              u32 peer_shutdown = READ_ONCE(vsk->peer_shutdown);
++
+               if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SHUTDOWN_RCV)
+-                      vsk->peer_shutdown |= RCV_SHUTDOWN;
++                      peer_shutdown |= RCV_SHUTDOWN;
+               if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SHUTDOWN_SEND)
+-                      vsk->peer_shutdown |= SEND_SHUTDOWN;
+-              if (vsk->peer_shutdown == SHUTDOWN_MASK) {
++                      peer_shutdown |= SEND_SHUTDOWN;
++              WRITE_ONCE(vsk->peer_shutdown, peer_shutdown);
++              if (peer_shutdown == SHUTDOWN_MASK) {
+                       if (vsock_stream_has_data(vsk) <= 0 && !sock_flag(sk, SOCK_DONE)) {
+                               (void)virtio_transport_reset(vsk, NULL);
+                               virtio_transport_do_close(vsk, true);
+@@ -1457,6 +1460,7 @@ virtio_transport_recv_connected(struct sock *sk,
+               if (le32_to_cpu(virtio_vsock_hdr(skb)->flags))
+                       sk->sk_state_change(sk);
+               break;
++      }
+       case VIRTIO_VSOCK_OP_RST:
+               virtio_transport_do_close(vsk, true);
+               break;
+diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
+index 4cd11f355e9d6b..443125e48f2481 100644
+--- a/net/vmw_vsock/vmci_transport.c
++++ b/net/vmw_vsock/vmci_transport.c
+@@ -811,7 +811,7 @@ static void vmci_transport_handle_detach(struct sock *sk)
+               /* On a detach the peer will not be sending or receiving
+                * anymore.
+                */
+-              vsk->peer_shutdown = SHUTDOWN_MASK;
++              WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+               /* We should not be sending anymore since the peer won't be
+                * there to receive, but we can still receive if there is data
+@@ -1534,7 +1534,9 @@ static int vmci_transport_recv_connected(struct sock *sk,
+               if (pkt->u.mode) {
+                       vsk = vsock_sk(sk);
+-                      vsk->peer_shutdown |= pkt->u.mode;
++                      WRITE_ONCE(vsk->peer_shutdown,
++                                 READ_ONCE(vsk->peer_shutdown) |
++                                 pkt->u.mode);
+                       sk->sk_state_change(sk);
+               }
+               break;
+@@ -1551,7 +1553,7 @@ static int vmci_transport_recv_connected(struct sock *sk,
+                * a clean shutdown.
+                */
+               sock_set_flag(sk, SOCK_DONE);
+-              vsk->peer_shutdown = SHUTDOWN_MASK;
++              WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+               if (vsock_stream_has_data(vsk) <= 0)
+                       sk->sk_state = TCP_CLOSING;
+-- 
+2.53.0
+
diff --git a/queue-6.12/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch b/queue-6.12/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
new file mode 100644 (file)
index 0000000..af80176
--- /dev/null
@@ -0,0 +1,54 @@
+From 7a38673e85f230e726cc7061e8841f05b8f951f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:36:42 +0000
+Subject: vxlan: do not reuse cached ip_hdr() value after
+ skb_tunnel_check_pmtu()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 7d9ef0cb271555d8cf39fefe6c981e1493b25ecf ]
+
+skb_tunnel_check_pmtu() can change skb->head.
+
+Reusing old_iph afer skb_tunnel_check_pmtu() can cause an UAF.
+
+Use instead ip_hdr(skb) as done in drivers/net/bareudp.c
+and drivers/net/geneve.c.
+
+Found by Sashiko.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525203642.2389723-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vxlan/vxlan_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
+index ed428293b0e579..765d25eee2fe48 100644
+--- a/drivers/net/vxlan/vxlan_core.c
++++ b/drivers/net/vxlan/vxlan_core.c
+@@ -2541,7 +2541,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr),
+                                     vni, md, flags, udp_sum);
+@@ -2601,7 +2601,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip6_dst_hoplimit(ndst);
+               skb_scrub_packet(skb, xnet);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
+-- 
+2.53.0
+
diff --git a/queue-6.12/xfrm-check-for-underflow-in-xfrm_state_mtu.patch b/queue-6.12/xfrm-check-for-underflow-in-xfrm_state_mtu.patch
new file mode 100644 (file)
index 0000000..d7d41d5
--- /dev/null
@@ -0,0 +1,85 @@
+From 12d3f6f2c51d183a3c95830ff09315181c474972 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 10:49:14 -0600
+Subject: xfrm: Check for underflow in xfrm_state_mtu
+
+From: David Ahern <dahern@nvidia.com>
+
+[ Upstream commit 742b04d0550b0ec89dcbc99537ec88653bd1ad90 ]
+
+Leo Lin reported OOB write issue in esp component:
+
+  xfrm_state_mtu() returns u32 but performs its arithmetic in unsigned
+  modulo-2^32 space using an attacker-influenced "header_len + authsize +
+  net_adj" subtracted from a small "mtu" argument. A nobody user can
+  install an IPv4 ESP tunnel SA with a large authentication key
+  (XFRMA_ALG_AUTH_TRUNC, e.g. hmac(sha512), 64-byte key, 64-byte trunc),
+  configure a small interface MTU (68 bytes), and set XFRMA_TFCPAD to a
+  large value. When a single UDP datagram is then sent through the
+  tunnel, xfrm_state_mtu() underflows to a near-2^32 value, and
+  esp_output() consumes it as a signed int via:
+
+        padto      = min(x->tfcpad, xfrm_state_mtu(x, mtu_cached))
+        esp.tfclen = padto - skb->len   (assigned to int)
+
+  esp.tfclen ends up negative (e.g. -207). It is sign-extended to size_t
+  when passed to memset() inside esp_output_fill_trailer(), producing a
+  ~16 EB write of zeroes at skb_tail_pointer(skb). KASAN logs it as
+  "Write of size 18446744073709551537 at addr ffff888...".
+
+Check for underflow and return 1. This causes the sendmsg attempt to
+fail with ENETUNREACH.
+
+Fixes: c5c252389374 ("[XFRM]: Optimize MTU calculation")
+Reported-by: Leo Lin <leo@depthfirst.com>
+Assisted-by: Codex:26.506.31004
+Signed-off-by: David Ahern <dahern@nvidia.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 6a92d88f9e0363..4823a9c054ae2b 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -3022,10 +3022,14 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+       const struct xfrm_type *type = READ_ONCE(x->type);
+       struct crypto_aead *aead;
+       u32 blksize, net_adj = 0;
++      u32 overhead, payload_mtu;
+       if (x->km.state != XFRM_STATE_VALID ||
+-          !type || type->proto != IPPROTO_ESP)
++          !type || type->proto != IPPROTO_ESP) {
++              if (mtu <= x->props.header_len)
++                      return 1;
+               return mtu - x->props.header_len;
++      }
+       aead = x->data;
+       blksize = ALIGN(crypto_aead_blocksize(aead), 4);
+@@ -3045,8 +3049,17 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+               break;
+       }
+-      return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
+-               net_adj) & ~(blksize - 1)) + net_adj - 2;
++      overhead = x->props.header_len + crypto_aead_authsize(aead) + net_adj;
++      if (mtu <= overhead)
++              return 1;
++
++      payload_mtu = mtu - overhead;
++      payload_mtu &= ~(blksize - 1);
++      if (payload_mtu <= 2)
++              return 1;
++
++      return payload_mtu + net_adj - 2;
++
+ }
+ EXPORT_SYMBOL_GPL(xfrm_state_mtu);
+-- 
+2.53.0
+
diff --git a/queue-6.18/accel-rocket-fix-uaf-via-dangling-gem-handle-in-crea.patch b/queue-6.18/accel-rocket-fix-uaf-via-dangling-gem-handle-in-crea.patch
new file mode 100644 (file)
index 0000000..3b56987
--- /dev/null
@@ -0,0 +1,86 @@
+From c94e9cdde08e0e5aa81516381ab511097f6da71b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 00:00:00 +0530
+Subject: accel/rocket: fix UAF via dangling GEM handle in create_bo
+
+From: Dhabaleshwar Das <dhabal123@gmail.com>
+
+[ Upstream commit f706e6a4ce75585af979aec3dcbdce68bc76306b ]
+
+rocket_ioctl_create_bo() inserts a GEM handle into the file's IDR via
+drm_gem_handle_create() early on, then performs several operations that
+can fail (sgt allocation, drm_mm insert, iommu_map). If any fail after
+the handle is live, the error path calls drm_gem_shmem_object_free()
+which kfree's the object without removing the handle from the IDR.
+
+This leaves a dangling handle pointing to freed slab memory. Any
+subsequent ioctl using that handle (PREP_BO, FINI_BO, SUBMIT) calls
+drm_gem_object_lookup() and dereferences freed memory (UAF).
+
+Fix by moving drm_gem_handle_create() to after all fallible operations
+succeed, matching the pattern used by panfrost, lima, and etnaviv.
+
+Also fix drm_mm_insert_node_generic() whose return value was silently
+overwritten by iommu_map_sgtable() on the next line. Add the missing
+error check.
+
+[tomeu: Move handle creation to the very end]
+
+Fixes: 658ebeac3351 ("accel/rocket: Add IOCTL for BO creation")
+Reported-by: Dhabaleshwar Das <dhabal123@gmail.com>
+Signed-off-by: Dhabaleshwar Das <dhabal123@gmail.com>
+Reviewed-by: Tomeu Vizoso <tomeu@tomeuvizoso.net>
+Link: https://patch.msgid.link/20260521165720.2113571-1-tomeu@tomeuvizoso.net
+Signed-off-by: Tomeu Vizoso <tomeu@tomeuvizoso.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/rocket/rocket_gem.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/accel/rocket/rocket_gem.c b/drivers/accel/rocket/rocket_gem.c
+index c3c86e1abd25a3..b1b24d60973e82 100644
+--- a/drivers/accel/rocket/rocket_gem.c
++++ b/drivers/accel/rocket/rocket_gem.c
+@@ -78,11 +78,6 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file *
+       rkt_obj->size = args->size;
+       rkt_obj->offset = 0;
+-      ret = drm_gem_handle_create(file, gem_obj, &args->handle);
+-      drm_gem_object_put(gem_obj);
+-      if (ret)
+-              goto err;
+-
+       sgt = drm_gem_shmem_get_pages_sgt(shmem_obj);
+       if (IS_ERR(sgt)) {
+               ret = PTR_ERR(sgt);
+@@ -94,6 +89,8 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file *
+                                        rkt_obj->size, PAGE_SIZE,
+                                        0, 0);
+       mutex_unlock(&rocket_priv->mm_lock);
++      if (ret)
++              goto err;
+       ret = iommu_map_sgtable(rocket_priv->domain->domain,
+                               rkt_obj->mm.start,
+@@ -111,8 +108,18 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file *
+       args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
+       args->dma_address = rkt_obj->mm.start;
++      ret = drm_gem_handle_create(file, gem_obj, &args->handle);
++      if (ret)
++              goto err_unmap;
++
++      drm_gem_object_put(gem_obj);
++
+       return 0;
++err_unmap:
++      iommu_unmap(rocket_priv->domain->domain,
++                  rkt_obj->mm.start, rkt_obj->size);
++
+ err_remove_node:
+       mutex_lock(&rocket_priv->mm_lock);
+       drm_mm_remove_node(&rkt_obj->mm);
+-- 
+2.53.0
+
diff --git a/queue-6.18/alsa-pcm-oss-fix-setup-list-uaf-on-proc-write-error.patch b/queue-6.18/alsa-pcm-oss-fix-setup-list-uaf-on-proc-write-error.patch
new file mode 100644 (file)
index 0000000..28cdb99
--- /dev/null
@@ -0,0 +1,84 @@
+From 8353904ca767496700211f3e492511b0b8b5d53f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 22:09:40 -0300
+Subject: ALSA: pcm: oss: Fix setup list UAF on proc write error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit 4cc54bdd54b337e77115be5b55577d1c58608eae ]
+
+snd_pcm_oss_proc_write() links a newly allocated setup entry into the
+OSS setup list before duplicating the task name. If the task-name
+allocation fails, the error path frees the already linked entry and
+leaves setup_list pointing at freed memory.
+
+A later OSS device open can then walk the stale list entry in
+snd_pcm_oss_look_for_setup() and dereference freed memory.
+
+Allocate the task name and initialize the setup entry before publishing
+the entry on setup_list. Also fetch the initial proc read iterator only
+after taking setup_mutex, so all setup_list traversal follows the same
+list lifetime rules.
+
+Reported-by: syzbot+8e498074a794999eb41c@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/6a1062b7.170a0220.35b2b7.0003.GAE@google.com
+Closes: https://syzkaller.appspot.com/bug?extid=8e498074a794999eb41c
+Fixes: 060d77b9c04a ("[ALSA] Fix / clean up PCM-OSS setup hooks")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260522-alsa-pcm-oss-setup-uaf-v1-1-40bdcc4d17e8@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/oss/pcm_oss.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
+index 9b5a3def8d2ce9..59d5153d111329 100644
+--- a/sound/core/oss/pcm_oss.c
++++ b/sound/core/oss/pcm_oss.c
+@@ -2965,8 +2965,10 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
+                                 struct snd_info_buffer *buffer)
+ {
+       struct snd_pcm_str *pstr = entry->private_data;
+-      struct snd_pcm_oss_setup *setup = pstr->oss.setup_list;
++      struct snd_pcm_oss_setup *setup;
++
+       guard(mutex)(&pstr->oss.setup_mutex);
++      setup = pstr->oss.setup_list;
+       while (setup) {
+               snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n",
+                           setup->task_name,
+@@ -3051,6 +3053,13 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
+                               buffer->error = -ENOMEM;
+                               return;
+                       }
++                      template.task_name = kstrdup(task_name, GFP_KERNEL);
++                      if (!template.task_name) {
++                              kfree(setup);
++                              buffer->error = -ENOMEM;
++                              return;
++                      }
++                      *setup = template;
+                       if (pstr->oss.setup_list == NULL)
+                               pstr->oss.setup_list = setup;
+                       else {
+@@ -3058,12 +3067,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
+                                    setup1->next; setup1 = setup1->next);
+                               setup1->next = setup;
+                       }
+-                      template.task_name = kstrdup(task_name, GFP_KERNEL);
+-                      if (! template.task_name) {
+-                              kfree(setup);
+-                              buffer->error = -ENOMEM;
+-                              return;
+-                      }
++                      continue;
+               }
+               *setup = template;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.18/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch b/queue-6.18/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
new file mode 100644 (file)
index 0000000..1e0b66c
--- /dev/null
@@ -0,0 +1,47 @@
+From de0181ab0dd485dbdac3966b2dae85da7aa3818f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 09:24:00 -0300
+Subject: ASoC: codecs: simple-mux: Fix enum control bounds check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit f63ad68e18d774a5d15cd7e405ead63f6b322679 ]
+
+simple_mux_control_put() rejects values greater than e->items, but
+enum control values are zero based. For the two-entry mux used by this
+driver, valid values are 0 and 1, so value 2 must be rejected as well.
+
+Accepting e->items can store an invalid mux state, pass it to the GPIO
+setter, and pass it on to the DAPM mux update path where it is used as
+an index into the enum text array.
+
+Use the same >= e->items check used by the ASoC enum helpers.
+
+Fixes: 342fbb7578d1 ("ASoC: add simple-mux")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260527-asoc-simple-mux-enum-bounds-v1-1-3f805b9fc671@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/simple-mux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/simple-mux.c b/sound/soc/codecs/simple-mux.c
+index 3906964401557d..cedd181ffdaf46 100644
+--- a/sound/soc/codecs/simple-mux.c
++++ b/sound/soc/codecs/simple-mux.c
+@@ -51,7 +51,7 @@ static int simple_mux_control_put(struct snd_kcontrol *kcontrol,
+       struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
+       struct simple_mux *priv = snd_soc_component_get_drvdata(c);
+-      if (ucontrol->value.enumerated.item[0] > e->items)
++      if (ucontrol->value.enumerated.item[0] >= e->items)
+               return -EINVAL;
+       if (priv->mux == ucontrol->value.enumerated.item[0])
+-- 
+2.53.0
+
diff --git a/queue-6.18/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch b/queue-6.18/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
new file mode 100644 (file)
index 0000000..7bfba61
--- /dev/null
@@ -0,0 +1,112 @@
+From 8c7c2adfae177c0e9b05e5f4613a983cc37ac25a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 13:51:47 -0300
+Subject: ASoC: Intel: bytcht_es8316: Fix MCLK leak on init errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit afb2a3a9d8369d18122a0d7cd294eba9a98259c6 ]
+
+byt_cht_es8316_init() enables MCLK before configuring the codec sysclk
+and creating the headset jack. If either of those later steps fails, the
+function returns without disabling MCLK, leaving the clock enabled after
+card registration fails.
+
+Track whether this driver enabled MCLK and disable it on the init error
+paths. Add the matching DAI link exit callback so the same clock enable
+is also balanced when ASoC cleans up a successfully initialized link.
+
+Fixes: a03bdaa565cb ("ASoC: Intel: add machine driver for BYT/CHT + ES8316")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260519-asoc-bytcht-es8316-mclk-leak-v1-1-b4a11cdc2afd@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcht_es8316.c | 29 ++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
+index 3b5f63112237ea..25044c0f4703b0 100644
+--- a/sound/soc/intel/boards/bytcht_es8316.c
++++ b/sound/soc/intel/boards/bytcht_es8316.c
+@@ -40,6 +40,7 @@ struct byt_cht_es8316_private {
+       struct gpio_desc *speaker_en_gpio;
+       struct device *codec_dev;
+       bool speaker_en;
++      bool mclk_enabled;
+ };
+ enum {
+@@ -170,6 +171,15 @@ static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
+       },
+ };
++static void byt_cht_es8316_disable_mclk(struct byt_cht_es8316_private *priv)
++{
++      if (!priv->mclk_enabled)
++              return;
++
++      clk_disable_unprepare(priv->mclk);
++      priv->mclk_enabled = false;
++}
++
+ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+ {
+       struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component;
+@@ -226,12 +236,14 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+       ret = clk_prepare_enable(priv->mclk);
+       if (ret)
+               dev_err(card->dev, "unable to enable MCLK\n");
++      else
++              priv->mclk_enabled = true;
+       ret = snd_soc_dai_set_sysclk(snd_soc_rtd_to_codec(runtime, 0), 0, 19200000,
+                                    SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               dev_err(card->dev, "can't set codec clock %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       ret = snd_soc_card_jack_new_pins(card, "Headset",
+@@ -240,13 +252,25 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+                                        ARRAY_SIZE(byt_cht_es8316_jack_pins));
+       if (ret) {
+               dev_err(card->dev, "jack creation failed %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+       snd_soc_component_set_jack(codec, &priv->jack, NULL);
+       return 0;
++
++err_disable_mclk:
++      byt_cht_es8316_disable_mclk(priv);
++      return ret;
++}
++
++static void byt_cht_es8316_exit(struct snd_soc_pcm_runtime *runtime)
++{
++      struct snd_soc_card *card = runtime->card;
++      struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
++
++      byt_cht_es8316_disable_mclk(priv);
+ }
+ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
+@@ -352,6 +376,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
+                                               | SND_SOC_DAIFMT_CBC_CFC,
+               .be_hw_params_fixup = byt_cht_es8316_codec_fixup,
+               .init = byt_cht_es8316_init,
++              .exit = byt_cht_es8316_exit,
+               SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
+       },
+ };
+-- 
+2.53.0
+
diff --git a/queue-6.18/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch b/queue-6.18/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
new file mode 100644 (file)
index 0000000..4b77ef8
--- /dev/null
@@ -0,0 +1,40 @@
+From 649cc6a649e6978e5cd04d99322d93ec4b3fac2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 11:21:39 +0800
+Subject: Bluetooth: 6lowpan: check skb_clone() return value in
+ send_mcast_pkt()
+
+From: Zhao Dongdong <zhaodongdong@kylinos.cn>
+
+[ Upstream commit 3c40d381ce04f9575a5d8b542898183c3b4b38dc ]
+
+The skb_clone() function can return NULL if memory allocation fails.
+send_mcast_pkt() calls skb_clone() without checking the return value, which
+can lead to a NULL pointer dereference in send_pkt() when it dereferences
+skb->data.
+Add a NULL check after skb_clone() and skip the peer if the clone fails.
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Signed-off-by: Zhao Dongdong <zhaodongdong@kylinos.cn>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 2c21ae8abadc22..038f01600eebab 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -486,6 +486,8 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
+                       int ret;
+                       local_skb = skb_clone(skb, GFP_ATOMIC);
++                      if (!local_skb)
++                              continue;
+                       BT_DBG("xmit %s to %pMR type %u IP %pI6c chan %p",
+                              netdev->name,
+-- 
+2.53.0
+
diff --git a/queue-6.18/bluetooth-hci_sync-reset-device-counters-in-hci_dev_.patch b/queue-6.18/bluetooth-hci_sync-reset-device-counters-in-hci_dev_.patch
new file mode 100644 (file)
index 0000000..e490314
--- /dev/null
@@ -0,0 +1,38 @@
+From 3718dc220ef216425944f12fa86b221d0faa97bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 10:50:59 -0300
+Subject: Bluetooth: hci_sync: Reset device counters in hci_dev_close_sync()
+
+From: Heitor Alves de Siqueira <halves@igalia.com>
+
+[ Upstream commit cdf88b35e06f1b385f7f6228060ae541d44fbb72 ]
+
+Before resetting or closing the device, protocol counters should also be
+zeroed.
+
+Fixes: d0b137062b2d ("Bluetooth: hci_sync: Rework init stages")
+Signed-off-by: Heitor Alves de Siqueira <halves@igalia.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 73e429c41e17b5..277de808ebeb5a 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -5338,6 +5338,10 @@ int hci_dev_close_sync(struct hci_dev *hdev)
+       /* Reset device */
+       skb_queue_purge(&hdev->cmd_q);
+       atomic_set(&hdev->cmd_cnt, 1);
++      hdev->acl_cnt = 0;
++      hdev->sco_cnt = 0;
++      hdev->le_cnt = 0;
++      hdev->iso_cnt = 0;
+       if (hci_test_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE) &&
+           !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
+               set_bit(HCI_INIT, &hdev->flags);
+-- 
+2.53.0
+
diff --git a/queue-6.18/bluetooth-hci_sync-set-hci_cmd_drain_workqueue-durin.patch b/queue-6.18/bluetooth-hci_sync-set-hci_cmd_drain_workqueue-durin.patch
new file mode 100644 (file)
index 0000000..461f9e9
--- /dev/null
@@ -0,0 +1,57 @@
+From dec5788e45a54c53a1973b4d0b1f946cf1667526 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 10:50:58 -0300
+Subject: Bluetooth: hci_sync: Set HCI_CMD_DRAIN_WORKQUEUE during device close
+
+From: Heitor Alves de Siqueira <halves@igalia.com>
+
+[ Upstream commit 525daaea459fc215f432de1b8debbd9144bf97b0 ]
+
+Since hci_dev_close_sync() can now be called during the reset path, we
+should also set HCI_CMD_DRAIN_WORKQUEUE. This avoids queuing timeouts
+while the hdev workqueue is being drained.
+
+Fixes: 877afadad2dc ("Bluetooth: When HCI work queue is drained, only queue chained work")
+Signed-off-by: Heitor Alves de Siqueira <halves@igalia.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index f498ab28f1aa06..73e429c41e17b5 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -5246,6 +5246,12 @@ int hci_dev_close_sync(struct hci_dev *hdev)
+       bt_dev_dbg(hdev, "");
++      /* Set HCI_DRAIN_WORKQUEUE flag to prevent queuing work during
++       * reset/close. See hci_cmd_work() and handle_cmd_cnt_and_timer().
++       */
++      hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
++      synchronize_rcu();
++
+       if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
+               disable_delayed_work(&hdev->power_off);
+               disable_delayed_work(&hdev->ncmd_timer);
+@@ -5269,6 +5275,7 @@ int hci_dev_close_sync(struct hci_dev *hdev)
+       if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
+               cancel_delayed_work_sync(&hdev->cmd_timer);
++              hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
+               return err;
+       }
+@@ -5368,6 +5375,7 @@ int hci_dev_close_sync(struct hci_dev *hdev)
+       /* Clear flags */
+       hdev->flags &= BIT(HCI_RAW);
+       hci_dev_clear_volatile_flags(hdev);
++      hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
+       memset(hdev->eir, 0, sizeof(hdev->eir));
+       memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
+-- 
+2.53.0
+
diff --git a/queue-6.18/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch b/queue-6.18/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
new file mode 100644 (file)
index 0000000..d1e6ba4
--- /dev/null
@@ -0,0 +1,62 @@
+From 1aa026fff16eb15eb249ca0fd40da386c5ca0ce9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 18:51:52 +0800
+Subject: Bluetooth: l2cap: clear chan->ident on ECRED reconfiguration success
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit 00e1950716c6ed67d74777b2db286b0fa23b4be9 ]
+
+l2cap_ecred_reconf_rsp() returns early on success without clearing
+chan->ident. Every other L2CAP response handler (l2cap_ecred_conn_rsp,
+l2cap_le_connect_rsp, l2cap_config_rsp) clears chan->ident after a
+successful transaction to prevent the channel from matching subsequent
+responses with the recycled ident value.
+
+A remote attacker that completed a reconfiguration as the peer can
+replay a failure response with the stale ident, causing the kernel to
+match and destroy the already-established channel via
+l2cap_chan_del(chan, ECONNRESET).
+
+Clear chan->ident for all matching channels on success, and harden the
+failure path by using l2cap_chan_hold_unless_zero() consistent with
+other L2CAP handlers (l2cap_le_command_rej, __l2cap_get_chan_by_ident).
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 87ebe81277c510..57f5e3c7429e79 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -5466,14 +5466,20 @@ static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
+       BT_DBG("result 0x%4.4x", result);
+-      if (!result)
++      if (!result) {
++              list_for_each_entry(chan, &conn->chan_l, list) {
++                      if (chan->ident == cmd->ident)
++                              chan->ident = 0;
++              }
+               return 0;
++      }
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
+               if (chan->ident != cmd->ident)
+                       continue;
+-              l2cap_chan_hold(chan);
++              if (!l2cap_chan_hold_unless_zero(chan))
++                      continue;
+               l2cap_chan_lock(chan);
+               l2cap_chan_del(chan, ECONNRESET);
+-- 
+2.53.0
+
diff --git a/queue-6.18/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch b/queue-6.18/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
new file mode 100644 (file)
index 0000000..17cc8b0
--- /dev/null
@@ -0,0 +1,82 @@
+From 4e9d3d16c00ca5768b40166cd201a5a1bf3dc7fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 May 2026 12:09:42 -0400
+Subject: Bluetooth: L2CAP: Fix possible crash on l2cap_ecred_conn_rsp
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 41c2713b204e6cb6a94587bc6bf6935107df5479 ]
+
+If dcid is received for an already-assigned destination CID the spec
+requires that both channels to be discarded, but calling l2cap_chan_del
+may invalidate the tmp cursor created by list_for_each_entry_safe and
+in fact it is the wrong procedure as the chan->dcid may be assigned
+previously it really needs to be disconnected.
+
+Calling l2cap_chan_clone directly may still lead to l2cap_chan_del so
+instead schedule l2cap_chan_timeout with delay 0 to close the channel
+asynchronously.
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 27 ++++++++++++++++++++++-----
+ 1 file changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 57f5e3c7429e79..9805908e6c6a06 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -5268,6 +5268,7 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+       cmd_len -= sizeof(*rsp);
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
++              struct l2cap_chan *orig;
+               u16 dcid;
+               if (chan->ident != cmd->ident ||
+@@ -5289,8 +5290,10 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+               BT_DBG("dcid[%d] 0x%4.4x", i, dcid);
++              orig = __l2cap_get_chan_by_dcid(conn, dcid);
++
+               /* Check if dcid is already in use */
+-              if (dcid && __l2cap_get_chan_by_dcid(conn, dcid)) {
++              if (dcid && orig) {
+                       /* If a device receives a
+                        * L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an
+                        * already-assigned Destination CID, then both the
+@@ -5299,10 +5302,24 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+                        */
+                       l2cap_chan_del(chan, ECONNREFUSED);
+                       l2cap_chan_unlock(chan);
+-                      chan = __l2cap_get_chan_by_dcid(conn, dcid);
+-                      l2cap_chan_lock(chan);
+-                      l2cap_chan_del(chan, ECONNRESET);
+-                      l2cap_chan_unlock(chan);
++
++                      /* Check that the dcid channel mode is
++                       * L2CAP_MODE_EXT_FLOWCTL since this procedure is only
++                       * valid for that mode and shouldn't disconnect a dcid
++                       * in other modes.
++                       */
++                      if (orig->mode == L2CAP_MODE_EXT_FLOWCTL) {
++                              l2cap_chan_lock(orig);
++                              /* Disconnect the original channel as it may be
++                               * considered connected since dcid has already
++                               * been assigned; don't call l2cap_chan_close
++                               * directly since that could lead to
++                               * l2cap_chan_del and then removing the channel
++                               * from the list while we're iterating over it.
++                               */
++                              __set_chan_timer(orig, 0);
++                              l2cap_chan_unlock(orig);
++                      }
+                       continue;
+               }
+-- 
+2.53.0
+
diff --git a/queue-6.18/bonding-refuse-to-enslave-can-devices.patch b/queue-6.18/bonding-refuse-to-enslave-can-devices.patch
new file mode 100644 (file)
index 0000000..88b81e2
--- /dev/null
@@ -0,0 +1,74 @@
+From 02ee1f8764feca89889e41fbf621bb3e98a6c705 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 21:33:19 +0200
+Subject: bonding: refuse to enslave CAN devices
+
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+
+[ Upstream commit 8ba68464e4787b6a7ec938826e16124df20fd23d ]
+
+syzbot reported a kernel paging request crash in
+can_rx_unregister() inside net/can/af_can.c. The crash occurs
+because a virtual CAN device (vxcan) is being enslaved to a
+bonding master.
+
+During the enslavement process, the bonding driver mutates
+and modifies the network device states to fit an Ethernet-like
+aggregation model. However, CAN devices operate on a completely
+different Layer 2 architecture, relying on the CAN mid-layer
+private data structure (can_ml_priv) instead of standard
+Ethernet structures. Since bonding does not initialize or
+maintain these CAN structures, subsequent operations on the
+half-enslaved interface (such as closing associated sockets
+via isotp_release) lead to a null-pointer dereference when
+accessing the CAN receiver lists.
+
+Bonding CAN interfaces is architecturally invalid as CAN lacks
+MAC addresses, ARP capabilities, and standard Ethernet
+link-layer mechanisms. While generic loopback devices are
+blocked globally in net/core/dev.c, virtual CAN devices
+bypass this check because they do not carry the IFF_LOOPBACK
+flag, despite acting as local software-loopbacks.
+
+Fix this by explicitly blocking network devices of type
+ARPHRD_CAN from being enslaved at the very beginning of
+bond_enslave(). This prevents illegal state mutations,
+eliminates the resulting KASAN crashes, and avoids potential
+memory leaks from incomplete socket cleanups.
+
+As the CAN support has been added a long time after bonding
+the Fixes-tag points to the introduction of ARPHRD_CAN that
+would have needed a specific handling in bonding_main.c.
+
+Fixes: cd05acfe65ed ("[CAN]: Allocate protocol numbers for PF_CAN")
+Reported-by: syzbot+8ed98cbd0161632bce95@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=8ed98cbd0161632bce95
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Link: https://patch.msgid.link/20260526-bonding-candev-v1-1-ba1df400918a@hartkopp.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 8b1422dda4c080..2132acff2e52c4 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1860,6 +1860,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
+       struct sockaddr_storage ss;
+       int res = 0, i;
++      if (slave_dev->type == ARPHRD_CAN) {
++              BOND_NL_ERR(bond_dev, extack,
++                          "CAN devices cannot be enslaved");
++              return -EPERM;
++      }
++
+       if (slave_dev->flags & IFF_MASTER &&
+           !netif_is_bond_master(slave_dev)) {
+               BOND_NL_ERR(bond_dev, extack,
+-- 
+2.53.0
+
diff --git a/queue-6.18/bridge-fix-sleep-in-atomic-context-in-netlink-path.patch b/queue-6.18/bridge-fix-sleep-in-atomic-context-in-netlink-path.patch
new file mode 100644 (file)
index 0000000..1410819
--- /dev/null
@@ -0,0 +1,149 @@
+From 7ae34c99bb03e7437c026e5634f732cfa1a3f221 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 09:48:16 +0300
+Subject: bridge: Fix sleep in atomic context in netlink path
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 5eec4427b89c2fb2beac54920101e55a2f1c0c21 ]
+
+Since the introduction of the netlink configuration path for bridge
+ports in commit 25c71c75ac87 ("bridge: bridge port parameters over
+netlink"), br_setport() was always called with the bridge lock held
+around it. Back then this decision made sense: The bridge lock protects
+the STP state of the bridge and its ports and at that time the function
+only processed three STP related netlink attributes (cost, priority and
+state).
+
+Nowadays, br_setport() processes a lot more attributes and most of them
+do not need the bridge lock:
+
+* Bridge flags: Only require RTNL. Read locklessly by the data path.
+  Annotations can be added in net-next.
+
+* FDB port flushing: Only requires the FDB lock.
+
+* Multicast attributes: Only require the multicast lock.
+
+* Group forward mask: Only requires RTNL. Read locklessly by the data
+  path. Annotations can be added in net-next.
+
+* Backup port and NHID: Only require RTNL. Read locklessly by the data
+  path.
+
+This is a problem as the bridge calls dev_set_promiscuity() when certain
+bridge port flags change and this function can sleep since the commit
+cited below, resulting in a splat such as [1].
+
+Fix this by reducing the scope of the bridge lock and only take it when
+processing the three STP related attributes that require it. This is
+consistent with the multicast attributes where each attribute acquires
+the multicast lock instead of having one critical section for all
+relevant attributes.
+
+[1]
+BUG: sleeping function called from invalid context at net/core/dev_addr_lists.c:1262
+in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 356, name: bridge
+preempt_count: 201, expected: 0
+RCU nest depth: 0, expected: 0
+2 locks held by bridge/356:
+#0: ffffffff919473a0 (rtnl_mutex){+.+.}-{4:4}, at: rtnetlink_rcv_msg (net/core/rtnetlink.c:80 net/core/rtnetlink.c:7002)
+#1: ffff888115072d58 (&br->lock){+...}-{3:3}, at: br_setlink (./include/linux/spinlock.h:348 net/bridge/br_netlink.c:1117)
+Preemption disabled at:
+ 0x0
+Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+Call Trace:
+<TASK>
+dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120)
+__might_resched.cold (kernel/sched/core.c:9163)
+netif_rx_mode_run (net/core/dev_addr_lists.c:1262)
+netif_rx_mode_sync (net/core/dev_addr_lists.c:1428)
+dev_set_promiscuity (net/core/dev_api.c:289)
+br_manage_promisc (net/bridge/br_if.c:135 net/bridge/br_if.c:172)
+br_port_flags_change (net/bridge/br_if.c:242 net/bridge/br_if.c:747)
+br_setport (net/bridge/br_netlink.c:1000)
+br_setlink (net/bridge/br_netlink.c:1118)
+rtnl_bridge_setlink (net/core/rtnetlink.c:5572)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:7005)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1318 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sock_sendmsg (net/socket.c:787 (discriminator 4) net/socket.c:802 (discriminator 4))
+____sys_sendmsg (net/socket.c:2698)
+___sys_sendmsg (net/socket.c:2752)
+__sys_sendmsg (net/socket.c:2784)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+Fixes: 78cd408356fe ("net: add missing instance lock to dev_set_promiscuity")
+Reviewed-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260526064818.272516-2-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/br_netlink.c | 17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
+index 4e2d53b2722104..6d5b2ef5f18d3d 100644
+--- a/net/bridge/br_netlink.c
++++ b/net/bridge/br_netlink.c
+@@ -1000,19 +1000,25 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[],
+       br_port_flags_change(p, changed_mask);
+       if (tb[IFLA_BRPORT_COST]) {
++              spin_lock_bh(&p->br->lock);
+               err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST]));
++              spin_unlock_bh(&p->br->lock);
+               if (err)
+                       return err;
+       }
+       if (tb[IFLA_BRPORT_PRIORITY]) {
++              spin_lock_bh(&p->br->lock);
+               err = br_stp_set_port_priority(p, nla_get_u16(tb[IFLA_BRPORT_PRIORITY]));
++              spin_unlock_bh(&p->br->lock);
+               if (err)
+                       return err;
+       }
+       if (tb[IFLA_BRPORT_STATE]) {
++              spin_lock_bh(&p->br->lock);
+               err = br_set_port_state(p, nla_get_u8(tb[IFLA_BRPORT_STATE]));
++              spin_unlock_bh(&p->br->lock);
+               if (err)
+                       return err;
+       }
+@@ -1114,9 +1120,7 @@ int br_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags,
+                       if (err)
+                               return err;
+-                      spin_lock_bh(&p->br->lock);
+                       err = br_setport(p, tb, extack);
+-                      spin_unlock_bh(&p->br->lock);
+               } else {
+                       /* Binary compatibility with old RSTP */
+                       if (nla_len(protinfo) < sizeof(u8))
+@@ -1203,17 +1207,10 @@ static int br_port_slave_changelink(struct net_device *brdev,
+                                   struct nlattr *data[],
+                                   struct netlink_ext_ack *extack)
+ {
+-      struct net_bridge *br = netdev_priv(brdev);
+-      int ret;
+-
+       if (!data)
+               return 0;
+-      spin_lock_bh(&br->lock);
+-      ret = br_setport(br_port_get_rtnl(dev), data, extack);
+-      spin_unlock_bh(&br->lock);
+-
+-      return ret;
++      return br_setport(br_port_get_rtnl(dev), data, extack);
+ }
+ static int br_port_fill_slave_info(struct sk_buff *skb,
+-- 
+2.53.0
+
diff --git a/queue-6.18/bridge-fix-sleep-in-atomic-context-in-sysfs-path.patch b/queue-6.18/bridge-fix-sleep-in-atomic-context-in-sysfs-path.patch
new file mode 100644 (file)
index 0000000..6ef97d1
--- /dev/null
@@ -0,0 +1,158 @@
+From ec010e21cbf9a8f3269aef3359f27e26e9969cd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 09:48:17 +0300
+Subject: bridge: Fix sleep in atomic context in sysfs path
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 6d34594cc619d0d4b07d5afcad8b5984f3526dcf ]
+
+Since the start of the git history, brport_store() always acquired the
+bridge lock. Back then this decision made sense: The bridge lock
+protects the STP state of the bridge and its ports and at that time the
+function was only used by two STP related attributes (cost and
+priority).
+
+Nowadays, brport_store() processes a lot more attributes and most of
+them do not need the bridge lock:
+
+* Bridge flags: Only require RTNL. Read locklessly by the data path.
+  Annotations can be added in net-next.
+
+* FDB port flushing: Only requires the FDB lock.
+
+* Multicast attributes: Only require the multicast lock.
+
+* Group forward mask: Only requires RTNL. Read locklessly by the data
+  path. Annotations can be added in net-next.
+
+* Backup port: Only requires RTNL. Read locklessly by the data path.
+
+This is a problem as the bridge calls dev_set_promiscuity() when certain
+bridge port flags change and this function can sleep since the commit
+cited below, resulting in a splat such as [1].
+
+Fix this by reducing the scope of the bridge lock and only take it when
+processing the two STP related attributes that require it. Remove the
+now stale comment from br_switchdev_set_port_flag(). The
+SWITCHDEV_F_DEFER flag can be removed in net-next.
+
+[1]
+BUG: sleeping function called from invalid context at net/core/dev_addr_lists.c:1262
+in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 372, name: bash
+preempt_count: 201, expected: 0
+RCU nest depth: 0, expected: 0
+5 locks held by bash/372:
+#0: ffff88810c51c3f0 (sb_writers#7){.+.+}-{0:0}, at: ksys_write (fs/read_write.c:740)
+#1: ffff888115ce9480 (&of->mutex){+.+.}-{4:4}, at: kernfs_fop_write_iter (fs/kernfs/file.c:343)
+#2: ffff88810b9fd330 (kn->active#37){.+.+}-{0:0}, at: kernfs_fop_write_iter (fs/kernfs/file.c:80 fs/kernfs/file.c:344)
+#3: ffffffffa59473a0 (rtnl_mutex){+.+.}-{4:4}, at: brport_store (net/bridge/br_sysfs_if.c:326)
+#4: ffff8881099d2d58 (&br->lock){+...}-{3:3}, at: brport_store (./include/linux/spinlock.h:348 net/bridge/br_sysfs_if.c:345)
+Preemption disabled at:
+ 0x0
+Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+Call Trace:
+<TASK>
+dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120)
+__might_resched.cold (kernel/sched/core.c:9163)
+netif_rx_mode_run (net/core/dev_addr_lists.c:1262)
+netif_rx_mode_sync (net/core/dev_addr_lists.c:1428)
+dev_set_promiscuity (net/core/dev_api.c:289)
+br_manage_promisc (net/bridge/br_if.c:135 net/bridge/br_if.c:172)
+br_port_flags_change (net/bridge/br_if.c:242 net/bridge/br_if.c:747)
+store_learning (net/bridge/br_sysfs_if.c:79 net/bridge/br_sysfs_if.c:235)
+brport_store (net/bridge/br_sysfs_if.c:346)
+kernfs_fop_write_iter (fs/kernfs/file.c:352)
+new_sync_write (fs/read_write.c:595)
+vfs_write (fs/read_write.c:688)
+ksys_write (fs/read_write.c:740)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+Fixes: 78cd408356fe ("net: add missing instance lock to dev_set_promiscuity")
+Reviewed-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260526064818.272516-3-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/br_switchdev.c |  1 -
+ net/bridge/br_sysfs_if.c  | 30 ++++++++++++++++++++++--------
+ 2 files changed, 22 insertions(+), 9 deletions(-)
+
+diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
+index fe3f7bbe86ee62..b5c6e314204f94 100644
+--- a/net/bridge/br_switchdev.c
++++ b/net/bridge/br_switchdev.c
+@@ -99,7 +99,6 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
+       attr.u.brport_flags.val = flags;
+       attr.u.brport_flags.mask = mask;
+-      /* We run from atomic context here */
+       err = call_switchdev_notifiers(SWITCHDEV_PORT_ATTR_SET, p->dev,
+                                      &info.info, extack);
+       err = notifier_to_errno(err);
+diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
+index 74fdd8105dca9e..3fe664fd1f5b82 100644
+--- a/net/bridge/br_sysfs_if.c
++++ b/net/bridge/br_sysfs_if.c
+@@ -86,16 +86,34 @@ static ssize_t show_path_cost(struct net_bridge_port *p, char *buf)
+       return sprintf(buf, "%d\n", p->path_cost);
+ }
+-static BRPORT_ATTR(path_cost, 0644,
+-                 show_path_cost, br_stp_set_path_cost);
++static int store_path_cost(struct net_bridge_port *p, unsigned long v)
++{
++      int ret;
++
++      spin_lock_bh(&p->br->lock);
++      ret = br_stp_set_path_cost(p, v);
++      spin_unlock_bh(&p->br->lock);
++      return ret;
++}
++
++static BRPORT_ATTR(path_cost, 0644, show_path_cost, store_path_cost);
+ static ssize_t show_priority(struct net_bridge_port *p, char *buf)
+ {
+       return sprintf(buf, "%d\n", p->priority);
+ }
+-static BRPORT_ATTR(priority, 0644,
+-                       show_priority, br_stp_set_port_priority);
++static int store_priority(struct net_bridge_port *p, unsigned long v)
++{
++      int ret;
++
++      spin_lock_bh(&p->br->lock);
++      ret = br_stp_set_port_priority(p, v);
++      spin_unlock_bh(&p->br->lock);
++      return ret;
++}
++
++static BRPORT_ATTR(priority, 0644, show_priority, store_priority);
+ static ssize_t show_designated_root(struct net_bridge_port *p, char *buf)
+ {
+@@ -334,17 +352,13 @@ static ssize_t brport_store(struct kobject *kobj,
+                       ret = -ENOMEM;
+                       goto out_unlock;
+               }
+-              spin_lock_bh(&p->br->lock);
+               ret = brport_attr->store_raw(p, buf_copy);
+-              spin_unlock_bh(&p->br->lock);
+               kfree(buf_copy);
+       } else if (brport_attr->store) {
+               val = simple_strtoul(buf, &endp, 0);
+               if (endp == buf)
+                       goto out_unlock;
+-              spin_lock_bh(&p->br->lock);
+               ret = brport_attr->store(p, val);
+-              spin_unlock_bh(&p->br->lock);
+       }
+       if (!ret) {
+-- 
+2.53.0
+
diff --git a/queue-6.18/cxl-test-update-mock-dev-array-before-calling-platfo.patch b/queue-6.18/cxl-test-update-mock-dev-array-before-calling-platfo.patch
new file mode 100644 (file)
index 0000000..416d59b
--- /dev/null
@@ -0,0 +1,272 @@
+From 20bd511145f9c4b316a8031d166c461dbae99f6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 20:14:57 +0800
+Subject: cxl/test: Update mock dev array before calling platform_device_add()
+
+From: Li Ming <ming.li@zohomail.com>
+
+[ Upstream commit d90f236f8b9e354848bd226f581db27755ab901d ]
+
+CXL test environment hits the following error sometimes.
+
+ cxl_mem mem9: endpoint7 failed probe
+
+All mock memdevs are platform firmware devices added by cxl_test module,
+and cxl_test module also provides a platform device driver for them to
+create a memdev device to CXL subsystem. cxl_test module uses
+cxl_rcd/mem_single/mem arrays to store different types of mock memdevs.
+CXL drivers calls registered mock functions for a mock memdev by
+checking if a given memdev is in these arrays.
+
+When cxl_test module adds these mock memdevs, it always calls
+platform_device_add() before adding them to a suitable mock memdev
+array. However, there is a small window where CXL drivers calls mock
+function for a added memdev before it added to a mock memdev array. In
+above case, cxl endpoint driver considers a added memdev was not a mock
+memdev, then calling devm_cxl_endpoint_decoders_setup() for it rather
+than mock_endpoint_decoders_setup().
+
+An appropriate solution is that adding a new mock device to a mock
+device array before calling platform_device_add() for it. It can
+guarantee the new mock device is visible to CXL subsystem.
+
+This patch introduces a new helped called cxl_mock_platform_device_add()
+to handle the issue, and uses the function for all mock devices addition.
+
+Fixes: 3a2b97b3210b ("cxl/test: Improve init-order fidelity relative to real-world systems")
+Signed-off-by: Li Ming <ming.li@zohomail.com>
+Tested-by: Alison Schofield <alison.schofield@intel.com>
+Reviewed-by: Alison Schofield <alison.schofield@intel.com>
+Link: https://patch.msgid.link/20260520121457.234404-1-ming.li@zohomail.com
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/cxl/test/cxl.c | 105 ++++++++++++++---------------------
+ 1 file changed, 43 insertions(+), 62 deletions(-)
+
+diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
+index 2d135ca533d02b..5771c75bc58893 100644
+--- a/tools/testing/cxl/test/cxl.c
++++ b/tools/testing/cxl/test/cxl.c
+@@ -1132,6 +1132,23 @@ static void mock_companion(struct acpi_device *adev, struct device *dev)
+ #define SZ_64G (SZ_32G * 2)
+ #endif
++static int cxl_mock_platform_device_add(struct platform_device *pdev,
++                                      struct platform_device **ppdev)
++{
++      int rc;
++
++      if (ppdev)
++              *ppdev = pdev;
++      rc = platform_device_add(pdev);
++      if (rc) {
++              platform_device_put(pdev);
++              if (ppdev)
++                      *ppdev = NULL;
++      }
++
++      return rc;
++}
++
+ static __init int cxl_rch_topo_init(void)
+ {
+       int rc, i;
+@@ -1146,13 +1163,10 @@ static __init int cxl_rch_topo_init(void)
+                       goto err_bridge;
+               mock_companion(adev, &pdev->dev);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_rch[i]);
++              if (rc)
+                       goto err_bridge;
+-              }
+-              cxl_rch[i] = pdev;
+               mock_pci_bus[idx].bridge = &pdev->dev;
+               rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
+                                      "firmware_node");
+@@ -1204,13 +1218,10 @@ static __init int cxl_single_topo_init(void)
+                       goto err_bridge;
+               mock_companion(adev, &pdev->dev);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_hb_single[i]);
++              if (rc)
+                       goto err_bridge;
+-              }
+-              cxl_hb_single[i] = pdev;
+               mock_pci_bus[i + NR_CXL_HOST_BRIDGES].bridge = &pdev->dev;
+               rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
+                                      "physical_node");
+@@ -1229,12 +1240,9 @@ static __init int cxl_single_topo_init(void)
+                       goto err_port;
+               pdev->dev.parent = &bridge->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_root_single[i]);
++              if (rc)
+                       goto err_port;
+-              }
+-              cxl_root_single[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_swu_single); i++) {
+@@ -1247,12 +1255,9 @@ static __init int cxl_single_topo_init(void)
+                       goto err_uport;
+               pdev->dev.parent = &root_port->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_swu_single[i]);
++              if (rc)
+                       goto err_uport;
+-              }
+-              cxl_swu_single[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_swd_single); i++) {
+@@ -1266,12 +1271,9 @@ static __init int cxl_single_topo_init(void)
+                       goto err_dport;
+               pdev->dev.parent = &uport->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_swd_single[i]);
++              if (rc)
+                       goto err_dport;
+-              }
+-              cxl_swd_single[i] = pdev;
+       }
+       return 0;
+@@ -1344,12 +1346,9 @@ static int cxl_mem_init(void)
+               pdev->dev.parent = &dport->dev;
+               set_dev_node(&pdev->dev, i % 2);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_mem[i]);
++              if (rc)
+                       goto err_mem;
+-              }
+-              cxl_mem[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_mem_single); i++) {
+@@ -1362,12 +1361,9 @@ static int cxl_mem_init(void)
+               pdev->dev.parent = &dport->dev;
+               set_dev_node(&pdev->dev, i % 2);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_mem_single[i]);
++              if (rc)
+                       goto err_single;
+-              }
+-              cxl_mem_single[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_rcd); i++) {
+@@ -1381,12 +1377,9 @@ static int cxl_mem_init(void)
+               pdev->dev.parent = &rch->dev;
+               set_dev_node(&pdev->dev, i % 2);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_rcd[i]);
++              if (rc)
+                       goto err_rcd;
+-              }
+-              cxl_rcd[i] = pdev;
+       }
+       return 0;
+@@ -1451,13 +1444,10 @@ static __init int cxl_test_init(void)
+                       goto err_bridge;
+               mock_companion(adev, &pdev->dev);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_host_bridge[i]);
++              if (rc)
+                       goto err_bridge;
+-              }
+-              cxl_host_bridge[i] = pdev;
+               mock_pci_bus[i].bridge = &pdev->dev;
+               rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
+                                      "physical_node");
+@@ -1475,12 +1465,9 @@ static __init int cxl_test_init(void)
+                       goto err_port;
+               pdev->dev.parent = &bridge->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_root_port[i]);
++              if (rc)
+                       goto err_port;
+-              }
+-              cxl_root_port[i] = pdev;
+       }
+       BUILD_BUG_ON(ARRAY_SIZE(cxl_switch_uport) != ARRAY_SIZE(cxl_root_port));
+@@ -1493,12 +1480,9 @@ static __init int cxl_test_init(void)
+                       goto err_uport;
+               pdev->dev.parent = &root_port->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_switch_uport[i]);
++              if (rc)
+                       goto err_uport;
+-              }
+-              cxl_switch_uport[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_switch_dport); i++) {
+@@ -1511,12 +1495,9 @@ static __init int cxl_test_init(void)
+                       goto err_dport;
+               pdev->dev.parent = &uport->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_switch_dport[i]);
++              if (rc)
+                       goto err_dport;
+-              }
+-              cxl_switch_dport[i] = pdev;
+       }
+       rc = cxl_single_topo_init();
+@@ -1534,9 +1515,9 @@ static __init int cxl_test_init(void)
+       mock_companion(&acpi0017_mock, &cxl_acpi->dev);
+       acpi0017_mock.dev.bus = &platform_bus_type;
+-      rc = platform_device_add(cxl_acpi);
++      rc = cxl_mock_platform_device_add(cxl_acpi, NULL);
+       if (rc)
+-              goto err_root;
++              goto err_rch;
+       rc = cxl_mem_init();
+       if (rc)
+-- 
+2.53.0
+
diff --git a/queue-6.18/drm-xe-restore-idledly-regiter-on-engine-reset.patch b/queue-6.18/drm-xe-restore-idledly-regiter-on-engine-reset.patch
new file mode 100644 (file)
index 0000000..710f2f1
--- /dev/null
@@ -0,0 +1,43 @@
+From 3e1f83ee7c1219adf3c5f51eada0ad850b451c88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 22:05:32 +0530
+Subject: drm/xe: Restore IDLEDLY regiter on engine reset
+
+From: Balasubramani Vivekanandan <balasubramani.vivekanandan@intel.com>
+
+[ Upstream commit f657a6a3ba4c20bc01f5be3752d53498ee1bfe35 ]
+
+Wa_16023105232 programs the register IDLEDLY. The register is reset
+whenever the engine is reset. Therefore it should be added to the GuC
+save-restore register list for it to be restored after reset.
+
+Fixes: 7c53ff050ba8 ("drm/xe: Apply Wa_16023105232")
+Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patch.msgid.link/20260522163531.1365540-2-balasubramani.vivekanandan@intel.com
+Signed-off-by: Balasubramani Vivekanandan <balasubramani.vivekanandan@intel.com>
+(cherry picked from commit df1cfe24743a93b71eab27687e148ab8ae9b69e3)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_ads.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_ads.c b/drivers/gpu/drm/xe/xe_guc_ads.c
+index 0e2bece1d8b83b..db71823b253801 100644
+--- a/drivers/gpu/drm/xe/xe_guc_ads.c
++++ b/drivers/gpu/drm/xe/xe_guc_ads.c
+@@ -772,6 +772,11 @@ static unsigned int guc_mmio_regset_write(struct xe_guc_ads *ads,
+               }
+       }
++      if (XE_GT_WA(hwe->gt, 16023105232))
++              guc_mmio_regset_write_one(ads, regset_map,
++                                        RING_IDLEDLY(hwe->mmio_base),
++                                        count++);
++
+       return count;
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-cmis-fix-u16-to-u8-truncation-of-msleep_pre_.patch b/queue-6.18/ethtool-cmis-fix-u16-to-u8-truncation-of-msleep_pre_.patch
new file mode 100644 (file)
index 0000000..fb67f8b
--- /dev/null
@@ -0,0 +1,52 @@
+From 71887194c285cba821f41e7f6293a7dbf281b6a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:10 -0700
+Subject: ethtool: cmis: fix u16-to-u8 truncation of msleep_pre_rpl
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 3e8c3d464c36bb342fe377b026577c7ec27fdbb4 ]
+
+ethtool_cmis_cdb_compose_args() accepts msleep_pre_rpl as u16 but stores
+it into the u8 field ethtool_cmis_cdb_cmd_args::msleep_pre_rpl, silently
+truncating values >= 256. Seven of the nine call sites pass 1000 ms
+(it's the third argument from the end).
+
+Fixes: a39c84d79625 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-8-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
+index 4a9a946cabf05d..778783a0f23c0b 100644
+--- a/net/ethtool/cmis.h
++++ b/net/ethtool/cmis.h
+@@ -63,9 +63,9 @@ struct ethtool_cmis_cdb_request {
+  * struct ethtool_cmis_cdb_cmd_args - CDB commands execution arguments
+  * @req: CDB command fields as described in the CMIS standard.
+  * @max_duration: Maximum duration time for command completion in msec.
++ * @msleep_pre_rpl: Waiting time before checking reply in msec.
+  * @read_write_len_ext: Allowable additional number of byte octets to the LPL
+  *                    in a READ or a WRITE commands.
+- * @msleep_pre_rpl: Waiting time before checking reply in msec.
+  * @rpl_exp_len: Expected reply length in bytes.
+  * @flags: Validation flags for CDB commands.
+  * @err_msg: Error message to be sent to user space.
+@@ -73,8 +73,8 @@ struct ethtool_cmis_cdb_request {
+ struct ethtool_cmis_cdb_cmd_args {
+       struct ethtool_cmis_cdb_request req;
+       u16                             max_duration;
++      u16                             msleep_pre_rpl;
+       u8                              read_write_len_ext;
+-      u8                              msleep_pre_rpl;
+       u8                              rpl_exp_len;
+       u8                              flags;
+       char                            *err_msg;
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-cmis-require-exact-cdb-reply-length.patch b/queue-6.18/ethtool-cmis-require-exact-cdb-reply-length.patch
new file mode 100644 (file)
index 0000000..f2accae
--- /dev/null
@@ -0,0 +1,70 @@
+From 01f3878a50dcd39f1707981a3568bc4e9a42a228 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:09 -0700
+Subject: ethtool: cmis: require exact CDB reply length
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 6c3f999a9d1338c6c89a9ff4549eafe72bc2e7b1 ]
+
+Malicious SFP module could respond with rpl_len longer than
+what cmis_cdb_process_reply() expected, leading to OOB writes.
+Malicious HW is a bit theoretical but some modules may just
+be buggy and/or the reads may occasionally get corrupted,
+so let's protect the kernel.
+
+The existing check protects from short replies. We need to
+protect from long ones, too. All callers that pass a non-zero
+rpl_exp_len cast the reply payload to a fixed-layout struct
+and read fields at fixed offsets, with no version negotiation
+or short-reply handling:
+
+  - cmis_cdb_validate_password()
+  - cmis_cdb_module_features_get()
+  - cmis_fw_update_fw_mng_features_get()
+
+so let's assume that responses longer than expected do not
+have to be handled gracefully here. Add a warning message
+to make the debug easier in case my understanding is wrong...
+
+Note that page_data->length (argument of kmalloc) comes from
+last arg to ethtool_cmis_page_init() which is rpl_exp_len.
+
+Note2 that AIs also like to point out overflows in args->req.payload
+itself (which is a fixed-size 120 B buffer, on the stack),
+but callers should be reading structs defined by the standard,
+so protecting from requests for more data than max seem like
+defensive programming.
+
+Fixes: a39c84d79625 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands")
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-7-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis_cdb.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
+index 3057576bc81e3d..fe156991d0becd 100644
+--- a/net/ethtool/cmis_cdb.c
++++ b/net/ethtool/cmis_cdb.c
+@@ -513,8 +513,13 @@ static int cmis_cdb_process_reply(struct net_device *dev,
+       }
+       rpl = (struct ethtool_cmis_cdb_rpl *)page_data->data;
+-      if ((args->rpl_exp_len > rpl->hdr.rpl_len + rpl_hdr_len) ||
+-          !rpl->hdr.rpl_chk_code) {
++      if (rpl->hdr.rpl_len != args->rpl_exp_len) {
++              netdev_warn(dev, "CDB reply length mismatch, expected %u got %u\n",
++                          args->rpl_exp_len, rpl->hdr.rpl_len);
++              err = -EIO;
++              goto out;
++      }
++      if (!rpl->hdr.rpl_chk_code) {
+               err = -EIO;
+               goto out;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-cmis-validate-fw-size-against-start_cmd_payl.patch b/queue-6.18/ethtool-cmis-validate-fw-size-against-start_cmd_payl.patch
new file mode 100644 (file)
index 0000000..4662398
--- /dev/null
@@ -0,0 +1,48 @@
+From 394f6b454fc4397492d529895d2821cd9ad0418c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:12 -0700
+Subject: ethtool: cmis: validate fw->size against start_cmd_payload_size
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit d5551f4c1800dc714cec86647bdd651ae0de923e ]
+
+cmis_fw_update_start_download() copies start_cmd_payload_size bytes
+from the firmware blob into the CDB LPL vendor_data[] payload without
+validating that the FW has enough data.
+
+Since the start_cmd_payload_size can only be ~120B an image too short
+is most likely corrupted, so reject it.
+
+Fixes: c4f78134d45c ("ethtool: cmis_fw_update: add a layer for supporting firmware update using CDB")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-10-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis_fw_update.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/ethtool/cmis_fw_update.c b/net/ethtool/cmis_fw_update.c
+index 16190c97e1f78c..291d04d2776a5c 100644
+--- a/net/ethtool/cmis_fw_update.c
++++ b/net/ethtool/cmis_fw_update.c
+@@ -130,6 +130,14 @@ cmis_fw_update_start_download(struct ethtool_cmis_cdb *cdb,
+       u8 lpl_len;
+       int err;
++      if (fw_update->fw->size < vendor_data_size) {
++              ethnl_module_fw_flash_ntf_err(fw_update->dev,
++                                            &fw_update->ntf_params,
++                                            "Firmware image too small for module's start payload",
++                                            NULL);
++              return -EINVAL;
++      }
++
+       pl.image_size = cpu_to_be32(fw_update->fw->size);
+       memcpy(pl.vendor_data, fw_update->fw->data, vendor_data_size);
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-cmis-validate-start_cmd_payload_size-from-mo.patch b/queue-6.18/ethtool-cmis-validate-start_cmd_payload_size-from-mo.patch
new file mode 100644 (file)
index 0000000..0134b9a
--- /dev/null
@@ -0,0 +1,96 @@
+From d92ba0160dd4d91dd6678261f64f5ed7fd6b6b24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:11 -0700
+Subject: ethtool: cmis: validate start_cmd_payload_size from module
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 12c2496a71f82f63617971ca9b730dffa05cf58b ]
+
+The CMIS firmware update code reads start_cmd_payload_size from
+the module's FW Management Features CDB reply and uses it directly
+as the byte count for memcpy. The destination buffer is 112 bytes
+(ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH - 8). So a malicious
+module (or corrupted response) can cause a OOB write later on in
+cmis_fw_update_start_download().
+
+Let's error out. If modules that expect longer LPL writes actually
+exist we should revisit.
+
+struct cmis_cdb_start_fw_download_pl's definition has to move,
+no change there.
+
+Fixes: c4f78134d45c ("ethtool: cmis_fw_update: add a layer for supporting firmware update using CDB")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-9-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis_fw_update.c | 36 ++++++++++++++++++++++--------------
+ 1 file changed, 22 insertions(+), 14 deletions(-)
+
+diff --git a/net/ethtool/cmis_fw_update.c b/net/ethtool/cmis_fw_update.c
+index df5f344209c47b..16190c97e1f78c 100644
+--- a/net/ethtool/cmis_fw_update.c
++++ b/net/ethtool/cmis_fw_update.c
+@@ -44,6 +44,20 @@ enum cmis_cdb_fw_write_mechanism {
+       CMIS_CDB_FW_WRITE_MECHANISM_BOTH        = 0x11,
+ };
++/* See section 9.7.2 "CMD 0101h: Start Firmware Download" in CMIS standard
++ * revision 5.2.
++ * struct cmis_cdb_start_fw_download_pl is a structured layout of the
++ * flat array, ethtool_cmis_cdb_request::payload.
++ */
++struct cmis_cdb_start_fw_download_pl {
++      __struct_group(cmis_cdb_start_fw_download_pl_h, head, /* no attrs */,
++                      __be32  image_size;
++                      __be32  resv1;
++      );
++      u8 vendor_data[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH -
++              sizeof(struct cmis_cdb_start_fw_download_pl_h)];
++};
++
+ static int
+ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
+                                  struct net_device *dev,
+@@ -86,6 +100,14 @@ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
+        */
+       cdb->read_write_len_ext = rpl->read_write_len_ext;
+       fw_mng->start_cmd_payload_size = rpl->start_cmd_payload_size;
++      if (fw_mng->start_cmd_payload_size >
++          sizeof_field(struct cmis_cdb_start_fw_download_pl, vendor_data)) {
++              ethnl_module_fw_flash_ntf_err(dev, ntf_params,
++                                            "Start cmd payload size exceeds max LPL payload",
++                                            NULL);
++              return -EINVAL;
++      }
++
+       fw_mng->write_mechanism =
+               rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_LPL ?
+               CMIS_CDB_FW_WRITE_MECHANISM_LPL :
+@@ -97,20 +119,6 @@ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
+       return 0;
+ }
+-/* See section 9.7.2 "CMD 0101h: Start Firmware Download" in CMIS standard
+- * revision 5.2.
+- * struct cmis_cdb_start_fw_download_pl is a structured layout of the
+- * flat array, ethtool_cmis_cdb_request::payload.
+- */
+-struct cmis_cdb_start_fw_download_pl {
+-      __struct_group(cmis_cdb_start_fw_download_pl_h, head, /* no attrs */,
+-                      __be32  image_size;
+-                      __be32  resv1;
+-      );
+-      u8 vendor_data[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH -
+-              sizeof(struct cmis_cdb_start_fw_download_pl_h)];
+-};
+-
+ static int
+ cmis_fw_update_start_download(struct ethtool_cmis_cdb *cdb,
+                             struct ethtool_cmis_fw_update_params *fw_update,
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-coalesce-cap-profile-updates-at-net_dim_para.patch b/queue-6.18/ethtool-coalesce-cap-profile-updates-at-net_dim_para.patch
new file mode 100644 (file)
index 0000000..c9f6ce6
--- /dev/null
@@ -0,0 +1,45 @@
+From 58d233b2ebb5dc1d314c3abf33a320e45d6294f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:24 -0700
+Subject: ethtool: coalesce: cap profile updates at NET_DIM_PARAMS_NUM_PROFILES
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 7281b096b072f6c6e30420e3467d738f2e4c4b57 ]
+
+ethnl_update_profile() walks the ETHTOOL_A_PROFILE_IRQ_MODERATION
+nest list with an index 'i' and writes new_profile[i++] without
+bounding i. The destination is kmemdup()'d at NET_DIM_PARAMS_NUM_PROFILES
+entries (5), but the Netlink nest count is entirely user-controlled.
+Netlink policies do not have support for constraining the number
+of nested entries (or number of multi-attr entries).
+
+Fixes: f750dfe825b9 ("ethtool: provide customized dim profile management")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-2-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/coalesce.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/ethtool/coalesce.c b/net/ethtool/coalesce.c
+index 3e18ca1ccc5ef6..cace02d964cb21 100644
+--- a/net/ethtool/coalesce.c
++++ b/net/ethtool/coalesce.c
+@@ -463,6 +463,12 @@ static int ethnl_update_profile(struct net_device *dev,
+       nla_for_each_nested_type(nest, ETHTOOL_A_PROFILE_IRQ_MODERATION,
+                                nests, rem) {
++              if (i >= NET_DIM_PARAMS_NUM_PROFILES) {
++                      NL_SET_BAD_ATTR(extack, nest);
++                      ret = -E2BIG;
++                      goto err_out;
++              }
++
+               ret = nla_parse_nested(tb, len_irq_moder - 1, nest,
+                                      coalesce_irq_moderation_policy,
+                                      extack);
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch b/queue-6.18/ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch
new file mode 100644 (file)
index 0000000..1e58526
--- /dev/null
@@ -0,0 +1,48 @@
+From 637d92e057c693b4597c17b89fe97155723406b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:32 -0700
+Subject: ethtool: eeprom: add missing ethnl_ops_begin() / _complete() during
+ fallback
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 2376586f85f972fefe701f095bb37dcfe7405d21 ]
+
+All ethtool driver op calls should be sandwiched between
+ethnl_ops_begin() / ethnl_ops_complete(). In Netlink eeprom code,
+if the paged access failed we fall back to old API, but we
+first call _complete() and the fallback never does its own
+ethnl_ops_begin(). Move the fallback into the _begin() / _complete()
+section.
+
+Fixes: 96d971e307cc ("ethtool: Add fallback to get_module_eeprom from netlink command")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-10-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/eeprom.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c
+index 3b8209e930fd3a..03cb418a15823b 100644
+--- a/net/ethtool/eeprom.c
++++ b/net/ethtool/eeprom.c
+@@ -140,12 +140,11 @@ static int eeprom_prepare_data(const struct ethnl_req_info *req_base,
+       return 0;
+ err_ops:
++      if (ret == -EOPNOTSUPP)
++              ret = eeprom_fallback(request, reply);
+       ethnl_ops_complete(dev);
+ err_free:
+       kfree(page_data.data);
+-
+-      if (ret == -EOPNOTSUPP)
+-              return eeprom_fallback(request, reply);
+       return ret;
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch b/queue-6.18/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
new file mode 100644 (file)
index 0000000..4e9cdaa
--- /dev/null
@@ -0,0 +1,62 @@
+From 32e6a7649ddbbac971ff8af78da3dfb63e930df2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:33 -0700
+Subject: ethtool: eeprom: add more safeties to EEPROM Netlink fallback
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 67cfdd9210b99f260b3e0afeb9525e0acc7be31e ]
+
+The Netlink fallback path for reading module EEPROM
+(fallback_set_params()) validates that offset < eeprom_len,
+but does not check that offset + length stays within eeprom_len.
+The ioctl equivalent (ethtool_get_any_eeprom() in ioctl.c) has
+always enforced both bounds:
+
+  if (eeprom.offset + eeprom.len > total_len)
+      return -EINVAL;
+
+This could lead to surprises in both drivers and device FW.
+Add the missing offset + length validation to fallback_set_params(),
+mirroring the ioctl.
+
+Similarly - ethtool core in general, and ethtool_get_any_eeprom()
+in particular tries to zero-init all buffers passed to the drivers
+to avoid any extra work of zeroing things out. eeprom_fallback()
+uses a plain kmalloc(), change it to zalloc.
+
+Fixes: 96d971e307cc ("ethtool: Add fallback to get_module_eeprom from netlink command")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-11-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/eeprom.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c
+index 03cb418a15823b..80af38a6c76acf 100644
+--- a/net/ethtool/eeprom.c
++++ b/net/ethtool/eeprom.c
+@@ -43,6 +43,9 @@ static int fallback_set_params(struct eeprom_req_info *request,
+       if (offset >= modinfo->eeprom_len)
+               return -EINVAL;
++      if (length > modinfo->eeprom_len - offset)
++              return -EINVAL;
++
+       eeprom->cmd = ETHTOOL_GMODULEEEPROM;
+       eeprom->len = length;
+       eeprom->offset = offset;
+@@ -68,7 +71,7 @@ static int eeprom_fallback(struct eeprom_req_info *request,
+       if (err < 0)
+               return err;
+-      data = kmalloc(eeprom.len, GFP_KERNEL);
++      data = kzalloc(eeprom.len, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+       err = ethtool_get_module_eeprom_call(dev, &eeprom, data);
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-linkstate-fix-unbalanced-ethnl_ops_complete-.patch b/queue-6.18/ethtool-linkstate-fix-unbalanced-ethnl_ops_complete-.patch
new file mode 100644 (file)
index 0000000..54bf63e
--- /dev/null
@@ -0,0 +1,43 @@
+From 2f4548a2f2a530b33e8fcdf0f35b07c310a7ccd4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:26 -0700
+Subject: ethtool: linkstate: fix unbalanced ethnl_ops_complete() on PHY lookup
+ error
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 596c51ed9e125b12c4d85b4530dfd4c7847634b7 ]
+
+linkstate_prepare_data() calls ethnl_req_get_phydev() before
+ethnl_ops_begin(), but routes its error path through "goto out"
+which calls ethnl_ops_complete().
+
+Fixes: fe55b1d401c6 ("ethtool: linkstate: migrate linkstate functions to support multi-PHY setups")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-4-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/linkstate.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/net/ethtool/linkstate.c b/net/ethtool/linkstate.c
+index 05a5f72c99fab1..3dc52a39d34525 100644
+--- a/net/ethtool/linkstate.c
++++ b/net/ethtool/linkstate.c
+@@ -105,10 +105,8 @@ static int linkstate_prepare_data(const struct ethnl_req_info *req_base,
+       phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_LINKSTATE_HEADER,
+                                     info->extack);
+-      if (IS_ERR(phydev)) {
+-              ret = PTR_ERR(phydev);
+-              goto out;
+-      }
++      if (IS_ERR(phydev))
++              return PTR_ERR(phydev);
+       ret = ethnl_ops_begin(dev);
+       if (ret < 0)
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-module-avoid-leaking-a-netdev-ref-on-module-.patch b/queue-6.18/ethtool-module-avoid-leaking-a-netdev-ref-on-module-.patch
new file mode 100644 (file)
index 0000000..a16fd12
--- /dev/null
@@ -0,0 +1,50 @@
+From 0f4d67c484013322a6f85a0b0c9379a1e18bc8f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:05 -0700
+Subject: ethtool: module: avoid leaking a netdev ref on module flash errors
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit fb7f511d62692661846c47f199e0afe25c2982db ]
+
+module_flash_fw_schedule() is missing undo for setting
+the "in_progress" flag and taking the netdev reference.
+Delay taking these, the device can't disappear while
+we are holding rtnl_lock.
+
+Fixes: 32b4c8b53ee7 ("ethtool: Add ability to flash transceiver modules' firmware")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-3-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/module.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/module.c b/net/ethtool/module.c
+index 05e4c1d785656f..fb61bb47083e62 100644
+--- a/net/ethtool/module.c
++++ b/net/ethtool/module.c
+@@ -319,8 +319,6 @@ module_flash_fw_schedule(struct net_device *dev, const char *file_name,
+       if (err < 0)
+               goto err_release_firmware;
+-      dev->ethtool->module_fw_flash_in_progress = true;
+-      netdev_hold(dev, &module_fw->dev_tracker, GFP_KERNEL);
+       fw_update->dev = dev;
+       fw_update->ntf_params.portid = info->snd_portid;
+       fw_update->ntf_params.seq = info->snd_seq;
+@@ -335,6 +333,9 @@ module_flash_fw_schedule(struct net_device *dev, const char *file_name,
+       if (err < 0)
+               goto err_release_firmware;
++      dev->ethtool->module_fw_flash_in_progress = true;
++      netdev_hold(dev, &module_fw->dev_tracker, GFP_KERNEL);
++
+       schedule_work(&module_fw->work);
+       return 0;
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-module-avoid-racy-updates-to-dev-ethtool-bit.patch b/queue-6.18/ethtool-module-avoid-racy-updates-to-dev-ethtool-bit.patch
new file mode 100644 (file)
index 0000000..7f2392e
--- /dev/null
@@ -0,0 +1,64 @@
+From 258ac0ffb852706b67725a68707387bdd7327d6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:06 -0700
+Subject: ethtool: module: avoid racy updates to dev->ethtool bitfield
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 7a84b965ffc12030af63cd10a8f3a1123ff39b7a ]
+
+When reviewing other changes Gemini points out that we currently
+update module_fw_flash_in_progress without holding any locks.
+Since module_fw_flash_in_progress is part of a bitfield this
+is not great, updates to other fields may be lost.
+
+We could use a bool and sprinkle some READ_ONCE/WRITE_ONCE here
+but seems like the issue is rather than the work is an unusual
+writer. The other writers already hold the right locks. So just
+very briefly take these locks when the work completes.
+
+Note that nothing ever cancels the FW update work, so there's
+no concern with deadlocks vs cancel.
+
+Fixes: 32b4c8b53ee7 ("ethtool: Add ability to flash transceiver modules' firmware")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-4-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/module.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/module.c b/net/ethtool/module.c
+index fb61bb47083e62..8929b7fb2fa79c 100644
+--- a/net/ethtool/module.c
++++ b/net/ethtool/module.c
+@@ -221,14 +221,22 @@ static void module_flash_fw_work_list_del(struct list_head *list)
+ static void module_flash_fw_work(struct work_struct *work)
+ {
+       struct ethtool_module_fw_flash *module_fw;
++      struct net_device *dev;
+       module_fw = container_of(work, struct ethtool_module_fw_flash, work);
++      dev = module_fw->fw_update.dev;
+       ethtool_cmis_fw_update(&module_fw->fw_update);
+       module_flash_fw_work_list_del(&module_fw->list);
+-      module_fw->fw_update.dev->ethtool->module_fw_flash_in_progress = false;
+-      netdev_put(module_fw->fw_update.dev, &module_fw->dev_tracker);
++
++      rtnl_lock();
++      netdev_lock_ops(dev);
++      dev->ethtool->module_fw_flash_in_progress = false;
++      netdev_unlock_ops(dev);
++      rtnl_unlock();
++
++      netdev_put(dev, &module_fw->dev_tracker);
+       release_firmware(module_fw->fw_update.fw);
+       kfree(module_fw);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-module-call-ethnl_ops_complete-on-module-fla.patch b/queue-6.18/ethtool-module-call-ethnl_ops_complete-on-module-fla.patch
new file mode 100644 (file)
index 0000000..0290755
--- /dev/null
@@ -0,0 +1,42 @@
+From e477c2b51f6eba050ce3a011a7f097ff75cbe261 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:04 -0700
+Subject: ethtool: module: call ethnl_ops_complete() on module flash errors
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 84371fb58423f997939aacdcbc02d128d76a54e5 ]
+
+When validate() fails we are skipping over ethnl_ops_complete()
+even tho we already called ethnl_ops_begin().
+
+Fixes: 32b4c8b53ee7 ("ethtool: Add ability to flash transceiver modules' firmware")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-2-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/module.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/module.c b/net/ethtool/module.c
+index 4d4e0a82579a2b..05e4c1d785656f 100644
+--- a/net/ethtool/module.c
++++ b/net/ethtool/module.c
+@@ -427,10 +427,11 @@ int ethnl_act_module_fw_flash(struct sk_buff *skb, struct genl_info *info)
+       ret = ethnl_module_fw_flash_validate(dev, info->extack);
+       if (ret < 0)
+-              goto out_unlock;
++              goto out_complete;
+       ret = module_flash_fw(dev, tb, skb, info);
++out_complete:
+       ethnl_ops_complete(dev);
+ out_unlock:
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-module-check-fw_flash_in_progress-under-rtnl.patch b/queue-6.18/ethtool-module-check-fw_flash_in_progress-under-rtnl.patch
new file mode 100644 (file)
index 0000000..e9f86d8
--- /dev/null
@@ -0,0 +1,56 @@
+From 6824894de8ebb2942bcfc2ea19ca807cd75c3800 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:07 -0700
+Subject: ethtool: module: check fw_flash_in_progress under rtnl_lock
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 504eaefa44c8dec50f7499edcb36d24f3aefab2a ]
+
+ethnl_set_module_validate() inspects module_fw_flash_in_progress
+but validate is meant for _input_ validation, not state validation.
+rtnl_lock is not held, yet. Move the check into ethnl_set_module().
+
+Fixes: 32b4c8b53ee7 ("ethtool: Add ability to flash transceiver modules' firmware")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-5-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/module.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/net/ethtool/module.c b/net/ethtool/module.c
+index 8929b7fb2fa79c..202e4c25280a76 100644
+--- a/net/ethtool/module.c
++++ b/net/ethtool/module.c
+@@ -120,12 +120,6 @@ ethnl_set_module_validate(struct ethnl_req_info *req_info,
+       if (!tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY])
+               return 0;
+-      if (req_info->dev->ethtool->module_fw_flash_in_progress) {
+-              NL_SET_ERR_MSG(info->extack,
+-                             "Module firmware flashing is in progress");
+-              return -EBUSY;
+-      }
+-
+       if (!ops->get_module_power_mode || !ops->set_module_power_mode) {
+               NL_SET_ERR_MSG_ATTR(info->extack,
+                                   tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY],
+@@ -148,6 +142,12 @@ ethnl_set_module(struct ethnl_req_info *req_info, struct genl_info *info)
+       ops = dev->ethtool_ops;
++      if (dev->ethtool->module_fw_flash_in_progress) {
++              NL_SET_ERR_MSG(info->extack,
++                             "Module firmware flashing is in progress");
++              return -EBUSY;
++      }
++
+       power_new.policy = nla_get_u8(tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY]);
+       ret = ops->get_module_power_mode(dev, &power, info->extack);
+       if (ret < 0)
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-module-fix-cleanup-if-socket-used-for-flashi.patch b/queue-6.18/ethtool-module-fix-cleanup-if-socket-used-for-flashi.patch
new file mode 100644 (file)
index 0000000..e79abea
--- /dev/null
@@ -0,0 +1,105 @@
+From 632e6a08d5eb4ad328ab4ac446b37bf5bd72ffc7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:08 -0700
+Subject: ethtool: module: fix cleanup if socket used for flashing multiple
+ devices
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 760d04ebad5c4304f22c0d2251c9623b87a117c8 ]
+
+When a single Netlink socket issues MODULE_FW_FLASH_ACT against multiple
+devices, ethnl_sock_priv_set() overwrites sk_priv->dev on each call,
+retaining only the last one. The socket priv is used on socket close,
+to walk the global work list and mark the uncompleted flashing work
+as "orphaned". Otherwise if another socket reuses the PID it will
+unexpectedly receive the flashing notifications.
+
+Don't record the device, record net pointer instead. The purpose of
+the dev is to scope the work to a netns, anyway. If we store netns
+the overrides are safe/a nop since all flashed devices must be in
+the same netns as the socket.
+
+Fixes: 32b4c8b53ee7 ("ethtool: Add ability to flash transceiver modules' firmware")
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-6-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/module.c  | 9 ++++-----
+ net/ethtool/netlink.c | 4 ++--
+ net/ethtool/netlink.h | 4 ++--
+ 3 files changed, 8 insertions(+), 9 deletions(-)
+
+diff --git a/net/ethtool/module.c b/net/ethtool/module.c
+index 202e4c25280a76..9a11e7def0029a 100644
+--- a/net/ethtool/module.c
++++ b/net/ethtool/module.c
+@@ -291,11 +291,9 @@ void ethnl_module_fw_flash_sock_destroy(struct ethnl_sock_priv *sk_priv)
+       spin_lock(&module_fw_flash_work_list_lock);
+       list_for_each_entry(work, &module_fw_flash_work_list, list) {
+-              if (work->fw_update.dev == sk_priv->dev &&
+-                  work->fw_update.ntf_params.portid == sk_priv->portid) {
++              if (work->fw_update.ntf_params.portid == sk_priv->portid &&
++                  dev_net(work->fw_update.dev) == sk_priv->net)
+                       work->fw_update.ntf_params.closed_sock = true;
+-                      break;
+-              }
+       }
+       spin_unlock(&module_fw_flash_work_list_lock);
+ }
+@@ -332,7 +330,8 @@ module_flash_fw_schedule(struct net_device *dev, const char *file_name,
+       fw_update->ntf_params.seq = info->snd_seq;
+       fw_update->ntf_params.closed_sock = false;
+-      err = ethnl_sock_priv_set(skb, dev, fw_update->ntf_params.portid,
++      err = ethnl_sock_priv_set(skb, dev_net(dev),
++                                fw_update->ntf_params.portid,
+                                 ETHTOOL_SOCK_TYPE_MODULE_FW_FLASH);
+       if (err < 0)
+               goto err_release_firmware;
+diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
+index 2f813f25f07e1a..28577b878fd5b5 100644
+--- a/net/ethtool/netlink.c
++++ b/net/ethtool/netlink.c
+@@ -52,7 +52,7 @@ const struct nla_policy ethnl_header_policy_phy_stats[] = {
+       [ETHTOOL_A_HEADER_PHY_INDEX]            = NLA_POLICY_MIN(NLA_U32, 1),
+ };
+-int ethnl_sock_priv_set(struct sk_buff *skb, struct net_device *dev, u32 portid,
++int ethnl_sock_priv_set(struct sk_buff *skb, struct net *net, u32 portid,
+                       enum ethnl_sock_type type)
+ {
+       struct ethnl_sock_priv *sk_priv;
+@@ -61,7 +61,7 @@ int ethnl_sock_priv_set(struct sk_buff *skb, struct net_device *dev, u32 portid,
+       if (IS_ERR(sk_priv))
+               return PTR_ERR(sk_priv);
+-      sk_priv->dev = dev;
++      sk_priv->net = net;
+       sk_priv->portid = portid;
+       sk_priv->type = type;
+diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h
+index 1d4f9ecb3d263b..3923188097ac0a 100644
+--- a/net/ethtool/netlink.h
++++ b/net/ethtool/netlink.h
+@@ -318,12 +318,12 @@ enum ethnl_sock_type {
+ };
+ struct ethnl_sock_priv {
+-      struct net_device *dev;
++      struct net *net;
+       u32 portid;
+       enum ethnl_sock_type type;
+ };
+-int ethnl_sock_priv_set(struct sk_buff *skb, struct net_device *dev, u32 portid,
++int ethnl_sock_priv_set(struct sk_buff *skb, struct net *net, u32 portid,
+                       enum ethnl_sock_type type);
+ /**
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-pse-pd-fix-missing-ethnl_ops_complete.patch b/queue-6.18/ethtool-pse-pd-fix-missing-ethnl_ops_complete.patch
new file mode 100644 (file)
index 0000000..4f34059
--- /dev/null
@@ -0,0 +1,59 @@
+From 3cb77c4b69f235db9db4b6d178c7d4db595a5466 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:27 -0700
+Subject: ethtool: pse-pd: fix missing ethnl_ops_complete()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit ab5bf428fb6bd361163c7247b92750d1d24ca2ed ]
+
+pse_prepare_data() is missing ethnl_ops_complete() if
+ethnl_req_get_phydev() returned an error. Move getting
+phydev up so that we don't have to worry about this
+(similar order to linkstate_prepare_data()).
+
+Note that phydev may still be NULL (this is checked in
+pse_get_pse_attributes()), the goal isn't really to avoid
+the _begin() / _complete() calls, only to simplify the error
+handling.
+
+While at it propagate the original error. Why this code
+overrides the error with -ENODEV but !phydev generates
+-EOPNOTSUPP is unclear to me...
+
+Fixes: 31748765bed3 ("net: ethtool: pse-pd: Target the command to the requested PHY")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-5-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/pse-pd.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
+index 24def9c9dd54bf..aa4514333d13bd 100644
+--- a/net/ethtool/pse-pd.c
++++ b/net/ethtool/pse-pd.c
+@@ -61,14 +61,14 @@ static int pse_prepare_data(const struct ethnl_req_info *req_base,
+       struct phy_device *phydev;
+       int ret;
+-      ret = ethnl_ops_begin(dev);
+-      if (ret < 0)
+-              return ret;
+-
+       phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_PSE_HEADER,
+                                     info->extack);
+       if (IS_ERR(phydev))
+-              return -ENODEV;
++              return PTR_ERR(phydev);
++
++      ret = ethnl_ops_begin(dev);
++      if (ret < 0)
++              return ret;
+       ret = pse_get_pse_attributes(phydev, info->extack, data);
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-rss-add-missing-errno-on-rss-context-delete.patch b/queue-6.18/ethtool-rss-add-missing-errno-on-rss-context-delete.patch
new file mode 100644 (file)
index 0000000..0e27efb
--- /dev/null
@@ -0,0 +1,40 @@
+From 2b6a324a6092ff341b79d75115a7d89ebf559b74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:06:43 -0700
+Subject: ethtool: rss: add missing errno on RSS context delete
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 3e6c6e9782ff8a8d8ded774b07ad4590cd61d04c ]
+
+Remember to set ret before jumping out if someone tries
+to delete a context on a device which doesn't support
+contexts.
+
+Fixes: fbe09277fa63 ("ethtool: rss: support removing contexts via Netlink")
+Link: https://patch.msgid.link/20260522230647.1705600-3-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/rss.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
+index 926be5698ba4cc..688c0e4bba69db 100644
+--- a/net/ethtool/rss.c
++++ b/net/ethtool/rss.c
+@@ -1160,8 +1160,10 @@ int ethnl_rss_delete_doit(struct sk_buff *skb, struct genl_info *info)
+       dev = req.dev;
+       ops = dev->ethtool_ops;
+-      if (!ops->create_rxfh_context)
++      if (!ops->create_rxfh_context) {
++              ret = -EOPNOTSUPP;
+               goto exit_free_dev;
++      }
+       rtnl_lock();
+       netdev_lock_ops(dev);
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-rss-avoid-device-context-leak-on-reply-build.patch b/queue-6.18/ethtool-rss-avoid-device-context-leak-on-reply-build.patch
new file mode 100644 (file)
index 0000000..ed10604
--- /dev/null
@@ -0,0 +1,55 @@
+From 1b9d6536f1f48649c5b2f13cc9342ad80b9e35c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:06:47 -0700
+Subject: ethtool: rss: avoid device context leak on reply-build failure
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 32a9ecde62731c9f7412507709192c84dafc38d1 ]
+
+We wait with filling the reply for new RSS context creation
+until after the driver ->create_rxfh_context call. The driver
+needs to fill some of the defaults in the context. The failure
+of rss_fill_reply() is somewhat theoretical, but doesn't take
+much effort to handle it properly. Call ->remove_rxfh_context().
+
+If the driver's remove callback fails (some implementations like sfc
+can return real command errors from firmware RPCs) - skip the xa_erase
+and kfree, leaving the context in the xarray. This matches how
+ethnl_rss_delete_doit() behaves.
+
+Fixes: a166ab7816c5 ("ethtool: rss: support creating contexts via Netlink")
+Link: https://patch.msgid.link/20260522230647.1705600-7-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/rss.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
+index f745ddec6fbab8..b122f67dbde1d6 100644
+--- a/net/ethtool/rss.c
++++ b/net/ethtool/rss.c
+@@ -1096,7 +1096,7 @@ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
+       ntf_fail |= rss_fill_reply(rsp, &req.base, &data.base);
+       if (WARN_ON(!hdr || ntf_fail)) {
+               ret = -EMSGSIZE;
+-              goto exit_unlock;
++              goto err_remove_ctx;
+       }
+       genlmsg_end(rsp, hdr);
+@@ -1124,6 +1124,10 @@ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
+       nlmsg_free(rsp);
+       return ret;
++err_remove_ctx:
++      if (ops->remove_rxfh_context(dev, ctx, req.rss_context, NULL))
++              /* leave the context on failure, like ethnl_rss_delete_doit() */
++              goto exit_unlock;
+ err_ctx_id_free:
+       xa_erase(&dev->ethtool->rss_ctx, req.rss_context);
+ err_unlock_free_ctx:
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-rss-avoid-modifying-the-rss-context-response.patch b/queue-6.18/ethtool-rss-avoid-modifying-the-rss-context-response.patch
new file mode 100644 (file)
index 0000000..23443f7
--- /dev/null
@@ -0,0 +1,73 @@
+From a6b2877500f8710ed43af00422686dd004d58627 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:06:42 -0700
+Subject: ethtool: rss: avoid modifying the RSS context response
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit c75b6f6eaacd0b74b832414cc3b9289c3686e941 ]
+
+Gemini says that we're modifying the RSS_CREATE response skb.
+I think it's right, the comment says that unicast() should
+unshare the skb but I'm not entirely sure what I meant there.
+netlink_trim() does a copy but only if skb is not well sized
+(it's at least 2x larger than necessary for the payload).
+
+Fixes: a166ab7816c5 ("ethtool: rss: support creating contexts via Netlink")
+Link: https://patch.msgid.link/20260522230647.1705600-2-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/rss.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
+index da5934cceb0757..926be5698ba4cc 100644
+--- a/net/ethtool/rss.c
++++ b/net/ethtool/rss.c
+@@ -974,11 +974,17 @@ ethnl_rss_create_validate(struct net_device *dev, struct genl_info *info)
+ }
+ static void
+-ethnl_rss_create_send_ntf(struct sk_buff *rsp, struct net_device *dev)
++ethnl_rss_create_send_ntf(const struct sk_buff *rsp, struct net_device *dev)
+ {
+-      struct nlmsghdr *nlh = (void *)rsp->data;
+       struct genlmsghdr *genl_hdr;
++      struct nlmsghdr *nlh;
++      struct sk_buff *ntf;
++
++      ntf = skb_copy_expand(rsp, 0, 0, GFP_KERNEL);
++      if (!ntf)
++              return;
++      nlh = nlmsg_hdr(ntf);
+       /* Convert the reply into a notification */
+       nlh->nlmsg_pid = 0;
+       nlh->nlmsg_seq = ethnl_bcast_seq_next();
+@@ -986,7 +992,7 @@ ethnl_rss_create_send_ntf(struct sk_buff *rsp, struct net_device *dev)
+       genl_hdr = nlmsg_data(nlh);
+       genl_hdr->cmd = ETHTOOL_MSG_RSS_CREATE_NTF;
+-      ethnl_multicast(rsp, dev);
++      ethnl_multicast(ntf, dev);
+ }
+ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
+@@ -1094,12 +1100,8 @@ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
+       genlmsg_end(rsp, hdr);
+-      /* Use the same skb for the response and the notification,
+-       * genlmsg_reply() will copy the skb if it has elevated user count.
+-       */
+-      skb_get(rsp);
+-      ret = genlmsg_reply(rsp, info);
+       ethnl_rss_create_send_ntf(rsp, dev);
++      ret = genlmsg_reply(rsp, info);
+       rsp = NULL;
+ exit_unlock:
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-rss-fix-falsely-ignoring-indir-table-updates.patch b/queue-6.18/ethtool-rss-fix-falsely-ignoring-indir-table-updates.patch
new file mode 100644 (file)
index 0000000..f9ea8d9
--- /dev/null
@@ -0,0 +1,38 @@
+From e877edeca867eba255eda621fc0c9b87fe8ab13c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:06:44 -0700
+Subject: ethtool: rss: fix falsely ignoring indir table updates
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 8d60141a32875248ef71d49c9920fa5e2aa40b29 ]
+
+rss_set_prep_indir() compares the new indirection table against the
+current one to determine whether any update is needed. The memcmp
+call passes data->indir_size as the length argument, but indir_size
+is the number of u32 entries, not the byte count.
+
+Fixes: c0ae03588bbb ("ethtool: rss: initial RSS_SET (indirection table handling)")
+Link: https://patch.msgid.link/20260522230647.1705600-4-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/rss.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
+index 688c0e4bba69db..4877655f724419 100644
+--- a/net/ethtool/rss.c
++++ b/net/ethtool/rss.c
+@@ -684,7 +684,7 @@ rss_set_prep_indir(struct net_device *dev, struct genl_info *info,
+                               ethtool_rxfh_indir_default(i, num_rx_rings);
+       }
+-      *mod |= memcmp(rxfh->indir, data->indir_table, data->indir_size);
++      *mod |= memcmp(rxfh->indir, data->indir_table, alloc_size);
+       return 0;
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-rss-fix-hkey-leak-when-indir_size-is-0.patch b/queue-6.18/ethtool-rss-fix-hkey-leak-when-indir_size-is-0.patch
new file mode 100644 (file)
index 0000000..1ae23d7
--- /dev/null
@@ -0,0 +1,47 @@
+From b52bc769fa7c9519a6067d3916c55c8b43371999 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:06:46 -0700
+Subject: ethtool: rss: fix hkey leak when indir_size is 0
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 78ccf1a70c6378e1f5073a8c2209b5129067b925 ]
+
+rss_get_data_alloc() allocates a single buffer that backs both the
+indirection table and the hash key, but only assigned data->indir_table
+when indir_size was nonzero. The expectation was that no driver
+implements RSS without supporting indirection table but apparently
+enic does just that (it's the only such in-tree driver).
+enic has get_rxfh_key_size but no get_rxfh_indir_size.
+data->indir_table stays as NULL, hkey gets set but rss_get_data_free()
+kfree(data->indir_table) is a nop and the allocation leaks.
+
+Always store the allocation base in data->indir_table so the free path
+is unambiguous. No caller treats indir_table as a sentinel; everything
+keys off indir_size.
+
+Fixes: 7112a04664bf ("ethtool: add netlink based get rss support")
+Link: https://patch.msgid.link/20260522230647.1705600-6-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/rss.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
+index 5416aec13b7fe7..f745ddec6fbab8 100644
+--- a/net/ethtool/rss.c
++++ b/net/ethtool/rss.c
+@@ -132,8 +132,7 @@ rss_get_data_alloc(struct net_device *dev, struct rss_reply_data *data)
+       if (!rss_config)
+               return -ENOMEM;
+-      if (data->indir_size)
+-              data->indir_table = (u32 *)rss_config;
++      data->indir_table = (u32 *)rss_config;
+       if (data->hkey_size)
+               data->hkey = rss_config + indir_bytes;
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-rss-fix-indir_table-and-hkey-leak-on-get_rxf.patch b/queue-6.18/ethtool-rss-fix-indir_table-and-hkey-leak-on-get_rxf.patch
new file mode 100644 (file)
index 0000000..fb4bad4
--- /dev/null
@@ -0,0 +1,41 @@
+From 321c11d7e8206244e7a8a8b27c735a5fe32acc09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:06:45 -0700
+Subject: ethtool: rss: fix indir_table and hkey leak on get_rxfh failure
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 266297692f97008ca48bc311775c087c59bd7fe3 ]
+
+rss_prepare_get() allocates the indirection table and hash key buffer
+via rss_get_data_alloc(), then calls ops->get_rxfh() to populate them.
+If get_rxfh() fails, the function returns an error without freeing
+the allocation.
+
+Fixes: 4f038a6a02d2 ("net: ethtool: Don't call .cleanup_data when prepare_data fails")
+Link: https://patch.msgid.link/20260522230647.1705600-5-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/rss.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
+index 4877655f724419..5416aec13b7fe7 100644
+--- a/net/ethtool/rss.c
++++ b/net/ethtool/rss.c
+@@ -168,8 +168,10 @@ rss_prepare_get(const struct rss_req_info *request, struct net_device *dev,
+       rxfh.key = data->hkey;
+       ret = ops->get_rxfh(dev, &rxfh);
+-      if (ret)
++      if (ret) {
++              rss_get_data_free(data);
+               goto out_unlock;
++      }
+       data->hfunc = rxfh.hfunc;
+       data->input_xfrm = rxfh.input_xfrm;
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-strset-fix-header-attribute-index-in-ethnl_r.patch b/queue-6.18/ethtool-strset-fix-header-attribute-index-in-ethnl_r.patch
new file mode 100644 (file)
index 0000000..6fa800e
--- /dev/null
@@ -0,0 +1,42 @@
+From faabee6674234c8a1f1896028c1580f4f9618b42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:31 -0700
+Subject: ethtool: strset: fix header attribute index in ethnl_req_get_phydev()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit a8d8bef6b45bf7cc0b1f6110c5cd8d0160a9bad7 ]
+
+strset_prepare_data() passes ETHTOOL_A_HEADER_FLAGS (3) as the header
+attribute to ethnl_req_get_phydev(). This is incorrect, in the main
+attr space 3 is ETHTOOL_A_STRSET_COUNTS_ONLY, not the request
+header attr. The correct constant is ETHTOOL_A_STRSET_HEADER (1).
+
+ethnl_req_get_phydev() only uses this value for the extack,
+so this is not a "functionally visible"(?) bug.
+
+Fixes: e96c93aa4be9 ("net: ethtool: strset: Allow querying phy stats by index")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-9-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/strset.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ethtool/strset.c b/net/ethtool/strset.c
+index f6a67109beda1b..872ca593b97668 100644
+--- a/net/ethtool/strset.c
++++ b/net/ethtool/strset.c
+@@ -309,7 +309,7 @@ static int strset_prepare_data(const struct ethnl_req_info *req_base,
+               return 0;
+       }
+-      phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_HEADER_FLAGS,
++      phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_STRSET_HEADER,
+                                     info->extack);
+       /* phydev can be NULL, check for errors only */
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-tsconfig-fix-missing-ethnl_ops_complete.patch b/queue-6.18/ethtool-tsconfig-fix-missing-ethnl_ops_complete.patch
new file mode 100644 (file)
index 0000000..06b3981
--- /dev/null
@@ -0,0 +1,42 @@
+From ea036757a9073fda66746ba73e5bd50e38672736 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:28 -0700
+Subject: ethtool: tsconfig: fix missing ethnl_ops_complete()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 6386bd772de64e6760306eb91c7e86163af6c22f ]
+
+tsconfig_prepare_data() calls ethnl_ops_begin(), we need to call
+ethnl_ops_complete() before returning the error.
+
+Fixes: 6e9e2eed4f39 ("net: ethtool: Add support for tsconfig command to get/set hwtstamp config")
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-6-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/tsconfig.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/tsconfig.c b/net/ethtool/tsconfig.c
+index 041de8687472bd..a121928038b055 100644
+--- a/net/ethtool/tsconfig.c
++++ b/net/ethtool/tsconfig.c
+@@ -69,8 +69,10 @@ static int tsconfig_prepare_data(const struct ethnl_req_info *req_base,
+               if (ret)
+                       goto out;
+-              if (ts_info.phc_index == -1)
+-                      return -ENODEV;
++              if (ts_info.phc_index == -1) {
++                      ret = -ENODEV;
++                      goto out;
++              }
+               data->hwprov_desc.index = ts_info.phc_index;
+               data->hwprov_desc.qualifier = ts_info.phc_qualifier;
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-tsconfig-fix-reply-error-handling.patch b/queue-6.18/ethtool-tsconfig-fix-reply-error-handling.patch
new file mode 100644 (file)
index 0000000..8ee195f
--- /dev/null
@@ -0,0 +1,55 @@
+From 183d1c373f0347a9aae5dcde9ea698c5db266276 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:25 -0700
+Subject: ethtool: tsconfig: fix reply error handling
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit a888bbd43940cada72f7686337741ce86d1cf869 ]
+
+A couple of trivial bugs in error handling in tsconfig_send_reply().
+If we failed to allocate rskb we need to set the error.
+If we did allocate it but failed to send it - we need to remember
+to free it.
+
+Fixes: 6e9e2eed4f39 ("net: ethtool: Add support for tsconfig command to get/set hwtstamp config")
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-3-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/tsconfig.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/tsconfig.c b/net/ethtool/tsconfig.c
+index 169b413b31fc5f..041de8687472bd 100644
+--- a/net/ethtool/tsconfig.c
++++ b/net/ethtool/tsconfig.c
+@@ -224,16 +224,21 @@ static int tsconfig_send_reply(struct net_device *dev, struct genl_info *info)
+       reply_len = ret + ethnl_reply_header_size();
+       rskb = ethnl_reply_init(reply_len, dev, ETHTOOL_MSG_TSCONFIG_SET_REPLY,
+                               ETHTOOL_A_TSCONFIG_HEADER, info, &reply_payload);
+-      if (!rskb)
++      if (!rskb) {
++              ret = -ENOMEM;
+               goto err_cleanup;
++      }
+       ret = tsconfig_fill_reply(rskb, &req_info->base, &reply_data->base);
+       if (ret < 0)
+-              goto err_cleanup;
++              goto err_free_msg;
+       genlmsg_end(rskb, reply_payload);
+       ret = genlmsg_reply(rskb, info);
++      rskb = NULL;
++err_free_msg:
++      nlmsg_free(rskb);
+ err_cleanup:
+       kfree(reply_data);
+       kfree(req_info);
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-tsinfo-don-t-pass-err_ptr-to-genlmsg_cancel-.patch b/queue-6.18/ethtool-tsinfo-don-t-pass-err_ptr-to-genlmsg_cancel-.patch
new file mode 100644 (file)
index 0000000..928a481
--- /dev/null
@@ -0,0 +1,49 @@
+From 07d3e946d4f9dfcf01e7ac59f9b5a9fb1ba8cb3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:30 -0700
+Subject: ethtool: tsinfo: don't pass ERR_PTR to genlmsg_cancel on prepare
+ failure
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit c3fc9976f686f9a95baf87db9d387f218fd65394 ]
+
+The goto err label leads to:
+
+       genlmsg_cancel(skb, ehdr);
+       return ret;
+
+If ethnl_tsinfo_prepare_dump() failed, it has not started a genlmsg.
+There's nothing to cancel, and passing an error pointer to
+genlmsg_cancel() would cause a crash.
+
+Fixes: b9e3f7dc9ed9 ("net: ethtool: tsinfo: Enhance tsinfo to support several hwtstamp by net topology")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-8-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/tsinfo.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/net/ethtool/tsinfo.c b/net/ethtool/tsinfo.c
+index fcc28fca526d82..53f12128a1a580 100644
+--- a/net/ethtool/tsinfo.c
++++ b/net/ethtool/tsinfo.c
+@@ -405,10 +405,8 @@ static int ethnl_tsinfo_dump_one_netdev(struct sk_buff *skb,
+                       continue;
+               ehdr = ethnl_tsinfo_prepare_dump(skb, dev, reply_data, cb);
+-              if (IS_ERR(ehdr)) {
+-                      ret = PTR_ERR(ehdr);
+-                      goto err;
+-              }
++              if (IS_ERR(ehdr))
++                      return PTR_ERR(ehdr);
+               reply_data->ts_info.phc_qualifier = ctx->pos_phcqualifier;
+               ret = ops->get_ts_info(dev, &reply_data->ts_info);
+-- 
+2.53.0
+
diff --git a/queue-6.18/ethtool-tsinfo-fix-uninitialized-stats-on-the-by-phc.patch b/queue-6.18/ethtool-tsinfo-fix-uninitialized-stats-on-the-by-phc.patch
new file mode 100644 (file)
index 0000000..329f26f
--- /dev/null
@@ -0,0 +1,75 @@
+From 7e2211ce4c08a8ec3a99d49949f93cda9aec2877 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:29 -0700
+Subject: ethtool: tsinfo: fix uninitialized stats on the by-PHC path
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 1de405699c62c3a9544bcdcfb9eff8a01cfc7582 ]
+
+tsinfo_prepare_data() has two code paths: a "by-PHC" path for
+user-specified hardware timestamping providers, and the old path.
+Commit 89e281ebff72 ("ethtool: init tsinfo stats if requested") added
+ethtool_stats_init() to mark stat slots as ETHTOOL_STAT_NOT_SET before
+the driver callback populates them, but placed the call inside the
+old-path block.
+
+When commit b9e3f7dc9ed9 ("net: ethtool: tsinfo: Enhance tsinfo to
+support several hwtstamp by net topology") added the by-PHC early
+return, it landed above the stats initialization. On that path
+the stats array retains the zero-fill from ethnl_init_reply_data()'s
+zalloc. This leads to the reply including a stats nest with four
+zero-valued attributes that should have been absent.
+
+Reject GET requests for stats with HWTSTAMP_PROVIDER or dump.
+
+Fixes: b9e3f7dc9ed9 ("net: ethtool: tsinfo: Enhance tsinfo to support several hwtstamp by net topology")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-7-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/tsinfo.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/net/ethtool/tsinfo.c b/net/ethtool/tsinfo.c
+index 8c654caa6805a5..fcc28fca526d82 100644
+--- a/net/ethtool/tsinfo.c
++++ b/net/ethtool/tsinfo.c
+@@ -81,6 +81,11 @@ tsinfo_parse_request(struct ethnl_req_info *req_base, struct nlattr **tb,
+       if (!tb[ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER])
+               return 0;
++      if (req_base->flags & ETHTOOL_FLAG_STATS) {
++              NL_SET_ERR_MSG(extack, "can't query statistics for a provider");
++              return -EOPNOTSUPP;
++      }
++
+       return ts_parse_hwtst_provider(tb[ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER],
+                                      &req->hwprov_desc, extack, &mod);
+ }
+@@ -521,6 +526,12 @@ int ethnl_tsinfo_start(struct netlink_callback *cb)
+       if (ret < 0)
+               goto free_reply_data;
++      if (req_info->base.flags & ETHTOOL_FLAG_STATS) {
++              NL_SET_ERR_MSG(cb->extack, "stats not supported in dump");
++              ret = -EOPNOTSUPP;
++              goto err_dev_put;
++      }
++
+       ctx->req_info = req_info;
+       ctx->reply_data = reply_data;
+       ctx->pos_ifindex = 0;
+@@ -530,6 +541,8 @@ int ethnl_tsinfo_start(struct netlink_callback *cb)
+       return 0;
++err_dev_put:
++      ethnl_parse_header_dev_put(&req_info->base);
+ free_reply_data:
+       kfree(reply_data);
+ free_req_info:
+-- 
+2.53.0
+
diff --git a/queue-6.18/gpio-adnp-fix-flow-control-regression-caused-by-scop.patch b/queue-6.18/gpio-adnp-fix-flow-control-regression-caused-by-scop.patch
new file mode 100644 (file)
index 0000000..1c11068
--- /dev/null
@@ -0,0 +1,43 @@
+From e9212538ef0e994373e57ded91eb1ed4cc781b2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 09:35:27 +0200
+Subject: gpio: adnp: fix flow control regression caused by scoped_guard()
+
+From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+
+[ Upstream commit a5c627d90809b793fc053849b3a00609db305776 ]
+
+scoped_guard() is implemented as a for loop. Using it to protect code
+using the continue statement changes the flow as we now only break out
+of the hidden loop inside scoped_guard(), not the original for loop. Use
+a regular code block instead.
+
+Fixes: c7fe19ed3973 ("gpio: adnp: use lock guards for the I2C lock")
+Reported-by: David Lechner <dlechner@baylibre.com>
+Closes: https://lore.kernel.org/all/cde2abb2-4cc8-4fc9-b34a-0c5d2b95779f@baylibre.com/
+Reviewed-by: Linus Walleij <linusw@kernel.org>
+Link: https://patch.msgid.link/20260522073527.9812-1-bartosz.golaszewski@oss.qualcomm.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-adnp.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c
+index e5ac2d2110137f..fe5bcaa90496aa 100644
+--- a/drivers/gpio/gpio-adnp.c
++++ b/drivers/gpio/gpio-adnp.c
+@@ -237,7 +237,9 @@ static irqreturn_t adnp_irq(int irq, void *data)
+               unsigned long pending;
+               int err;
+-              scoped_guard(mutex, &adnp->i2c_lock) {
++              {
++                      guard(mutex)(&adnp->i2c_lock);
++
+                       err = adnp_read(adnp, GPIO_PLR(adnp) + i, &level);
+                       if (err < 0)
+                               continue;
+-- 
+2.53.0
+
diff --git a/queue-6.18/gpio-mxc-fix-irq_high-handling.patch b/queue-6.18/gpio-mxc-fix-irq_high-handling.patch
new file mode 100644 (file)
index 0000000..472b3b5
--- /dev/null
@@ -0,0 +1,38 @@
+From affb3074346d5d6b6f11ac84db0e0f739e483db5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:01 +0200
+Subject: gpio: mxc: fix irq_high handling
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit dac917ed5aead741004db8d0d5151dd577802df8 ]
+
+If port->irq_high is -1 (fsl,imx21-gpio compatible) and gpio_idx is >= 16
+enable_irq_wake() is called with -1 which is wrong.
+
+Fixes: 5f6d1998adeb ("gpio: mxc: release the parent IRQ in runtime suspend")
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260526063504.25916-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-mxc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
+index 441ba95b38cf9b..dbdf0f41b6bb91 100644
+--- a/drivers/gpio/gpio-mxc.c
++++ b/drivers/gpio/gpio-mxc.c
+@@ -469,7 +469,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
+                * the handler is needed only once, but doing it for every port
+                * is more robust and easier.
+                */
+-              port->irq_high = -1;
++              port->irq_high = 0;
+               port->mx_irq_handler = mx2_gpio_irq_handler;
+       } else
+               port->mx_irq_handler = mx3_gpio_irq_handler;
+-- 
+2.53.0
+
diff --git a/queue-6.18/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch b/queue-6.18/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
new file mode 100644 (file)
index 0000000..2cc17f2
--- /dev/null
@@ -0,0 +1,78 @@
+From 8eca85a401d248a8643ce188954e2ed6c3117449 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:02:45 +0200
+Subject: gpio: rockchip: convert bank->clk to devm_clk_get_enabled()
+
+From: Marco Scardovi <scardracs@disroot.org>
+
+[ Upstream commit 3e46c18d5d87f063a93ae0fe7662fbf6660459d5 ]
+
+The bank->clk was previously obtained via of_clk_get() and manually
+prepared/enabled. However, it was missing a corresponding clk_put() in
+both the error paths and the remove function, leading to a reference leak.
+
+Convert the allocation to devm_clk_get_enabled(), which also properly
+propagates failures from clk_prepare_enable() that were previously ignored.
+
+The GPIO bank device uses the same OF node as the previous of_clk_get()
+call, so devm_clk_get_enabled(dev, NULL) correctly resolves the same
+clock provider entry.
+
+Fix the reference leak and simplify the code by removing the manual
+clk_disable_unprepare() calls in the probe error paths and in the
+remove function.
+
+Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
+Assisted-by: Antigravity:gemini-3.5-flash
+Signed-off-by: Marco Scardovi <scardracs@disroot.org>
+Link: https://patch.msgid.link/20260526171050.12785-2-scardracs@disroot.org
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-rockchip.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index 0fff4a699f12d1..f910220141f712 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -656,11 +656,10 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+       if (!bank->irq)
+               return -EINVAL;
+-      bank->clk = of_clk_get(bank->of_node, 0);
++      bank->clk = devm_clk_get_enabled(bank->dev, NULL);
+       if (IS_ERR(bank->clk))
+               return PTR_ERR(bank->clk);
+-      clk_prepare_enable(bank->clk);
+       id = readl(bank->reg_base + gpio_regs_v2.version_id);
+       switch (id) {
+@@ -672,7 +671,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+               bank->db_clk = of_clk_get(bank->of_node, 1);
+               if (IS_ERR(bank->db_clk)) {
+                       dev_err(bank->dev, "cannot find debounce clk\n");
+-                      clk_disable_unprepare(bank->clk);
+                       return -EINVAL;
+               }
+               break;
+@@ -751,7 +749,6 @@ static int rockchip_gpio_probe(struct platform_device *pdev)
+       ret = rockchip_gpiolib_register(bank);
+       if (ret) {
+-              clk_disable_unprepare(bank->clk);
+               mutex_unlock(&bank->deferred_lock);
+               return ret;
+       }
+@@ -792,7 +789,6 @@ static void rockchip_gpio_remove(struct platform_device *pdev)
+ {
+       struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);
+-      clk_disable_unprepare(bank->clk);
+       gpiochip_remove(&bank->gpio_chip);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.18/gpio-rockchip-teardown-bugs-and-resource-leaks.patch b/queue-6.18/gpio-rockchip-teardown-bugs-and-resource-leaks.patch
new file mode 100644 (file)
index 0000000..4cf1fd8
--- /dev/null
@@ -0,0 +1,88 @@
+From 7dc30495148ab049146bc3e38ccd9545b81a5e3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:02:46 +0200
+Subject: gpio: rockchip: teardown bugs and resource leaks
+
+From: Marco Scardovi <scardracs@disroot.org>
+
+[ Upstream commit 9500077678230e36d22bf16d2b9539c13e59a801 ]
+
+Address several teardown issues and resource leaks in the driver's remove
+path and error handling:
+
+1. Debounce clock reference leak: The debounce clock (bank->db_clk) is
+   obtained using of_clk_get() which increments the clock's reference
+   count, but clk_put() is never called. Register a devm action to
+   cleanly release it on unbind. Note that of_clk_get(..., 1) remains
+   necessary over devm_clk_get() because the DT binding does not define
+   clock-names, precluding name-based lookup.
+
+2. Unregistered chained IRQ handler: The chained IRQ handler is not
+   disconnected in remove(). If a stray interrupt fires after the driver
+   is removed, the kernel attempts to execute a stale handler, leading
+   to a panic. Fix this by clearing the handler in remove().
+
+3. IRQ domain leak: The linear IRQ domain and its generic chips are
+   allocated manually during probe but never removed. Remove the IRQ
+   domain during driver teardown to free the associated generic chips
+   and mappings.
+
+Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
+Assisted-by: Antigravity:gemini-3.5-flash
+Signed-off-by: Marco Scardovi <scardracs@disroot.org>
+Link: https://patch.msgid.link/20260526171050.12785-3-scardracs@disroot.org
+[Bartosz: don't emit an error message on devres allocation failure]
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-rockchip.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index f910220141f712..1ef0ba956cfd8c 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -638,10 +638,17 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
+       return ret;
+ }
++static void rockchip_clk_put(void *data)
++{
++      struct clk *clk = data;
++
++      clk_put(clk);
++}
++
+ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+ {
+       struct resource res;
+-      int id = 0;
++      int id = 0, ret;
+       if (of_address_to_resource(bank->of_node, 0, &res)) {
+               dev_err(bank->dev, "cannot find IO resource for bank\n");
+@@ -673,6 +680,11 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+                       dev_err(bank->dev, "cannot find debounce clk\n");
+                       return -EINVAL;
+               }
++
++              ret = devm_add_action_or_reset(bank->dev, rockchip_clk_put,
++                                             bank->db_clk);
++              if (ret)
++                      return ret;
+               break;
+       case GPIO_TYPE_V1:
+               bank->gpio_regs = &gpio_regs_v1;
+@@ -789,6 +801,9 @@ static void rockchip_gpio_remove(struct platform_device *pdev)
+ {
+       struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);
++      irq_set_chained_handler_and_data(bank->irq, NULL, NULL);
++      if (bank->domain)
++              irq_domain_remove(bank->domain);
+       gpiochip_remove(&bank->gpio_chip);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.18/gpio-virtuser-fix-uninitialized-data-bug-in-gpio_vir.patch b/queue-6.18/gpio-virtuser-fix-uninitialized-data-bug-in-gpio_vir.patch
new file mode 100644 (file)
index 0000000..ca8d04b
--- /dev/null
@@ -0,0 +1,49 @@
+From f93379d15c9f67df6bab4a6a6fcc9ab5c2e15897 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 10:15:16 +0300
+Subject: gpio: virtuser: Fix uninitialized data bug in
+ gpio_virtuser_direction_do_write()
+
+From: Dan Carpenter <error27@gmail.com>
+
+[ Upstream commit 8a122b5e72cc0043705f0d524bcd15f0c0b3ec15 ]
+
+If *ppos is non-zero (user-space write split over multiple calls to
+write()) then simple_write_to_buffer() won't initialize the start of the
+buffer. Really, non-zero values for *ppos aren't going to work at all.
+Check for that and return -EINVAL at the start of the function.
+
+Fixes: 91581c4b3f29 ("gpio: virtuser: new virtual testing driver for the GPIO API")
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Link: https://patch.msgid.link/ahP3BJWWy-m_qI0X@stanley.mountain
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-virtuser.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpio/gpio-virtuser.c b/drivers/gpio/gpio-virtuser.c
+index 252fec5ea38354..1901b4ba558f0c 100644
+--- a/drivers/gpio/gpio-virtuser.c
++++ b/drivers/gpio/gpio-virtuser.c
+@@ -399,7 +399,7 @@ static ssize_t gpio_virtuser_direction_do_write(struct file *file,
+       char buf[32], *trimmed;
+       int ret, dir, val = 0;
+-      if (count >= sizeof(buf))
++      if (*ppos != 0 || count >= sizeof(buf))
+               return -EINVAL;
+       ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
+@@ -626,7 +626,7 @@ static ssize_t gpio_virtuser_consumer_write(struct file *file,
+       char buf[GPIO_VIRTUSER_NAME_BUF_LEN + 2];
+       int ret;
+-      if (count >= sizeof(buf))
++      if (*ppos != 0 || count >= sizeof(buf))
+               return -EINVAL;
+       ret = simple_write_to_buffer(buf, GPIO_VIRTUSER_NAME_BUF_LEN, ppos,
+-- 
+2.53.0
+
diff --git a/queue-6.18/hid-remove-duplicate-hid_warn_ratelimited-definition.patch b/queue-6.18/hid-remove-duplicate-hid_warn_ratelimited-definition.patch
new file mode 100644 (file)
index 0000000..d98c330
--- /dev/null
@@ -0,0 +1,43 @@
+From bbfd0abc8a18bc125d503b8190000180e8bec32d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 16:32:04 +0800
+Subject: HID: remove duplicate hid_warn_ratelimited definition
+
+From: Liu Kai <lukace97@outlook.com>
+
+[ Upstream commit dd2147375a8fe7c5bc3f1f1b1d3a9567c26faefa ]
+
+The hid_warn_ratelimited macro is defined twice in include/linux/hid.h:
+- first one added by commit 4051ead99888 ("HID: rate-limit hid_warn to
+  prevent log flooding")
+- second one added by commit 1d64624243af ("HID: core: Add
+  printk_ratelimited variants to hid_warn() etc")).
+
+The second definition is correctly grouped with other ratelimited macros.
+Remove the duplicate definition.
+
+Fixes: 1d64624243af ("HID: core: Add printk_ratelimited variants to hid_warn() etc")
+Signed-off-by: Liu Kai <lukace97@outlook.com>
+[bentiss: edited commit message]
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/hid.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/include/linux/hid.h b/include/linux/hid.h
+index 204ada8d12e5c8..29561887bea8c0 100644
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -1276,8 +1276,6 @@ void hid_quirks_exit(__u16 bus);
+       dev_notice(&(hid)->dev, fmt, ##__VA_ARGS__)
+ #define hid_warn(hid, fmt, ...)                               \
+       dev_warn(&(hid)->dev, fmt, ##__VA_ARGS__)
+-#define hid_warn_ratelimited(hid, fmt, ...)                           \
+-      dev_warn_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__)
+ #define hid_info(hid, fmt, ...)                               \
+       dev_info(&(hid)->dev, fmt, ##__VA_ARGS__)
+ #define hid_dbg(hid, fmt, ...)                                \
+-- 
+2.53.0
+
diff --git a/queue-6.18/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch b/queue-6.18/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
new file mode 100644 (file)
index 0000000..2511889
--- /dev/null
@@ -0,0 +1,48 @@
+From dfe1a80b8eaf7812fda563b7967c6bedb1ea2ae4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 12:21:47 +0000
+Subject: ipv4: free net->ipv4.sysctl_local_reserved_ports after
+ unregister_net_sysctl_table()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 87a1e0fe7776da7ab411be332b4be58ac8840d10 ]
+
+ipv4_sysctl_exit_net() is currently freeing net->ipv4.sysctl_local_reserved_ports
+too soon.
+
+Only after unregister_net_sysctl_table() we can be sure no threads can possibly
+use the sysctls, including /proc/sys/net/ipv4/ip_local_reserved_ports.
+
+Fixes: 122ff243f5f1 ("ipv4: make ip_local_reserved_ports per netns")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Link: https://patch.msgid.link/20260521122147.3584624-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/sysctl_net_ipv4.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 0f1dd75dbf37bf..ce9b077343cac2 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -1669,10 +1669,10 @@ static __net_exit void ipv4_sysctl_exit_net(struct net *net)
+ {
+       const struct ctl_table *table;
+-      kfree(net->ipv4.sysctl_local_reserved_ports);
+       table = net->ipv4.ipv4_hdr->ctl_table_arg;
+       unregister_net_sysctl_table(net->ipv4.ipv4_hdr);
+       kfree(table);
++      kfree(net->ipv4.sysctl_local_reserved_ports);
+ }
+ static __net_initdata struct pernet_operations ipv4_sysctl_ops = {
+-- 
+2.53.0
+
diff --git a/queue-6.18/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch b/queue-6.18/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch
new file mode 100644 (file)
index 0000000..f3ea215
--- /dev/null
@@ -0,0 +1,49 @@
+From 9d3976e22d79e4a1b07dba67d3223218be4a3c71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 13:31:31 +0800
+Subject: ipv6: fix possible infinite loop in fib6_select_path()
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 9c7da87c2dc860bb17ca1ece942495d28b1ce3b9 ]
+
+Found while auditing the same pattern Sashiko reported in
+rt6_fill_node() [1]. Apply the same fix as
+commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").
+
+Writers holding tb6_lock can list_del_rcu(&first->fib6_siblings)
+without waiting for RCU readers; first->fib6_siblings.next then
+still points into the old ring and this softirq-side walker never
+reaches &first->fib6_siblings as its terminator. fib6_purge_rt()
+always WRITE_ONCE()s first->fib6_nsiblings to 0 before
+list_del_rcu(), so an inside-loop check is a reliable detach signal.
+
+[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev
+
+Fixes: d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260527053133.180695-2-jiayuan.chen@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index cf9546047b5749..f89220929c4e24 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -481,6 +481,9 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
+               const struct fib6_nh *nh = sibling->fib6_nh;
+               int nh_upper_bound;
++              if (!READ_ONCE(first->fib6_nsiblings))
++                      break;
++
+               nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);
+               if (hash > nh_upper_bound)
+                       continue;
+-- 
+2.53.0
+
diff --git a/queue-6.18/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch b/queue-6.18/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch
new file mode 100644 (file)
index 0000000..1e7fd8e
--- /dev/null
@@ -0,0 +1,47 @@
+From 018bd9df99a7885b7085da96c09831b6160dd257 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 13:31:30 +0800
+Subject: ipv6: fix possible infinite loop in rt6_fill_node()
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 9f72412bcf60144f252b0d6205106abf14344abc ]
+
+Sashiko reported this issue [1]. Apply the same fix as
+commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").
+
+Writers holding tb6_lock can list_del_rcu(&rt->fib6_siblings)
+without waiting for RCU readers; rt->fib6_siblings.next then still
+points into the old ring and this softirq-side walker never reaches
+&rt->fib6_siblings, causing a CPU stall. fib6_del_route() always
+WRITE_ONCE()s rt->fib6_nsiblings to 0 before list_del_rcu(), so an
+inside-loop check is a reliable detach signal.
+
+[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev
+
+Fixes: d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260527053133.180695-1-jiayuan.chen@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 446f4de7d6a227..cf9546047b5749 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -5892,6 +5892,8 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
+                               goto nla_put_failure;
+                       }
++                      if (!READ_ONCE(rt->fib6_nsiblings))
++                              break;
+               }
+               rcu_read_unlock();
+-- 
+2.53.0
+
diff --git a/queue-6.18/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch b/queue-6.18/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
new file mode 100644 (file)
index 0000000..470a42f
--- /dev/null
@@ -0,0 +1,62 @@
+From aa4e3aef2b26b8c1d3527389570d761e05a3dd25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 21:10:31 +0530
+Subject: ipv6: rpl: fix hdrlen overflow in ipv6_rpl_srh_decompress()
+
+From: Rahul Chandelkar <rc@rexion.ai>
+
+[ Upstream commit 9d5e7a46a9f6d8f503b41bfefef70659845f1679 ]
+
+ipv6_rpl_srh_decompress() computes:
+
+    outhdr->hdrlen = (((n + 1) * sizeof(struct in6_addr)) >> 3);
+
+hdrlen is __u8. For n >= 127 the result exceeds 255 and silently
+truncates. With n=127 (cmpri=15, cmpre=15, pad=0, hdrlen=16):
+
+    (128 * 16) >> 3 = 256, truncated to 0 as __u8
+
+The caller in ipv6_rpl_srh_rcv() then places the compressed header
+at buf + ((ohdr->hdrlen + 1) << 3). With hdrlen=0 this is buf + 8,
+but the decompressed region occupies buf[0..2055] (8-byte header
+plus 128 full addresses). The compressed header overlaps the
+decompressed data, and ipv6_rpl_srh_compress() writes into this
+overlap, corrupting the routing header of the forwarded packet.
+
+The existing guard at exthdrs.c:546 checks (n + 1) > 255, which
+prevents n+1 from overflowing unsigned char (the segments_left
+field), but does not prevent the computed hdrlen from overflowing
+__u8. n=127 passes because 128 <= 255, yet hdrlen=256 does not
+fit.
+
+Tighten the bound to (n + 1) > 127. This caps n at 126, giving
+hdrlen = (127 * 16) >> 3 = 254, which fits in __u8. The compressed
+header then lands at buf + ((254 + 1) << 3) = buf + 2040, exactly
+past the decompressed region (buf[0..2039]). No overlap. 127
+segments is well beyond any realistic RPL deployment.
+
+Fixes: 8610c7c6e3bd ("net: ipv6: add support for rpl sr exthdr")
+Signed-off-by: Rahul Chandelkar <rc@rexion.ai>
+Link: https://patch.msgid.link/20260525154031.2290876-1-rc@rexion.ai
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index d15e6094382094..830131b427f098 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -544,7 +544,7 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
+        * unsigned char which is segments_left field. Should not be
+        * higher than that.
+        */
+-      if (r || (n + 1) > 255) {
++      if (r || (n + 1) > 127) {
+               kfree_skb(skb);
+               return -1;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.18/kernel-fork-validate-exit_signal-in-kernel_clone.patch b/queue-6.18/kernel-fork-validate-exit_signal-in-kernel_clone.patch
new file mode 100644 (file)
index 0000000..508285d
--- /dev/null
@@ -0,0 +1,116 @@
+From fcca61d3635730759712bd3d6b18c31021219c96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Mar 2026 20:49:56 +0530
+Subject: kernel/fork: validate exit_signal in kernel_clone()
+
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+
+[ Upstream commit 09e7827e785729f391c8d46dc71becce70d296ab ]
+
+When a child process exits, it sends exit_signal to its parent via
+do_notify_parent().  The clone() syscall constructs exit_signal as:
+
+(lower_32_bits(clone_flags) & CSIGNAL)
+
+CSIGNAL is 0xff, so values in the range 65-255 are possible.  However,
+valid_signal() only accepts signals up to _NSIG (64 on x86_64).  A
+non-zero non-valid exit_signal acts the same as exit_signal == 0: the
+parent process is not signaled when the child terminates.
+
+The syzkaller reproducer triggers this by calling clone() with flags=0x80,
+resulting in exit_signal = (0x80 & CSIGNAL) = 128, which exceeds _NSIG and
+is not a valid signal.
+
+The v1 of this patch added the check only in the clone() syscall handler,
+which is incomplete.  kernel_clone() has other callers such as
+sys_ia32_clone() which would remain unprotected.  Move the check to
+kernel_clone() to cover all callers.
+
+Since the valid_signal() check is now in kernel_clone() and covers all
+callers including clone3(), the same check in copy_clone_args_from_user()
+becomes redundant and is removed.  The higher 32bits check for clone3() is
+kept as it is clone3() specific.
+
+Note that this is a user-visible change: previously, passing an invalid
+exit_signal to clone() was silently accepted.  The man page for clone()
+does not document any defined behavior for invalid exit_signal values, so
+rejecting them with -EINVAL is the correct behavior.  It is unlikely that
+any sane application relies on passing an invalid exit_signal.
+
+[oleg@redhat.com: the comment above kernel_clone() should be updated]
+  Link: https://lore.kernel.org/abwvgU17W8wuW2-J@redhat.com
+Link: https://lore.kernel.org/20260316151956.563558-1-kartikey406@gmail.com
+Fixes: 3f2c788a1314 ("fork: prevent accidental access to clone3 features")
+Signed-off-by: Deepanshu Kartikey <Kartikey406@gmail.com>
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Reported-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bbe6b99feefc3a0842de
+Tested-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/20260307064202.353405-1-kartikey406@gmail.com/T/ [v1]
+Link: https://lore.kernel.org/all/20260316104536.558108-1-kartikey406@gmail.com/T/ [v2]
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Ben Segall <bsegall@google.com>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Juri Lelli <juri.lelli@redhat.com>
+Cc: Kees Cook <kees@kernel.org>
+Cc: Liam Howlett <liam@infradead.org>
+Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Valentin Schneider <vschneid@redhat.com>
+Cc: Vincent Guittot <vincent.guittot@linaro.org>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/fork.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 1215d3f52c6d21..521e9d2be6f097 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -2562,8 +2562,6 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
+  *
+  * It copies the process, and if successful kick-starts
+  * it and waits for it to finish using the VM if required.
+- *
+- * args->exit_signal is expected to be checked for sanity by the caller.
+  */
+ pid_t kernel_clone(struct kernel_clone_args *args)
+ {
+@@ -2588,6 +2586,9 @@ pid_t kernel_clone(struct kernel_clone_args *args)
+           (args->pidfd == args->parent_tid))
+               return -EINVAL;
++      if (!valid_signal(args->exit_signal))
++              return -EINVAL;
++
+       /*
+        * Determine whether and which event to report to ptracer.  When
+        * called from kernel_thread or CLONE_UNTRACED is explicitly
+@@ -2786,11 +2787,9 @@ static noinline int copy_clone_args_from_user(struct kernel_clone_args *kargs,
+               return -EINVAL;
+       /*
+-       * Verify that higher 32bits of exit_signal are unset and that
+-       * it is a valid signal
++       * Verify that higher 32bits of exit_signal are unset
+        */
+-      if (unlikely((args.exit_signal & ~((u64)CSIGNAL)) ||
+-                   !valid_signal(args.exit_signal)))
++      if (unlikely(args.exit_signal & ~((u64)CSIGNAL)))
+               return -EINVAL;
+       if ((args.flags & CLONE_INTO_CGROUP) &&
+-- 
+2.53.0
+
diff --git a/queue-6.18/ksmbd-fix-fsctl-permission-bypass-by-adding-a-permis.patch b/queue-6.18/ksmbd-fix-fsctl-permission-bypass-by-adding-a-permis.patch
new file mode 100644 (file)
index 0000000..fb97f14
--- /dev/null
@@ -0,0 +1,69 @@
+From 547624fcd83637e995485b6fef6128bcfe8c9539 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 22:07:16 +0900
+Subject: ksmbd: fix FSCTL permission bypass by adding a permission check for
+ FSCTL_SET_SPARSE
+
+From: Sean Shen <grayhat@foxmail.com>
+
+[ Upstream commit cc57232cae23c0df91b4a59d0f519141ce9b5b02 ]
+
+FSCTL_SET_SPARSE in fsctl_set_sparse() modifies the file's sparse
+attribute and saves it through xattr without any permission checks.
+
+This exposes two issues:
+
+1) A client on a read-only share can change the sparse attribute
+   on files it opened, even though the share is read-only.
+   Other FSCTL write operations already check
+   test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE),
+   but FSCTL_SET_SPARSE does not.
+
+2) Even on writable shares, clients without FILE_WRITE_DATA or
+   FILE_WRITE_ATTRIBUTES access should not modify the sparse
+   attribute. Similar handle-level checks exist in other functions
+   but are missing here.
+
+Add both share-level writable check and per-handle access check.
+Use goto out on error to avoid leaking file references.
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Cc: Namjae Jeon <linkinjeon@kernel.org>
+Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Cc: Steve French <smfrench@gmail.com>
+Signed-off-by: Sean Shen <grayhat@foxmail.com>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/smb2pdu.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
+index da7b96707186e4..4689aac12c14ea 100644
+--- a/fs/smb/server/smb2pdu.c
++++ b/fs/smb/server/smb2pdu.c
+@@ -8203,9 +8203,20 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id,
+       int ret = 0;
+       __le32 old_fattr;
++      if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
++              ksmbd_debug(SMB, "User does not have write permission\n");
++              return -EACCES;
++      }
++
+       fp = ksmbd_lookup_fd_fast(work, id);
+       if (!fp)
+               return -ENOENT;
++
++      if (!(fp->daccess & (FILE_WRITE_DATA_LE | FILE_WRITE_ATTRIBUTES_LE))) {
++              ret = -EACCES;
++              goto out;
++      }
++
+       idmap = file_mnt_idmap(fp->filp);
+       old_fattr = fp->f_ci->m_fattr;
+-- 
+2.53.0
+
diff --git a/queue-6.18/kunit-fix-use-after-free-in-debugfs-when-using-kunit.patch b/queue-6.18/kunit-fix-use-after-free-in-debugfs-when-using-kunit.patch
new file mode 100644 (file)
index 0000000..7aa9fea
--- /dev/null
@@ -0,0 +1,110 @@
+From e3871ffbce2816ef17cf496c755149431883c879 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 10:48:54 +0200
+Subject: kunit: fix use-after-free in debugfs when using kunit.filter
+
+From: Florian Schmaus <florian.schmaus@codasip.com>
+
+[ Upstream commit fb6988b83b4cafe8db63999c1ddff1b7c66d2ff5 ]
+
+When the kernel is booted with a kunit filter (e.g.,
+kunit.filter="speed!=slow"), the kunit executor dynamically allocates
+copies of the filtered test suites using kmalloc/kmemdup.
+
+During the initial boot execution, kunit_debugfs_create_suite() creates
+debugfs files (such as /sys/kernel/debug/kunit/<suite>/run) and
+permanently stores a pointer to the dynamically allocated suite in the
+inode's i_private field.
+
+Previously, the executor freed this dynamically allocated suite_set
+immediately after executing the boot-time tests. Because the debugfs
+nodes were not destroyed, any subsequent interaction with the debugfs
+`run` file from userspace triggered a use-after-free (UAF). On systems
+with architectural capabilities, like CHERI RISC-V, this resulted in
+an immediate fatal hardware exception due to the invalidation of the
+capability tags on the reclaimed memory. On other architectures, it
+resulted in silent memory corruption.
+
+Fix this UAF by properly coupling the lifetime of the filtered suite
+memory allocation to the lifetime of the kunit subsystem and its
+associated VFS nodes. Ownership of the boot-time suite_set is now
+transferred to a global tracker ('kunit_boot_suites'), and the memory
+is cleanly released in kunit_exit() during module teardown.
+
+Link: https://lore.kernel.org/r/20260507084854.233984-1-florian.schmaus@codasip.com
+Fixes: e2219db280e3 ("kunit: add debugfs /sys/kernel/debug/kunit/<suite>/results display")
+Signed-off-by: Florian Schmaus <florian.schmaus@codasip.com>
+Reviewed-by: Martin Kaiser <martin@kaiser.cx>
+Reviewed-by: David Gow <david@davidgow.net>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/kunit/test.h |  1 +
+ lib/kunit/executor.c | 19 ++++++++++++++++---
+ lib/kunit/test.c     |  1 +
+ 3 files changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/include/kunit/test.h b/include/kunit/test.h
+index 5ec5182b5e5751..aedffe2f2d49de 100644
+--- a/include/kunit/test.h
++++ b/include/kunit/test.h
+@@ -613,6 +613,7 @@ unsigned long kunit_vm_mmap(struct kunit *test, struct file *file,
+                           unsigned long offset);
+ void kunit_cleanup(struct kunit *test);
++void kunit_free_boot_suites(void);
+ void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt, ...);
+diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c
+index 0061d4c7e35170..9abaed8275845f 100644
+--- a/lib/kunit/executor.c
++++ b/lib/kunit/executor.c
+@@ -15,6 +15,16 @@ extern struct kunit_suite * const __kunit_suites_end[];
+ extern struct kunit_suite * const __kunit_init_suites_start[];
+ extern struct kunit_suite * const __kunit_init_suites_end[];
++static struct kunit_suite_set kunit_boot_suites;
++
++void kunit_free_boot_suites(void)
++{
++      if (kunit_boot_suites.start) {
++              kunit_free_suite_set(kunit_boot_suites);
++              kunit_boot_suites = (struct kunit_suite_set){ NULL, NULL };
++      }
++}
++
+ static char *action_param;
+ module_param_named(action, action_param, charp, 0400);
+@@ -409,9 +419,12 @@ int kunit_run_all_tests(void)
+               pr_err("kunit executor: unknown action '%s'\n", action_param);
+ free_out:
+-      if (filter_glob_param || filter_param)
+-              kunit_free_suite_set(suite_set);
+-      else if (init_num_suites > 0)
++      if (filter_glob_param || filter_param) {
++              if (err)
++                      kunit_free_suite_set(suite_set);
++              else
++                      kunit_boot_suites = suite_set;
++      } else if (init_num_suites > 0)
+               /* Don't use kunit_free_suite_set because suites aren't individually allocated */
+               kfree(suite_set.start);
+diff --git a/lib/kunit/test.c b/lib/kunit/test.c
+index 62eb529824c657..f0e1e02a98d8b3 100644
+--- a/lib/kunit/test.c
++++ b/lib/kunit/test.c
+@@ -1056,6 +1056,7 @@ static void __exit kunit_exit(void)
+       kunit_bus_shutdown();
+       kunit_debugfs_cleanup();
++      kunit_free_boot_suites();
+ }
+ module_exit(kunit_exit);
+-- 
+2.53.0
+
diff --git a/queue-6.18/media-rc-fix-race-between-unregister-and-urb-irq-cal.patch b/queue-6.18/media-rc-fix-race-between-unregister-and-urb-irq-cal.patch
new file mode 100644 (file)
index 0000000..31dbbac
--- /dev/null
@@ -0,0 +1,759 @@
+From e24b727294a59bbfbac7217b908b6364663d1f79 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Dec 2025 10:33:26 +0000
+Subject: media: rc: fix race between unregister and urb/irq callbacks
+
+From: Sean Young <sean@mess.org>
+
+[ Upstream commit dccc0c3ddf8f16071736f98a7d6dd46a2d43e037 ]
+
+Some rc device drivers have a race condition between rc_unregister_device()
+and irq or urb callbacks. This is because rc_unregister_device() does two
+things, it marks the device as unregistered so no new commands can be
+issued and then it calls rc_free_device(). This means the driver has no
+chance to cancel any pending urb callbacks or interrupts after the device
+has been marked as unregistered. Those callbacks may access struct rc_dev
+or its members (e.g. struct ir_raw_event_ctrl), which have been freed by
+rc_free_device().
+
+This change removes the implicit call to rc_free_device() from
+rc_unregister_device(). This means that device drivers can call
+rc_unregister_device() in their remove or disconnect function, then cancel
+all the urbs and interrupts before explicitly calling rc_free_device().
+
+Note this is an alternative fix for an issue found by Haotian Zhang, see
+the Closes: tags.
+
+Reported-by: Haotian Zhang <vulab@iscas.ac.cn>
+Closes: https://lore.kernel.org/linux-media/20251114101432.2566-1-vulab@iscas.ac.cn/
+Closes: https://lore.kernel.org/linux-media/20251114101418.2548-1-vulab@iscas.ac.cn/
+Closes: https://lore.kernel.org/linux-media/20251114101346.2530-1-vulab@iscas.ac.cn/
+Closes: https://lore.kernel.org/linux-media/20251114090605.2413-1-vulab@iscas.ac.cn/
+Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+Stable-dep-of: 646ebdd31058 ("media: rc: ttusbir: fix inverted error logic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/sil-sii8620.c        | 1 +
+ drivers/hid/hid-picolcd_cir.c               | 1 +
+ drivers/media/cec/core/cec-core.c           | 2 +-
+ drivers/media/common/siano/smsir.c          | 1 +
+ drivers/media/i2c/ir-kbd-i2c.c              | 2 ++
+ drivers/media/pci/bt8xx/bttv-input.c        | 3 ++-
+ drivers/media/pci/cx23885/cx23885-input.c   | 1 +
+ drivers/media/pci/cx88/cx88-input.c         | 3 ++-
+ drivers/media/pci/dm1105/dm1105.c           | 1 +
+ drivers/media/pci/mantis/mantis_input.c     | 1 +
+ drivers/media/pci/saa7134/saa7134-input.c   | 1 +
+ drivers/media/pci/smipcie/smipcie-ir.c      | 1 +
+ drivers/media/pci/ttpci/budget-ci.c         | 1 +
+ drivers/media/rc/ati_remote.c               | 6 +++---
+ drivers/media/rc/ene_ir.c                   | 2 +-
+ drivers/media/rc/fintek-cir.c               | 3 ++-
+ drivers/media/rc/igorplugusb.c              | 1 +
+ drivers/media/rc/iguanair.c                 | 1 +
+ drivers/media/rc/img-ir/img-ir-hw.c         | 3 ++-
+ drivers/media/rc/img-ir/img-ir-raw.c        | 3 ++-
+ drivers/media/rc/imon.c                     | 3 ++-
+ drivers/media/rc/ir-hix5hd2.c               | 2 +-
+ drivers/media/rc/ir_toy.c                   | 1 +
+ drivers/media/rc/ite-cir.c                  | 2 +-
+ drivers/media/rc/mceusb.c                   | 1 +
+ drivers/media/rc/rc-ir-raw.c                | 5 -----
+ drivers/media/rc/rc-loopback.c              | 1 +
+ drivers/media/rc/rc-main.c                  | 6 +-----
+ drivers/media/rc/redrat3.c                  | 4 +++-
+ drivers/media/rc/st_rc.c                    | 2 +-
+ drivers/media/rc/streamzap.c                | 7 ++++---
+ drivers/media/rc/sunxi-cir.c                | 1 +
+ drivers/media/rc/ttusbir.c                  | 2 +-
+ drivers/media/rc/winbond-cir.c              | 2 +-
+ drivers/media/rc/xbox_remote.c              | 5 +++--
+ drivers/media/usb/au0828/au0828-input.c     | 1 +
+ drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 1 +
+ drivers/media/usb/dvb-usb/dvb-usb-remote.c  | 6 ++++--
+ drivers/media/usb/em28xx/em28xx-input.c     | 1 +
+ drivers/staging/media/av7110/av7110_ir.c    | 1 +
+ include/media/rc-core.h                     | 2 --
+ 41 files changed, 58 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
+index 9e48ad39e1cc99..923e2ed30624b7 100644
+--- a/drivers/gpu/drm/bridge/sil-sii8620.c
++++ b/drivers/gpu/drm/bridge/sil-sii8620.c
+@@ -2221,6 +2221,7 @@ static void sii8620_detach(struct drm_bridge *bridge)
+               return;
+       rc_unregister_device(ctx->rc_dev);
++      rc_free_device(ctx->rc_dev);
+ }
+ static int sii8620_is_packing_required(struct sii8620 *ctx,
+diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c
+index d6faa0e00f95ac..6d4c636e1c9f7e 100644
+--- a/drivers/hid/hid-picolcd_cir.c
++++ b/drivers/hid/hid-picolcd_cir.c
+@@ -134,5 +134,6 @@ void picolcd_exit_cir(struct picolcd_data *data)
+       data->rc_dev = NULL;
+       rc_unregister_device(rdev);
++      rc_free_device(rdev);
+ }
+diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c
+index dd6e24a0899bda..1b8a33c05b3c92 100644
+--- a/drivers/media/cec/core/cec-core.c
++++ b/drivers/media/cec/core/cec-core.c
+@@ -338,8 +338,8 @@ int cec_register_adapter(struct cec_adapter *adap,
+       res = cec_devnode_register(&adap->devnode, adap->owner);
+       if (res) {
+ #ifdef CONFIG_MEDIA_CEC_RC
+-              /* Note: rc_unregister also calls rc_free */
+               rc_unregister_device(adap->rc);
++              rc_free_device(adap->rc);
+               adap->rc = NULL;
+ #endif
+               return res;
+diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c
+index d85c78c104b990..5f4c0aa7a0d72a 100644
+--- a/drivers/media/common/siano/smsir.c
++++ b/drivers/media/common/siano/smsir.c
+@@ -92,6 +92,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
+ void sms_ir_exit(struct smscore_device_t *coredev)
+ {
+       rc_unregister_device(coredev->ir.dev);
++      rc_free_device(coredev->ir.dev);
+       pr_debug("\n");
+ }
+diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c
+index 5588cdd7ec20de..60474531700433 100644
+--- a/drivers/media/i2c/ir-kbd-i2c.c
++++ b/drivers/media/i2c/ir-kbd-i2c.c
+@@ -355,6 +355,7 @@ static void ir_work(struct work_struct *work)
+               mutex_unlock(&ir->lock);
+               if (rc == -ENODEV) {
+                       rc_unregister_device(ir->rc);
++                      rc_free_device(ir->rc);
+                       ir->rc = NULL;
+                       return;
+               }
+@@ -972,6 +973,7 @@ static void ir_remove(struct i2c_client *client)
+       i2c_unregister_device(ir->tx_c);
+       rc_unregister_device(ir->rc);
++      rc_free_device(ir->rc);
+ }
+ static const struct i2c_device_id ir_kbd_id[] = {
+diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c
+index 84aa269248fd36..f84fcf96eca983 100644
+--- a/drivers/media/pci/bt8xx/bttv-input.c
++++ b/drivers/media/pci/bt8xx/bttv-input.c
+@@ -572,8 +572,9 @@ void bttv_input_fini(struct bttv *btv)
+       if (btv->remote == NULL)
+               return;
+-      bttv_ir_stop(btv);
+       rc_unregister_device(btv->remote->dev);
++      bttv_ir_stop(btv);
++      rc_free_device(btv->remote->dev);
+       kfree(btv->remote);
+       btv->remote = NULL;
+ }
+diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c
+index d2e84c6457e0ab..722329ef3fd2cc 100644
+--- a/drivers/media/pci/cx23885/cx23885-input.c
++++ b/drivers/media/pci/cx23885/cx23885-input.c
+@@ -402,6 +402,7 @@ void cx23885_input_fini(struct cx23885_dev *dev)
+       if (dev->kernel_ir == NULL)
+               return;
+       rc_unregister_device(dev->kernel_ir->rc);
++      rc_free_device(dev->kernel_ir->rc);
+       kfree(dev->kernel_ir->phys);
+       kfree(dev->kernel_ir->name);
+       kfree(dev->kernel_ir);
+diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c
+index b9f2c14d62b408..4757787c3f5935 100644
+--- a/drivers/media/pci/cx88/cx88-input.c
++++ b/drivers/media/pci/cx88/cx88-input.c
+@@ -509,8 +509,9 @@ int cx88_ir_fini(struct cx88_core *core)
+       if (!ir)
+               return 0;
+-      cx88_ir_stop(core);
+       rc_unregister_device(ir->dev);
++      cx88_ir_stop(core);
++      rc_free_device(ir->dev);
+       kfree(ir);
+       /* done */
+diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
+index 9e9c7c071accce..e1185aa669f480 100644
+--- a/drivers/media/pci/dm1105/dm1105.c
++++ b/drivers/media/pci/dm1105/dm1105.c
+@@ -763,6 +763,7 @@ static int dm1105_ir_init(struct dm1105_dev *dm1105)
+ static void dm1105_ir_exit(struct dm1105_dev *dm1105)
+ {
+       rc_unregister_device(dm1105->ir.dev);
++      rc_free_device(dm1105->ir.dev);
+ }
+ static int dm1105_hw_init(struct dm1105_dev *dev)
+diff --git a/drivers/media/pci/mantis/mantis_input.c b/drivers/media/pci/mantis/mantis_input.c
+index 34c0d979240fda..edb4cacf55d229 100644
+--- a/drivers/media/pci/mantis/mantis_input.c
++++ b/drivers/media/pci/mantis/mantis_input.c
+@@ -72,5 +72,6 @@ EXPORT_SYMBOL_GPL(mantis_input_init);
+ void mantis_input_exit(struct mantis_pci *mantis)
+ {
+       rc_unregister_device(mantis->rc);
++      rc_free_device(mantis->rc);
+ }
+ EXPORT_SYMBOL_GPL(mantis_input_exit);
+diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c
+index 468dbe8d552f82..d39537c95d9d3b 100644
+--- a/drivers/media/pci/saa7134/saa7134-input.c
++++ b/drivers/media/pci/saa7134/saa7134-input.c
+@@ -834,6 +834,7 @@ void saa7134_input_fini(struct saa7134_dev *dev)
+               return;
+       rc_unregister_device(dev->remote->dev);
++      rc_free_device(dev->remote->dev);
+       kfree(dev->remote);
+       dev->remote = NULL;
+ }
+diff --git a/drivers/media/pci/smipcie/smipcie-ir.c b/drivers/media/pci/smipcie/smipcie-ir.c
+index c0604d9c70119a..0bbe4fa2d5a84e 100644
+--- a/drivers/media/pci/smipcie/smipcie-ir.c
++++ b/drivers/media/pci/smipcie/smipcie-ir.c
+@@ -181,5 +181,6 @@ void smi_ir_exit(struct smi_dev *dev)
+       rc_unregister_device(rc_dev);
+       smi_ir_stop(ir);
++      rc_free_device(rc_dev);
+       ir->rc_dev = NULL;
+ }
+diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c
+index 33f08adf4feb10..16973ac8e6a920 100644
+--- a/drivers/media/pci/ttpci/budget-ci.c
++++ b/drivers/media/pci/ttpci/budget-ci.c
+@@ -249,6 +249,7 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci)
+       cancel_work_sync(&budget_ci->ir.msp430_irq_bh_work);
+       rc_unregister_device(budget_ci->ir.dev);
++      rc_free_device(budget_ci->ir.dev);
+ }
+ static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
+diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c
+index a733914a257424..f1fd4765651cac 100644
+--- a/drivers/media/rc/ati_remote.c
++++ b/drivers/media/rc/ati_remote.c
+@@ -921,7 +921,6 @@ static int ati_remote_probe(struct usb_interface *interface,
+       input_free_device(input_dev);
+  exit_unregister_device:
+       rc_unregister_device(rc_dev);
+-      rc_dev = NULL;
+  exit_kill_urbs:
+       usb_kill_urb(ati_remote->irq_urb);
+       usb_kill_urb(ati_remote->out_urb);
+@@ -941,18 +940,19 @@ static void ati_remote_disconnect(struct usb_interface *interface)
+       struct ati_remote *ati_remote;
+       ati_remote = usb_get_intfdata(interface);
+-      usb_set_intfdata(interface, NULL);
+       if (!ati_remote) {
+               dev_warn(&interface->dev, "%s - null device?\n", __func__);
+               return;
+       }
++      rc_unregister_device(ati_remote->rdev);
++      usb_set_intfdata(interface, NULL);
+       usb_kill_urb(ati_remote->irq_urb);
+       usb_kill_urb(ati_remote->out_urb);
+       if (ati_remote->idev)
+               input_unregister_device(ati_remote->idev);
+-      rc_unregister_device(ati_remote->rdev);
+       ati_remote_free_buffers(ati_remote);
++      rc_free_device(ati_remote->rdev);
+       kfree(ati_remote);
+ }
+diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c
+index d6c54a3bccc26d..136fc4192265da 100644
+--- a/drivers/media/rc/ene_ir.c
++++ b/drivers/media/rc/ene_ir.c
+@@ -1090,7 +1090,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
+       release_region(dev->hw_io, ENE_IO_SIZE);
+ exit_unregister_device:
+       rc_unregister_device(rdev);
+-      rdev = NULL;
+ exit_free_dev_rdev:
+       rc_free_device(rdev);
+       kfree(dev);
+@@ -1110,6 +1109,7 @@ static void ene_remove(struct pnp_dev *pnp_dev)
+       ene_rx_restore_hw_buffer(dev);
+       spin_unlock_irqrestore(&dev->hw_lock, flags);
++      rc_free_device(dev->rdev);
+       free_irq(dev->irq, dev);
+       release_region(dev->hw_io, ENE_IO_SIZE);
+       kfree(dev);
+diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c
+index 3fb0968efd57d3..9b789097cdd4c3 100644
+--- a/drivers/media/rc/fintek-cir.c
++++ b/drivers/media/rc/fintek-cir.c
+@@ -568,6 +568,7 @@ static void fintek_remove(struct pnp_dev *pdev)
+       struct fintek_dev *fintek = pnp_get_drvdata(pdev);
+       unsigned long flags;
++      rc_unregister_device(fintek->rdev);
+       spin_lock_irqsave(&fintek->fintek_lock, flags);
+       /* disable CIR */
+       fintek_disable_cir(fintek);
+@@ -580,7 +581,7 @@ static void fintek_remove(struct pnp_dev *pdev)
+       free_irq(fintek->cir_irq, fintek);
+       release_region(fintek->cir_addr, fintek->cir_port_len);
+-      rc_unregister_device(fintek->rdev);
++      rc_free_device(fintek->rdev);
+       kfree(fintek);
+ }
+diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c
+index e7e31776453c11..439f95e6879fc4 100644
+--- a/drivers/media/rc/igorplugusb.c
++++ b/drivers/media/rc/igorplugusb.c
+@@ -247,6 +247,7 @@ static void igorplugusb_disconnect(struct usb_interface *intf)
+       usb_set_intfdata(intf, NULL);
+       usb_unpoison_urb(ir->urb);
+       usb_free_urb(ir->urb);
++      rc_free_device(ir->rc);
+       kfree(ir->buf_in);
+       kfree(ir->request);
+ }
+diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c
+index 8af94246e5916e..7bd6dd7254157a 100644
+--- a/drivers/media/rc/iguanair.c
++++ b/drivers/media/rc/iguanair.c
+@@ -500,6 +500,7 @@ static void iguanair_disconnect(struct usb_interface *intf)
+       usb_set_intfdata(intf, NULL);
+       usb_kill_urb(ir->urb_in);
+       usb_kill_urb(ir->urb_out);
++      rc_free_device(ir->rc);
+       usb_free_urb(ir->urb_in);
+       usb_free_urb(ir->urb_out);
+       usb_free_coherent(ir->udev, MAX_IN_PACKET, ir->buf_in, ir->dma_in);
+diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c
+index 63f6f5b36838d0..f30adf4d8444dd 100644
+--- a/drivers/media/rc/img-ir/img-ir-hw.c
++++ b/drivers/media/rc/img-ir/img-ir-hw.c
+@@ -1118,9 +1118,10 @@ void img_ir_remove_hw(struct img_ir_priv *priv)
+       struct rc_dev *rdev = hw->rdev;
+       if (!rdev)
+               return;
++      rc_unregister_device(rdev);
+       img_ir_set_decoder(priv, NULL, 0);
+       hw->rdev = NULL;
+-      rc_unregister_device(rdev);
++      rc_free_device(rdev);
+ #ifdef CONFIG_COMMON_CLK
+       if (!IS_ERR(priv->clk))
+               clk_notifier_unregister(priv->clk, &hw->clk_nb);
+diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c
+index 92fb7b555a0f65..f1460d4acf3e8a 100644
+--- a/drivers/media/rc/img-ir/img-ir-raw.c
++++ b/drivers/media/rc/img-ir/img-ir-raw.c
+@@ -136,6 +136,7 @@ void img_ir_remove_raw(struct img_ir_priv *priv)
+       if (!rdev)
+               return;
++      rc_unregister_device(rdev);
+       /* switch off and disable raw (edge) interrupts */
+       spin_lock_irq(&priv->lock);
+       raw->rdev = NULL;
+@@ -145,7 +146,7 @@ void img_ir_remove_raw(struct img_ir_priv *priv)
+       img_ir_write(priv, IMG_IR_IRQ_CLEAR, IMG_IR_IRQ_EDGE);
+       spin_unlock_irq(&priv->lock);
+-      rc_unregister_device(rdev);
++      rc_free_device(rdev);
+       timer_delete_sync(&raw->timer);
+ }
+diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
+index 35b9e07003d889..48534bb52e4d04 100644
+--- a/drivers/media/rc/imon.c
++++ b/drivers/media/rc/imon.c
+@@ -2541,9 +2541,10 @@ static void imon_disconnect(struct usb_interface *interface)
+       if (ifnum == 0) {
+               ictx->dev_present_intf0 = false;
++              rc_unregister_device(ictx->rdev);
+               usb_kill_urb(ictx->rx_urb_intf0);
+               input_unregister_device(ictx->idev);
+-              rc_unregister_device(ictx->rdev);
++              rc_free_device(ictx->rdev);
+               if (ictx->display_supported) {
+                       if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
+                               usb_deregister_dev(interface, &imon_lcd_class);
+diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c
+index afd80d2350c6d3..bb0f95833df57e 100644
+--- a/drivers/media/rc/ir-hix5hd2.c
++++ b/drivers/media/rc/ir-hix5hd2.c
+@@ -331,7 +331,6 @@ static int hix5hd2_ir_probe(struct platform_device *pdev)
+ regerr:
+       rc_unregister_device(rdev);
+-      rdev = NULL;
+ clkerr:
+       clk_disable_unprepare(priv->clock);
+ err:
+@@ -346,6 +345,7 @@ static void hix5hd2_ir_remove(struct platform_device *pdev)
+       clk_disable_unprepare(priv->clock);
+       rc_unregister_device(priv->rdev);
++      rc_free_device(priv->rdev);
+ }
+ #ifdef CONFIG_PM_SLEEP
+diff --git a/drivers/media/rc/ir_toy.c b/drivers/media/rc/ir_toy.c
+index 533faa11751744..e79de56997a426 100644
+--- a/drivers/media/rc/ir_toy.c
++++ b/drivers/media/rc/ir_toy.c
+@@ -536,6 +536,7 @@ static void irtoy_disconnect(struct usb_interface *intf)
+       usb_free_urb(ir->urb_out);
+       usb_kill_urb(ir->urb_in);
+       usb_free_urb(ir->urb_in);
++      rc_free_device(ir->rc);
+       kfree(ir->in);
+       kfree(ir->out);
+       kfree(ir);
+diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
+index 2bacecb022623e..23afbafb557488 100644
+--- a/drivers/media/rc/ite-cir.c
++++ b/drivers/media/rc/ite-cir.c
+@@ -1414,7 +1414,6 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
+       release_region(itdev->cir_addr, itdev->params->io_region_size);
+ exit_unregister_device:
+       rc_unregister_device(rdev);
+-      rdev = NULL;
+ exit_free_dev_rdev:
+       rc_free_device(rdev);
+       kfree(itdev);
+@@ -1439,6 +1438,7 @@ static void ite_remove(struct pnp_dev *pdev)
+       release_region(dev->cir_addr, dev->params->io_region_size);
+       rc_unregister_device(dev->rdev);
++      rc_free_device(dev->rdev);
+       kfree(dev);
+ }
+diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
+index 044767eb3a38c9..a4c94fdf767ca1 100644
+--- a/drivers/media/rc/mceusb.c
++++ b/drivers/media/rc/mceusb.c
+@@ -1850,6 +1850,7 @@ static void mceusb_dev_disconnect(struct usb_interface *intf)
+       usb_free_urb(ir->urb_in);
+       usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in);
+       usb_put_dev(dev);
++      rc_free_device(ir->rc);
+       kfree(ir);
+ }
+diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
+index 5dafe11f61c6b1..76c3d1307f9f1b 100644
+--- a/drivers/media/rc/rc-ir-raw.c
++++ b/drivers/media/rc/rc-ir-raw.c
+@@ -648,9 +648,6 @@ int ir_raw_event_register(struct rc_dev *dev)
+ void ir_raw_event_free(struct rc_dev *dev)
+ {
+-      if (!dev)
+-              return;
+-
+       kfree(dev->raw);
+       dev->raw = NULL;
+ }
+@@ -674,8 +671,6 @@ void ir_raw_event_unregister(struct rc_dev *dev)
+       lirc_bpf_free(dev);
+-      ir_raw_event_free(dev);
+-
+       /*
+        * A user can be calling bpf(BPF_PROG_{QUERY|ATTACH|DETACH}), so
+        * ensure that the raw member is null on unlock; this is how
+diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
+index 8288366f891fc9..a108b057b5fd56 100644
+--- a/drivers/media/rc/rc-loopback.c
++++ b/drivers/media/rc/rc-loopback.c
+@@ -263,6 +263,7 @@ static int __init loop_init(void)
+ static void __exit loop_exit(void)
+ {
+       rc_unregister_device(loopdev.dev);
++      rc_free_device(loopdev.dev);
+ }
+ module_init(loop_init);
+diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
+index b9bf5cdcde4ae3..6bdf32cb4a17d8 100644
+--- a/drivers/media/rc/rc-main.c
++++ b/drivers/media/rc/rc-main.c
+@@ -1611,6 +1611,7 @@ static void rc_dev_release(struct device *device)
+ {
+       struct rc_dev *dev = to_rc_dev(device);
++      ir_raw_event_free(dev);
+       kfree(dev);
+ }
+@@ -1773,7 +1774,6 @@ struct rc_dev *devm_rc_allocate_device(struct device *dev,
+       }
+       rc->dev.parent = dev;
+-      rc->managed_alloc = true;
+       *dr = rc;
+       devres_add(dev, dr);
+@@ -2042,11 +2042,7 @@ void rc_unregister_device(struct rc_dev *dev)
+       device_del(&dev->dev);
+       ida_free(&rc_ida, dev->minor);
+-
+-      if (!dev->managed_alloc)
+-              rc_free_device(dev);
+ }
+-
+ EXPORT_SYMBOL_GPL(rc_unregister_device);
+ /*
+diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
+index a49173f54a4d0e..b8289327f6a206 100644
+--- a/drivers/media/rc/redrat3.c
++++ b/drivers/media/rc/redrat3.c
+@@ -1133,11 +1133,13 @@ static void redrat3_dev_disconnect(struct usb_interface *intf)
+ {
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct redrat3_dev *rr3 = usb_get_intfdata(intf);
++      struct rc_dev *rc = rr3->rc;
+       usb_set_intfdata(intf, NULL);
+-      rc_unregister_device(rr3->rc);
++      rc_unregister_device(rc);
+       led_classdev_unregister(&rr3->led);
+       redrat3_delete(rr3, udev);
++      rc_free_device(rc);
+ }
+ static int redrat3_dev_suspend(struct usb_interface *intf, pm_message_t message)
+diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c
+index 6b70bac5f45d6c..0ba06bfc9e14b6 100644
+--- a/drivers/media/rc/st_rc.c
++++ b/drivers/media/rc/st_rc.c
+@@ -203,6 +203,7 @@ static void st_rc_remove(struct platform_device *pdev)
+       device_init_wakeup(&pdev->dev, false);
+       clk_disable_unprepare(rc_dev->sys_clock);
+       rc_unregister_device(rc_dev->rdev);
++      rc_free_device(rc_dev->rdev);
+ }
+ static int st_rc_open(struct rc_dev *rdev)
+@@ -334,7 +335,6 @@ static int st_rc_probe(struct platform_device *pdev)
+       return ret;
+ rcerr:
+       rc_unregister_device(rdev);
+-      rdev = NULL;
+ clkerr:
+       clk_disable_unprepare(rc_dev->sys_clock);
+ err:
+diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
+index 8e9b156e430022..8c85b9f30a3a96 100644
+--- a/drivers/media/rc/streamzap.c
++++ b/drivers/media/rc/streamzap.c
+@@ -392,15 +392,16 @@ static void streamzap_disconnect(struct usb_interface *interface)
+       struct streamzap_ir *sz = usb_get_intfdata(interface);
+       struct usb_device *usbdev = interface_to_usbdev(interface);
+-      usb_set_intfdata(interface, NULL);
+-
+       if (!sz)
+               return;
+-      usb_kill_urb(sz->urb_in);
+       rc_unregister_device(sz->rdev);
++      usb_set_intfdata(interface, NULL);
++
++      usb_kill_urb(sz->urb_in);
+       usb_free_urb(sz->urb_in);
+       usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in);
++      rc_free_device(sz->rdev);
+       kfree(sz);
+ }
+diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c
+index 92ef4e7c6f69fc..cb4c56bf0752a8 100644
+--- a/drivers/media/rc/sunxi-cir.c
++++ b/drivers/media/rc/sunxi-cir.c
+@@ -371,6 +371,7 @@ static void sunxi_ir_remove(struct platform_device *pdev)
+       struct sunxi_ir *ir = platform_get_drvdata(pdev);
+       rc_unregister_device(ir->rc);
++      rc_free_device(ir->rc);
+       sunxi_ir_hw_exit(&pdev->dev);
+ }
+diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c
+index dde446a95eaa93..a670d4b008cb0d 100644
+--- a/drivers/media/rc/ttusbir.c
++++ b/drivers/media/rc/ttusbir.c
+@@ -336,7 +336,6 @@ static int ttusbir_probe(struct usb_interface *intf,
+       return 0;
+ out3:
+       rc_unregister_device(rc);
+-      rc = NULL;
+ out2:
+       led_classdev_unregister(&tt->led);
+ out:
+@@ -378,6 +377,7 @@ static void ttusbir_disconnect(struct usb_interface *intf)
+       usb_kill_urb(tt->bulk_urb);
+       usb_free_urb(tt->bulk_urb);
+       kfree(tt->bulk_buffer);
++      rc_free_device(tt->rc);
+       usb_set_intfdata(intf, NULL);
+       kfree(tt);
+ }
+diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
+index 25884a79985c8a..14d8b58e283980 100644
+--- a/drivers/media/rc/winbond-cir.c
++++ b/drivers/media/rc/winbond-cir.c
+@@ -1132,7 +1132,6 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
+       release_region(data->wbase, WAKEUP_IOMEM_LEN);
+ exit_unregister_device:
+       rc_unregister_device(data->dev);
+-      data->dev = NULL;
+ exit_free_rc:
+       rc_free_device(data->dev);
+ exit_unregister_led:
+@@ -1163,6 +1162,7 @@ wbcir_remove(struct pnp_dev *device)
+       wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07);
+       rc_unregister_device(data->dev);
++      rc_free_device(data->dev);
+       led_classdev_unregister(&data->led);
+diff --git a/drivers/media/rc/xbox_remote.c b/drivers/media/rc/xbox_remote.c
+index 0c9c855ced729c..80b7c247932a8f 100644
+--- a/drivers/media/rc/xbox_remote.c
++++ b/drivers/media/rc/xbox_remote.c
+@@ -283,14 +283,15 @@ static void xbox_remote_disconnect(struct usb_interface *interface)
+       struct xbox_remote *xbox_remote;
+       xbox_remote = usb_get_intfdata(interface);
+-      usb_set_intfdata(interface, NULL);
+       if (!xbox_remote) {
+               dev_warn(&interface->dev, "%s - null device?\n", __func__);
+               return;
+       }
+-      usb_kill_urb(xbox_remote->irq_urb);
+       rc_unregister_device(xbox_remote->rdev);
++      usb_set_intfdata(interface, NULL);
++      usb_kill_urb(xbox_remote->irq_urb);
++      rc_free_device(xbox_remote->rdev);
+       usb_free_urb(xbox_remote->irq_urb);
+       kfree(xbox_remote->inbuf);
+       kfree(xbox_remote);
+diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c
+index 3d3368202cd018..283ad2c6288cd5 100644
+--- a/drivers/media/usb/au0828/au0828-input.c
++++ b/drivers/media/usb/au0828/au0828-input.c
+@@ -357,6 +357,7 @@ void au0828_rc_unregister(struct au0828_dev *dev)
+               return;
+       rc_unregister_device(ir->rc);
++      rc_free_device(ir->rc);
+       /* done */
+       kfree(ir);
+diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
+index f1c79f351ec8de..17e8961179d14b 100644
+--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
++++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
+@@ -187,6 +187,7 @@ static int dvb_usbv2_remote_exit(struct dvb_usb_device *d)
+       if (d->rc_dev) {
+               cancel_delayed_work_sync(&d->rc_query_work);
+               rc_unregister_device(d->rc_dev);
++              rc_free_device(d->rc_dev);
+               d->rc_dev = NULL;
+       }
+diff --git a/drivers/media/usb/dvb-usb/dvb-usb-remote.c b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
+index 65e2c9e2cdc99f..6dc11718dfb985 100644
+--- a/drivers/media/usb/dvb-usb/dvb-usb-remote.c
++++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
+@@ -347,10 +347,12 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d)
+ {
+       if (d->state & DVB_USB_STATE_REMOTE) {
+               cancel_delayed_work_sync(&d->rc_query_work);
+-              if (d->props.rc.mode == DVB_RC_LEGACY)
++              if (d->props.rc.mode == DVB_RC_LEGACY) {
+                       input_unregister_device(d->input_dev);
+-              else
++              } else {
+                       rc_unregister_device(d->rc_dev);
++                      rc_free_device(d->rc_dev);
++              }
+       }
+       d->state &= ~DVB_USB_STATE_REMOTE;
+       return 0;
+diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
+index 5f3b00869bdbc9..26f333b5be7325 100644
+--- a/drivers/media/usb/em28xx/em28xx-input.c
++++ b/drivers/media/usb/em28xx/em28xx-input.c
+@@ -853,6 +853,7 @@ static int em28xx_ir_fini(struct em28xx *dev)
+               goto ref_put;
+       rc_unregister_device(ir->rc);
++      rc_free_device(ir->rc);
+       kfree(ir->i2c_client);
+diff --git a/drivers/staging/media/av7110/av7110_ir.c b/drivers/staging/media/av7110/av7110_ir.c
+index 68b3979ba5f20c..fdae467fd7ab81 100644
+--- a/drivers/staging/media/av7110/av7110_ir.c
++++ b/drivers/staging/media/av7110/av7110_ir.c
+@@ -151,6 +151,7 @@ int av7110_ir_init(struct av7110 *av7110)
+ void av7110_ir_exit(struct av7110 *av7110)
+ {
+       rc_unregister_device(av7110->ir.rcdev);
++      rc_free_device(av7110->ir.rcdev);
+ }
+ //MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>, Oliver Endriss <o.endriss@gmx.de>");
+diff --git a/include/media/rc-core.h b/include/media/rc-core.h
+index 35c7a0546f02ee..7c964b5ad79269 100644
+--- a/include/media/rc-core.h
++++ b/include/media/rc-core.h
+@@ -81,7 +81,6 @@ struct lirc_fh {
+ /**
+  * struct rc_dev - represents a remote control device
+  * @dev: driver model's view of this device
+- * @managed_alloc: devm_rc_allocate_device was used to create rc_dev
+  * @registered: set to true by rc_register_device(), false by
+  *    rc_unregister_device
+  * @idle: used to keep track of RX state
+@@ -156,7 +155,6 @@ struct lirc_fh {
+  */
+ struct rc_dev {
+       struct device                   dev;
+-      bool                            managed_alloc;
+       bool                            registered;
+       bool                            idle;
+       bool                            encode_wakeup;
+-- 
+2.53.0
+
diff --git a/queue-6.18/media-rc-ttusbir-fix-inverted-error-logic.patch b/queue-6.18/media-rc-ttusbir-fix-inverted-error-logic.patch
new file mode 100644 (file)
index 0000000..fa14c30
--- /dev/null
@@ -0,0 +1,38 @@
+From e5e5d46bac5151188892f4c7801d3276e3301b34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2026 23:03:09 +0200
+Subject: media: rc: ttusbir: fix inverted error logic
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit 646ebdd3105809d84ed04aa9e92e47e89cc44502 ]
+
+We have to report ENOMEM if no buffer is allocated.
+Typo dropped a "!". Restore it.
+
+Fixes: 50acaad3d202 ("media: rc: ttusbir: respect DMA coherency rules")
+Cc: stable@vger.kernel.org
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/rc/ttusbir.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c
+index a670d4b008cb0d..3452b5aefd2848 100644
+--- a/drivers/media/rc/ttusbir.c
++++ b/drivers/media/rc/ttusbir.c
+@@ -191,7 +191,7 @@ static int ttusbir_probe(struct usb_interface *intf,
+       tt = kzalloc(sizeof(*tt), GFP_KERNEL);
+       buffer = kzalloc(5, GFP_KERNEL);
+       rc = rc_allocate_device(RC_DRIVER_IR_RAW);
+-      if (!tt || !rc || buffer) {
++      if (!tt || !rc || !buffer) {
+               ret = -ENOMEM;
+               goto out;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-avoid-checksumming-unreadable-skb-tail-on-trim.patch b/queue-6.18/net-avoid-checksumming-unreadable-skb-tail-on-trim.patch
new file mode 100644 (file)
index 0000000..a0026fc
--- /dev/null
@@ -0,0 +1,102 @@
+From bda2bf3f5162bc1c99d8dd439ad2af1a37dcfec2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 14:06:40 +0200
+Subject: net: Avoid checksumming unreadable skb tail on trim
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Björn Töpel <bjorn@kernel.org>
+
+[ Upstream commit 2e357f002c61fd76fd8f12468744a06a5ec48eaa ]
+
+pskb_trim_rcsum_slow() keeps CHECKSUM_COMPLETE valid by subtracting
+the checksum of the bytes removed from the skb tail. That assumes the
+removed bytes can be read.
+
+io_uring zcrx skbs may contain unreadable net_iov frags. With fbnic
+header/data split, small TCP/IPv4 packets can carry Ethernet padding
+in such a frag. ip_rcv_core() trims the skb to iph->tot_len before TCP
+sees it, and the CHECKSUM_COMPLETE adjustment then calls
+skb_checksum() on the padding.
+
+This is exposed by IPv4 because small TCP/IPv4 frames can be shorter
+than the Ethernet minimum payload. TCP/IPv6 frames are large enough in
+the normal zcrx path, so they do not hit the same padding trim.
+
+Keep the existing checksum adjustment for readable skbs. If the
+remaining packet is fully linear, drop CHECKSUM_COMPLETE and let the
+stack validate the packet after trimming. If unreadable payload would
+remain, fail the trim; the checksum cannot be adjusted without reading
+the trimmed tail.
+
+Also clear skb->unreadable when trimming removes all frags.
+
+Fixes: 65249feb6b3d ("net: add support for skbs with unreadable frags")
+Signed-off-by: Björn Töpel <bjorn@kernel.org>
+Reviewed-by: Breno Leitao <leitao@debian.org>
+Link: https://patch.msgid.link/20260522120643.242974-1-bjorn@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 31 +++++++++++++++++++++++++++----
+ 1 file changed, 27 insertions(+), 4 deletions(-)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index a8911f1b90c15d..6618bfa70ca444 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -2739,6 +2739,8 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len)
+               skb->data_len  = 0;
+               skb_set_tail_pointer(skb, len);
+       }
++      if (!skb_shinfo(skb)->nr_frags && !skb_has_frag_list(skb))
++              skb->unreadable = 0;
+       if (!skb->sk || skb->destructor == sock_edemux)
+               skb_condense(skb);
+@@ -2746,16 +2748,37 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len)
+ }
+ EXPORT_SYMBOL(___pskb_trim);
++static int pskb_trim_rcsum_complete(struct sk_buff *skb, unsigned int len)
++{
++      int delta = skb->len - len;
++
++      if (skb_frags_readable(skb)) {
++              skb->csum = csum_block_sub(skb->csum,
++                                         skb_checksum(skb, len, delta, 0),
++                                         len);
++              return 0;
++      }
++
++      if (len > skb_headlen(skb))
++              return -EFAULT;
++
++      /* The trimmed bytes are unreadable, but the remaining packet can be
++       * checksummed by software after trimming.
++       */
++      skb->ip_summed = CHECKSUM_NONE;
++      return 0;
++}
++
+ /* Note : use pskb_trim_rcsum() instead of calling this directly
+  */
+ int pskb_trim_rcsum_slow(struct sk_buff *skb, unsigned int len)
+ {
+       if (skb->ip_summed == CHECKSUM_COMPLETE) {
+-              int delta = skb->len - len;
++              int err;
+-              skb->csum = csum_block_sub(skb->csum,
+-                                         skb_checksum(skb, len, delta, 0),
+-                                         len);
++              err = pskb_trim_rcsum_complete(skb, len);
++              if (err)
++                      return err;
+       } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               int hdlen = (len > skb_headlen(skb)) ? skb_headlen(skb) : len;
+               int offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-handshake-pass-negative-errno-through-handshake_.patch b/queue-6.18/net-handshake-pass-negative-errno-through-handshake_.patch
new file mode 100644 (file)
index 0000000..24c1fba
--- /dev/null
@@ -0,0 +1,212 @@
+From 47a42c35e7ae4c6e580abf2c6475186bb80bdaec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:17 -0400
+Subject: net/handshake: Pass negative errno through handshake_complete()
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 6b22d433aa13f68e3cd9534ca9a5f4277bfa01c2 ]
+
+handshake_complete() declares status as unsigned int and
+tls_handshake_done() negates that value (-status) before handing
+it to the TLS consumer. Consumers match on negative errno
+constants -- xs_tls_handshake_done() has
+
+       switch (status) {
+       case 0:
+       case -EACCES:
+       case -ETIMEDOUT:
+               lower_transport->xprt_err = status;
+               break;
+       default:
+               lower_transport->xprt_err = -EACCES;
+       }
+
+so the API as designed expects callers to pass positive errno
+values that the tlshd shim then negates.
+
+Three internal callers in handshake_nl_accept_doit(), the
+net-exit drain, and a kunit test follow kernel convention and
+pass negative errnos -- -EIO, -ETIMEDOUT, -ETIMEDOUT. The
+implicit conversion to unsigned int turns -ETIMEDOUT into
+0xFFFFFF92; the subsequent -status in tls_handshake_done()
+wraps back to 110, the consumer's switch falls through, and
+the xprt reports -EACCES on what should be -ETIMEDOUT or -EIO.
+
+Fix the API rather than the call sites. The natural kernel
+convention is negative errno in, negative errno out. Change
+handshake_complete() and hp_done to take int status, drop the
+negation in tls_handshake_done(), and negate once in
+handshake_nl_done_doit() where status arrives from the wire
+as an unsigned netlink attribute. The three internal callers
+were already correct under that convention and need no change.
+
+At the same wire boundary, declare MAX_ERRNO as the netlink
+policy upper bound for HANDSHAKE_A_DONE_STATUS. Attribute
+validation rejects out-of-range values before
+handshake_nl_done_doit() runs, and negating a bounded u32 there
+stays within int range -- closing the UBSAN-visible signed-
+integer overflow that an unconstrained u32 would invoke.
+
+Fixes: 3b3009ea8abb ("net/handshake: Create a NETLINK service for handling handshake requests")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-3-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/netlink/specs/handshake.yaml | 8 ++++++++
+ net/handshake/genl.c                       | 3 ++-
+ net/handshake/genl.h                       | 1 +
+ net/handshake/handshake-test.c             | 2 +-
+ net/handshake/handshake.h                  | 4 ++--
+ net/handshake/netlink.c                    | 2 +-
+ net/handshake/request.c                    | 2 +-
+ net/handshake/tlshd.c                      | 4 ++--
+ 8 files changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/Documentation/netlink/specs/handshake.yaml b/Documentation/netlink/specs/handshake.yaml
+index 95c3fade7a8d7b..1024297b38513a 100644
+--- a/Documentation/netlink/specs/handshake.yaml
++++ b/Documentation/netlink/specs/handshake.yaml
+@@ -12,6 +12,12 @@ protocol: genetlink
+ doc: Netlink protocol to request a transport layer security handshake.
+ definitions:
++  -
++    type: const
++    name: max-errno
++    value: 4095
++    header: linux/err.h
++    scope: kernel
+   -
+     type: enum
+     name: handler-class
+@@ -80,6 +86,8 @@ attribute-sets:
+       -
+         name: status
+         type: u32
++        checks:
++          max: max-errno
+       -
+         name: sockfd
+         type: s32
+diff --git a/net/handshake/genl.c b/net/handshake/genl.c
+index f55d14d7b7269d..a5fa8b27f22423 100644
+--- a/net/handshake/genl.c
++++ b/net/handshake/genl.c
+@@ -9,6 +9,7 @@
+ #include "genl.h"
+ #include <uapi/linux/handshake.h>
++#include <linux/err.h>
+ /* HANDSHAKE_CMD_ACCEPT - do */
+ static const struct nla_policy handshake_accept_nl_policy[HANDSHAKE_A_ACCEPT_HANDLER_CLASS + 1] = {
+@@ -17,7 +18,7 @@ static const struct nla_policy handshake_accept_nl_policy[HANDSHAKE_A_ACCEPT_HAN
+ /* HANDSHAKE_CMD_DONE - do */
+ static const struct nla_policy handshake_done_nl_policy[HANDSHAKE_A_DONE_REMOTE_AUTH + 1] = {
+-      [HANDSHAKE_A_DONE_STATUS] = { .type = NLA_U32, },
++      [HANDSHAKE_A_DONE_STATUS] = NLA_POLICY_MAX(NLA_U32, MAX_ERRNO),
+       [HANDSHAKE_A_DONE_SOCKFD] = { .type = NLA_S32, },
+       [HANDSHAKE_A_DONE_REMOTE_AUTH] = { .type = NLA_U32, },
+ };
+diff --git a/net/handshake/genl.h b/net/handshake/genl.h
+index ae72a596f6cc3e..684e5fd684481b 100644
+--- a/net/handshake/genl.h
++++ b/net/handshake/genl.h
+@@ -10,6 +10,7 @@
+ #include <net/genetlink.h>
+ #include <uapi/linux/handshake.h>
++#include <linux/err.h>
+ int handshake_nl_accept_doit(struct sk_buff *skb, struct genl_info *info);
+ int handshake_nl_done_doit(struct sk_buff *skb, struct genl_info *info);
+diff --git a/net/handshake/handshake-test.c b/net/handshake/handshake-test.c
+index 55442b2f518afb..df3948e807a0fd 100644
+--- a/net/handshake/handshake-test.c
++++ b/net/handshake/handshake-test.c
+@@ -25,7 +25,7 @@ static int test_accept_func(struct handshake_req *req, struct genl_info *info,
+       return 0;
+ }
+-static void test_done_func(struct handshake_req *req, unsigned int status,
++static void test_done_func(struct handshake_req *req, int status,
+                          struct genl_info *info)
+ {
+ }
+diff --git a/net/handshake/handshake.h b/net/handshake/handshake.h
+index a48163765a7a1d..2289b0e274f40a 100644
+--- a/net/handshake/handshake.h
++++ b/net/handshake/handshake.h
+@@ -57,7 +57,7 @@ struct handshake_proto {
+       int                     (*hp_accept)(struct handshake_req *req,
+                                            struct genl_info *info, int fd);
+       void                    (*hp_done)(struct handshake_req *req,
+-                                         unsigned int status,
++                                         int status,
+                                          struct genl_info *info);
+       void                    (*hp_destroy)(struct handshake_req *req);
+ };
+@@ -86,7 +86,7 @@ struct handshake_req *handshake_req_hash_lookup(struct sock *sk);
+ struct handshake_req *handshake_req_next(struct handshake_net *hn, int class);
+ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+                        gfp_t flags);
+-void handshake_complete(struct handshake_req *req, unsigned int status,
++void handshake_complete(struct handshake_req *req, int status,
+                       struct genl_info *info);
+ bool handshake_req_cancel(struct sock *sk);
+diff --git a/net/handshake/netlink.c b/net/handshake/netlink.c
+index 394e270cc505cb..d8211e0ba75c69 100644
+--- a/net/handshake/netlink.c
++++ b/net/handshake/netlink.c
+@@ -161,7 +161,7 @@ int handshake_nl_done_doit(struct sk_buff *skb, struct genl_info *info)
+       status = -EIO;
+       if (info->attrs[HANDSHAKE_A_DONE_STATUS])
+-              status = nla_get_u32(info->attrs[HANDSHAKE_A_DONE_STATUS]);
++              status = -(int)nla_get_u32(info->attrs[HANDSHAKE_A_DONE_STATUS]);
+       handshake_complete(req, status, info);
+       sockfd_put(sock);
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 654e55b141cded..62efb7e32730ea 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -284,7 +284,7 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+ }
+ EXPORT_SYMBOL(handshake_req_submit);
+-void handshake_complete(struct handshake_req *req, unsigned int status,
++void handshake_complete(struct handshake_req *req, int status,
+                       struct genl_info *info)
+ {
+       struct sock *sk = req->hr_sk;
+diff --git a/net/handshake/tlshd.c b/net/handshake/tlshd.c
+index af294c6cc71731..7567150c2a4f95 100644
+--- a/net/handshake/tlshd.c
++++ b/net/handshake/tlshd.c
+@@ -93,7 +93,7 @@ static void tls_handshake_remote_peerids(struct tls_handshake_req *treq,
+  *
+  */
+ static void tls_handshake_done(struct handshake_req *req,
+-                             unsigned int status, struct genl_info *info)
++                             int status, struct genl_info *info)
+ {
+       struct tls_handshake_req *treq = handshake_req_private(req);
+@@ -104,7 +104,7 @@ static void tls_handshake_done(struct handshake_req *req,
+       if (!status)
+               set_bit(HANDSHAKE_F_REQ_SESSION, &req->hr_flags);
+-      treq->th_consumer_done(treq->th_consumer_data, -status,
++      treq->th_consumer_done(treq->th_consumer_data, status,
+                              treq->th_peerid[0]);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-handshake-use-spin_lock_bh-for-hn_lock.patch b/queue-6.18/net-handshake-use-spin_lock_bh-for-hn_lock.patch
new file mode 100644 (file)
index 0000000..1960985
--- /dev/null
@@ -0,0 +1,138 @@
+From a33244e7d99f1609cfe06f3fe1cff7cf9163baaa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:15 -0400
+Subject: net/handshake: Use spin_lock_bh for hn_lock
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit cc993e0927ec8bd98ea33377ada03295fcda0f24 ]
+
+nvmet_tcp_state_change(), a socket callback that runs in BH context,
+can reach handshake_req_cancel() via nvmet_tcp_schedule_release_queue()
+and tls_handshake_cancel().  handshake_req_cancel() acquires
+hn->hn_lock with plain spin_lock().  If a process-context thread on
+the same CPU holds hn->hn_lock when a softirq invokes the cancel path,
+the lock attempt deadlocks.  This is the only caller that invokes
+tls_handshake_cancel() from BH context; every other consumer calls it
+from process context.
+
+Deferring the cancel to process context in the NVMe target is not
+straightforward: nvmet_tcp_schedule_release_queue() must call
+tls_handshake_cancel() atomically with its state transition to
+DISCONNECTING.  If the cancel were deferred, the handshake completion
+callback could fire in the window before the cancel runs, observe the
+unexpected state, and return without dropping its kref on the queue.
+Reworking that interlock is considerably more invasive than hardening
+the handshake lock.  Convert all hn->hn_lock acquisitions from
+spin_lock/spin_unlock to spin_lock_bh/spin_unlock_bh so the lock is
+never taken with softirqs enabled.
+
+Fixes: 675b453e0241 ("nvmet-tcp: enable TLS handshake upcall")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-1-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/netlink.c |  4 ++--
+ net/handshake/request.c | 14 +++++++-------
+ net/handshake/tlshd.c   |  2 ++
+ 3 files changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/net/handshake/netlink.c b/net/handshake/netlink.c
+index 7e46d130dce2cd..394e270cc505cb 100644
+--- a/net/handshake/netlink.c
++++ b/net/handshake/netlink.c
+@@ -203,10 +203,10 @@ static void __net_exit handshake_net_exit(struct net *net)
+        * accepted and are in progress will be destroyed when
+        * the socket is closed.
+        */
+-      spin_lock(&hn->hn_lock);
++      spin_lock_bh(&hn->hn_lock);
+       set_bit(HANDSHAKE_F_NET_DRAINING, &hn->hn_flags);
+       list_splice_init(&requests, &hn->hn_requests);
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+       while (!list_empty(&requests)) {
+               req = list_first_entry(&requests, struct handshake_req, hr_list);
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 6b7e3e0bf3996e..654e55b141cded 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -167,12 +167,12 @@ static bool remove_pending(struct handshake_net *hn, struct handshake_req *req)
+ {
+       bool ret = false;
+-      spin_lock(&hn->hn_lock);
++      spin_lock_bh(&hn->hn_lock);
+       if (!list_empty(&req->hr_list)) {
+               __remove_pending_locked(hn, req);
+               ret = true;
+       }
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+       return ret;
+ }
+@@ -182,7 +182,7 @@ struct handshake_req *handshake_req_next(struct handshake_net *hn, int class)
+       struct handshake_req *req, *pos;
+       req = NULL;
+-      spin_lock(&hn->hn_lock);
++      spin_lock_bh(&hn->hn_lock);
+       list_for_each_entry(pos, &hn->hn_requests, hr_list) {
+               if (pos->hr_proto->hp_handler_class != class)
+                       continue;
+@@ -190,7 +190,7 @@ struct handshake_req *handshake_req_next(struct handshake_net *hn, int class)
+               req = pos;
+               break;
+       }
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+       return req;
+ }
+@@ -249,7 +249,7 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+       if (READ_ONCE(hn->hn_pending) >= hn->hn_pending_max)
+               goto out_err;
+-      spin_lock(&hn->hn_lock);
++      spin_lock_bh(&hn->hn_lock);
+       ret = -EOPNOTSUPP;
+       if (test_bit(HANDSHAKE_F_NET_DRAINING, &hn->hn_flags))
+               goto out_unlock;
+@@ -258,7 +258,7 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+               goto out_unlock;
+       if (!__add_pending_locked(hn, req))
+               goto out_unlock;
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+       ret = handshake_genl_notify(net, req->hr_proto, flags);
+       if (ret) {
+@@ -274,7 +274,7 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+       return 0;
+ out_unlock:
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+ out_err:
+       /* Restore original destructor so socket teardown still runs on failure */
+       req->hr_sk->sk_destruct = req->hr_odestruct;
+diff --git a/net/handshake/tlshd.c b/net/handshake/tlshd.c
+index 8f9532a15f43f9..af294c6cc71731 100644
+--- a/net/handshake/tlshd.c
++++ b/net/handshake/tlshd.c
+@@ -425,6 +425,8 @@ EXPORT_SYMBOL(tls_server_hello_psk);
+  * Request cancellation races with request completion. To determine
+  * who won, callers examine the return value from this function.
+  *
++ * Context: May be called from process or softirq context.
++ *
+  * Return values:
+  *   %true - Uncompleted handshake request was canceled
+  *   %false - Handshake request already completed or not found
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-hibmcge-disable-relaxed-ordering-to-fix-rx-packe.patch b/queue-6.18/net-hibmcge-disable-relaxed-ordering-to-fix-rx-packe.patch
new file mode 100644 (file)
index 0000000..864c6b4
--- /dev/null
@@ -0,0 +1,45 @@
+From 08e4faeb7394f9a82e7ab35363657b40585aa62d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 22:45:24 +0800
+Subject: net: hibmcge: disable Relaxed Ordering to fix RX packet corruption
+
+From: Jijie Shao <shaojijie@huawei.com>
+
+[ Upstream commit 463a1271aa26eac992851b9d98cc75bc3cd4a1ed ]
+
+When SMMU is disabled, the hibmcge driver may receive corrupted packets.
+The hardware writes packet data and descriptors to the same page, but
+with Relaxed Ordering enabled, PCI write transactions may not be
+strictly ordered. This can cause the driver to observe a valid
+descriptor before the corresponding packet data is fully written.
+
+Fix this by clearing PCI_EXP_DEVCTL_RELAX_EN in the PCI bridge control
+register to ensure strict write ordering between packet data and
+descriptors.
+
+Fixes: f72e25594061 ("net: hibmcge: Implement rx_poll function to receive packets")
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Link: https://patch.msgid.link/20260525144525.94884-2-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c
+index 0b92a2e5e98694..cf0f14aa014cf8 100644
+--- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c
++++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c
+@@ -420,6 +420,9 @@ static int hbg_pci_init(struct pci_dev *pdev)
+               return -ENOMEM;
+       pci_set_master(pdev);
++      pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL,
++                                 PCI_EXP_DEVCTL_RELAX_EN);
++      pci_save_state(pdev);
+       return 0;
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-hsr-fix-potential-oob-access-in-supervision-fram.patch b/queue-6.18/net-hsr-fix-potential-oob-access-in-supervision-fram.patch
new file mode 100644 (file)
index 0000000..2fbd290
--- /dev/null
@@ -0,0 +1,48 @@
+From 604a3e9565b3d1f5fa85fa3dc850e3c78eaad2a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 May 2026 15:03:30 +0200
+Subject: net: hsr: fix potential OOB access in supervision frame handling
+
+From: Luka Gejak <luka.gejak@linux.dev>
+
+[ Upstream commit f229426072fc865654a60978bb7fda790a051ff3 ]
+
+Ensure the entire TLV header is linearized before access by adding
+sizeof(struct hsr_sup_tlv) to the pskb_may_pull() calls. Without this,
+a truncated frame could cause an out-of-bounds access.
+
+Fixes: eafaa88b3eb7 ("net: hsr: Add support for redbox supervision frames")
+Signed-off-by: Luka Gejak <luka.gejak@linux.dev>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260523130330.61880-1-luka.gejak@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_forward.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index aefc9b6936ba0c..299de290ddaa5c 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -84,7 +84,7 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb)
+       /* Get next tlv */
+       total_length += hsr_sup_tag->tlv.HSR_TLV_length;
+-      if (!pskb_may_pull(skb, total_length))
++      if (!pskb_may_pull(skb, total_length + sizeof(struct hsr_sup_tlv)))
+               return false;
+       skb_pull(skb, total_length);
+       hsr_sup_tlv = (struct hsr_sup_tlv *)skb->data;
+@@ -100,7 +100,7 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb)
+               /* make sure another tlv follows */
+               total_length += sizeof(struct hsr_sup_tlv) + hsr_sup_tlv->HSR_TLV_length;
+-              if (!pskb_may_pull(skb, total_length))
++              if (!pskb_may_pull(skb, total_length + sizeof(struct hsr_sup_tlv)))
+                       return false;
+               /* get next tlv */
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-iucv-fix-locking-in-.getsockopt.patch b/queue-6.18/net-iucv-fix-locking-in-.getsockopt.patch
new file mode 100644 (file)
index 0000000..118b4a5
--- /dev/null
@@ -0,0 +1,87 @@
+From e443cb27cab1aad8c06f8c21ff977251de1d80fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 07:11:45 -0700
+Subject: net/iucv: fix locking in .getsockopt
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 3589d20a666caf30ad100c960a2de7de390fce88 ]
+
+Mirror iucv_sock_setsockopt() and wrap the whole switch in
+lock_sock()/release_sock(). The pre-existing SO_MSGLIMIT-only lock
+becomes redundant and is removed.
+
+Any AF_IUCV HIPER user can potentially crash the kernel by racing
+recvmsg() with getsockopt(SO_MSGSIZE): the SO_MSGSIZE arm dereferences
+iucv->hs_dev->mtu after iucv_sock_close() (called from the racing
+recvmsg()) has set hs_dev to NULL, producing a NULL pointer dereference
+oops.
+
+Suggested-by: Stanislav Fomichev <sdf.kernel@gmail.com>
+Fixes: 51363b8751a6 ("af_iucv: allow retrieval of maximum message size")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Tested-by: Alexandra Winter <wintera@linux.ibm.com>
+Link: https://patch.msgid.link/20260521-af_iucv_fix2-v1-1-f16b1c510aa9@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index 6c717a7ef29283..c66b90c912e78e 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -1538,7 +1538,7 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       struct sock *sk = sock->sk;
+       struct iucv_sock *iucv = iucv_sk(sk);
+       unsigned int val;
+-      int len;
++      int len, rc;
+       if (level != SOL_IUCV)
+               return -ENOPROTOOPT;
+@@ -1551,26 +1551,34 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       len = min_t(unsigned int, len, sizeof(int));
++      rc = 0;
++
++      lock_sock(sk);
+       switch (optname) {
+       case SO_IPRMDATA_MSG:
+               val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0;
+               break;
+       case SO_MSGLIMIT:
+-              lock_sock(sk);
+               val = (iucv->path != NULL) ? iucv->path->msglim /* connected */
+                                          : iucv->msglimit;    /* default */
+-              release_sock(sk);
+               break;
+       case SO_MSGSIZE:
+-              if (sk->sk_state == IUCV_OPEN)
+-                      return -EBADFD;
++              if (sk->sk_state == IUCV_OPEN) {
++                      rc = -EBADFD;
++                      break;
++              }
+               val = (iucv->hs_dev) ? iucv->hs_dev->mtu -
+                               sizeof(struct af_iucv_trans_hdr) - ETH_HLEN :
+                               0x7fffffff;
+               break;
+       default:
+-              return -ENOPROTOOPT;
++              rc = -ENOPROTOOPT;
++              break;
+       }
++      release_sock(sk);
++
++      if (rc)
++              return rc;
+       if (put_user(len, optlen))
+               return -EFAULT;
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-mana-add-null-guards-in-teardown-path-to-prevent.patch b/queue-6.18/net-mana-add-null-guards-in-teardown-path-to-prevent.patch
new file mode 100644 (file)
index 0000000..aef4a55
--- /dev/null
@@ -0,0 +1,148 @@
+From e791dc5b86c87f00ea159d61e83c6bf69b468967 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 01:08:24 -0700
+Subject: net: mana: Add NULL guards in teardown path to prevent panic on
+ attach failure
+
+From: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+
+[ Upstream commit 17bfe0a8c014ee1d542ad352cd6a0a505361664a ]
+
+When queue allocation fails partway through, the error cleanup frees
+and NULLs apc->tx_qp and apc->rxqs. Multiple teardown paths such as
+mana_remove(), mana_change_mtu() recovery, and internal error handling
+in mana_alloc_queues() can subsequently call into functions that
+dereference these pointers without NULL checks:
+
+- mana_chn_setxdp() dereferences apc->rxqs[0], causing a NULL pointer
+  dereference panic (CR2: 0000000000000000 at mana_chn_setxdp+0x26).
+- mana_destroy_vport() iterates apc->rxqs without a NULL check.
+- mana_fence_rqs() iterates apc->rxqs without a NULL check.
+- mana_dealloc_queues() iterates apc->tx_qp without a NULL check.
+
+Add NULL guards for apc->rxqs in mana_fence_rqs(),
+mana_destroy_vport(), and before the mana_chn_setxdp() call. Add a
+NULL guard for apc->tx_qp in mana_dealloc_queues() to skip TX queue
+draining when TX queues were never allocated or already freed.
+
+Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
+Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+Link: https://patch.msgid.link/20260525081129.1230035-2-dipayanroy@linux.microsoft.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microsoft/mana/mana_en.c | 70 +++++++++++--------
+ 1 file changed, 41 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
+index d1eb77d540427d..6ef2a3ee44c6b0 100644
+--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
+@@ -1720,6 +1720,9 @@ static void mana_fence_rqs(struct mana_port_context *apc)
+       struct mana_rxq *rxq;
+       int err;
++      if (!apc->rxqs)
++              return;
++
+       for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
+               rxq = apc->rxqs[rxq_idx];
+               err = mana_fence_rq(apc, rxq);
+@@ -2830,13 +2833,16 @@ static void mana_destroy_vport(struct mana_port_context *apc)
+       struct mana_rxq *rxq;
+       u32 rxq_idx;
+-      for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
+-              rxq = apc->rxqs[rxq_idx];
+-              if (!rxq)
+-                      continue;
++      if (apc->rxqs) {
+-              mana_destroy_rxq(apc, rxq, true);
+-              apc->rxqs[rxq_idx] = NULL;
++              for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
++                      rxq = apc->rxqs[rxq_idx];
++                      if (!rxq)
++                              continue;
++
++                      mana_destroy_rxq(apc, rxq, true);
++                      apc->rxqs[rxq_idx] = NULL;
++              }
+       }
+       mana_destroy_txq(apc);
+@@ -3241,7 +3247,8 @@ static int mana_dealloc_queues(struct net_device *ndev)
+       if (apc->port_is_up)
+               return -EINVAL;
+-      mana_chn_setxdp(apc, NULL);
++      if (apc->rxqs)
++              mana_chn_setxdp(apc, NULL);
+       if (gd->gdma_context->is_pf && !apc->ac->bm_hostmode)
+               mana_pf_deregister_filter(apc);
+@@ -3259,33 +3266,38 @@ static int mana_dealloc_queues(struct net_device *ndev)
+        * number of queues.
+        */
+-      for (i = 0; i < apc->num_queues; i++) {
+-              txq = &apc->tx_qp[i].txq;
+-              tsleep = 1000;
+-              while (atomic_read(&txq->pending_sends) > 0 &&
+-                     time_before(jiffies, timeout)) {
+-                      usleep_range(tsleep, tsleep + 1000);
+-                      tsleep <<= 1;
+-              }
+-              if (atomic_read(&txq->pending_sends)) {
+-                      err = pcie_flr(to_pci_dev(gd->gdma_context->dev));
+-                      if (err) {
+-                              netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
+-                                         err, atomic_read(&txq->pending_sends),
+-                                         txq->gdma_txq_id);
++      if (apc->tx_qp) {
++              for (i = 0; i < apc->num_queues; i++) {
++                      txq = &apc->tx_qp[i].txq;
++                      tsleep = 1000;
++                      while (atomic_read(&txq->pending_sends) > 0 &&
++                             time_before(jiffies, timeout)) {
++                              usleep_range(tsleep, tsleep + 1000);
++                              tsleep <<= 1;
++                      }
++                      if (atomic_read(&txq->pending_sends)) {
++                              err =
++                                  pcie_flr(to_pci_dev(gd->gdma_context->dev));
++                              if (err) {
++                                      netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
++                                                 err,
++                                          atomic_read(&txq->pending_sends),
++                                          txq->gdma_txq_id);
++                              }
++                              break;
+                       }
+-                      break;
+               }
+-      }
+-      for (i = 0; i < apc->num_queues; i++) {
+-              txq = &apc->tx_qp[i].txq;
+-              while ((skb = skb_dequeue(&txq->pending_skbs))) {
+-                      mana_unmap_skb(skb, apc);
+-                      dev_kfree_skb_any(skb);
++              for (i = 0; i < apc->num_queues; i++) {
++                      txq = &apc->tx_qp[i].txq;
++                      while ((skb = skb_dequeue(&txq->pending_skbs))) {
++                              mana_unmap_skb(skb, apc);
++                              dev_kfree_skb_any(skb);
++                      }
++                      atomic_set(&txq->pending_sends, 0);
+               }
+-              atomic_set(&txq->pending_sends, 0);
+       }
++
+       /* We're 100% sure the queues can no longer be woken up, because
+        * we're sure now mana_poll_tx_cq() can't be running.
+        */
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-mana-skip-redundant-detach-on-already-detached-p.patch b/queue-6.18/net-mana-skip-redundant-detach-on-already-detached-p.patch
new file mode 100644 (file)
index 0000000..6077ca7
--- /dev/null
@@ -0,0 +1,51 @@
+From 2922a922b3d1b6e167b46606ed0b574627f7a7a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 01:08:25 -0700
+Subject: net: mana: Skip redundant detach on already-detached port
+
+From: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+
+[ Upstream commit 5b05aa36ee24297d7296ca58dfd8c448d0e4cda3 ]
+
+When mana_per_port_queue_reset_work_handler() runs after a previous
+detach succeeded but attach failed, the port is left in a detached
+state with apc->tx_qp and apc->rxqs already freed. Calling
+mana_detach() again unconditionally leads to NULL pointer dereferences
+during queue teardown.
+
+Add an early exit in mana_detach() when the port is already in
+detached state (!netif_device_present) for non-close callers, making
+it safe to call idempotently. This allows the queue reset handler and
+other recovery paths to simply retry mana_attach() without redundant
+teardown.
+
+Fixes: 3b194343c250 ("net: mana: Implement ndo_tx_timeout and serialize queue resets per port.")
+Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+Link: https://patch.msgid.link/20260525081129.1230035-3-dipayanroy@linux.microsoft.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microsoft/mana/mana_en.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
+index 6ef2a3ee44c6b0..1f723c0ea12837 100644
+--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
+@@ -3322,6 +3322,12 @@ int mana_detach(struct net_device *ndev, bool from_close)
+       ASSERT_RTNL();
++      /* If already detached (indicates detach succeeded but attach failed
++       * previously). Now skip mana detach and just retry mana_attach.
++       */
++      if (!from_close && !netif_device_present(ndev))
++              return 0;
++
+       apc->port_st_save = apc->port_is_up;
+       apc->port_is_up = false;
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-mlx5-hws-reject-unsupported-remove-header-action.patch b/queue-6.18/net-mlx5-hws-reject-unsupported-remove-header-action.patch
new file mode 100644 (file)
index 0000000..c717401
--- /dev/null
@@ -0,0 +1,50 @@
+From 84b76baf8114b699baabfa7199465e44090d70ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 May 2026 01:00:31 +0100
+Subject: net/mlx5: HWS: Reject unsupported remove-header action
+
+From: Prathamesh Deshpande <prathameshdeshpande7@gmail.com>
+
+[ Upstream commit 86f1d0f063e423a5c1982db1e5e7a8eac511e603 ]
+
+mlx5_cmd_hws_packet_reformat_alloc() handles
+MLX5_REFORMAT_TYPE_REMOVE_HDR by looking up a matching HWS remove-header
+action.
+
+If mlx5_fs_get_action_remove_header_vlan() returns NULL, the code only
+logs an error and continues. The function then returns success with a NULL
+HWS action stored in the packet-reformat object.
+
+Return an error when no matching remove-header action is available.
+
+Fixes: aecd9d1020e3 ("net/mlx5: fs, add HWS packet reformat API function")
+Signed-off-by: Prathamesh Deshpande <prathameshdeshpande7@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
+Acked-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20260506000054.51797-1-prathameshdeshpande7@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c
+index 6a4c4cccd64342..c45a7ca66ad8ed 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c
+@@ -1323,8 +1323,10 @@ mlx5_cmd_hws_packet_reformat_alloc(struct mlx5_flow_root_namespace *ns,
+               break;
+       case MLX5_REFORMAT_TYPE_REMOVE_HDR:
+               hws_action = mlx5_fs_get_action_remove_header_vlan(fs_ctx, params);
+-              if (!hws_action)
++              if (!hws_action) {
+                       mlx5_core_err(dev, "Only vlan remove header supported\n");
++                      return -EOPNOTSUPP;
++              }
+               break;
+       default:
+               mlx5_core_err(ns->dev, "Packet-reformat not supported(%d)\n",
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-netlink-don-t-set-nsid-on-local-notifications.patch b/queue-6.18/net-netlink-don-t-set-nsid-on-local-notifications.patch
new file mode 100644 (file)
index 0000000..7aa8f07
--- /dev/null
@@ -0,0 +1,82 @@
+From 0a31a5650d70f4fccaf4d56e70a49cd2697e221e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:36 +0200
+Subject: net: netlink: don't set nsid on local notifications
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 88b126b39f9757e9debc322d4679239e9af089c7 ]
+
+In most cases, notifications on sockets with NETLINK_LISTEN_ALL_NSID
+do not contain NSID in their ancillary data in case the event is local
+to the listener.
+
+However, when a self-referential NSID is allocated for a namespace,
+every local notification starts sending this ID to the user space.
+
+This is problematic, because the listener cannot tell if those
+notifications are local or not anymore without making extra requests
+to figure out if the provided NSID is local or not.  The listener
+can also not figure out the local NSID beforehand as it can be
+allocated at any point in time by other processes, changing the
+structure of the future notifications for everyone.
+
+The value is practically not useful, since it's the namespace's own
+ID that the application has to obtain from other sources in order to
+figure out if it's the same or not.  So, for the application it's
+just an extra busy work with no benefits.  Moreover, applications
+that do not know about this quirk may be mishandling notifications
+with NSID set as notifications from remote namespaces.  This is the
+case for ovs-vswitchd and the iproute2's 'ip monitor' that stops
+printing 'current' and starts printing the nsid number mid-session.
+
+Lack of clear documentation for this behavior is also not helping.
+
+A search though open-source projects doesn't reveal any projects
+that use NETNSA_NSID_NOT_ASSIGNED and rely on metadata to contain
+self-referential NSIDs (expected, since the value is not useful).
+Quite the opposite, as already mentioned, there are few applications
+that rely on NSID to not be present in local events.
+
+Since the value is not useful and actively harmful in some cases,
+let's not report it for local events, making the notifications more
+consistent.
+
+Also adding some blank lines for readability.
+
+Fixes: 59324cf35aba ("netlink: allow to listen "all" netns")
+Reported-by: Matteo Perin <matteo.perin@canonical.com>
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-3-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 0e6dfd01d9b419..1d1b3bd54a916b 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1484,10 +1484,14 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++
+       NETLINK_CB(p->skb2).nsid_is_set = false;
+-      NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+-      if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+-              NETLINK_CB(p->skb2).nsid_is_set = true;
++      if (!net_eq(sock_net(sk), p->net)) {
++              NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
++              if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
++                      NETLINK_CB(p->skb2).nsid_is_set = true;
++      }
++
+       val = netlink_broadcast_deliver(sk, p->skb2);
+       if (val < 0) {
+               netlink_overrun(sk);
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-netlink-fix-sending-unassigned-nsid-after-assign.patch b/queue-6.18/net-netlink-fix-sending-unassigned-nsid-after-assign.patch
new file mode 100644 (file)
index 0000000..868f9b7
--- /dev/null
@@ -0,0 +1,45 @@
+From b065309029ea5a81e1836547d84bcb1cc58ebfe1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:35 +0200
+Subject: net: netlink: fix sending unassigned nsid after assigned one
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 70f8592ee90585272018a725054b6eb2ab7e99ca ]
+
+If the current skb is not shared, it is re-used directly for all the
+sockets subscribed to the notification.  If we have remote all-nsid
+socket receiving a message first, then the 'nsid_is_set' will be
+set to 'true'.  If the nsid is NOT_ASSIGNED for the next socket in
+the list, the 'nsid_is_set' will remain 'true' and the negative value
+is be delivered to the user space.  All subsequent nsid values will be
+delivered as well, since there is no code path that sets the flag
+back to 'false'.
+
+Fix that by always dropping the flag to 'false' first.
+
+Fixes: 7212462fa6fd ("netlink: don't send unknown nsid")
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-2-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 2b46c0cd752a31..0e6dfd01d9b419 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1484,6 +1484,7 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++      NETLINK_CB(p->skb2).nsid_is_set = false;
+       NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+       if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+               NETLINK_CB(p->skb2).nsid_is_set = true;
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-sched-revert-net-sched-restrict-conditions-for-a.patch b/queue-6.18/net-sched-revert-net-sched-restrict-conditions-for-a.patch
new file mode 100644 (file)
index 0000000..1d48981
--- /dev/null
@@ -0,0 +1,102 @@
+From 8c1d2e30c6dc44cc920179bd372738ba12172d90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:49 -0400
+Subject: net/sched: Revert "net/sched: Restrict conditions for adding
+ duplicating netems to qdisc tree"
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit eda0b7f203bb166c98d1418b204135bd566ac83b ]
+
+This reverts commit ec8e0e3d7adef940cdf9475e2352c0680189d14e.
+
+The original patch rejects any tree containing two netems when
+either has duplication set, even when they sit on unrelated classes
+of the same classful parent. That broke configurations that have
+worked since netem was introduced.
+
+The re-entrancy problem the original commit was trying to solve is
+handled by later patch using tc_depth flag.
+
+Doing this revert will (re)expose the original bug with multiple
+netem duplication. When this patch is backported make sure
+and get the full series.
+
+Fixes: ec8e0e3d7ade ("net/sched: Restrict conditions for adding duplicating netems to qdisc tree")
+Reported-by: Ji-Soo Chung <jschung2@proton.me>
+Reported-by: Gerlinde <lrGerlinde@mailfence.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220774
+Reported-by: zyc zyc <zyc199902@zohomail.cn>
+Closes: https://lore.kernel.org/all/19adda5a1e2.12410b78222774.9191120410578703463@zohomail.cn/
+Reported-by: Manas Ghandat <ghandatmanas@gmail.com>
+Closes: https://lore.kernel.org/netdev/f69b2c8f-8325-4c2e-a011-6dbc089f30e4@gmail.com/
+Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-3-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_netem.c | 40 ----------------------------------------
+ 1 file changed, 40 deletions(-)
+
+diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
+index 47db6da905c585..73b3a8ce2f4350 100644
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -1006,41 +1006,6 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
+       return 0;
+ }
+-static const struct Qdisc_class_ops netem_class_ops;
+-
+-static int check_netem_in_tree(struct Qdisc *sch, bool duplicates,
+-                             struct netlink_ext_ack *extack)
+-{
+-      struct Qdisc *root, *q;
+-      unsigned int i;
+-
+-      root = qdisc_root_sleeping(sch);
+-
+-      if (sch != root && root->ops->cl_ops == &netem_class_ops) {
+-              if (duplicates ||
+-                  ((struct netem_sched_data *)qdisc_priv(root))->duplicate)
+-                      goto err;
+-      }
+-
+-      if (!qdisc_dev(root))
+-              return 0;
+-
+-      hash_for_each(qdisc_dev(root)->qdisc_hash, i, q, hash) {
+-              if (sch != q && q->ops->cl_ops == &netem_class_ops) {
+-                      if (duplicates ||
+-                          ((struct netem_sched_data *)qdisc_priv(q))->duplicate)
+-                              goto err;
+-              }
+-      }
+-
+-      return 0;
+-
+-err:
+-      NL_SET_ERR_MSG(extack,
+-                     "netem: cannot mix duplicating netems with other netems in tree");
+-      return -EINVAL;
+-}
+-
+ /* Parse netlink message to set options */
+ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+                       struct netlink_ext_ack *extack)
+@@ -1117,11 +1082,6 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+       q->gap = qopt->gap;
+       q->counter = 0;
+       q->loss = qopt->loss;
+-
+-      ret = check_netem_in_tree(sch, qopt->duplicate, extack);
+-      if (ret)
+-              goto unlock;
+-
+       q->duplicate = qopt->duplicate;
+       /* for compatibility with earlier versions.
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch b/queue-6.18/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch
new file mode 100644 (file)
index 0000000..ffd59e9
--- /dev/null
@@ -0,0 +1,64 @@
+From ce1b823828a9d42d026f9b1b299a47c1384ab20b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 May 2026 19:43:53 +0100
+Subject: net: skbuff: fix pskb_carve leaking zcopy pages
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit ff6e798c2eac3ebd0501ad7e796f583fab928de8 ]
+
+When SKBFL_MANAGED_FRAG_REFS is set, frag pages are not refcounted but
+their lifetime is controlled by the attached ubuf_info. To make a copy
+of the skb_shared_info, we either should clear the flag and reference
+the frags, or keep the flag and have frags unreferenced.
+
+pskb_carve_inside_header() and pskb_carve_inside_nonlinear() don't
+follow the rule and thus can leak page references. Let's clear
+SKBFL_MANAGED_FRAG_REFS from the original skb to fix it. It's the
+simplest way to address it, but there are more performant ways to do
+that if it ever becomes a problem.
+
+Link: https://lore.kernel.org/all/20260523085809.26331-1-nvminh232@clc.fitus.edu.vn/
+Fixes: 753f1ca4e1e50 ("net: introduce managed frags infrastructure")
+Reported-by: Minh Nguyen <minhnguyen.080505@gmail.com>
+Reported-by: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/1e2086aa69217d7f9c8da3d38f5be7160f1b4cd1.1779993185.git.asml.silence@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 6618bfa70ca444..a52aa79b0fdbaf 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -6772,6 +6772,11 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
+       skb_copy_from_linear_data_offset(skb, off, data, new_hlen);
+       skb->len -= off;
++      /* Remove SKBFL_MANAGED_FRAG_REFS instead of trying to honour it
++       * while refcounting frags below.
++       */
++      skb_zcopy_downgrade_managed(skb);
++
+       memcpy((struct skb_shared_info *)(data + size),
+              skb_shinfo(skb),
+              offsetof(struct skb_shared_info,
+@@ -6883,6 +6888,11 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,
+               return -ENOMEM;
+       size = SKB_WITH_OVERHEAD(size);
++      /* Remove SKBFL_MANAGED_FRAG_REFS instead of trying to honour it
++       * while refcounting frags below.
++       */
++      skb_zcopy_downgrade_managed(skb);
++
+       memcpy((struct skb_shared_info *)(data + size),
+              skb_shinfo(skb), offsetof(struct skb_shared_info, frags[0]));
+       if (skb_orphan_frags(skb, gfp_mask)) {
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-smc-do-not-re-initialize-smc-hashtables.patch b/queue-6.18/net-smc-do-not-re-initialize-smc-hashtables.patch
new file mode 100644 (file)
index 0000000..557a806
--- /dev/null
@@ -0,0 +1,59 @@
+From 2e2cca4092c507b7df463f9706010f2085c47330 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 16:56:39 +0200
+Subject: net/smc: Do not re-initialize smc hashtables
+
+From: Alexandra Winter <wintera@linux.ibm.com>
+
+[ Upstream commit 9e4389b0038781f19f97895186ed941ff8ac1678 ]
+
+INIT_HLIST_HEAD(&smc_v*_hashinfo.ht) are called after smc_nl_init(),
+proto_register() and sock_register(). This can lead to smc_v*_hashinfo.ht
+being reset even though hash entries already exist and are being used,
+possibly resulting in a corrupted list.
+
+Remove unnecessary and dangerous re-initialisation of smc_v*_hashinfo.ht in
+smc_init(); it is implicitly initialised to zero anyhow. Add
+HLIST_HEAD_INIT to the definitions for clarity.
+
+Fixes: f16a7dd5cf27 ("smc: netlink interface for SMC sockets")
+Suggested-by: Halil Pasic <pasic@linux.ibm.com>
+Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
+Acked-by: Halil Pasic <pasic@linux.ibm.com>
+Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
+Link: https://patch.msgid.link/20260521145639.10317-1-wintera@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index 5915fcdef743d2..21d0c62bcf4644 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -188,10 +188,12 @@ static bool smc_hs_congested(const struct sock *sk)
+ struct smc_hashinfo smc_v4_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v4_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ struct smc_hashinfo smc_v6_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v6_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ int smc_hash_sk(struct sock *sk)
+@@ -3595,8 +3597,6 @@ static int __init smc_init(void)
+               pr_err("%s: sock_register fails with %d\n", __func__, rc);
+               goto out_proto6;
+       }
+-      INIT_HLIST_HEAD(&smc_v4_hashinfo.ht);
+-      INIT_HLIST_HEAD(&smc_v6_hashinfo.ht);
+       rc = smc_ib_register_client();
+       if (rc) {
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-team-fix-null-pointer-dereference-in-team_xmit-d.patch b/queue-6.18/net-team-fix-null-pointer-dereference-in-team_xmit-d.patch
new file mode 100644 (file)
index 0000000..0ab97f3
--- /dev/null
@@ -0,0 +1,149 @@
+From 1e841a0236db85219d7a6178887759ca393288f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 01:12:01 -0700
+Subject: net: team: fix NULL pointer dereference in team_xmit during mode
+ change
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 25fe708bbc59289d3d1ea4b126fbc1b460a072a5 ]
+
+__team_change_mode() clears team->ops with memset() before restoring
+safe dummy handlers via team_adjust_ops(). A concurrent team_xmit()
+running under RCU on another CPU can read team->ops.transmit during
+this window and call a NULL function pointer, crashing the kernel.
+
+The race requires a mode change (CAP_NET_ADMIN) concurrent with
+transmit on the team device.
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000000
+ Oops: 0010 [#1] SMP KASAN NOPTI
+ RIP: 0010:0x0
+ Call Trace:
+  team_xmit (drivers/net/team/team_core.c:1853)
+  dev_hard_start_xmit (net/core/dev.c:3904)
+  __dev_queue_xmit (net/core/dev.c:4871)
+  packet_sendmsg (net/packet/af_packet.c:3109)
+  __sys_sendto (net/socket.c:2265)
+
+The original code assumed that no ports means no traffic, so mode
+changes could freely memset()/memcpy() the ops.  AF_PACKET with
+forced carrier breaks that assumption.
+
+Prevent the race instead of making it safe: replace memset()/memcpy()
+with per-field updates that never touch transmit or receive.  Those
+two handlers are managed solely by team_adjust_ops(), which already
+installs dummies when tx_en_port_count == 0 (always true during mode
+change since no ports are present).  WRITE_ONCE/READ_ONCE prevent
+store/load tearing on the handler pointers.
+
+synchronize_net() before exit_op() drains in-flight readers that may
+still reference old mode state from before port removal switched the
+handlers to dummies.
+
+Fixes: 3d249d4ca7d0 ("net: introduce ethernet teaming device")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Link: https://patch.msgid.link/20260521081159.1491563-3-bestswngs@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/team/team_core.c | 45 +++++++++++++++++++++++++-----------
+ 1 file changed, 32 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/team/team_core.c b/drivers/net/team/team_core.c
+index 11c8e6551dd357..ff4dcd6035cd10 100644
+--- a/drivers/net/team/team_core.c
++++ b/drivers/net/team/team_core.c
+@@ -535,21 +535,23 @@ static void team_adjust_ops(struct team *team)
+       if (!team->en_port_count || !team_is_mode_set(team) ||
+           !team->mode->ops->transmit)
+-              team->ops.transmit = team_dummy_transmit;
++              WRITE_ONCE(team->ops.transmit, team_dummy_transmit);
+       else
+-              team->ops.transmit = team->mode->ops->transmit;
++              WRITE_ONCE(team->ops.transmit, team->mode->ops->transmit);
+       if (!team->en_port_count || !team_is_mode_set(team) ||
+           !team->mode->ops->receive)
+-              team->ops.receive = team_dummy_receive;
++              WRITE_ONCE(team->ops.receive, team_dummy_receive);
+       else
+-              team->ops.receive = team->mode->ops->receive;
++              WRITE_ONCE(team->ops.receive, team->mode->ops->receive);
+ }
+ /*
+- * We can benefit from the fact that it's ensured no port is present
+- * at the time of mode change. Therefore no packets are in fly so there's no
+- * need to set mode operations in any special way.
++ * team_change_mode() ensures no ports are present during mode change,
++ * but lockless readers can still reach team_xmit().  Avoid touching
++ * transmit/receive -- they are already set to dummies by
++ * team_adjust_ops() since no ports are enabled.  synchronize_net()
++ * drains in-flight readers before destroying old mode state.
+  */
+ static int __team_change_mode(struct team *team,
+                             const struct team_mode *new_mode)
+@@ -558,9 +560,21 @@ static int __team_change_mode(struct team *team,
+       if (team_is_mode_set(team)) {
+               void (*exit_op)(struct team *team) = team->ops.exit;
+-              /* Clear ops area so no callback is called any longer */
+-              memset(&team->ops, 0, sizeof(struct team_mode_ops));
+-              team_adjust_ops(team);
++              /* Clear cold-path ops used only under RTNL.  transmit and
++               * receive are already dummies (no ports) so leave them
++               * alone -- overwriting them is the source of the race.
++               */
++              team->ops.init = NULL;
++              team->ops.exit = NULL;
++              team->ops.port_enter = NULL;
++              team->ops.port_leave = NULL;
++              team->ops.port_change_dev_addr = NULL;
++              team->ops.port_tx_disabled = NULL;
++
++              /* Wait for in-flight readers before tearing down mode
++               * state they may reference.
++               */
++              synchronize_net();
+               if (exit_op)
+                       exit_op(team);
+@@ -583,7 +597,12 @@ static int __team_change_mode(struct team *team,
+       }
+       team->mode = new_mode;
+-      memcpy(&team->ops, new_mode->ops, sizeof(struct team_mode_ops));
++      team->ops.init = new_mode->ops->init;
++      team->ops.exit = new_mode->ops->exit;
++      team->ops.port_enter = new_mode->ops->port_enter;
++      team->ops.port_leave = new_mode->ops->port_leave;
++      team->ops.port_change_dev_addr = new_mode->ops->port_change_dev_addr;
++      team->ops.port_tx_disabled = new_mode->ops->port_tx_disabled;
+       team_adjust_ops(team);
+       return 0;
+@@ -744,7 +763,7 @@ static rx_handler_result_t team_handle_frame(struct sk_buff **pskb)
+               /* allow exact match delivery for disabled ports */
+               res = RX_HANDLER_EXACT;
+       } else {
+-              res = team->ops.receive(team, port, skb);
++              res = READ_ONCE(team->ops.receive)(team, port, skb);
+       }
+       if (res == RX_HANDLER_ANOTHER) {
+               struct team_pcpu_stats *pcpu_stats;
+@@ -1683,7 +1702,7 @@ static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev)
+       tx_success = team_queue_override_transmit(team, skb);
+       if (!tx_success)
+-              tx_success = team->ops.transmit(team, skb);
++              tx_success = READ_ONCE(team->ops.transmit)(team, skb);
+       if (tx_success) {
+               struct team_pcpu_stats *pcpu_stats;
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-team-remove-unused-team_mode_op-port_enabled.patch b/queue-6.18/net-team-remove-unused-team_mode_op-port_enabled.patch
new file mode 100644 (file)
index 0000000..d75586b
--- /dev/null
@@ -0,0 +1,51 @@
+From 2ed1433987933b7277c9e36cbd38e2150d3ed936 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Apr 2026 02:59:24 +0000
+Subject: net: team: Remove unused team_mode_op, port_enabled
+
+From: Marc Harvey <marcharvey@google.com>
+
+[ Upstream commit 014f249121d73909528df320818fba7693d0ec92 ]
+
+This team_mode_op wasn't used by any of the team modes, so remove it.
+
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: Marc Harvey <marcharvey@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260409-teaming-driver-internal-v7-2-f47e7589685d@google.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 25fe708bbc59 ("net: team: fix NULL pointer dereference in team_xmit during mode change")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/team/team_core.c | 2 --
+ include/linux/if_team.h      | 1 -
+ 2 files changed, 3 deletions(-)
+
+diff --git a/drivers/net/team/team_core.c b/drivers/net/team/team_core.c
+index a98f5e5061544c..712d8043e66e17 100644
+--- a/drivers/net/team/team_core.c
++++ b/drivers/net/team/team_core.c
+@@ -945,8 +945,6 @@ static void team_port_enable(struct team *team,
+                          team_port_index_hash(team, port->index));
+       team_adjust_ops(team);
+       team_queue_override_port_add(team, port);
+-      if (team->ops.port_enabled)
+-              team->ops.port_enabled(team, port);
+       team_notify_peers(team);
+       team_mcast_rejoin(team);
+       team_lower_state_changed(port);
+diff --git a/include/linux/if_team.h b/include/linux/if_team.h
+index ce97d891cf720f..0d550d44a1c230 100644
+--- a/include/linux/if_team.h
++++ b/include/linux/if_team.h
+@@ -121,7 +121,6 @@ struct team_mode_ops {
+       int (*port_enter)(struct team *team, struct team_port *port);
+       void (*port_leave)(struct team *team, struct team_port *port);
+       void (*port_change_dev_addr)(struct team *team, struct team_port *port);
+-      void (*port_enabled)(struct team *team, struct team_port *port);
+       void (*port_disabled)(struct team *team, struct team_port *port);
+ };
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-team-rename-port_disabled-team-mode-op-to-port_t.patch b/queue-6.18/net-team-rename-port_disabled-team-mode-op-to-port_t.patch
new file mode 100644 (file)
index 0000000..2ca9733
--- /dev/null
@@ -0,0 +1,78 @@
+From 203bf220d218b45f7299feb33e96437a90f9e2bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Apr 2026 02:59:25 +0000
+Subject: net: team: Rename port_disabled team mode op to port_tx_disabled
+
+From: Marc Harvey <marcharvey@google.com>
+
+[ Upstream commit cfa477df2cc62ba53cb936669886361152b594a7 ]
+
+This team mode op is only used by the load balance mode, and it only
+uses it in the tx path.
+
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: Marc Harvey <marcharvey@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260409-teaming-driver-internal-v7-3-f47e7589685d@google.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 25fe708bbc59 ("net: team: fix NULL pointer dereference in team_xmit during mode change")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/team/team_core.c             | 4 ++--
+ drivers/net/team/team_mode_loadbalance.c | 4 ++--
+ include/linux/if_team.h                  | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/team/team_core.c b/drivers/net/team/team_core.c
+index 712d8043e66e17..11c8e6551dd357 100644
+--- a/drivers/net/team/team_core.c
++++ b/drivers/net/team/team_core.c
+@@ -969,8 +969,8 @@ static void team_port_disable(struct team *team,
+ {
+       if (!team_port_enabled(port))
+               return;
+-      if (team->ops.port_disabled)
+-              team->ops.port_disabled(team, port);
++      if (team->ops.port_tx_disabled)
++              team->ops.port_tx_disabled(team, port);
+       hlist_del_rcu(&port->hlist);
+       __reconstruct_port_hlist(team, port->index);
+       port->index = -1;
+diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c
+index b14538bde2f824..b27e44a4df5f6e 100644
+--- a/drivers/net/team/team_mode_loadbalance.c
++++ b/drivers/net/team/team_mode_loadbalance.c
+@@ -655,7 +655,7 @@ static void lb_port_leave(struct team *team, struct team_port *port)
+       free_percpu(lb_port_priv->pcpu_stats);
+ }
+-static void lb_port_disabled(struct team *team, struct team_port *port)
++static void lb_port_tx_disabled(struct team *team, struct team_port *port)
+ {
+       lb_tx_hash_to_port_mapping_null_port(team, port);
+ }
+@@ -665,7 +665,7 @@ static const struct team_mode_ops lb_mode_ops = {
+       .exit                   = lb_exit,
+       .port_enter             = lb_port_enter,
+       .port_leave             = lb_port_leave,
+-      .port_disabled          = lb_port_disabled,
++      .port_tx_disabled       = lb_port_tx_disabled,
+       .receive                = lb_receive,
+       .transmit               = lb_transmit,
+ };
+diff --git a/include/linux/if_team.h b/include/linux/if_team.h
+index 0d550d44a1c230..cd5acf40040d2e 100644
+--- a/include/linux/if_team.h
++++ b/include/linux/if_team.h
+@@ -121,7 +121,7 @@ struct team_mode_ops {
+       int (*port_enter)(struct team *team, struct team_port *port);
+       void (*port_leave)(struct team *team, struct team_port *port);
+       void (*port_change_dev_addr)(struct team *team, struct team_port *port);
+-      void (*port_disabled)(struct team *team, struct team_port *port);
++      void (*port_tx_disabled)(struct team *team, struct team_port *port);
+ };
+ extern int team_modeop_port_enter(struct team *team, struct team_port *port);
+-- 
+2.53.0
+
diff --git a/queue-6.18/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch b/queue-6.18/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
new file mode 100644 (file)
index 0000000..6c3ba9c
--- /dev/null
@@ -0,0 +1,107 @@
+From 643e783857c1c0b549731ca97802ad7f8d16d798 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 22:52:07 +0200
+Subject: netfilter: ebtables: fix OOB read in compat_mtw_from_user
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit f438d1786d657d57790c5d138d6db3fc9fdac392 ]
+
+Luxiao Xu says:
+
+ The function compat_mtw_from_user() converts ebtables extensions from
+ 32-bit user structures to kernel native structures. However, it lacks
+ proper validation of the user-supplied match_size/target_size.
+
+ When certain extensions are processed, the kernel-side translation
+ logic may perform memory accesses based on the extension's expected
+ size. If the user provides a size smaller than what the extension
+ requires, it results in an out-of-bounds read as reported by KASAN.
+
+ This fix introduces a check to ensure match_size is at least as large
+ as the extension's required compatsize. This covers matches, watchers,
+ and targets, while maintaining compatibility with standard targets.
+
+AFAIU this is relevant for matches that need to go though
+match->compat_from_user() call.  Those that use plain memcpy with the
+user-provided size are ok because the caller checks that size vs the
+start of the next rule entry offset (which itself is checked vs. total
+size copied from userspace).
+
+The ->compat_from_user() callbacks assume they can read compatsize bytes,
+so they need this extra check.
+
+Based on an earlier patch from Luxiao Xu.
+
+Fixes: 81e675c227ec ("netfilter: ebtables: add CONFIG_COMPAT support")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/netfilter/ebtables.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
+index 77df9e856c2e73..ecd7baa25d7268 100644
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1956,6 +1956,25 @@ enum compat_mwt {
+       EBT_COMPAT_TARGET,
+ };
++static bool match_size_ok(const struct xt_match *match, unsigned int match_size)
++{
++      u16 csize;
++
++      if (match->matchsize == -1) /* cannot validate ebt_among */
++              return true;
++
++      csize = match->compatsize ? : match->matchsize;
++
++      return match_size >= csize;
++}
++
++static bool tgt_size_ok(const struct xt_target *tgt, unsigned int tgt_size)
++{
++      u16 csize = tgt->compatsize ? : tgt->targetsize;
++
++      return tgt_size >= csize;
++}
++
+ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                               enum compat_mwt compat_mwt,
+                               struct ebt_entries_buf_state *state,
+@@ -1981,6 +2000,11 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+               if (IS_ERR(match))
+                       return PTR_ERR(match);
++              if (!match_size_ok(match, match_size)) {
++                      module_put(match->me);
++                      return -EINVAL;
++              }
++
+               off = ebt_compat_match_offset(match, match_size);
+               if (dst) {
+                       if (match->compat_from_user)
+@@ -2000,6 +2024,12 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                                           mwt->u.revision);
+               if (IS_ERR(wt))
+                       return PTR_ERR(wt);
++
++              if (!tgt_size_ok(wt, match_size)) {
++                      module_put(wt->me);
++                      return -EINVAL;
++              }
++
+               off = xt_compat_target_offset(wt);
+               if (dst) {
+-- 
+2.53.0
+
diff --git a/queue-6.18/netfilter-nf_tables-fix-dst-corruption-in-same-regis.patch b/queue-6.18/netfilter-nf_tables-fix-dst-corruption-in-same-regis.patch
new file mode 100644 (file)
index 0000000..f80b54e
--- /dev/null
@@ -0,0 +1,141 @@
+From bfee6a1b3dab7f70873eed83daae7b12a05dc5f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 May 2026 16:37:56 +0200
+Subject: netfilter: nf_tables: fix dst corruption in same register operation
+
+From: Fernando Fernandez Mancera <fmancera@suse.de>
+
+[ Upstream commit 18014147d3ee7831dce53fe65d7fc8d428b02552 ]
+
+For lshift and rshift, the shift operations are performed in a loop over
+32-bit words. The loop calculates the shifted value and write it to dst,
+and then immediately reads from src to calculate the carry for the next
+iteration. Because src and dst could point to the same memory location,
+the carry is incorrectly calculated using the newly modified dst value
+instead of the original src value.
+
+Adding a temporary local variable to cache the original value before
+writing to dst and using it for the carry calculation solves the
+problem. In addition, partial overlap is rejected from control plane for
+all kind of operations including byteorder. This was tested with the
+following bytecode:
+
+table test_table ip flags 0 use 1 handle 1
+ip test_table test_chain use 3 type filter hook input prio 0 policy accept packets 0 bytes 0 flags 1
+ip test_table test_chain 2
+  [ immediate reg 1 0x44332211 0x88776655 ]
+  [ bitwise reg 1 = ( reg 1 << 0x08000000 ) ]
+  [ cmp eq reg 1 0x66443322 0x00887766 ]
+  [ counter pkts 0 bytes 0 ]
+ip test_table test_chain 4 3
+  [ immediate reg 1 0x44332211 0x88776655 ]
+  [ bitwise reg 1 = ( reg 1 << 0x08000000 ) ]
+  [ cmp eq reg 1 0x55443322 0x00887766 ]
+  [ counter pkts 21794 bytes 1917798 ]
+
+Fixes: 567d746b55bc ("netfilter: bitwise: add support for shifts.")
+Acked-by: Jeremy Sowden <jeremy@azazel.net>
+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>
+---
+ include/net/netfilter/nf_tables.h |  7 +++++++
+ net/netfilter/nft_bitwise.c       | 18 ++++++++++++++----
+ net/netfilter/nft_byteorder.c     | 13 ++++++++++---
+ 3 files changed, 31 insertions(+), 7 deletions(-)
+
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index 4dc080f7f27c65..b35e8c02fadcd5 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -188,6 +188,13 @@ static inline u64 nft_reg_load64(const u32 *sreg)
+       return get_unaligned((u64 *)sreg);
+ }
++static inline bool nft_reg_overlap(u8 src, u8 dst, u32 len)
++{
++      unsigned int n = DIV_ROUND_UP(len, sizeof(u32));
++
++      return src != dst && src < dst + n && dst < src + n;
++}
++
+ static inline void nft_data_copy(u32 *dst, const struct nft_data *src,
+                                unsigned int len)
+ {
+diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
+index af990c600745be..1afb36fb5994db 100644
+--- a/net/netfilter/nft_bitwise.c
++++ b/net/netfilter/nft_bitwise.c
+@@ -43,8 +43,10 @@ static void nft_bitwise_eval_lshift(u32 *dst, const u32 *src,
+       u32 carry = 0;
+       for (i = DIV_ROUND_UP(priv->len, sizeof(u32)); i > 0; i--) {
+-              dst[i - 1] = (src[i - 1] << shift) | carry;
+-              carry = src[i - 1] >> (BITS_PER_TYPE(u32) - shift);
++              u32 tmp_src = src[i - 1];
++
++              dst[i - 1] = (tmp_src << shift) | carry;
++              carry = tmp_src >> (BITS_PER_TYPE(u32) - shift);
+       }
+ }
+@@ -56,8 +58,10 @@ static void nft_bitwise_eval_rshift(u32 *dst, const u32 *src,
+       u32 carry = 0;
+       for (i = 0; i < DIV_ROUND_UP(priv->len, sizeof(u32)); i++) {
+-              dst[i] = carry | (src[i] >> shift);
+-              carry = src[i] << (BITS_PER_TYPE(u32) - shift);
++              u32 tmp_src = src[i];
++
++              dst[i] = carry | (tmp_src >> shift);
++              carry = tmp_src << (BITS_PER_TYPE(u32) - shift);
+       }
+ }
+@@ -235,6 +239,9 @@ static int nft_bitwise_init_bool(const struct nft_ctx *ctx,
+                                             &priv->sreg2, priv->len);
+               if (err < 0)
+                       return err;
++
++              if (nft_reg_overlap(priv->sreg2, priv->dreg, priv->len))
++                      return -EINVAL;
+       }
+       return 0;
+@@ -265,6 +272,9 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
+       if (err < 0)
+               return err;
++      if (nft_reg_overlap(priv->sreg, priv->dreg, priv->len))
++              return -EINVAL;
++
+       if (tb[NFTA_BITWISE_OP]) {
+               priv->op = ntohl(nla_get_be32(tb[NFTA_BITWISE_OP]));
+               switch (priv->op) {
+diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
+index af9206a3afd181..5e7a7841b789b0 100644
+--- a/net/netfilter/nft_byteorder.c
++++ b/net/netfilter/nft_byteorder.c
+@@ -144,9 +144,16 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
+       if (err < 0)
+               return err;
+-      return nft_parse_register_store(ctx, tb[NFTA_BYTEORDER_DREG],
+-                                      &priv->dreg, NULL, NFT_DATA_VALUE,
+-                                      priv->len);
++      err = nft_parse_register_store(ctx, tb[NFTA_BYTEORDER_DREG],
++                                     &priv->dreg, NULL, NFT_DATA_VALUE,
++                                     priv->len);
++      if (err < 0)
++              return err;
++
++      if (nft_reg_overlap(priv->sreg, priv->dreg, priv->len))
++              return -EINVAL;
++
++      return 0;
+ }
+ static int nft_byteorder_dump(struct sk_buff *skb,
+-- 
+2.53.0
+
diff --git a/queue-6.18/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch b/queue-6.18/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
new file mode 100644 (file)
index 0000000..d5eb81a
--- /dev/null
@@ -0,0 +1,68 @@
+From 4830d5363650d65456d43a285b1ca3839f7b7d37 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 12:36:14 -0700
+Subject: netfilter: synproxy: refresh tcphdr after skb_ensure_writable
+
+From: Chris Mason <clm@meta.com>
+
+[ Upstream commit 92170e6afe927ab2792a3f71902845789c8e31b1 ]
+
+synproxy_tstamp_adjust() rewrites the TCP timestamp option in place
+and then patches the TCP checksum via inet_proto_csum_replace4() on
+the caller-supplied tcphdr pointer.  Both ipv4_synproxy_hook() and
+ipv6_synproxy_hook() obtain that pointer with skb_header_pointer()
+before calling in, so it may either alias skb->head directly or
+point at the caller's on-stack _tcph buffer.
+
+Between obtaining the pointer and using it, the function calls
+skb_ensure_writable(skb, optend), which on a cloned or non-linear
+skb invokes pskb_expand_head() and frees the old skb->head.  After
+that point the cached th is stale:
+
+    caller (ipv[46]_synproxy_hook)
+      th = skb_header_pointer(skb, ..., &_tcph)
+      synproxy_tstamp_adjust(skb, protoff, th, ...)
+        skb_ensure_writable(skb, optend)
+          pskb_expand_head()        /* kfree(old skb->head) */
+        ...
+        inet_proto_csum_replace4(&th->check, ...)
+                                    /* writes into freed head, or
+                                       into the caller's stack copy
+                                       leaving the on-wire checksum
+                                       stale */
+
+The option bytes are written through skb->data and are fine; only
+the checksum update goes through th and so lands in the wrong
+place.  The result is either a write into freed slab memory or a
+packet leaving with a checksum that does not match its payload.
+
+Fix by re-deriving th from skb->data + protoff immediately after
+skb_ensure_writable() succeeds, so the subsequent checksum update
+targets the linear, writable header.
+
+Fixes: 48b1de4c110a ("netfilter: add SYNPROXY core/target")
+Assisted-by: kres (claude-opus-4-7)
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-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_synproxy_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c
+index 3fa3f5dfb26444..6a851ac4dd048f 100644
+--- a/net/netfilter/nf_synproxy_core.c
++++ b/net/netfilter/nf_synproxy_core.c
+@@ -199,6 +199,8 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff,
+       if (skb_ensure_writable(skb, optend))
+               return 0;
++      th = (struct tcphdr *)(skb->data + protoff);
++
+       while (optoff < optend) {
+               unsigned char *op = skb->data + optoff;
+-- 
+2.53.0
+
diff --git a/queue-6.18/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch b/queue-6.18/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
new file mode 100644 (file)
index 0000000..98b94c7
--- /dev/null
@@ -0,0 +1,48 @@
+From 38bc8a6c115dc3c07a8ff919578ae71a87058d94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 20:10:08 +0200
+Subject: netfilter: xt_cpu: prefer raw_smp_processor_id
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit c376f07e16c02239ed44cabb97145d03f65b4d15 ]
+
+With PREEMPT_RCU we get splat:
+
+BUG: using smp_processor_id() in preemptible [..]
+caller is cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+CPU: 1 .. Comm: syz.3.1377 #0 PREEMPT(full)
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
+ check_preemption_disabled+0xd3/0xe0 lib/smp_processor_id.c:47
+ cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+ [..]
+
+Just use raw version instead.
+This is similar to 14d14a5d2957 ("netfilter: nft_meta: use raw_smp_processor_id()").
+
+Fixes: 0ca743a55991 ("netfilter: nf_tables: add compatibility layer for x_tables")
+Reported-by: syzbot+690d3e3ffa7335ac10eb@syzkaller.appspotmail.com
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_cpu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/xt_cpu.c b/net/netfilter/xt_cpu.c
+index 3bdc302a0f9137..9cb259902a586b 100644
+--- a/net/netfilter/xt_cpu.c
++++ b/net/netfilter/xt_cpu.c
+@@ -34,7 +34,7 @@ static bool cpu_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       const struct xt_cpu_info *info = par->matchinfo;
+-      return (info->cpu == smp_processor_id()) ^ info->invert;
++      return (info->cpu == raw_smp_processor_id()) ^ info->invert;
+ }
+ static struct xt_match cpu_mt_reg __read_mostly = {
+-- 
+2.53.0
+
diff --git a/queue-6.18/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch b/queue-6.18/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
new file mode 100644 (file)
index 0000000..f3a6cc4
--- /dev/null
@@ -0,0 +1,40 @@
+From a94f21950d9c2cbad3089b32f60249705a61f773 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:41 +0000
+Subject: nfc: llcp: Fix use-after-free in llcp_sock_release()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit f4268b466190dae95a7585f69b4f1f8ad097632c ]
+
+llcp_sock_release() unconditionally unlinks the socket from the local
+sockets list.  However, if the socket is still in connecting state, it
+is on the connecting list.
+
+Fix this by checking the socket state and unlinking from the correct list.
+
+Fixes: b4011239a08e ("NFC: llcp: Fix non blocking sockets connections")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-1-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_sock.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index 57a2f97004e172..915929cd724f90 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -633,6 +633,8 @@ static int llcp_sock_release(struct socket *sock)
+       if (sock->type == SOCK_RAW)
+               nfc_llcp_sock_unlink(&local->raw_sockets, sk);
++      else if (sk->sk_state == LLCP_CONNECTING)
++              nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       else
+               nfc_llcp_sock_unlink(&local->sockets, sk);
+-- 
+2.53.0
+
diff --git a/queue-6.18/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch b/queue-6.18/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
new file mode 100644 (file)
index 0000000..01a2be8
--- /dev/null
@@ -0,0 +1,67 @@
+From 6cb2942eb336a91362789fc998f38c57e7ed7f58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:42 +0000
+Subject: nfc: llcp: Fix use-after-free race in nfc_llcp_recv_cc()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit b493ea2765cc17cb8aa7e7544a4b6dcb05b6ed77 ]
+
+A race condition exists in the NFC LLCP connection state machine where
+the connection acceptance packet (CC) can be processed concurrently with
+socket release.  This can lead to a use-after-free of the socket object.
+
+When nfc_llcp_recv_cc() moves the socket from the connecting_sockets
+list to the sockets list, it does so without holding the socket lock.
+If llcp_sock_release() is executing concurrently, it might have already
+unlinked the socket and dropped its references, which can result in
+nfc_llcp_recv_cc() linking a freed socket into the live list.
+
+Fix this by holding lock_sock() during the state transition and list
+movement in nfc_llcp_recv_cc().  After acquiring the lock, check if
+the socket is still hashed to ensure it hasn't already been unlinked
+and marked for destruction by the release path.  This aligns the locking
+pattern with recv_hdlc() and recv_disc().
+
+Fixes: a69f32af86e3 ("NFC: Socket linked list")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-2-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_core.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
+index da8d3add0018f3..c83a00e429852c 100644
+--- a/net/nfc/llcp_core.c
++++ b/net/nfc/llcp_core.c
+@@ -1218,6 +1218,15 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk = &llcp_sock->sk;
++      lock_sock(sk);
++
++      /* Check if socket was destroyed whilst waiting for the lock */
++      if (!sk_hashed(sk)) {
++              release_sock(sk);
++              nfc_llcp_sock_put(llcp_sock);
++              return;
++      }
++
+       /* Unlink from connecting and link to the client array */
+       nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       nfc_llcp_sock_link(&local->sockets, sk);
+@@ -1229,6 +1238,8 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk->sk_state = LLCP_CONNECTED;
+       sk->sk_state_change(sk);
++      release_sock(sk);
++
+       nfc_llcp_sock_put(llcp_sock);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.18/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch b/queue-6.18/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
new file mode 100644 (file)
index 0000000..63feabe
--- /dev/null
@@ -0,0 +1,83 @@
+From 26612ad39d67ec0a0ce1de4c003ea619ac4e24ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 May 2026 19:55:18 +0800
+Subject: nfc: nxp-nci: i2c: use rising-edge IRQ on ACPI systems
+
+From: Carl Lee <carl.lee@amd.com>
+
+[ Upstream commit f23bf992d65a42007c517b060ca35cebdea3525a ]
+
+Some ACPI-based platforms report incorrect IRQ trigger types (e.g.
+IRQF_TRIGGER_HIGH), which can lead to interrupt storms.
+
+Use the historically working rising-edge trigger on ACPI systems to
+avoid this regression.
+
+Device Tree-based systems continue to use the firmware-provided
+trigger type.
+
+Fixes: 57be33f85e36 ("nfc: nxp-nci: remove interrupt trigger type")
+Signed-off-by: Carl Lee <carl.lee@amd.com>
+Tested-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Luca Stefani <luca.stefani.ge1@gmail.com>
+Link: https://patch.msgid.link/20260516-nfc-nxp-nci-i2c-restore-irq-trigger-fallback-v3-1-37ba4b6e9086@amd.com
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/nxp-nci/i2c.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c
+index b3d34433bd14a0..a6c08175d9dd93 100644
+--- a/drivers/nfc/nxp-nci/i2c.c
++++ b/drivers/nfc/nxp-nci/i2c.c
+@@ -16,6 +16,7 @@
+ #include <linux/delay.h>
+ #include <linux/i2c.h>
+ #include <linux/interrupt.h>
++#include <linux/irq.h>
+ #include <linux/module.h>
+ #include <linux/nfc.h>
+ #include <linux/gpio/consumer.h>
+@@ -267,6 +268,7 @@ static int nxp_nci_i2c_probe(struct i2c_client *client)
+ {
+       struct device *dev = &client->dev;
+       struct nxp_nci_i2c_phy *phy;
++      unsigned long irqflags;
+       int r;
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+@@ -303,9 +305,26 @@ static int nxp_nci_i2c_probe(struct i2c_client *client)
+       if (r < 0)
+               return r;
++      /*
++       * ACPI platforms may report incorrect IRQ trigger types
++       * (e.g. level-high), which can lead to interrupt storms.
++       *
++       * Use the historically stable rising-edge trigger for ACPI devices.
++       *
++       * On non-ACPI systems (e.g. Device Tree), prefer the firmware-
++       * provided trigger type, falling back to rising-edge if not set.
++       */
++      if (ACPI_COMPANION(dev)) {
++              irqflags = IRQF_TRIGGER_RISING;
++      } else {
++              irqflags = irq_get_trigger_type(client->irq);
++              if (!irqflags)
++                      irqflags = IRQF_TRIGGER_RISING;
++      }
++
+       r = request_threaded_irq(client->irq, NULL,
+                                nxp_nci_i2c_irq_thread_fn,
+-                               IRQF_ONESHOT,
++                               irqflags | IRQF_ONESHOT,
+                                NXP_NCI_I2C_DRIVER_NAME, phy);
+       if (r < 0)
+               nfc_err(&client->dev, "Unable to register IRQ handler\n");
+-- 
+2.53.0
+
diff --git a/queue-6.18/nvme-tcp-store-negative-errno-in-queue-tls_err.patch b/queue-6.18/nvme-tcp-store-negative-errno-in-queue-tls_err.patch
new file mode 100644 (file)
index 0000000..87589be
--- /dev/null
@@ -0,0 +1,52 @@
+From acfb4c09bcdfaa01c1905a2c3d82e0693773f884 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:16 -0400
+Subject: nvme-tcp: store negative errno in queue->tls_err
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 9015985b5eb1a90eb86caf5bce1dfcf1aa38f8ad ]
+
+nvme_tcp_tls_done() assigns queue->tls_err in three branches.  The
+ENOKEY lookup failure and the EOPNOTSUPP initializer both store
+negative errnos.  The third branch, reached when the handshake
+layer reports a non-zero status, stores -status.
+
+The handshake layer delivers status to the consumer callback as a
+negative errno; the other in-tree consumers --
+xs_tls_handshake_done() and the nvmet target callback -- treat
+their status argument that way.  The extra negation in
+nvme_tcp_tls_done() flips the sign, leaving tls_err as a positive
+value (for instance, +EIO), which nvme_tcp_start_tls() then
+returns to its caller.
+
+Drop the extra negation so queue->tls_err uniformly carries a
+negative errno on failure.
+
+Fixes: be8e82caa685 ("nvme-tcp: enable TLS handshake upcall")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-2-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/tcp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
+index 9a96df1a511c02..afdbcff3d4821e 100644
+--- a/drivers/nvme/host/tcp.c
++++ b/drivers/nvme/host/tcp.c
+@@ -1687,7 +1687,7 @@ static void nvme_tcp_tls_done(void *data, int status, key_serial_t pskid)
+               qid, pskid, status);
+       if (status) {
+-              queue->tls_err = -status;
++              queue->tls_err = status;
+               goto out_complete;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.18/scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch b/queue-6.18/scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch
new file mode 100644 (file)
index 0000000..f8ce976
--- /dev/null
@@ -0,0 +1,80 @@
+From 6bbfc57ed729e96a5c3f1cd80d0ef3d706af24cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 14:09:41 -0400
+Subject: scsi: core: Run queues for all non-SDEV_DEL devices from
+ scsi_run_host_queues
+
+From: David Jeffery <djeffery@redhat.com>
+
+[ Upstream commit 7205b58702273baf21d6ba7992e6ba15852325f7 ]
+
+While a SCSI host is in a recovery state, scsi_mq_requeue_cmd() will not
+set the requeue list for a requeued command to be kicked in the future.
+The expectation is a call to scsi_run_host_queues() will kick all SCSI
+devices once the recovery state is cleared.
+
+However, scsi_run_host_queues() uses shost_for_each_device() which uses
+scsi_device_get() and so will ignore devices in a partially removed
+state like SDEV_CANCEL. But these devices may also have requeued
+requests, leaving their requests stuck from not being kicked and causing
+the removal process of the device to hang.
+
+scsi_run_host_queues() needs to run against more devices than the macro
+shost_for_each_device() allows. Instead of using the too limiting
+scsi_device_get() state checks, only ignore devices in SDEV_DEL state or
+when unable to acquire a reference. Attempt to run the queues for all
+other devices when scsi_run_host_queues() is called.
+
+Fixes: 8b566edbdbfb ("scsi: core: Only kick the requeue list if necessary")
+Signed-off-by: David Jeffery <djeffery@redhat.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://patch.msgid.link/20260515180941.9698-1-djeffery@redhat.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_lib.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index 7ddb73cd6d9fe5..3f7ba6d3987f15 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -572,10 +572,33 @@ void scsi_requeue_run_queue(struct work_struct *work)
+ void scsi_run_host_queues(struct Scsi_Host *shost)
+ {
+-      struct scsi_device *sdev;
++      struct scsi_device *sdev, *prev = NULL;
++      unsigned long flags;
+-      shost_for_each_device(sdev, shost)
++      spin_lock_irqsave(shost->host_lock, flags);
++      __shost_for_each_device(sdev, shost) {
++              /*
++               * Only skip devices so deep into removal they will never need
++               * another kick to their queues. Thus scsi_device_get() cannot
++               * be used as it would skip devices in SDEV_CANCEL state which
++               * may need a queue kick.
++               */
++              if (sdev->sdev_state == SDEV_DEL ||
++                  !get_device(&sdev->sdev_gendev))
++                      continue;
++              spin_unlock_irqrestore(shost->host_lock, flags);
++
++              if (prev)
++                      put_device(&prev->sdev_gendev);
+               scsi_run_queue(sdev->request_queue);
++
++              prev = sdev;
++
++              spin_lock_irqsave(shost->host_lock, flags);
++      }
++      spin_unlock_irqrestore(shost->host_lock, flags);
++      if (prev)
++              put_device(&prev->sdev_gendev);
+ }
+ static void scsi_uninit_cmd(struct scsi_cmnd *cmd)
+-- 
+2.53.0
+
diff --git a/queue-6.18/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch b/queue-6.18/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
new file mode 100644 (file)
index 0000000..9e406f5
--- /dev/null
@@ -0,0 +1,50 @@
+From a9d1c5d40a10e64c351c5154bfa58289e228be8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 11:24:11 +0800
+Subject: sctp: fix race between sctp_wait_for_connect and peeloff
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit f14fe6395a8b3d961a61e138ad7b36ba3626dd4e ]
+
+sctp_wait_for_connect() drops and re-acquires the socket lock while
+waiting for the association to reach ESTABLISHED state. During this
+window, another thread can peeloff the association to a new socket via
+getsockopt(SCTP_SOCKOPT_PEELOFF), changing asoc->base.sk. After
+re-acquiring the old socket lock, sctp_wait_for_connect() returns
+success without noticing the migration â€” the caller then accesses
+the association under the wrong lock in sctp_datamsg_from_user().
+
+Add the same sk != asoc->base.sk check that sctp_wait_for_sndbuf()
+already has, returning an error if the association was migrated while
+we slept.
+
+Fixes: 668c9beb9020 ("sctp: implement assign_number for sctp_stream_interleave")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260527032411.60959-1-kipreyyy@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/socket.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 2c5ad53984906c..c763eb3296b3ee 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -9350,6 +9350,8 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p)
+               release_sock(sk);
+               current_timeo = schedule_timeout(current_timeo);
+               lock_sock(sk);
++              if (sk != asoc->base.sk)
++                      goto do_error;
+               *timeo_p = current_timeo;
+       }
+-- 
+2.53.0
+
index 003f0fd2a1d30aaa18ee8ac65095f37c4cc231d9..982c70b6f892f92af811b0274d70e147e00eb91e 100644 (file)
@@ -3,3 +3,93 @@ net-mctp-ensure-our-nlmsg-responses-are-initialised.patch
 xfrm-move-policy_bydst-rcu-sync-from-per-netns-.exit.patch
 net-sched-sch_sfb-replace-direct-dequeue-call-with-p.patch
 bcache-fix-uninitialized-closure-object.patch
+nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
+nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
+xfrm-check-for-underflow-in-xfrm_state_mtu.patch
+nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
+tools-bootconfig-fix-buf-leaks-in-apply_xbc.patch
+hid-remove-duplicate-hid_warn_ratelimited-definition.patch
+kunit-fix-use-after-free-in-debugfs-when-using-kunit.patch
+accel-rocket-fix-uaf-via-dangling-gem-handle-in-crea.patch
+kernel-fork-validate-exit_signal-in-kernel_clone.patch
+netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
+netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
+netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
+netfilter-nf_tables-fix-dst-corruption-in-same-regis.patch
+tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
+tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch
+vsock-keep-poll-shutdown-state-consistent.patch
+net-netlink-fix-sending-unassigned-nsid-after-assign.patch
+net-netlink-don-t-set-nsid-on-local-notifications.patch
+net-smc-do-not-re-initialize-smc-hashtables.patch
+net-iucv-fix-locking-in-.getsockopt.patch
+scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch
+ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
+alsa-pcm-oss-fix-setup-list-uaf-on-proc-write-error.patch
+asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
+net-mlx5-hws-reject-unsupported-remove-header-action.patch
+net-hsr-fix-potential-oob-access-in-supervision-fram.patch
+gpio-mxc-fix-irq_high-handling.patch
+net-team-remove-unused-team_mode_op-port_enabled.patch
+net-team-rename-port_disabled-team-mode-op-to-port_t.patch
+net-team-fix-null-pointer-dereference-in-team_xmit-d.patch
+net-avoid-checksumming-unreadable-skb-tail-on-trim.patch
+ethtool-rss-avoid-modifying-the-rss-context-response.patch
+ethtool-rss-add-missing-errno-on-rss-context-delete.patch
+ethtool-rss-fix-falsely-ignoring-indir-table-updates.patch
+ethtool-rss-fix-indir_table-and-hkey-leak-on-get_rxf.patch
+ethtool-rss-fix-hkey-leak-when-indir_size-is-0.patch
+ethtool-rss-avoid-device-context-leak-on-reply-build.patch
+ethtool-module-call-ethnl_ops_complete-on-module-fla.patch
+ethtool-module-avoid-leaking-a-netdev-ref-on-module-.patch
+ethtool-module-avoid-racy-updates-to-dev-ethtool-bit.patch
+ethtool-module-check-fw_flash_in_progress-under-rtnl.patch
+ethtool-module-fix-cleanup-if-socket-used-for-flashi.patch
+ethtool-cmis-require-exact-cdb-reply-length.patch
+ethtool-cmis-fix-u16-to-u8-truncation-of-msleep_pre_.patch
+ethtool-cmis-validate-start_cmd_payload_size-from-mo.patch
+ethtool-cmis-validate-fw-size-against-start_cmd_payl.patch
+cxl-test-update-mock-dev-array-before-calling-platfo.patch
+tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
+vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
+tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
+ksmbd-fix-fsctl-permission-bypass-by-adding-a-permis.patch
+asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
+drm-xe-restore-idledly-regiter-on-engine-reset.patch
+bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
+bonding-refuse-to-enslave-can-devices.patch
+bridge-fix-sleep-in-atomic-context-in-netlink-path.patch
+bridge-fix-sleep-in-atomic-context-in-sysfs-path.patch
+ethtool-coalesce-cap-profile-updates-at-net_dim_para.patch
+ethtool-tsconfig-fix-reply-error-handling.patch
+ethtool-linkstate-fix-unbalanced-ethnl_ops_complete-.patch
+ethtool-pse-pd-fix-missing-ethnl_ops_complete.patch
+ethtool-tsconfig-fix-missing-ethnl_ops_complete.patch
+ethtool-tsinfo-fix-uninitialized-stats-on-the-by-phc.patch
+ethtool-tsinfo-don-t-pass-err_ptr-to-genlmsg_cancel-.patch
+ethtool-strset-fix-header-attribute-index-in-ethnl_r.patch
+ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch
+ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
+ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
+net-sched-revert-net-sched-restrict-conditions-for-a.patch
+net-hibmcge-disable-relaxed-ordering-to-fix-rx-packe.patch
+net-handshake-use-spin_lock_bh-for-hn_lock.patch
+nvme-tcp-store-negative-errno-in-queue-tls_err.patch
+net-handshake-pass-negative-errno-through-handshake_.patch
+bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
+bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
+bluetooth-hci_sync-set-hci_cmd_drain_workqueue-durin.patch
+bluetooth-hci_sync-reset-device-counters-in-hci_dev_.patch
+gpio-adnp-fix-flow-control-regression-caused-by-scop.patch
+gpio-virtuser-fix-uninitialized-data-bug-in-gpio_vir.patch
+gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
+gpio-rockchip-teardown-bugs-and-resource-leaks.patch
+net-mana-add-null-guards-in-teardown-path-to-prevent.patch
+net-mana-skip-redundant-detach-on-already-detached-p.patch
+sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
+vsock-virtio-bind-uarg-before-filling-zerocopy-skb.patch
+ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch
+ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch
+net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch
+media-rc-fix-race-between-unregister-and-urb-irq-cal.patch
+media-rc-ttusbir-fix-inverted-error-logic.patch
diff --git a/queue-6.18/tools-bootconfig-fix-buf-leaks-in-apply_xbc.patch b/queue-6.18/tools-bootconfig-fix-buf-leaks-in-apply_xbc.patch
new file mode 100644 (file)
index 0000000..a3c1bad
--- /dev/null
@@ -0,0 +1,40 @@
+From 695a3801af3a423d02ed4da4025350f397518f68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 11:01:26 +0800
+Subject: tools/bootconfig: Fix buf leaks in apply_xbc
+
+From: Hongtao Lee <lihongtao@kylinos.cn>
+
+[ Upstream commit f42d01aadcedd7bbf4f9a466cabe25c1781dedad ]
+
+If data calloc failed, free the buf before return.
+
+Link: https://lore.kernel.org/all/20260520030126.147782-1-lihongtao@kylinos.cn/
+
+Fixes: 950313ebf79c ("tools: bootconfig: Add bootconfig command")
+Signed-off-by: Hongtao Lee <lihongtao@kylinos.cn>
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bootconfig/main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
+index 643f707b8f1da1..ddabde20585f21 100644
+--- a/tools/bootconfig/main.c
++++ b/tools/bootconfig/main.c
+@@ -390,8 +390,10 @@ static int apply_xbc(const char *path, const char *xbc_path)
+       /* Backup the bootconfig data */
+       data = calloc(size + BOOTCONFIG_ALIGN + BOOTCONFIG_FOOTER_SIZE, 1);
+-      if (!data)
++      if (!data) {
++              free(buf);
+               return -ENOMEM;
++      }
+       memcpy(data, buf, size);
+       /* Check the data format */
+-- 
+2.53.0
+
diff --git a/queue-6.18/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch b/queue-6.18/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch
new file mode 100644 (file)
index 0000000..446e0d9
--- /dev/null
@@ -0,0 +1,47 @@
+From 6c5887a6154b0b34ab68ee1f60d28719d1bc7b75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 09:33:13 -0700
+Subject: tun: free page on build_skb failure in tun_xdp_one()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit aa8963fdce667a42fb7f0bdd2909fadcab02f9a8 ]
+
+When build_skb() fails in tun_xdp_one(), the function sets ret to
+-ENOMEM and jumps to the out label, which returns without freeing the
+page that vhost_net_build_xdp() allocated for the frame. As with the
+short-frame rejection path, tun_sendmsg() discards the per-buffer error
+and still returns total_len, so vhost_tx_batch() takes the success path
+and never frees the page. Each build_skb() failure in a batch leaks one
+page-frag chunk.
+
+Free the page before taking the error path, matching the put_page() the
+other error exits of tun_xdp_one() already perform.
+
+Fixes: 043d222f93ab ("tuntap: accept an array of XDP buffs through sendmsg()")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260521163312.1479805-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index afba37965ce3b7..9a767da38c71e7 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2437,6 +2437,7 @@ static int tun_xdp_one(struct tun_struct *tun,
+ build:
+       skb = build_skb(xdp->data_hard_start, buflen);
+       if (!skb) {
++              put_page(virt_to_head_page(xdp->data));
+               ret = -ENOMEM;
+               goto out;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.18/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch b/queue-6.18/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
new file mode 100644 (file)
index 0000000..24b2865
--- /dev/null
@@ -0,0 +1,54 @@
+From 767160ea23e9313076ed069880cfe3c8f799343a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 09:00:21 -0700
+Subject: tun: free page on short-frame rejection in tun_xdp_one()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f4feb1e20058e407cb00f45aff47f5b7e19a6bbf ]
+
+tun_xdp_one() returns -EINVAL on a frame shorter than ETH_HLEN without
+freeing the page that vhost_net_build_xdp() allocated for it.
+tun_sendmsg() discards that -EINVAL and still returns total_len, so
+vhost_tx_batch() takes the success path and never frees the page; each
+short frame in a batch leaks one page-frag chunk.
+
+A local process that can open /dev/net/tun and /dev/vhost-net can hit
+this path: it attaches a tun/tap device as the vhost-net backend and
+feeds TX descriptors whose length minus the virtio-net header is below
+ETH_HLEN. Each kick leaks the page-frag chunks for that batch, and a
+tight submission loop exhausts host memory and triggers an OOM panic.
+Free the page before returning -EINVAL, matching the XDP-program error
+path in the same function.
+
+Fixes: 049584807f1d ("tun: add missing verification for short frame")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260520160020.375349-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 8192740357a09c..afba37965ce3b7 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2392,8 +2392,10 @@ static int tun_xdp_one(struct tun_struct *tun,
+       bool skb_xdp = false;
+       struct page *page;
+-      if (unlikely(datasize < ETH_HLEN))
++      if (unlikely(datasize < ETH_HLEN)) {
++              put_page(virt_to_head_page(xdp->data));
+               return -EINVAL;
++      }
+       xdp_prog = rcu_dereference(tun->xdp_prog);
+       if (xdp_prog) {
+-- 
+2.53.0
+
diff --git a/queue-6.18/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch b/queue-6.18/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
new file mode 100644 (file)
index 0000000..1002be2
--- /dev/null
@@ -0,0 +1,67 @@
+From 56f526ea159163503dce217ec7513fe2eb476aea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 11:55:12 +0000
+Subject: tunnels: do not assume transport header in
+ iptunnel_pmtud_check_icmp()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 509323077ef79a26ba0c60bb556e45c12c398b2d ]
+
+In some cases, iptunnel_pmtud_check_icmp() can be called while
+skb transport header is not set.
+
+This triggers an out-of-bound access, because
+(typeof(skb->transport_header))~0U is 65535.
+
+Access the icmp header based on IPv4 network header,
+after making sure icmp->type is present in skb linear part.
+
+Note that iptunnel_pmtud_check_icmpv6()) is fine.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Reported-by: Damiano Melotti <melotti@google.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260522115512.1519110-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index d5a63155a05597..4b5fd4b13722ca 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -280,7 +280,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct icmphdr *icmph = icmp_hdr(skb);
+       const struct iphdr *iph = ip_hdr(skb);
+       if (mtu < 576 || iph->frag_off != htons(IP_DF))
+@@ -291,9 +290,17 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+           ipv4_is_lbcast(iph->saddr)  || ipv4_is_multicast(iph->saddr))
+               return 0;
+-      if (iph->protocol == IPPROTO_ICMP && icmp_is_err(icmph->type))
+-              return 0;
++      if (iph->protocol == IPPROTO_ICMP) {
++              const struct icmphdr *icmph;
++              if (!pskb_network_may_pull(skb, iph->ihl * 4 +
++                                              offsetofend(struct icmphdr, type)))
++                      return 0;
++              iph = ip_hdr(skb);
++              icmph = (void *)iph + iph->ihl * 4;
++              if (icmp_is_err(icmph->type))
++                      return 0;
++      }
+       return iptunnel_pmtud_build_icmp(skb, mtu);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.18/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch b/queue-6.18/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
new file mode 100644 (file)
index 0000000..3c3f782
--- /dev/null
@@ -0,0 +1,87 @@
+From b4c2edc7be9365366aba5f0547ab1d733f9f3d71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:13:35 +0000
+Subject: tunnels: load network headers after skb_cow() in
+ iptunnel_pmtud_build_icmp[v6]()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b4bc94353050b1fa7b702bd4c6600710dd926cff ]
+
+Sashiko found that iptunnel_pmtud_build_icmp() and
+iptunnel_pmtud_build_icmpv6() were caching ip_hdr() and ipv6_hdr()
+before an skb_cow() call which can reallocate skb->head.
+
+Fix this possible UAF by initializing the local variables
+after the skb_cow() call.
+
+Remove skb_reset_network_header() calls which were not needed.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525201335.2361845-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index 5683c328990f49..d5a63155a05597 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -212,7 +212,7 @@ EXPORT_SYMBOL_GPL(iptunnel_handle_offloads);
+  */
+ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct iphdr *iph = ip_hdr(skb);
++      const struct iphdr *iph;
+       struct icmphdr *icmph;
+       struct iphdr *niph;
+       struct ethhdr eh;
+@@ -226,7 +226,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, 576 - sizeof(*niph) - sizeof(*icmph));
+       if (err)
+@@ -236,7 +235,7 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       err = skb_cow(skb, sizeof(*niph) + sizeof(*icmph) + ETH_HLEN);
+       if (err)
+               return err;
+-
++      iph = ip_hdr(skb);
+       icmph = skb_push(skb, sizeof(*icmph));
+       *icmph = (struct icmphdr) {
+               .type                   = ICMP_DEST_UNREACH,
+@@ -308,7 +307,7 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+ {
+-      const struct ipv6hdr *ip6h = ipv6_hdr(skb);
++      const struct ipv6hdr *ip6h;
+       struct icmp6hdr *icmp6h;
+       struct ipv6hdr *nip6h;
+       struct ethhdr eh;
+@@ -323,7 +322,6 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, IPV6_MIN_MTU - sizeof(*nip6h) - sizeof(*icmp6h));
+       if (err)
+@@ -334,6 +332,7 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       if (err)
+               return err;
++      ip6h = ipv6_hdr(skb);
+       icmp6h = skb_push(skb, sizeof(*icmp6h));
+       *icmp6h = (struct icmp6hdr) {
+               .icmp6_type             = ICMPV6_PKT_TOOBIG,
+-- 
+2.53.0
+
diff --git a/queue-6.18/vsock-keep-poll-shutdown-state-consistent.patch b/queue-6.18/vsock-keep-poll-shutdown-state-consistent.patch
new file mode 100644 (file)
index 0000000..8bfeb1d
--- /dev/null
@@ -0,0 +1,247 @@
+From 86b3cb82627f19ebd8b6921b555385e4dc773e38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 00:56:36 +0800
+Subject: vsock: keep poll shutdown state consistent
+
+From: Ziyu Zhang <ziyuzhang201@gmail.com>
+
+[ Upstream commit aae9d8a5528b8ee9ff8dc5d3558b8a9f852a724a ]
+
+vsock_poll() reads vsk->peer_shutdown before taking the socket lock
+to set EPOLLHUP and EPOLLRDHUP, then reads it again after taking
+the lock to report EOF readability. A shutdown packet can update
+peer_shutdown while poll is waiting for the lock, so one poll invocation
+can report EOF readability without the corresponding HUP/RDHUP bits.
+
+For connectible sockets, take one peer_shutdown snapshot after
+lock_sock() and use it for all peer-shutdown-derived poll bits. For
+datagram sockets, which do not take lock_sock() in poll(), take one
+lockless READ_ONCE() snapshot and pair it with WRITE_ONCE() on the
+writer side.
+
+This keeps the peer-shutdown-derived bits internally consistent for each
+poll pass.
+
+Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
+Signed-off-by: Ziyu Zhang <ziyuzhang201@gmail.com>
+Link: https://patch.msgid.link/20260519165636.62542-1-ziyuzhang201@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/vmw_vsock/af_vsock.c                | 49 ++++++++++++++++---------
+ net/vmw_vsock/hyperv_transport.c        |  9 +++--
+ net/vmw_vsock/virtio_transport_common.c | 14 ++++---
+ net/vmw_vsock/vmci_transport.c          |  8 ++--
+ 4 files changed, 52 insertions(+), 28 deletions(-)
+
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index 9d0e1915abbe86..2db48b53e47c77 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -523,7 +523,7 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
+                */
+               sock_reset_flag(sk, SOCK_DONE);
+               sk->sk_state = TCP_CLOSE;
+-              vsk->peer_shutdown = 0;
++              WRITE_ONCE(vsk->peer_shutdown, 0);
+       }
+       if (sk->sk_type == SOCK_SEQPACKET) {
+@@ -814,7 +814,7 @@ static struct sock *__vsock_create(struct net *net,
+       vsk->rejected = false;
+       vsk->sent_request = false;
+       vsk->ignore_connecting_rst = false;
+-      vsk->peer_shutdown = 0;
++      WRITE_ONCE(vsk->peer_shutdown, 0);
+       INIT_DELAYED_WORK(&vsk->connect_work, vsock_connect_timeout);
+       INIT_DELAYED_WORK(&vsk->pending_work, vsock_pending_work);
+@@ -1122,6 +1122,25 @@ static int vsock_shutdown(struct socket *sock, int mode)
+       return err;
+ }
++static __poll_t vsock_poll_shutdown(struct sock *sk, u32 peer_shutdown)
++{
++      __poll_t mask = 0;
++
++      /* INET sockets treat local write shutdown and peer write shutdown as a
++       * case of EPOLLHUP set.
++       */
++      if (sk->sk_shutdown == SHUTDOWN_MASK ||
++          ((sk->sk_shutdown & SEND_SHUTDOWN) &&
++           (peer_shutdown & SEND_SHUTDOWN)))
++              mask |= EPOLLHUP;
++
++      if (sk->sk_shutdown & RCV_SHUTDOWN ||
++          peer_shutdown & SEND_SHUTDOWN)
++              mask |= EPOLLRDHUP;
++
++      return mask;
++}
++
+ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+                              poll_table *wait)
+ {
+@@ -1139,24 +1158,17 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+               /* Signify that there has been an error on this socket. */
+               mask |= EPOLLERR;
+-      /* INET sockets treat local write shutdown and peer write shutdown as a
+-       * case of EPOLLHUP set.
+-       */
+-      if ((sk->sk_shutdown == SHUTDOWN_MASK) ||
+-          ((sk->sk_shutdown & SEND_SHUTDOWN) &&
+-           (vsk->peer_shutdown & SEND_SHUTDOWN))) {
+-              mask |= EPOLLHUP;
+-      }
+-
+-      if (sk->sk_shutdown & RCV_SHUTDOWN ||
+-          vsk->peer_shutdown & SEND_SHUTDOWN) {
+-              mask |= EPOLLRDHUP;
+-      }
+-
+       if (sk_is_readable(sk))
+               mask |= EPOLLIN | EPOLLRDNORM;
+       if (sock->type == SOCK_DGRAM) {
++              u32 peer_shutdown = READ_ONCE(vsk->peer_shutdown);
++
++              /* DGRAM sockets do not take lock_sock() in poll(), so use one
++               * lockless snapshot for all shutdown-derived mask bits.
++               */
++              mask |= vsock_poll_shutdown(sk, peer_shutdown);
++
+               /* For datagram sockets we can read if there is something in
+                * the queue and write as long as the socket isn't shutdown for
+                * sending.
+@@ -1171,6 +1183,7 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+       } else if (sock_type_connectible(sk->sk_type)) {
+               const struct vsock_transport *transport;
++              u32 peer_shutdown;
+               lock_sock(sk);
+@@ -1203,8 +1216,10 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+                * terminated should also be considered read, and we check the
+                * shutdown flag for that.
+                */
++              peer_shutdown = READ_ONCE(vsk->peer_shutdown);
++              mask |= vsock_poll_shutdown(sk, peer_shutdown);
+               if (sk->sk_shutdown & RCV_SHUTDOWN ||
+-                  vsk->peer_shutdown & SEND_SHUTDOWN) {
++                  peer_shutdown & SEND_SHUTDOWN) {
+                       mask |= EPOLLIN | EPOLLRDNORM;
+               }
+diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
+index f9dc9b4d302383..4da752b47b116f 100644
+--- a/net/vmw_vsock/hyperv_transport.c
++++ b/net/vmw_vsock/hyperv_transport.c
+@@ -264,7 +264,7 @@ static void hvs_do_close_lock_held(struct vsock_sock *vsk,
+       struct sock *sk = sk_vsock(vsk);
+       sock_set_flag(sk, SOCK_DONE);
+-      vsk->peer_shutdown = SHUTDOWN_MASK;
++      WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+       if (vsock_stream_has_data(vsk) <= 0)
+               sk->sk_state = TCP_CLOSING;
+       sk->sk_state_change(sk);
+@@ -593,7 +593,9 @@ static int hvs_update_recv_data(struct hvsock *hvs)
+               return -EIO;
+       if (payload_len == 0)
+-              hvs->vsk->peer_shutdown |= SEND_SHUTDOWN;
++              WRITE_ONCE(hvs->vsk->peer_shutdown,
++                         READ_ONCE(hvs->vsk->peer_shutdown) |
++                         SEND_SHUTDOWN);
+       hvs->recv_data_len = payload_len;
+       hvs->recv_data_off = 0;
+@@ -736,7 +738,8 @@ static s64 hvs_stream_has_data(struct vsock_sock *vsk)
+                       return ret;
+               return hvs->recv_data_len;
+       case 0:
+-              vsk->peer_shutdown |= SEND_SHUTDOWN;
++              WRITE_ONCE(vsk->peer_shutdown,
++                         READ_ONCE(vsk->peer_shutdown) | SEND_SHUTDOWN);
+               ret = 0;
+               break;
+       default: /* -1 */
+diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
+index ed42e08798a967..1e07d3b1a0e800 100644
+--- a/net/vmw_vsock/virtio_transport_common.c
++++ b/net/vmw_vsock/virtio_transport_common.c
+@@ -1206,7 +1206,7 @@ static void virtio_transport_do_close(struct vsock_sock *vsk,
+       struct sock *sk = sk_vsock(vsk);
+       sock_set_flag(sk, SOCK_DONE);
+-      vsk->peer_shutdown = SHUTDOWN_MASK;
++      WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+       if (vsock_stream_has_data(vsk) <= 0)
+               sk->sk_state = TCP_CLOSING;
+       sk->sk_state_change(sk);
+@@ -1409,12 +1409,15 @@ virtio_transport_recv_connected(struct sock *sk,
+       case VIRTIO_VSOCK_OP_CREDIT_UPDATE:
+               sk->sk_write_space(sk);
+               break;
+-      case VIRTIO_VSOCK_OP_SHUTDOWN:
++      case VIRTIO_VSOCK_OP_SHUTDOWN: {
++              u32 peer_shutdown = READ_ONCE(vsk->peer_shutdown);
++
+               if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SHUTDOWN_RCV)
+-                      vsk->peer_shutdown |= RCV_SHUTDOWN;
++                      peer_shutdown |= RCV_SHUTDOWN;
+               if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SHUTDOWN_SEND)
+-                      vsk->peer_shutdown |= SEND_SHUTDOWN;
+-              if (vsk->peer_shutdown == SHUTDOWN_MASK) {
++                      peer_shutdown |= SEND_SHUTDOWN;
++              WRITE_ONCE(vsk->peer_shutdown, peer_shutdown);
++              if (peer_shutdown == SHUTDOWN_MASK) {
+                       if (vsock_stream_has_data(vsk) <= 0 && !sock_flag(sk, SOCK_DONE)) {
+                               (void)virtio_transport_reset(vsk, NULL);
+                               virtio_transport_do_close(vsk, true);
+@@ -1429,6 +1432,7 @@ virtio_transport_recv_connected(struct sock *sk,
+               if (le32_to_cpu(virtio_vsock_hdr(skb)->flags))
+                       sk->sk_state_change(sk);
+               break;
++      }
+       case VIRTIO_VSOCK_OP_RST:
+               virtio_transport_do_close(vsk, true);
+               break;
+diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
+index 4cd11f355e9d6b..443125e48f2481 100644
+--- a/net/vmw_vsock/vmci_transport.c
++++ b/net/vmw_vsock/vmci_transport.c
+@@ -811,7 +811,7 @@ static void vmci_transport_handle_detach(struct sock *sk)
+               /* On a detach the peer will not be sending or receiving
+                * anymore.
+                */
+-              vsk->peer_shutdown = SHUTDOWN_MASK;
++              WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+               /* We should not be sending anymore since the peer won't be
+                * there to receive, but we can still receive if there is data
+@@ -1534,7 +1534,9 @@ static int vmci_transport_recv_connected(struct sock *sk,
+               if (pkt->u.mode) {
+                       vsk = vsock_sk(sk);
+-                      vsk->peer_shutdown |= pkt->u.mode;
++                      WRITE_ONCE(vsk->peer_shutdown,
++                                 READ_ONCE(vsk->peer_shutdown) |
++                                 pkt->u.mode);
+                       sk->sk_state_change(sk);
+               }
+               break;
+@@ -1551,7 +1553,7 @@ static int vmci_transport_recv_connected(struct sock *sk,
+                * a clean shutdown.
+                */
+               sock_set_flag(sk, SOCK_DONE);
+-              vsk->peer_shutdown = SHUTDOWN_MASK;
++              WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+               if (vsock_stream_has_data(vsk) <= 0)
+                       sk->sk_state = TCP_CLOSING;
+-- 
+2.53.0
+
diff --git a/queue-6.18/vsock-virtio-bind-uarg-before-filling-zerocopy-skb.patch b/queue-6.18/vsock-virtio-bind-uarg-before-filling-zerocopy-skb.patch
new file mode 100644 (file)
index 0000000..ad8a4f9
--- /dev/null
@@ -0,0 +1,89 @@
+From c3c98736e7173eb7601c1bfe46787924caec6364 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 10:33:01 +0800
+Subject: vsock/virtio: bind uarg before filling zerocopy skb
+
+From: Jingguo Tan <tanjingguo@huawei.com>
+
+[ Upstream commit 1e584c304cfb94a759417130b1fc6d30b30c4cce ]
+
+virtio_transport_send_pkt_info() allocates or reuses the zerocopy uarg
+before entering the send loop, but virtio_transport_alloc_skb() still
+fills the skb before it inherits that uarg. When fixed-buffer vectored
+zerocopy hits MAX_SKB_FRAGS, io_sg_from_iter() may partially attach
+managed frags and return -EMSGSIZE. The rollback path call kfree_skb()
+to free an skb that carries SKBFL_MANAGED_FRAG_REFS but no uarg, so
+skb_release_data() falls through to ordinary frag unref.
+
+Pass the uarg into virtio_transport_alloc_skb() and bind it immediately
+before virtio_transport_fill_skb(). This keeps control or no-payload skbs
+untouched while ensuring success and rollback share one lifetime rule.
+
+Fixes: 581512a6dc93 ("vsock/virtio: MSG_ZEROCOPY flag support")
+Signed-off-by: Lin Ma <malin89@huawei.com>
+Signed-off-by: Rongzhen Cui <cuirongzhen@huawei.com>
+Signed-off-by: Jingguo Tan <tanjingguo@huawei.com>
+Acked-by: Arseniy Krasnov <avkrasnov@salutedevices.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
+Link: https://patch.msgid.link/20260527023301.1075581-1-malin89@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/vmw_vsock/virtio_transport_common.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
+index 1e07d3b1a0e800..c925b5c5b35a57 100644
+--- a/net/vmw_vsock/virtio_transport_common.c
++++ b/net/vmw_vsock/virtio_transport_common.c
+@@ -207,6 +207,7 @@ static u16 virtio_transport_get_type(struct sock *sk)
+ static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *info,
+                                                 size_t payload_len,
+                                                 bool zcopy,
++                                                struct ubuf_info *uarg,
+                                                 u32 src_cid,
+                                                 u32 src_port,
+                                                 u32 dst_cid,
+@@ -247,6 +248,12 @@ static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *
+       if (info->msg && payload_len > 0) {
+               int err;
++              /* Bind the zerocopy lifetime before filling frags so error
++               * rollback frees managed fixed-buffer pages through
++               * the uarg-aware path.
++               */
++              skb_zcopy_set(skb, uarg, NULL);
++
+               err = virtio_transport_fill_skb(skb, info, payload_len, zcopy);
+               if (err)
+                       goto out;
+@@ -366,6 +373,7 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
+               skb_len = min(max_skb_len, rest_len);
+               skb = virtio_transport_alloc_skb(info, skb_len, can_zcopy,
++                                               uarg,
+                                                src_cid, src_port,
+                                                dst_cid, dst_port);
+               if (!skb) {
+@@ -373,8 +381,6 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
+                       break;
+               }
+-              skb_zcopy_set(skb, uarg, NULL);
+-
+               virtio_transport_inc_tx_pkt(vvs, skb);
+               ret = t_ops->send_pkt(skb);
+@@ -1161,7 +1167,7 @@ static int virtio_transport_reset_no_sock(const struct virtio_transport *t,
+       if (!t)
+               return -ENOTCONN;
+-      reply = virtio_transport_alloc_skb(&info, 0, false,
++      reply = virtio_transport_alloc_skb(&info, 0, false, NULL,
+                                          le64_to_cpu(hdr->dst_cid),
+                                          le32_to_cpu(hdr->dst_port),
+                                          le64_to_cpu(hdr->src_cid),
+-- 
+2.53.0
+
diff --git a/queue-6.18/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch b/queue-6.18/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
new file mode 100644 (file)
index 0000000..b922546
--- /dev/null
@@ -0,0 +1,54 @@
+From 3897216ca1fc418d3628857218bb08c04317baac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:36:42 +0000
+Subject: vxlan: do not reuse cached ip_hdr() value after
+ skb_tunnel_check_pmtu()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 7d9ef0cb271555d8cf39fefe6c981e1493b25ecf ]
+
+skb_tunnel_check_pmtu() can change skb->head.
+
+Reusing old_iph afer skb_tunnel_check_pmtu() can cause an UAF.
+
+Use instead ip_hdr(skb) as done in drivers/net/bareudp.c
+and drivers/net/geneve.c.
+
+Found by Sashiko.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525203642.2389723-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vxlan/vxlan_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
+index d2d0e0bd43716c..a4ff66e354f532 100644
+--- a/drivers/net/vxlan/vxlan_core.c
++++ b/drivers/net/vxlan/vxlan_core.c
+@@ -2532,7 +2532,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr),
+                                     vni, md, flags, udp_sum);
+@@ -2606,7 +2606,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip6_dst_hoplimit(ndst);
+               skb_scrub_packet(skb, xnet);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
+-- 
+2.53.0
+
diff --git a/queue-6.18/xfrm-check-for-underflow-in-xfrm_state_mtu.patch b/queue-6.18/xfrm-check-for-underflow-in-xfrm_state_mtu.patch
new file mode 100644 (file)
index 0000000..94518e8
--- /dev/null
@@ -0,0 +1,85 @@
+From 806f98afcdf628e7f1744c8b16d910975d22c286 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 10:49:14 -0600
+Subject: xfrm: Check for underflow in xfrm_state_mtu
+
+From: David Ahern <dahern@nvidia.com>
+
+[ Upstream commit 742b04d0550b0ec89dcbc99537ec88653bd1ad90 ]
+
+Leo Lin reported OOB write issue in esp component:
+
+  xfrm_state_mtu() returns u32 but performs its arithmetic in unsigned
+  modulo-2^32 space using an attacker-influenced "header_len + authsize +
+  net_adj" subtracted from a small "mtu" argument. A nobody user can
+  install an IPv4 ESP tunnel SA with a large authentication key
+  (XFRMA_ALG_AUTH_TRUNC, e.g. hmac(sha512), 64-byte key, 64-byte trunc),
+  configure a small interface MTU (68 bytes), and set XFRMA_TFCPAD to a
+  large value. When a single UDP datagram is then sent through the
+  tunnel, xfrm_state_mtu() underflows to a near-2^32 value, and
+  esp_output() consumes it as a signed int via:
+
+        padto      = min(x->tfcpad, xfrm_state_mtu(x, mtu_cached))
+        esp.tfclen = padto - skb->len   (assigned to int)
+
+  esp.tfclen ends up negative (e.g. -207). It is sign-extended to size_t
+  when passed to memset() inside esp_output_fill_trailer(), producing a
+  ~16 EB write of zeroes at skb_tail_pointer(skb). KASAN logs it as
+  "Write of size 18446744073709551537 at addr ffff888...".
+
+Check for underflow and return 1. This causes the sendmsg attempt to
+fail with ENETUNREACH.
+
+Fixes: c5c252389374 ("[XFRM]: Optimize MTU calculation")
+Reported-by: Leo Lin <leo@depthfirst.com>
+Assisted-by: Codex:26.506.31004
+Signed-off-by: David Ahern <dahern@nvidia.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index f6ba58f18ac18e..1b81e92e3eee78 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -3113,10 +3113,14 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+       const struct xfrm_type *type = READ_ONCE(x->type);
+       struct crypto_aead *aead;
+       u32 blksize, net_adj = 0;
++      u32 overhead, payload_mtu;
+       if (x->km.state != XFRM_STATE_VALID ||
+-          !type || type->proto != IPPROTO_ESP)
++          !type || type->proto != IPPROTO_ESP) {
++              if (mtu <= x->props.header_len)
++                      return 1;
+               return mtu - x->props.header_len;
++      }
+       aead = x->data;
+       blksize = ALIGN(crypto_aead_blocksize(aead), 4);
+@@ -3139,8 +3143,17 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+               break;
+       }
+-      return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
+-               net_adj) & ~(blksize - 1)) + net_adj - 2;
++      overhead = x->props.header_len + crypto_aead_authsize(aead) + net_adj;
++      if (mtu <= overhead)
++              return 1;
++
++      payload_mtu = mtu - overhead;
++      payload_mtu &= ~(blksize - 1);
++      if (payload_mtu <= 2)
++              return 1;
++
++      return payload_mtu + net_adj - 2;
++
+ }
+ EXPORT_SYMBOL_GPL(xfrm_state_mtu);
+-- 
+2.53.0
+
diff --git a/queue-6.6/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch b/queue-6.6/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
new file mode 100644 (file)
index 0000000..7edcdd0
--- /dev/null
@@ -0,0 +1,47 @@
+From c7726f90e5dfa49ae7d153dba4eb96edb5518569 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 09:24:00 -0300
+Subject: ASoC: codecs: simple-mux: Fix enum control bounds check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit f63ad68e18d774a5d15cd7e405ead63f6b322679 ]
+
+simple_mux_control_put() rejects values greater than e->items, but
+enum control values are zero based. For the two-entry mux used by this
+driver, valid values are 0 and 1, so value 2 must be rejected as well.
+
+Accepting e->items can store an invalid mux state, pass it to the GPIO
+setter, and pass it on to the DAPM mux update path where it is used as
+an index into the enum text array.
+
+Use the same >= e->items check used by the ASoC enum helpers.
+
+Fixes: 342fbb7578d1 ("ASoC: add simple-mux")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260527-asoc-simple-mux-enum-bounds-v1-1-3f805b9fc671@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/simple-mux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/simple-mux.c b/sound/soc/codecs/simple-mux.c
+index bf67de12d20b7f..02ccaa4c9a0804 100644
+--- a/sound/soc/codecs/simple-mux.c
++++ b/sound/soc/codecs/simple-mux.c
+@@ -40,7 +40,7 @@ static int simple_mux_control_put(struct snd_kcontrol *kcontrol,
+       struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
+       struct simple_mux *priv = snd_soc_component_get_drvdata(c);
+-      if (ucontrol->value.enumerated.item[0] > e->items)
++      if (ucontrol->value.enumerated.item[0] >= e->items)
+               return -EINVAL;
+       if (priv->mux == ucontrol->value.enumerated.item[0])
+-- 
+2.53.0
+
diff --git a/queue-6.6/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch b/queue-6.6/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
new file mode 100644 (file)
index 0000000..c94234f
--- /dev/null
@@ -0,0 +1,112 @@
+From 039fc69523512acd9447a888c2a337e968467e94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 13:51:47 -0300
+Subject: ASoC: Intel: bytcht_es8316: Fix MCLK leak on init errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit afb2a3a9d8369d18122a0d7cd294eba9a98259c6 ]
+
+byt_cht_es8316_init() enables MCLK before configuring the codec sysclk
+and creating the headset jack. If either of those later steps fails, the
+function returns without disabling MCLK, leaving the clock enabled after
+card registration fails.
+
+Track whether this driver enabled MCLK and disable it on the init error
+paths. Add the matching DAI link exit callback so the same clock enable
+is also balanced when ASoC cleans up a successfully initialized link.
+
+Fixes: a03bdaa565cb ("ASoC: Intel: add machine driver for BYT/CHT + ES8316")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260519-asoc-bytcht-es8316-mclk-leak-v1-1-b4a11cdc2afd@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcht_es8316.c | 29 ++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
+index fbd7e1f0783fd9..d334d748f76fb0 100644
+--- a/sound/soc/intel/boards/bytcht_es8316.c
++++ b/sound/soc/intel/boards/bytcht_es8316.c
+@@ -39,6 +39,7 @@ struct byt_cht_es8316_private {
+       struct gpio_desc *speaker_en_gpio;
+       struct device *codec_dev;
+       bool speaker_en;
++      bool mclk_enabled;
+ };
+ enum {
+@@ -169,6 +170,15 @@ static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
+       },
+ };
++static void byt_cht_es8316_disable_mclk(struct byt_cht_es8316_private *priv)
++{
++      if (!priv->mclk_enabled)
++              return;
++
++      clk_disable_unprepare(priv->mclk);
++      priv->mclk_enabled = false;
++}
++
+ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+ {
+       struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component;
+@@ -225,12 +235,14 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+       ret = clk_prepare_enable(priv->mclk);
+       if (ret)
+               dev_err(card->dev, "unable to enable MCLK\n");
++      else
++              priv->mclk_enabled = true;
+       ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(runtime, 0), 0, 19200000,
+                                    SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               dev_err(card->dev, "can't set codec clock %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       ret = snd_soc_card_jack_new_pins(card, "Headset",
+@@ -239,13 +251,25 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+                                        ARRAY_SIZE(byt_cht_es8316_jack_pins));
+       if (ret) {
+               dev_err(card->dev, "jack creation failed %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+       snd_soc_component_set_jack(codec, &priv->jack, NULL);
+       return 0;
++
++err_disable_mclk:
++      byt_cht_es8316_disable_mclk(priv);
++      return ret;
++}
++
++static void byt_cht_es8316_exit(struct snd_soc_pcm_runtime *runtime)
++{
++      struct snd_soc_card *card = runtime->card;
++      struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
++
++      byt_cht_es8316_disable_mclk(priv);
+ }
+ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
+@@ -355,6 +379,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
+               .dpcm_playback = 1,
+               .dpcm_capture = 1,
+               .init = byt_cht_es8316_init,
++              .exit = byt_cht_es8316_exit,
+               SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
+       },
+ };
+-- 
+2.53.0
+
diff --git a/queue-6.6/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch b/queue-6.6/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
new file mode 100644 (file)
index 0000000..0b96487
--- /dev/null
@@ -0,0 +1,40 @@
+From 1030ebb9fe7fdb4d9a59ec56cd58a2ef59f300b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 11:21:39 +0800
+Subject: Bluetooth: 6lowpan: check skb_clone() return value in
+ send_mcast_pkt()
+
+From: Zhao Dongdong <zhaodongdong@kylinos.cn>
+
+[ Upstream commit 3c40d381ce04f9575a5d8b542898183c3b4b38dc ]
+
+The skb_clone() function can return NULL if memory allocation fails.
+send_mcast_pkt() calls skb_clone() without checking the return value, which
+can lead to a NULL pointer dereference in send_pkt() when it dereferences
+skb->data.
+Add a NULL check after skb_clone() and skip the peer if the clone fails.
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Signed-off-by: Zhao Dongdong <zhaodongdong@kylinos.cn>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index e65d4754c94f4c..b3132079573d4d 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -485,6 +485,8 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
+                       int ret;
+                       local_skb = skb_clone(skb, GFP_ATOMIC);
++                      if (!local_skb)
++                              continue;
+                       BT_DBG("xmit %s to %pMR type %u IP %pI6c chan %p",
+                              netdev->name,
+-- 
+2.53.0
+
diff --git a/queue-6.6/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch b/queue-6.6/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
new file mode 100644 (file)
index 0000000..8a51833
--- /dev/null
@@ -0,0 +1,62 @@
+From 70d428f6357dc6f750dd9b44a3925956066ea5a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 18:51:52 +0800
+Subject: Bluetooth: l2cap: clear chan->ident on ECRED reconfiguration success
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit 00e1950716c6ed67d74777b2db286b0fa23b4be9 ]
+
+l2cap_ecred_reconf_rsp() returns early on success without clearing
+chan->ident. Every other L2CAP response handler (l2cap_ecred_conn_rsp,
+l2cap_le_connect_rsp, l2cap_config_rsp) clears chan->ident after a
+successful transaction to prevent the channel from matching subsequent
+responses with the recycled ident value.
+
+A remote attacker that completed a reconfiguration as the peer can
+replay a failure response with the stale ident, causing the kernel to
+match and destroy the already-established channel via
+l2cap_chan_del(chan, ECONNRESET).
+
+Clear chan->ident for all matching channels on success, and harden the
+failure path by using l2cap_chan_hold_unless_zero() consistent with
+other L2CAP handlers (l2cap_le_command_rej, __l2cap_get_chan_by_ident).
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index bbaf0070ca6176..0295a18a1cb3d7 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -5393,14 +5393,20 @@ static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
+       BT_DBG("result 0x%4.4x", result);
+-      if (!result)
++      if (!result) {
++              list_for_each_entry(chan, &conn->chan_l, list) {
++                      if (chan->ident == cmd->ident)
++                              chan->ident = 0;
++              }
+               return 0;
++      }
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
+               if (chan->ident != cmd->ident)
+                       continue;
+-              l2cap_chan_hold(chan);
++              if (!l2cap_chan_hold_unless_zero(chan))
++                      continue;
+               l2cap_chan_lock(chan);
+               l2cap_chan_del(chan, ECONNRESET);
+-- 
+2.53.0
+
diff --git a/queue-6.6/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch b/queue-6.6/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
new file mode 100644 (file)
index 0000000..731b7b5
--- /dev/null
@@ -0,0 +1,82 @@
+From 07b8edce9a6ce1d862196700267295326a8ae5e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 May 2026 12:09:42 -0400
+Subject: Bluetooth: L2CAP: Fix possible crash on l2cap_ecred_conn_rsp
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 41c2713b204e6cb6a94587bc6bf6935107df5479 ]
+
+If dcid is received for an already-assigned destination CID the spec
+requires that both channels to be discarded, but calling l2cap_chan_del
+may invalidate the tmp cursor created by list_for_each_entry_safe and
+in fact it is the wrong procedure as the chan->dcid may be assigned
+previously it really needs to be disconnected.
+
+Calling l2cap_chan_clone directly may still lead to l2cap_chan_del so
+instead schedule l2cap_chan_timeout with delay 0 to close the channel
+asynchronously.
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 27 ++++++++++++++++++++++-----
+ 1 file changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 0295a18a1cb3d7..1f5d5343d380e4 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -5195,6 +5195,7 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+       cmd_len -= sizeof(*rsp);
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
++              struct l2cap_chan *orig;
+               u16 dcid;
+               if (chan->ident != cmd->ident ||
+@@ -5216,8 +5217,10 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+               BT_DBG("dcid[%d] 0x%4.4x", i, dcid);
++              orig = __l2cap_get_chan_by_dcid(conn, dcid);
++
+               /* Check if dcid is already in use */
+-              if (dcid && __l2cap_get_chan_by_dcid(conn, dcid)) {
++              if (dcid && orig) {
+                       /* If a device receives a
+                        * L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an
+                        * already-assigned Destination CID, then both the
+@@ -5226,10 +5229,24 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+                        */
+                       l2cap_chan_del(chan, ECONNREFUSED);
+                       l2cap_chan_unlock(chan);
+-                      chan = __l2cap_get_chan_by_dcid(conn, dcid);
+-                      l2cap_chan_lock(chan);
+-                      l2cap_chan_del(chan, ECONNRESET);
+-                      l2cap_chan_unlock(chan);
++
++                      /* Check that the dcid channel mode is
++                       * L2CAP_MODE_EXT_FLOWCTL since this procedure is only
++                       * valid for that mode and shouldn't disconnect a dcid
++                       * in other modes.
++                       */
++                      if (orig->mode == L2CAP_MODE_EXT_FLOWCTL) {
++                              l2cap_chan_lock(orig);
++                              /* Disconnect the original channel as it may be
++                               * considered connected since dcid has already
++                               * been assigned; don't call l2cap_chan_close
++                               * directly since that could lead to
++                               * l2cap_chan_del and then removing the channel
++                               * from the list while we're iterating over it.
++                               */
++                              __set_chan_timer(orig, 0);
++                              l2cap_chan_unlock(orig);
++                      }
+                       continue;
+               }
+-- 
+2.53.0
+
diff --git a/queue-6.6/bonding-refuse-to-enslave-can-devices.patch b/queue-6.6/bonding-refuse-to-enslave-can-devices.patch
new file mode 100644 (file)
index 0000000..71ba947
--- /dev/null
@@ -0,0 +1,74 @@
+From 3f560f582a0e428c250d53768d4087a68701d8d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 21:33:19 +0200
+Subject: bonding: refuse to enslave CAN devices
+
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+
+[ Upstream commit 8ba68464e4787b6a7ec938826e16124df20fd23d ]
+
+syzbot reported a kernel paging request crash in
+can_rx_unregister() inside net/can/af_can.c. The crash occurs
+because a virtual CAN device (vxcan) is being enslaved to a
+bonding master.
+
+During the enslavement process, the bonding driver mutates
+and modifies the network device states to fit an Ethernet-like
+aggregation model. However, CAN devices operate on a completely
+different Layer 2 architecture, relying on the CAN mid-layer
+private data structure (can_ml_priv) instead of standard
+Ethernet structures. Since bonding does not initialize or
+maintain these CAN structures, subsequent operations on the
+half-enslaved interface (such as closing associated sockets
+via isotp_release) lead to a null-pointer dereference when
+accessing the CAN receiver lists.
+
+Bonding CAN interfaces is architecturally invalid as CAN lacks
+MAC addresses, ARP capabilities, and standard Ethernet
+link-layer mechanisms. While generic loopback devices are
+blocked globally in net/core/dev.c, virtual CAN devices
+bypass this check because they do not carry the IFF_LOOPBACK
+flag, despite acting as local software-loopbacks.
+
+Fix this by explicitly blocking network devices of type
+ARPHRD_CAN from being enslaved at the very beginning of
+bond_enslave(). This prevents illegal state mutations,
+eliminates the resulting KASAN crashes, and avoids potential
+memory leaks from incomplete socket cleanups.
+
+As the CAN support has been added a long time after bonding
+the Fixes-tag points to the introduction of ARPHRD_CAN that
+would have needed a specific handling in bonding_main.c.
+
+Fixes: cd05acfe65ed ("[CAN]: Allocate protocol numbers for PF_CAN")
+Reported-by: syzbot+8ed98cbd0161632bce95@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=8ed98cbd0161632bce95
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Link: https://patch.msgid.link/20260526-bonding-candev-v1-1-ba1df400918a@hartkopp.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 029a7f001dd8a0..7732f7023033ed 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1889,6 +1889,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
+       int link_reporting;
+       int res = 0, i;
++      if (slave_dev->type == ARPHRD_CAN) {
++              BOND_NL_ERR(bond_dev, extack,
++                          "CAN devices cannot be enslaved");
++              return -EPERM;
++      }
++
+       if (slave_dev->flags & IFF_MASTER &&
+           !netif_is_bond_master(slave_dev)) {
+               BOND_NL_ERR(bond_dev, extack,
+-- 
+2.53.0
+
diff --git a/queue-6.6/ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch b/queue-6.6/ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch
new file mode 100644 (file)
index 0000000..3d031f4
--- /dev/null
@@ -0,0 +1,48 @@
+From af8f6a69281db87e06a62d37f331b285c893aaaa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:32 -0700
+Subject: ethtool: eeprom: add missing ethnl_ops_begin() / _complete() during
+ fallback
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 2376586f85f972fefe701f095bb37dcfe7405d21 ]
+
+All ethtool driver op calls should be sandwiched between
+ethnl_ops_begin() / ethnl_ops_complete(). In Netlink eeprom code,
+if the paged access failed we fall back to old API, but we
+first call _complete() and the fallback never does its own
+ethnl_ops_begin(). Move the fallback into the _begin() / _complete()
+section.
+
+Fixes: 96d971e307cc ("ethtool: Add fallback to get_module_eeprom from netlink command")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-10-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/eeprom.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c
+index 6209c3a9c8f723..15546f2a5e4583 100644
+--- a/net/ethtool/eeprom.c
++++ b/net/ethtool/eeprom.c
+@@ -134,12 +134,11 @@ static int eeprom_prepare_data(const struct ethnl_req_info *req_base,
+       return 0;
+ err_ops:
++      if (ret == -EOPNOTSUPP)
++              ret = eeprom_fallback(request, reply);
+       ethnl_ops_complete(dev);
+ err_free:
+       kfree(page_data.data);
+-
+-      if (ret == -EOPNOTSUPP)
+-              return eeprom_fallback(request, reply);
+       return ret;
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.6/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch b/queue-6.6/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
new file mode 100644 (file)
index 0000000..7ecdf45
--- /dev/null
@@ -0,0 +1,62 @@
+From 740b8577bd6cfabd23459eb3304cb6feeebeaaa5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:33 -0700
+Subject: ethtool: eeprom: add more safeties to EEPROM Netlink fallback
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 67cfdd9210b99f260b3e0afeb9525e0acc7be31e ]
+
+The Netlink fallback path for reading module EEPROM
+(fallback_set_params()) validates that offset < eeprom_len,
+but does not check that offset + length stays within eeprom_len.
+The ioctl equivalent (ethtool_get_any_eeprom() in ioctl.c) has
+always enforced both bounds:
+
+  if (eeprom.offset + eeprom.len > total_len)
+      return -EINVAL;
+
+This could lead to surprises in both drivers and device FW.
+Add the missing offset + length validation to fallback_set_params(),
+mirroring the ioctl.
+
+Similarly - ethtool core in general, and ethtool_get_any_eeprom()
+in particular tries to zero-init all buffers passed to the drivers
+to avoid any extra work of zeroing things out. eeprom_fallback()
+uses a plain kmalloc(), change it to zalloc.
+
+Fixes: 96d971e307cc ("ethtool: Add fallback to get_module_eeprom from netlink command")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-11-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/eeprom.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c
+index 15546f2a5e4583..4e864824b64d28 100644
+--- a/net/ethtool/eeprom.c
++++ b/net/ethtool/eeprom.c
+@@ -43,6 +43,9 @@ static int fallback_set_params(struct eeprom_req_info *request,
+       if (offset >= modinfo->eeprom_len)
+               return -EINVAL;
++      if (length > modinfo->eeprom_len - offset)
++              return -EINVAL;
++
+       eeprom->cmd = ETHTOOL_GMODULEEEPROM;
+       eeprom->len = length;
+       eeprom->offset = offset;
+@@ -68,7 +71,7 @@ static int eeprom_fallback(struct eeprom_req_info *request,
+       if (err < 0)
+               return err;
+-      data = kmalloc(eeprom.len, GFP_KERNEL);
++      data = kzalloc(eeprom.len, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+       err = ethtool_get_module_eeprom_call(dev, &eeprom, data);
+-- 
+2.53.0
+
diff --git a/queue-6.6/gpio-mxc-fix-irq_high-handling.patch b/queue-6.6/gpio-mxc-fix-irq_high-handling.patch
new file mode 100644 (file)
index 0000000..41e6328
--- /dev/null
@@ -0,0 +1,38 @@
+From 189e711347181b3d03c83f45eff0894bb817dbd7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:01 +0200
+Subject: gpio: mxc: fix irq_high handling
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit dac917ed5aead741004db8d0d5151dd577802df8 ]
+
+If port->irq_high is -1 (fsl,imx21-gpio compatible) and gpio_idx is >= 16
+enable_irq_wake() is called with -1 which is wrong.
+
+Fixes: 5f6d1998adeb ("gpio: mxc: release the parent IRQ in runtime suspend")
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260526063504.25916-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-mxc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
+index 3cdc2b218a86af..a8ab78ae7fa30c 100644
+--- a/drivers/gpio/gpio-mxc.c
++++ b/drivers/gpio/gpio-mxc.c
+@@ -473,7 +473,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
+                * the handler is needed only once, but doing it for every port
+                * is more robust and easier.
+                */
+-              port->irq_high = -1;
++              port->irq_high = 0;
+               port->mx_irq_handler = mx2_gpio_irq_handler;
+       } else
+               port->mx_irq_handler = mx3_gpio_irq_handler;
+-- 
+2.53.0
+
diff --git a/queue-6.6/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch b/queue-6.6/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
new file mode 100644 (file)
index 0000000..8b9abed
--- /dev/null
@@ -0,0 +1,78 @@
+From aae89ddf77742bfd1e38c2e3735bce14a2545110 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:02:45 +0200
+Subject: gpio: rockchip: convert bank->clk to devm_clk_get_enabled()
+
+From: Marco Scardovi <scardracs@disroot.org>
+
+[ Upstream commit 3e46c18d5d87f063a93ae0fe7662fbf6660459d5 ]
+
+The bank->clk was previously obtained via of_clk_get() and manually
+prepared/enabled. However, it was missing a corresponding clk_put() in
+both the error paths and the remove function, leading to a reference leak.
+
+Convert the allocation to devm_clk_get_enabled(), which also properly
+propagates failures from clk_prepare_enable() that were previously ignored.
+
+The GPIO bank device uses the same OF node as the previous of_clk_get()
+call, so devm_clk_get_enabled(dev, NULL) correctly resolves the same
+clock provider entry.
+
+Fix the reference leak and simplify the code by removing the manual
+clk_disable_unprepare() calls in the probe error paths and in the
+remove function.
+
+Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
+Assisted-by: Antigravity:gemini-3.5-flash
+Signed-off-by: Marco Scardovi <scardracs@disroot.org>
+Link: https://patch.msgid.link/20260526171050.12785-2-scardracs@disroot.org
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-rockchip.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index 752bbc0c3d9db1..ff9a4b8611d7f4 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -647,11 +647,10 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+       if (!bank->irq)
+               return -EINVAL;
+-      bank->clk = of_clk_get(bank->of_node, 0);
++      bank->clk = devm_clk_get_enabled(bank->dev, NULL);
+       if (IS_ERR(bank->clk))
+               return PTR_ERR(bank->clk);
+-      clk_prepare_enable(bank->clk);
+       id = readl(bank->reg_base + gpio_regs_v2.version_id);
+       /* If not gpio v2, that is default to v1. */
+@@ -661,7 +660,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+               bank->db_clk = of_clk_get(bank->of_node, 1);
+               if (IS_ERR(bank->db_clk)) {
+                       dev_err(bank->dev, "cannot find debounce clk\n");
+-                      clk_disable_unprepare(bank->clk);
+                       return -EINVAL;
+               }
+       } else {
+@@ -735,7 +733,6 @@ static int rockchip_gpio_probe(struct platform_device *pdev)
+       ret = rockchip_gpiolib_register(bank);
+       if (ret) {
+-              clk_disable_unprepare(bank->clk);
+               mutex_unlock(&bank->deferred_lock);
+               return ret;
+       }
+@@ -776,7 +773,6 @@ static int rockchip_gpio_remove(struct platform_device *pdev)
+ {
+       struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);
+-      clk_disable_unprepare(bank->clk);
+       gpiochip_remove(&bank->gpio_chip);
+       return 0;
+-- 
+2.53.0
+
diff --git a/queue-6.6/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch b/queue-6.6/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
new file mode 100644 (file)
index 0000000..a4fc69b
--- /dev/null
@@ -0,0 +1,48 @@
+From 886d2b8dfd6a7279a446fc799e44f0dbde61aab3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 12:21:47 +0000
+Subject: ipv4: free net->ipv4.sysctl_local_reserved_ports after
+ unregister_net_sysctl_table()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 87a1e0fe7776da7ab411be332b4be58ac8840d10 ]
+
+ipv4_sysctl_exit_net() is currently freeing net->ipv4.sysctl_local_reserved_ports
+too soon.
+
+Only after unregister_net_sysctl_table() we can be sure no threads can possibly
+use the sysctls, including /proc/sys/net/ipv4/ip_local_reserved_ports.
+
+Fixes: 122ff243f5f1 ("ipv4: make ip_local_reserved_ports per netns")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Link: https://patch.msgid.link/20260521122147.3584624-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/sysctl_net_ipv4.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 96f1b8d39fac11..9c827751dad6a7 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -1560,10 +1560,10 @@ static __net_exit void ipv4_sysctl_exit_net(struct net *net)
+ {
+       struct ctl_table *table;
+-      kfree(net->ipv4.sysctl_local_reserved_ports);
+       table = net->ipv4.ipv4_hdr->ctl_table_arg;
+       unregister_net_sysctl_table(net->ipv4.ipv4_hdr);
+       kfree(table);
++      kfree(net->ipv4.sysctl_local_reserved_ports);
+ }
+ static __net_initdata struct pernet_operations ipv4_sysctl_ops = {
+-- 
+2.53.0
+
diff --git a/queue-6.6/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch b/queue-6.6/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch
new file mode 100644 (file)
index 0000000..2c8cffb
--- /dev/null
@@ -0,0 +1,49 @@
+From 1c232a559021e5a1c16a20cd4ed20ef861acd3c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 13:31:31 +0800
+Subject: ipv6: fix possible infinite loop in fib6_select_path()
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 9c7da87c2dc860bb17ca1ece942495d28b1ce3b9 ]
+
+Found while auditing the same pattern Sashiko reported in
+rt6_fill_node() [1]. Apply the same fix as
+commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").
+
+Writers holding tb6_lock can list_del_rcu(&first->fib6_siblings)
+without waiting for RCU readers; first->fib6_siblings.next then
+still points into the old ring and this softirq-side walker never
+reaches &first->fib6_siblings as its terminator. fib6_purge_rt()
+always WRITE_ONCE()s first->fib6_nsiblings to 0 before
+list_del_rcu(), so an inside-loop check is a reliable detach signal.
+
+[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev
+
+Fixes: d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260527053133.180695-2-jiayuan.chen@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 69659f2a6aea96..6d80e17c04c0d8 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -484,6 +484,9 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
+               const struct fib6_nh *nh = sibling->fib6_nh;
+               int nh_upper_bound;
++              if (!READ_ONCE(first->fib6_nsiblings))
++                      break;
++
+               nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);
+               if (hash > nh_upper_bound)
+                       continue;
+-- 
+2.53.0
+
diff --git a/queue-6.6/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch b/queue-6.6/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch
new file mode 100644 (file)
index 0000000..329c11b
--- /dev/null
@@ -0,0 +1,47 @@
+From 55d1d536cb1a7ca9a1552cd4c9ee3a0d3bcd2dba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 13:31:30 +0800
+Subject: ipv6: fix possible infinite loop in rt6_fill_node()
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 9f72412bcf60144f252b0d6205106abf14344abc ]
+
+Sashiko reported this issue [1]. Apply the same fix as
+commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").
+
+Writers holding tb6_lock can list_del_rcu(&rt->fib6_siblings)
+without waiting for RCU readers; rt->fib6_siblings.next then still
+points into the old ring and this softirq-side walker never reaches
+&rt->fib6_siblings, causing a CPU stall. fib6_del_route() always
+WRITE_ONCE()s rt->fib6_nsiblings to 0 before list_del_rcu(), so an
+inside-loop check is a reliable detach signal.
+
+[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev
+
+Fixes: d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260527053133.180695-1-jiayuan.chen@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index c5b71baf95e7b3..69659f2a6aea96 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -5797,6 +5797,8 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
+                               goto nla_put_failure;
+                       }
++                      if (!READ_ONCE(rt->fib6_nsiblings))
++                              break;
+               }
+               rcu_read_unlock();
+-- 
+2.53.0
+
diff --git a/queue-6.6/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch b/queue-6.6/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
new file mode 100644 (file)
index 0000000..37cc7de
--- /dev/null
@@ -0,0 +1,62 @@
+From 9d6d5a9a8501b4999151b8fb7b4f4089edd4aa5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 21:10:31 +0530
+Subject: ipv6: rpl: fix hdrlen overflow in ipv6_rpl_srh_decompress()
+
+From: Rahul Chandelkar <rc@rexion.ai>
+
+[ Upstream commit 9d5e7a46a9f6d8f503b41bfefef70659845f1679 ]
+
+ipv6_rpl_srh_decompress() computes:
+
+    outhdr->hdrlen = (((n + 1) * sizeof(struct in6_addr)) >> 3);
+
+hdrlen is __u8. For n >= 127 the result exceeds 255 and silently
+truncates. With n=127 (cmpri=15, cmpre=15, pad=0, hdrlen=16):
+
+    (128 * 16) >> 3 = 256, truncated to 0 as __u8
+
+The caller in ipv6_rpl_srh_rcv() then places the compressed header
+at buf + ((ohdr->hdrlen + 1) << 3). With hdrlen=0 this is buf + 8,
+but the decompressed region occupies buf[0..2055] (8-byte header
+plus 128 full addresses). The compressed header overlaps the
+decompressed data, and ipv6_rpl_srh_compress() writes into this
+overlap, corrupting the routing header of the forwarded packet.
+
+The existing guard at exthdrs.c:546 checks (n + 1) > 255, which
+prevents n+1 from overflowing unsigned char (the segments_left
+field), but does not prevent the computed hdrlen from overflowing
+__u8. n=127 passes because 128 <= 255, yet hdrlen=256 does not
+fit.
+
+Tighten the bound to (n + 1) > 127. This caps n at 126, giving
+hdrlen = (127 * 16) >> 3 = 254, which fits in __u8. The compressed
+header then lands at buf + ((254 + 1) << 3) = buf + 2040, exactly
+past the decompressed region (buf[0..2039]). No overlap. 127
+segments is well beyond any realistic RPL deployment.
+
+Fixes: 8610c7c6e3bd ("net: ipv6: add support for rpl sr exthdr")
+Signed-off-by: Rahul Chandelkar <rc@rexion.ai>
+Link: https://patch.msgid.link/20260525154031.2290876-1-rc@rexion.ai
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index 54e71623aac9cc..e1d632c12cc46a 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -546,7 +546,7 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
+        * unsigned char which is segments_left field. Should not be
+        * higher than that.
+        */
+-      if (r || (n + 1) > 255) {
++      if (r || (n + 1) > 127) {
+               kfree_skb(skb);
+               return -1;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.6/kernel-fork-validate-exit_signal-in-kernel_clone.patch b/queue-6.6/kernel-fork-validate-exit_signal-in-kernel_clone.patch
new file mode 100644 (file)
index 0000000..d542ba6
--- /dev/null
@@ -0,0 +1,116 @@
+From 36851a9ce229b214ca137515fd27a44d87e2f55a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Mar 2026 20:49:56 +0530
+Subject: kernel/fork: validate exit_signal in kernel_clone()
+
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+
+[ Upstream commit 09e7827e785729f391c8d46dc71becce70d296ab ]
+
+When a child process exits, it sends exit_signal to its parent via
+do_notify_parent().  The clone() syscall constructs exit_signal as:
+
+(lower_32_bits(clone_flags) & CSIGNAL)
+
+CSIGNAL is 0xff, so values in the range 65-255 are possible.  However,
+valid_signal() only accepts signals up to _NSIG (64 on x86_64).  A
+non-zero non-valid exit_signal acts the same as exit_signal == 0: the
+parent process is not signaled when the child terminates.
+
+The syzkaller reproducer triggers this by calling clone() with flags=0x80,
+resulting in exit_signal = (0x80 & CSIGNAL) = 128, which exceeds _NSIG and
+is not a valid signal.
+
+The v1 of this patch added the check only in the clone() syscall handler,
+which is incomplete.  kernel_clone() has other callers such as
+sys_ia32_clone() which would remain unprotected.  Move the check to
+kernel_clone() to cover all callers.
+
+Since the valid_signal() check is now in kernel_clone() and covers all
+callers including clone3(), the same check in copy_clone_args_from_user()
+becomes redundant and is removed.  The higher 32bits check for clone3() is
+kept as it is clone3() specific.
+
+Note that this is a user-visible change: previously, passing an invalid
+exit_signal to clone() was silently accepted.  The man page for clone()
+does not document any defined behavior for invalid exit_signal values, so
+rejecting them with -EINVAL is the correct behavior.  It is unlikely that
+any sane application relies on passing an invalid exit_signal.
+
+[oleg@redhat.com: the comment above kernel_clone() should be updated]
+  Link: https://lore.kernel.org/abwvgU17W8wuW2-J@redhat.com
+Link: https://lore.kernel.org/20260316151956.563558-1-kartikey406@gmail.com
+Fixes: 3f2c788a1314 ("fork: prevent accidental access to clone3 features")
+Signed-off-by: Deepanshu Kartikey <Kartikey406@gmail.com>
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Reported-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bbe6b99feefc3a0842de
+Tested-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/20260307064202.353405-1-kartikey406@gmail.com/T/ [v1]
+Link: https://lore.kernel.org/all/20260316104536.558108-1-kartikey406@gmail.com/T/ [v2]
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Ben Segall <bsegall@google.com>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Juri Lelli <juri.lelli@redhat.com>
+Cc: Kees Cook <kees@kernel.org>
+Cc: Liam Howlett <liam@infradead.org>
+Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Valentin Schneider <vschneid@redhat.com>
+Cc: Vincent Guittot <vincent.guittot@linaro.org>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/fork.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/fork.c b/kernel/fork.c
+index e280f02b6446ab..d68d40735a082a 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -2870,8 +2870,6 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
+  *
+  * It copies the process, and if successful kick-starts
+  * it and waits for it to finish using the VM if required.
+- *
+- * args->exit_signal is expected to be checked for sanity by the caller.
+  */
+ pid_t kernel_clone(struct kernel_clone_args *args)
+ {
+@@ -2896,6 +2894,9 @@ pid_t kernel_clone(struct kernel_clone_args *args)
+           (args->pidfd == args->parent_tid))
+               return -EINVAL;
++      if (!valid_signal(args->exit_signal))
++              return -EINVAL;
++
+       /*
+        * Determine whether and which event to report to ptracer.  When
+        * called from kernel_thread or CLONE_UNTRACED is explicitly
+@@ -3098,11 +3099,9 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
+               return -EINVAL;
+       /*
+-       * Verify that higher 32bits of exit_signal are unset and that
+-       * it is a valid signal
++       * Verify that higher 32bits of exit_signal are unset
+        */
+-      if (unlikely((args.exit_signal & ~((u64)CSIGNAL)) ||
+-                   !valid_signal(args.exit_signal)))
++      if (unlikely(args.exit_signal & ~((u64)CSIGNAL)))
+               return -EINVAL;
+       if ((args.flags & CLONE_INTO_CGROUP) &&
+-- 
+2.53.0
+
diff --git a/queue-6.6/ksmbd-fix-fsctl-permission-bypass-by-adding-a-permis.patch b/queue-6.6/ksmbd-fix-fsctl-permission-bypass-by-adding-a-permis.patch
new file mode 100644 (file)
index 0000000..17745db
--- /dev/null
@@ -0,0 +1,69 @@
+From 8b8b43d74f66682ed56b0d553934ce970cc1f9ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 22:07:16 +0900
+Subject: ksmbd: fix FSCTL permission bypass by adding a permission check for
+ FSCTL_SET_SPARSE
+
+From: Sean Shen <grayhat@foxmail.com>
+
+[ Upstream commit cc57232cae23c0df91b4a59d0f519141ce9b5b02 ]
+
+FSCTL_SET_SPARSE in fsctl_set_sparse() modifies the file's sparse
+attribute and saves it through xattr without any permission checks.
+
+This exposes two issues:
+
+1) A client on a read-only share can change the sparse attribute
+   on files it opened, even though the share is read-only.
+   Other FSCTL write operations already check
+   test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE),
+   but FSCTL_SET_SPARSE does not.
+
+2) Even on writable shares, clients without FILE_WRITE_DATA or
+   FILE_WRITE_ATTRIBUTES access should not modify the sparse
+   attribute. Similar handle-level checks exist in other functions
+   but are missing here.
+
+Add both share-level writable check and per-handle access check.
+Use goto out on error to avoid leaking file references.
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Cc: Namjae Jeon <linkinjeon@kernel.org>
+Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Cc: Steve French <smfrench@gmail.com>
+Signed-off-by: Sean Shen <grayhat@foxmail.com>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/smb2pdu.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
+index 04d4a784deaf98..97b03f76741ef2 100644
+--- a/fs/smb/server/smb2pdu.c
++++ b/fs/smb/server/smb2pdu.c
+@@ -8067,9 +8067,20 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id,
+       int ret = 0;
+       __le32 old_fattr;
++      if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
++              ksmbd_debug(SMB, "User does not have write permission\n");
++              return -EACCES;
++      }
++
+       fp = ksmbd_lookup_fd_fast(work, id);
+       if (!fp)
+               return -ENOENT;
++
++      if (!(fp->daccess & (FILE_WRITE_DATA_LE | FILE_WRITE_ATTRIBUTES_LE))) {
++              ret = -EACCES;
++              goto out;
++      }
++
+       idmap = file_mnt_idmap(fp->filp);
+       old_fattr = fp->f_ci->m_fattr;
+-- 
+2.53.0
+
diff --git a/queue-6.6/net-hsr-fix-potential-oob-access-in-supervision-fram.patch b/queue-6.6/net-hsr-fix-potential-oob-access-in-supervision-fram.patch
new file mode 100644 (file)
index 0000000..5d39349
--- /dev/null
@@ -0,0 +1,48 @@
+From fbc479667b40efe1a5a50ad2cb7b73f49fa07a3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 May 2026 15:03:30 +0200
+Subject: net: hsr: fix potential OOB access in supervision frame handling
+
+From: Luka Gejak <luka.gejak@linux.dev>
+
+[ Upstream commit f229426072fc865654a60978bb7fda790a051ff3 ]
+
+Ensure the entire TLV header is linearized before access by adding
+sizeof(struct hsr_sup_tlv) to the pskb_may_pull() calls. Without this,
+a truncated frame could cause an out-of-bounds access.
+
+Fixes: eafaa88b3eb7 ("net: hsr: Add support for redbox supervision frames")
+Signed-off-by: Luka Gejak <luka.gejak@linux.dev>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260523130330.61880-1-luka.gejak@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_forward.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index 3852fd99509f04..7a596c4f603e2d 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -84,7 +84,7 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb)
+       /* Get next tlv */
+       total_length += hsr_sup_tag->tlv.HSR_TLV_length;
+-      if (!pskb_may_pull(skb, total_length))
++      if (!pskb_may_pull(skb, total_length + sizeof(struct hsr_sup_tlv)))
+               return false;
+       skb_pull(skb, total_length);
+       hsr_sup_tlv = (struct hsr_sup_tlv *)skb->data;
+@@ -100,7 +100,7 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb)
+               /* make sure another tlv follows */
+               total_length += sizeof(struct hsr_sup_tlv) + hsr_sup_tlv->HSR_TLV_length;
+-              if (!pskb_may_pull(skb, total_length))
++              if (!pskb_may_pull(skb, total_length + sizeof(struct hsr_sup_tlv)))
+                       return false;
+               /* get next tlv */
+-- 
+2.53.0
+
diff --git a/queue-6.6/net-iucv-fix-locking-in-.getsockopt.patch b/queue-6.6/net-iucv-fix-locking-in-.getsockopt.patch
new file mode 100644 (file)
index 0000000..1616346
--- /dev/null
@@ -0,0 +1,87 @@
+From fcedd3c64a715fe10a9393ea4bf5db31437f4ea4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 07:11:45 -0700
+Subject: net/iucv: fix locking in .getsockopt
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 3589d20a666caf30ad100c960a2de7de390fce88 ]
+
+Mirror iucv_sock_setsockopt() and wrap the whole switch in
+lock_sock()/release_sock(). The pre-existing SO_MSGLIMIT-only lock
+becomes redundant and is removed.
+
+Any AF_IUCV HIPER user can potentially crash the kernel by racing
+recvmsg() with getsockopt(SO_MSGSIZE): the SO_MSGSIZE arm dereferences
+iucv->hs_dev->mtu after iucv_sock_close() (called from the racing
+recvmsg()) has set hs_dev to NULL, producing a NULL pointer dereference
+oops.
+
+Suggested-by: Stanislav Fomichev <sdf.kernel@gmail.com>
+Fixes: 51363b8751a6 ("af_iucv: allow retrieval of maximum message size")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Tested-by: Alexandra Winter <wintera@linux.ibm.com>
+Link: https://patch.msgid.link/20260521-af_iucv_fix2-v1-1-f16b1c510aa9@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index 0f660b1d3bd51c..e9a9bb0dee065a 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -1539,7 +1539,7 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       struct sock *sk = sock->sk;
+       struct iucv_sock *iucv = iucv_sk(sk);
+       unsigned int val;
+-      int len;
++      int len, rc;
+       if (level != SOL_IUCV)
+               return -ENOPROTOOPT;
+@@ -1552,26 +1552,34 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       len = min_t(unsigned int, len, sizeof(int));
++      rc = 0;
++
++      lock_sock(sk);
+       switch (optname) {
+       case SO_IPRMDATA_MSG:
+               val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0;
+               break;
+       case SO_MSGLIMIT:
+-              lock_sock(sk);
+               val = (iucv->path != NULL) ? iucv->path->msglim /* connected */
+                                          : iucv->msglimit;    /* default */
+-              release_sock(sk);
+               break;
+       case SO_MSGSIZE:
+-              if (sk->sk_state == IUCV_OPEN)
+-                      return -EBADFD;
++              if (sk->sk_state == IUCV_OPEN) {
++                      rc = -EBADFD;
++                      break;
++              }
+               val = (iucv->hs_dev) ? iucv->hs_dev->mtu -
+                               sizeof(struct af_iucv_trans_hdr) - ETH_HLEN :
+                               0x7fffffff;
+               break;
+       default:
+-              return -ENOPROTOOPT;
++              rc = -ENOPROTOOPT;
++              break;
+       }
++      release_sock(sk);
++
++      if (rc)
++              return rc;
+       if (put_user(len, optlen))
+               return -EFAULT;
+-- 
+2.53.0
+
diff --git a/queue-6.6/net-mana-add-null-guards-in-teardown-path-to-prevent.patch b/queue-6.6/net-mana-add-null-guards-in-teardown-path-to-prevent.patch
new file mode 100644 (file)
index 0000000..b9c43f7
--- /dev/null
@@ -0,0 +1,148 @@
+From bd11f75a6f9ad1296fb4c58e5162b0c43757f5d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 01:08:24 -0700
+Subject: net: mana: Add NULL guards in teardown path to prevent panic on
+ attach failure
+
+From: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+
+[ Upstream commit 17bfe0a8c014ee1d542ad352cd6a0a505361664a ]
+
+When queue allocation fails partway through, the error cleanup frees
+and NULLs apc->tx_qp and apc->rxqs. Multiple teardown paths such as
+mana_remove(), mana_change_mtu() recovery, and internal error handling
+in mana_alloc_queues() can subsequently call into functions that
+dereference these pointers without NULL checks:
+
+- mana_chn_setxdp() dereferences apc->rxqs[0], causing a NULL pointer
+  dereference panic (CR2: 0000000000000000 at mana_chn_setxdp+0x26).
+- mana_destroy_vport() iterates apc->rxqs without a NULL check.
+- mana_fence_rqs() iterates apc->rxqs without a NULL check.
+- mana_dealloc_queues() iterates apc->tx_qp without a NULL check.
+
+Add NULL guards for apc->rxqs in mana_fence_rqs(),
+mana_destroy_vport(), and before the mana_chn_setxdp() call. Add a
+NULL guard for apc->tx_qp in mana_dealloc_queues() to skip TX queue
+draining when TX queues were never allocated or already freed.
+
+Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
+Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+Link: https://patch.msgid.link/20260525081129.1230035-2-dipayanroy@linux.microsoft.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microsoft/mana/mana_en.c | 70 +++++++++++--------
+ 1 file changed, 41 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
+index 343f6e879af39e..3cf4ad1d91f67e 100644
+--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
+@@ -1304,6 +1304,9 @@ static void mana_fence_rqs(struct mana_port_context *apc)
+       struct mana_rxq *rxq;
+       int err;
++      if (!apc->rxqs)
++              return;
++
+       for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
+               rxq = apc->rxqs[rxq_idx];
+               err = mana_fence_rq(apc, rxq);
+@@ -2334,13 +2337,16 @@ static void mana_destroy_vport(struct mana_port_context *apc)
+       struct mana_rxq *rxq;
+       u32 rxq_idx;
+-      for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
+-              rxq = apc->rxqs[rxq_idx];
+-              if (!rxq)
+-                      continue;
++      if (apc->rxqs) {
+-              mana_destroy_rxq(apc, rxq, true);
+-              apc->rxqs[rxq_idx] = NULL;
++              for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
++                      rxq = apc->rxqs[rxq_idx];
++                      if (!rxq)
++                              continue;
++
++                      mana_destroy_rxq(apc, rxq, true);
++                      apc->rxqs[rxq_idx] = NULL;
++              }
+       }
+       mana_destroy_txq(apc);
+@@ -2577,7 +2583,8 @@ static int mana_dealloc_queues(struct net_device *ndev)
+       if (apc->port_is_up)
+               return -EINVAL;
+-      mana_chn_setxdp(apc, NULL);
++      if (apc->rxqs)
++              mana_chn_setxdp(apc, NULL);
+       if (gd->gdma_context->is_pf)
+               mana_pf_deregister_filter(apc);
+@@ -2595,33 +2602,38 @@ static int mana_dealloc_queues(struct net_device *ndev)
+        * number of queues.
+        */
+-      for (i = 0; i < apc->num_queues; i++) {
+-              txq = &apc->tx_qp[i].txq;
+-              tsleep = 1000;
+-              while (atomic_read(&txq->pending_sends) > 0 &&
+-                     time_before(jiffies, timeout)) {
+-                      usleep_range(tsleep, tsleep + 1000);
+-                      tsleep <<= 1;
+-              }
+-              if (atomic_read(&txq->pending_sends)) {
+-                      err = pcie_flr(to_pci_dev(gd->gdma_context->dev));
+-                      if (err) {
+-                              netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
+-                                         err, atomic_read(&txq->pending_sends),
+-                                         txq->gdma_txq_id);
++      if (apc->tx_qp) {
++              for (i = 0; i < apc->num_queues; i++) {
++                      txq = &apc->tx_qp[i].txq;
++                      tsleep = 1000;
++                      while (atomic_read(&txq->pending_sends) > 0 &&
++                             time_before(jiffies, timeout)) {
++                              usleep_range(tsleep, tsleep + 1000);
++                              tsleep <<= 1;
++                      }
++                      if (atomic_read(&txq->pending_sends)) {
++                              err =
++                                  pcie_flr(to_pci_dev(gd->gdma_context->dev));
++                              if (err) {
++                                      netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
++                                                 err,
++                                          atomic_read(&txq->pending_sends),
++                                          txq->gdma_txq_id);
++                              }
++                              break;
+                       }
+-                      break;
+               }
+-      }
+-      for (i = 0; i < apc->num_queues; i++) {
+-              txq = &apc->tx_qp[i].txq;
+-              while ((skb = skb_dequeue(&txq->pending_skbs))) {
+-                      mana_unmap_skb(skb, apc);
+-                      dev_kfree_skb_any(skb);
++              for (i = 0; i < apc->num_queues; i++) {
++                      txq = &apc->tx_qp[i].txq;
++                      while ((skb = skb_dequeue(&txq->pending_skbs))) {
++                              mana_unmap_skb(skb, apc);
++                              dev_kfree_skb_any(skb);
++                      }
++                      atomic_set(&txq->pending_sends, 0);
+               }
+-              atomic_set(&txq->pending_sends, 0);
+       }
++
+       /* We're 100% sure the queues can no longer be woken up, because
+        * we're sure now mana_poll_tx_cq() can't be running.
+        */
+-- 
+2.53.0
+
diff --git a/queue-6.6/net-netlink-don-t-set-nsid-on-local-notifications.patch b/queue-6.6/net-netlink-don-t-set-nsid-on-local-notifications.patch
new file mode 100644 (file)
index 0000000..cca9da7
--- /dev/null
@@ -0,0 +1,82 @@
+From df346a5056a1641ada9eded25e142c5340a7cfc1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:36 +0200
+Subject: net: netlink: don't set nsid on local notifications
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 88b126b39f9757e9debc322d4679239e9af089c7 ]
+
+In most cases, notifications on sockets with NETLINK_LISTEN_ALL_NSID
+do not contain NSID in their ancillary data in case the event is local
+to the listener.
+
+However, when a self-referential NSID is allocated for a namespace,
+every local notification starts sending this ID to the user space.
+
+This is problematic, because the listener cannot tell if those
+notifications are local or not anymore without making extra requests
+to figure out if the provided NSID is local or not.  The listener
+can also not figure out the local NSID beforehand as it can be
+allocated at any point in time by other processes, changing the
+structure of the future notifications for everyone.
+
+The value is practically not useful, since it's the namespace's own
+ID that the application has to obtain from other sources in order to
+figure out if it's the same or not.  So, for the application it's
+just an extra busy work with no benefits.  Moreover, applications
+that do not know about this quirk may be mishandling notifications
+with NSID set as notifications from remote namespaces.  This is the
+case for ovs-vswitchd and the iproute2's 'ip monitor' that stops
+printing 'current' and starts printing the nsid number mid-session.
+
+Lack of clear documentation for this behavior is also not helping.
+
+A search though open-source projects doesn't reveal any projects
+that use NETNSA_NSID_NOT_ASSIGNED and rely on metadata to contain
+self-referential NSIDs (expected, since the value is not useful).
+Quite the opposite, as already mentioned, there are few applications
+that rely on NSID to not be present in local events.
+
+Since the value is not useful and actively harmful in some cases,
+let's not report it for local events, making the notifications more
+consistent.
+
+Also adding some blank lines for readability.
+
+Fixes: 59324cf35aba ("netlink: allow to listen "all" netns")
+Reported-by: Matteo Perin <matteo.perin@canonical.com>
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-3-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index f8d9a04d5d8b11..f3a8c8338d203f 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1484,10 +1484,14 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++
+       NETLINK_CB(p->skb2).nsid_is_set = false;
+-      NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+-      if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+-              NETLINK_CB(p->skb2).nsid_is_set = true;
++      if (!net_eq(sock_net(sk), p->net)) {
++              NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
++              if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
++                      NETLINK_CB(p->skb2).nsid_is_set = true;
++      }
++
+       val = netlink_broadcast_deliver(sk, p->skb2);
+       if (val < 0) {
+               netlink_overrun(sk);
+-- 
+2.53.0
+
diff --git a/queue-6.6/net-netlink-fix-sending-unassigned-nsid-after-assign.patch b/queue-6.6/net-netlink-fix-sending-unassigned-nsid-after-assign.patch
new file mode 100644 (file)
index 0000000..b333569
--- /dev/null
@@ -0,0 +1,45 @@
+From db98437ed52e551948572283ee4072486c9c3475 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:35 +0200
+Subject: net: netlink: fix sending unassigned nsid after assigned one
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 70f8592ee90585272018a725054b6eb2ab7e99ca ]
+
+If the current skb is not shared, it is re-used directly for all the
+sockets subscribed to the notification.  If we have remote all-nsid
+socket receiving a message first, then the 'nsid_is_set' will be
+set to 'true'.  If the nsid is NOT_ASSIGNED for the next socket in
+the list, the 'nsid_is_set' will remain 'true' and the negative value
+is be delivered to the user space.  All subsequent nsid values will be
+delivered as well, since there is no code path that sets the flag
+back to 'false'.
+
+Fix that by always dropping the flag to 'false' first.
+
+Fixes: 7212462fa6fd ("netlink: don't send unknown nsid")
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-2-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index a5ffda87daf63b..f8d9a04d5d8b11 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1484,6 +1484,7 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++      NETLINK_CB(p->skb2).nsid_is_set = false;
+       NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+       if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+               NETLINK_CB(p->skb2).nsid_is_set = true;
+-- 
+2.53.0
+
diff --git a/queue-6.6/net-sched-revert-net-sched-restrict-conditions-for-a.patch b/queue-6.6/net-sched-revert-net-sched-restrict-conditions-for-a.patch
new file mode 100644 (file)
index 0000000..a1b944e
--- /dev/null
@@ -0,0 +1,102 @@
+From a932c98b8851c7876d67b1af2e0141a344502b88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:49 -0400
+Subject: net/sched: Revert "net/sched: Restrict conditions for adding
+ duplicating netems to qdisc tree"
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit eda0b7f203bb166c98d1418b204135bd566ac83b ]
+
+This reverts commit ec8e0e3d7adef940cdf9475e2352c0680189d14e.
+
+The original patch rejects any tree containing two netems when
+either has duplication set, even when they sit on unrelated classes
+of the same classful parent. That broke configurations that have
+worked since netem was introduced.
+
+The re-entrancy problem the original commit was trying to solve is
+handled by later patch using tc_depth flag.
+
+Doing this revert will (re)expose the original bug with multiple
+netem duplication. When this patch is backported make sure
+and get the full series.
+
+Fixes: ec8e0e3d7ade ("net/sched: Restrict conditions for adding duplicating netems to qdisc tree")
+Reported-by: Ji-Soo Chung <jschung2@proton.me>
+Reported-by: Gerlinde <lrGerlinde@mailfence.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220774
+Reported-by: zyc zyc <zyc199902@zohomail.cn>
+Closes: https://lore.kernel.org/all/19adda5a1e2.12410b78222774.9191120410578703463@zohomail.cn/
+Reported-by: Manas Ghandat <ghandatmanas@gmail.com>
+Closes: https://lore.kernel.org/netdev/f69b2c8f-8325-4c2e-a011-6dbc089f30e4@gmail.com/
+Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-3-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_netem.c | 40 ----------------------------------------
+ 1 file changed, 40 deletions(-)
+
+diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
+index f8c5c506180858..827489b31626bb 100644
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -1005,41 +1005,6 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
+       return 0;
+ }
+-static const struct Qdisc_class_ops netem_class_ops;
+-
+-static int check_netem_in_tree(struct Qdisc *sch, bool duplicates,
+-                             struct netlink_ext_ack *extack)
+-{
+-      struct Qdisc *root, *q;
+-      unsigned int i;
+-
+-      root = qdisc_root_sleeping(sch);
+-
+-      if (sch != root && root->ops->cl_ops == &netem_class_ops) {
+-              if (duplicates ||
+-                  ((struct netem_sched_data *)qdisc_priv(root))->duplicate)
+-                      goto err;
+-      }
+-
+-      if (!qdisc_dev(root))
+-              return 0;
+-
+-      hash_for_each(qdisc_dev(root)->qdisc_hash, i, q, hash) {
+-              if (sch != q && q->ops->cl_ops == &netem_class_ops) {
+-                      if (duplicates ||
+-                          ((struct netem_sched_data *)qdisc_priv(q))->duplicate)
+-                              goto err;
+-              }
+-      }
+-
+-      return 0;
+-
+-err:
+-      NL_SET_ERR_MSG(extack,
+-                     "netem: cannot mix duplicating netems with other netems in tree");
+-      return -EINVAL;
+-}
+-
+ /* Parse netlink message to set options */
+ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+                       struct netlink_ext_ack *extack)
+@@ -1116,11 +1081,6 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+       q->gap = qopt->gap;
+       q->counter = 0;
+       q->loss = qopt->loss;
+-
+-      ret = check_netem_in_tree(sch, qopt->duplicate, extack);
+-      if (ret)
+-              goto unlock;
+-
+       q->duplicate = qopt->duplicate;
+       /* for compatibility with earlier versions.
+-- 
+2.53.0
+
diff --git a/queue-6.6/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch b/queue-6.6/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch
new file mode 100644 (file)
index 0000000..f51c9cf
--- /dev/null
@@ -0,0 +1,64 @@
+From 28b57b90365da92cb18898718d1f86b0cf8cd81a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 May 2026 19:43:53 +0100
+Subject: net: skbuff: fix pskb_carve leaking zcopy pages
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit ff6e798c2eac3ebd0501ad7e796f583fab928de8 ]
+
+When SKBFL_MANAGED_FRAG_REFS is set, frag pages are not refcounted but
+their lifetime is controlled by the attached ubuf_info. To make a copy
+of the skb_shared_info, we either should clear the flag and reference
+the frags, or keep the flag and have frags unreferenced.
+
+pskb_carve_inside_header() and pskb_carve_inside_nonlinear() don't
+follow the rule and thus can leak page references. Let's clear
+SKBFL_MANAGED_FRAG_REFS from the original skb to fix it. It's the
+simplest way to address it, but there are more performant ways to do
+that if it ever becomes a problem.
+
+Link: https://lore.kernel.org/all/20260523085809.26331-1-nvminh232@clc.fitus.edu.vn/
+Fixes: 753f1ca4e1e50 ("net: introduce managed frags infrastructure")
+Reported-by: Minh Nguyen <minhnguyen.080505@gmail.com>
+Reported-by: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/1e2086aa69217d7f9c8da3d38f5be7160f1b4cd1.1779993185.git.asml.silence@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 8b05866e93b195..2282b6ad4be21a 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -6397,6 +6397,11 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
+       skb_copy_from_linear_data_offset(skb, off, data, new_hlen);
+       skb->len -= off;
++      /* Remove SKBFL_MANAGED_FRAG_REFS instead of trying to honour it
++       * while refcounting frags below.
++       */
++      skb_zcopy_downgrade_managed(skb);
++
+       memcpy((struct skb_shared_info *)(data + size),
+              skb_shinfo(skb),
+              offsetof(struct skb_shared_info,
+@@ -6509,6 +6514,11 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,
+               return -ENOMEM;
+       size = SKB_WITH_OVERHEAD(size);
++      /* Remove SKBFL_MANAGED_FRAG_REFS instead of trying to honour it
++       * while refcounting frags below.
++       */
++      skb_zcopy_downgrade_managed(skb);
++
+       memcpy((struct skb_shared_info *)(data + size),
+              skb_shinfo(skb), offsetof(struct skb_shared_info, frags[0]));
+       if (skb_orphan_frags(skb, gfp_mask)) {
+-- 
+2.53.0
+
diff --git a/queue-6.6/net-smc-do-not-re-initialize-smc-hashtables.patch b/queue-6.6/net-smc-do-not-re-initialize-smc-hashtables.patch
new file mode 100644 (file)
index 0000000..a165a77
--- /dev/null
@@ -0,0 +1,59 @@
+From 02743852ff7637214bf2731ea35d49304ab58302 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 16:56:39 +0200
+Subject: net/smc: Do not re-initialize smc hashtables
+
+From: Alexandra Winter <wintera@linux.ibm.com>
+
+[ Upstream commit 9e4389b0038781f19f97895186ed941ff8ac1678 ]
+
+INIT_HLIST_HEAD(&smc_v*_hashinfo.ht) are called after smc_nl_init(),
+proto_register() and sock_register(). This can lead to smc_v*_hashinfo.ht
+being reset even though hash entries already exist and are being used,
+possibly resulting in a corrupted list.
+
+Remove unnecessary and dangerous re-initialisation of smc_v*_hashinfo.ht in
+smc_init(); it is implicitly initialised to zero anyhow. Add
+HLIST_HEAD_INIT to the definitions for clarity.
+
+Fixes: f16a7dd5cf27 ("smc: netlink interface for SMC sockets")
+Suggested-by: Halil Pasic <pasic@linux.ibm.com>
+Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
+Acked-by: Halil Pasic <pasic@linux.ibm.com>
+Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
+Link: https://patch.msgid.link/20260521145639.10317-1-wintera@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index 6629fd61be06a6..7a82e1a8a83f4b 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -181,10 +181,12 @@ static bool smc_hs_congested(const struct sock *sk)
+ static struct smc_hashinfo smc_v4_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v4_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ static struct smc_hashinfo smc_v6_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v6_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ int smc_hash_sk(struct sock *sk)
+@@ -3579,8 +3581,6 @@ static int __init smc_init(void)
+               pr_err("%s: sock_register fails with %d\n", __func__, rc);
+               goto out_proto6;
+       }
+-      INIT_HLIST_HEAD(&smc_v4_hashinfo.ht);
+-      INIT_HLIST_HEAD(&smc_v6_hashinfo.ht);
+       rc = smc_ib_register_client();
+       if (rc) {
+-- 
+2.53.0
+
diff --git a/queue-6.6/netfilter-bitwise-add-support-for-doing-and-or-and-x.patch b/queue-6.6/netfilter-bitwise-add-support-for-doing-and-or-and-x.patch
new file mode 100644 (file)
index 0000000..40c34b0
--- /dev/null
@@ -0,0 +1,300 @@
+From 18b5a57676c1eff651be3ff4f29bc73fa2f2e66f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Nov 2024 22:08:13 +0100
+Subject: netfilter: bitwise: add support for doing AND, OR and XOR directly
+
+From: Jeremy Sowden <jeremy@azazel.net>
+
+[ Upstream commit b0ccf4f53d968e794a4ea579d5135cc1aaf1a53f ]
+
+Hitherto, these operations have been converted in user space to
+mask-and-xor operations on one register and two immediate values, and it
+is the latter which have been evaluated by the kernel.  We add support
+for evaluating these operations directly in kernel space on one register
+and either an immediate value or a second register.
+
+Pablo made a few changes to the original patch:
+
+- EINVAL if NFTA_BITWISE_SREG2 is used with fast version.
+- Allow _AND,_OR,_XOR with _DATA != sizeof(u32)
+- Dump _SREG2 or _DATA with _AND,_OR,_XOR
+
+Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: 18014147d3ee ("netfilter: nf_tables: fix dst corruption in same register operation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/netfilter/nf_tables.h |   8 ++
+ net/netfilter/nft_bitwise.c              | 134 +++++++++++++++++++++--
+ 2 files changed, 131 insertions(+), 11 deletions(-)
+
+diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
+index cbb1b58e181fca..f8867f198f3104 100644
+--- a/include/uapi/linux/netfilter/nf_tables.h
++++ b/include/uapi/linux/netfilter/nf_tables.h
+@@ -564,11 +564,17 @@ enum nft_immediate_attributes {
+  *                        and XOR boolean operations
+  * @NFT_BITWISE_LSHIFT: left-shift operation
+  * @NFT_BITWISE_RSHIFT: right-shift operation
++ * @NFT_BITWISE_AND: and operation
++ * @NFT_BITWISE_OR: or operation
++ * @NFT_BITWISE_XOR: xor operation
+  */
+ enum nft_bitwise_ops {
+       NFT_BITWISE_MASK_XOR,
+       NFT_BITWISE_LSHIFT,
+       NFT_BITWISE_RSHIFT,
++      NFT_BITWISE_AND,
++      NFT_BITWISE_OR,
++      NFT_BITWISE_XOR,
+ };
+ /*
+  * Old name for NFT_BITWISE_MASK_XOR.  Retained for backwards-compatibility.
+@@ -586,6 +592,7 @@ enum nft_bitwise_ops {
+  * @NFTA_BITWISE_OP: type of operation (NLA_U32: nft_bitwise_ops)
+  * @NFTA_BITWISE_DATA: argument for non-boolean operations
+  *                     (NLA_NESTED: nft_data_attributes)
++ * @NFTA_BITWISE_SREG2: second source register (NLA_U32: nft_registers)
+  *
+  * The bitwise expression supports boolean and shift operations.  It implements
+  * the boolean operations by performing the following operation:
+@@ -609,6 +616,7 @@ enum nft_bitwise_attributes {
+       NFTA_BITWISE_XOR,
+       NFTA_BITWISE_OP,
+       NFTA_BITWISE_DATA,
++      NFTA_BITWISE_SREG2,
+       __NFTA_BITWISE_MAX
+ };
+ #define NFTA_BITWISE_MAX      (__NFTA_BITWISE_MAX - 1)
+diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
+index 86abbe4c1308b3..af990c600745be 100644
+--- a/net/netfilter/nft_bitwise.c
++++ b/net/netfilter/nft_bitwise.c
+@@ -17,6 +17,7 @@
+ struct nft_bitwise {
+       u8                      sreg;
++      u8                      sreg2;
+       u8                      dreg;
+       enum nft_bitwise_ops    op:8;
+       u8                      len;
+@@ -60,28 +61,72 @@ static void nft_bitwise_eval_rshift(u32 *dst, const u32 *src,
+       }
+ }
++static void nft_bitwise_eval_and(u32 *dst, const u32 *src, const u32 *src2,
++                               const struct nft_bitwise *priv)
++{
++      unsigned int i, n;
++
++      for (i = 0, n = DIV_ROUND_UP(priv->len, sizeof(u32)); i < n; i++)
++              dst[i] = src[i] & src2[i];
++}
++
++static void nft_bitwise_eval_or(u32 *dst, const u32 *src, const u32 *src2,
++                              const struct nft_bitwise *priv)
++{
++      unsigned int i, n;
++
++      for (i = 0, n = DIV_ROUND_UP(priv->len, sizeof(u32)); i < n; i++)
++              dst[i] = src[i] | src2[i];
++}
++
++static void nft_bitwise_eval_xor(u32 *dst, const u32 *src, const u32 *src2,
++                               const struct nft_bitwise *priv)
++{
++      unsigned int i, n;
++
++      for (i = 0, n = DIV_ROUND_UP(priv->len, sizeof(u32)); i < n; i++)
++              dst[i] = src[i] ^ src2[i];
++}
++
+ void nft_bitwise_eval(const struct nft_expr *expr,
+                     struct nft_regs *regs, const struct nft_pktinfo *pkt)
+ {
+       const struct nft_bitwise *priv = nft_expr_priv(expr);
+-      const u32 *src = &regs->data[priv->sreg];
++      const u32 *src = &regs->data[priv->sreg], *src2;
+       u32 *dst = &regs->data[priv->dreg];
+-      switch (priv->op) {
+-      case NFT_BITWISE_MASK_XOR:
++      if (priv->op == NFT_BITWISE_MASK_XOR) {
+               nft_bitwise_eval_mask_xor(dst, src, priv);
+-              break;
+-      case NFT_BITWISE_LSHIFT:
++              return;
++      }
++      if (priv->op == NFT_BITWISE_LSHIFT) {
+               nft_bitwise_eval_lshift(dst, src, priv);
+-              break;
+-      case NFT_BITWISE_RSHIFT:
++              return;
++      }
++      if (priv->op == NFT_BITWISE_RSHIFT) {
+               nft_bitwise_eval_rshift(dst, src, priv);
+-              break;
++              return;
++      }
++
++      src2 = priv->sreg2 ? &regs->data[priv->sreg2] : priv->data.data;
++
++      if (priv->op == NFT_BITWISE_AND) {
++              nft_bitwise_eval_and(dst, src, src2, priv);
++              return;
++      }
++      if (priv->op == NFT_BITWISE_OR) {
++              nft_bitwise_eval_or(dst, src, src2, priv);
++              return;
++      }
++      if (priv->op == NFT_BITWISE_XOR) {
++              nft_bitwise_eval_xor(dst, src, src2, priv);
++              return;
+       }
+ }
+ static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = {
+       [NFTA_BITWISE_SREG]     = { .type = NLA_U32 },
++      [NFTA_BITWISE_SREG2]    = { .type = NLA_U32 },
+       [NFTA_BITWISE_DREG]     = { .type = NLA_U32 },
+       [NFTA_BITWISE_LEN]      = { .type = NLA_U32 },
+       [NFTA_BITWISE_MASK]     = { .type = NLA_NESTED },
+@@ -105,7 +150,8 @@ static int nft_bitwise_init_mask_xor(struct nft_bitwise *priv,
+       };
+       int err;
+-      if (tb[NFTA_BITWISE_DATA])
++      if (tb[NFTA_BITWISE_DATA] ||
++          tb[NFTA_BITWISE_SREG2])
+               return -EINVAL;
+       if (!tb[NFTA_BITWISE_MASK] ||
+@@ -139,7 +185,8 @@ static int nft_bitwise_init_shift(struct nft_bitwise *priv,
+       int err;
+       if (tb[NFTA_BITWISE_MASK] ||
+-          tb[NFTA_BITWISE_XOR])
++          tb[NFTA_BITWISE_XOR]  ||
++          tb[NFTA_BITWISE_SREG2])
+               return -EINVAL;
+       if (!tb[NFTA_BITWISE_DATA])
+@@ -158,6 +205,41 @@ static int nft_bitwise_init_shift(struct nft_bitwise *priv,
+       return 0;
+ }
++static int nft_bitwise_init_bool(const struct nft_ctx *ctx,
++                               struct nft_bitwise *priv,
++                               const struct nlattr *const tb[])
++{
++      int err;
++
++      if (tb[NFTA_BITWISE_MASK] ||
++          tb[NFTA_BITWISE_XOR])
++              return -EINVAL;
++
++      if ((!tb[NFTA_BITWISE_DATA] && !tb[NFTA_BITWISE_SREG2]) ||
++          (tb[NFTA_BITWISE_DATA] && tb[NFTA_BITWISE_SREG2]))
++              return -EINVAL;
++
++      if (tb[NFTA_BITWISE_DATA]) {
++              struct nft_data_desc desc = {
++                      .type   = NFT_DATA_VALUE,
++                      .size   = sizeof(priv->data),
++                      .len    = priv->len,
++              };
++
++              err = nft_data_init(NULL, &priv->data, &desc,
++                                  tb[NFTA_BITWISE_DATA]);
++              if (err < 0)
++                      return err;
++      } else {
++              err = nft_parse_register_load(ctx, tb[NFTA_BITWISE_SREG2],
++                                            &priv->sreg2, priv->len);
++              if (err < 0)
++                      return err;
++      }
++
++      return 0;
++}
++
+ static int nft_bitwise_init(const struct nft_ctx *ctx,
+                           const struct nft_expr *expr,
+                           const struct nlattr * const tb[])
+@@ -189,6 +271,9 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
+               case NFT_BITWISE_MASK_XOR:
+               case NFT_BITWISE_LSHIFT:
+               case NFT_BITWISE_RSHIFT:
++              case NFT_BITWISE_AND:
++              case NFT_BITWISE_OR:
++              case NFT_BITWISE_XOR:
+                       break;
+               default:
+                       return -EOPNOTSUPP;
+@@ -205,6 +290,11 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
+       case NFT_BITWISE_RSHIFT:
+               err = nft_bitwise_init_shift(priv, tb);
+               break;
++      case NFT_BITWISE_AND:
++      case NFT_BITWISE_OR:
++      case NFT_BITWISE_XOR:
++              err = nft_bitwise_init_bool(ctx, priv, tb);
++              break;
+       }
+       return err;
+@@ -233,6 +323,21 @@ static int nft_bitwise_dump_shift(struct sk_buff *skb,
+       return 0;
+ }
++static int nft_bitwise_dump_bool(struct sk_buff *skb,
++                               const struct nft_bitwise *priv)
++{
++      if (priv->sreg2) {
++              if (nft_dump_register(skb, NFTA_BITWISE_SREG2, priv->sreg2))
++                      return -1;
++      } else {
++              if (nft_data_dump(skb, NFTA_BITWISE_DATA, &priv->data,
++                                NFT_DATA_VALUE, sizeof(u32)) < 0)
++                      return -1;
++      }
++
++      return 0;
++}
++
+ static int nft_bitwise_dump(struct sk_buff *skb,
+                           const struct nft_expr *expr, bool reset)
+ {
+@@ -256,6 +361,11 @@ static int nft_bitwise_dump(struct sk_buff *skb,
+       case NFT_BITWISE_RSHIFT:
+               err = nft_bitwise_dump_shift(skb, priv);
+               break;
++      case NFT_BITWISE_AND:
++      case NFT_BITWISE_OR:
++      case NFT_BITWISE_XOR:
++              err = nft_bitwise_dump_bool(skb, priv);
++              break;
+       }
+       return err;
+@@ -300,6 +410,7 @@ static bool nft_bitwise_reduce(struct nft_regs_track *track,
+           track->regs[priv->dreg].bitwise &&
+           track->regs[priv->dreg].bitwise->ops == expr->ops &&
+           priv->sreg == bitwise->sreg &&
++          priv->sreg2 == bitwise->sreg2 &&
+           priv->dreg == bitwise->dreg &&
+           priv->op == bitwise->op &&
+           priv->len == bitwise->len &&
+@@ -376,7 +487,8 @@ static int nft_bitwise_fast_init(const struct nft_ctx *ctx,
+       if (err < 0)
+               return err;
+-      if (tb[NFTA_BITWISE_DATA])
++      if (tb[NFTA_BITWISE_DATA] ||
++          tb[NFTA_BITWISE_SREG2])
+               return -EINVAL;
+       if (!tb[NFTA_BITWISE_MASK] ||
+-- 
+2.53.0
+
diff --git a/queue-6.6/netfilter-bitwise-rename-some-boolean-operation-func.patch b/queue-6.6/netfilter-bitwise-rename-some-boolean-operation-func.patch
new file mode 100644 (file)
index 0000000..7d7fd48
--- /dev/null
@@ -0,0 +1,164 @@
+From 402652d68fff1a19f21133acfdabb8f34c1905e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Nov 2024 22:07:51 +0100
+Subject: netfilter: bitwise: rename some boolean operation functions
+
+From: Jeremy Sowden <jeremy@azazel.net>
+
+[ Upstream commit a12143e6084c502fc3cfaa8b717bffc8c14cf806 ]
+
+In the next patch we add support for doing AND, OR and XOR operations
+directly in the kernel, so rename some functions and an enum constant
+related to mask-and-xor boolean operations.
+
+Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: 18014147d3ee ("netfilter: nf_tables: fix dst corruption in same register operation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/netfilter/nf_tables.h | 10 ++++---
+ net/netfilter/nft_bitwise.c              | 34 ++++++++++++------------
+ 2 files changed, 24 insertions(+), 20 deletions(-)
+
+diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
+index 9c29015d09c10f..cbb1b58e181fca 100644
+--- a/include/uapi/linux/netfilter/nf_tables.h
++++ b/include/uapi/linux/netfilter/nf_tables.h
+@@ -560,16 +560,20 @@ enum nft_immediate_attributes {
+ /**
+  * enum nft_bitwise_ops - nf_tables bitwise operations
+  *
+- * @NFT_BITWISE_BOOL: mask-and-xor operation used to implement NOT, AND, OR and
+- *                    XOR boolean operations
++ * @NFT_BITWISE_MASK_XOR: mask-and-xor operation used to implement NOT, AND, OR
++ *                        and XOR boolean operations
+  * @NFT_BITWISE_LSHIFT: left-shift operation
+  * @NFT_BITWISE_RSHIFT: right-shift operation
+  */
+ enum nft_bitwise_ops {
+-      NFT_BITWISE_BOOL,
++      NFT_BITWISE_MASK_XOR,
+       NFT_BITWISE_LSHIFT,
+       NFT_BITWISE_RSHIFT,
+ };
++/*
++ * Old name for NFT_BITWISE_MASK_XOR.  Retained for backwards-compatibility.
++ */
++#define NFT_BITWISE_BOOL NFT_BITWISE_MASK_XOR
+ /**
+  * enum nft_bitwise_attributes - nf_tables bitwise expression netlink attributes
+diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
+index 2cfb0104680c62..86abbe4c1308b3 100644
+--- a/net/netfilter/nft_bitwise.c
++++ b/net/netfilter/nft_bitwise.c
+@@ -25,8 +25,8 @@ struct nft_bitwise {
+       struct nft_data         data;
+ };
+-static void nft_bitwise_eval_bool(u32 *dst, const u32 *src,
+-                                const struct nft_bitwise *priv)
++static void nft_bitwise_eval_mask_xor(u32 *dst, const u32 *src,
++                                    const struct nft_bitwise *priv)
+ {
+       unsigned int i;
+@@ -68,8 +68,8 @@ void nft_bitwise_eval(const struct nft_expr *expr,
+       u32 *dst = &regs->data[priv->dreg];
+       switch (priv->op) {
+-      case NFT_BITWISE_BOOL:
+-              nft_bitwise_eval_bool(dst, src, priv);
++      case NFT_BITWISE_MASK_XOR:
++              nft_bitwise_eval_mask_xor(dst, src, priv);
+               break;
+       case NFT_BITWISE_LSHIFT:
+               nft_bitwise_eval_lshift(dst, src, priv);
+@@ -90,8 +90,8 @@ static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = {
+       [NFTA_BITWISE_DATA]     = { .type = NLA_NESTED },
+ };
+-static int nft_bitwise_init_bool(struct nft_bitwise *priv,
+-                               const struct nlattr *const tb[])
++static int nft_bitwise_init_mask_xor(struct nft_bitwise *priv,
++                                   const struct nlattr *const tb[])
+ {
+       struct nft_data_desc mask = {
+               .type   = NFT_DATA_VALUE,
+@@ -186,7 +186,7 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
+       if (tb[NFTA_BITWISE_OP]) {
+               priv->op = ntohl(nla_get_be32(tb[NFTA_BITWISE_OP]));
+               switch (priv->op) {
+-              case NFT_BITWISE_BOOL:
++              case NFT_BITWISE_MASK_XOR:
+               case NFT_BITWISE_LSHIFT:
+               case NFT_BITWISE_RSHIFT:
+                       break;
+@@ -194,12 +194,12 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
+                       return -EOPNOTSUPP;
+               }
+       } else {
+-              priv->op = NFT_BITWISE_BOOL;
++              priv->op = NFT_BITWISE_MASK_XOR;
+       }
+       switch(priv->op) {
+-      case NFT_BITWISE_BOOL:
+-              err = nft_bitwise_init_bool(priv, tb);
++      case NFT_BITWISE_MASK_XOR:
++              err = nft_bitwise_init_mask_xor(priv, tb);
+               break;
+       case NFT_BITWISE_LSHIFT:
+       case NFT_BITWISE_RSHIFT:
+@@ -210,8 +210,8 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
+       return err;
+ }
+-static int nft_bitwise_dump_bool(struct sk_buff *skb,
+-                               const struct nft_bitwise *priv)
++static int nft_bitwise_dump_mask_xor(struct sk_buff *skb,
++                                   const struct nft_bitwise *priv)
+ {
+       if (nft_data_dump(skb, NFTA_BITWISE_MASK, &priv->mask,
+                         NFT_DATA_VALUE, priv->len) < 0)
+@@ -249,8 +249,8 @@ static int nft_bitwise_dump(struct sk_buff *skb,
+               return -1;
+       switch (priv->op) {
+-      case NFT_BITWISE_BOOL:
+-              err = nft_bitwise_dump_bool(skb, priv);
++      case NFT_BITWISE_MASK_XOR:
++              err = nft_bitwise_dump_mask_xor(skb, priv);
+               break;
+       case NFT_BITWISE_LSHIFT:
+       case NFT_BITWISE_RSHIFT:
+@@ -270,7 +270,7 @@ static int nft_bitwise_offload(struct nft_offload_ctx *ctx,
+       const struct nft_bitwise *priv = nft_expr_priv(expr);
+       struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
+-      if (priv->op != NFT_BITWISE_BOOL)
++      if (priv->op != NFT_BITWISE_MASK_XOR)
+               return -EOPNOTSUPP;
+       if (memcmp(&priv->xor, &zero, sizeof(priv->xor)) ||
+@@ -407,7 +407,7 @@ nft_bitwise_fast_dump(struct sk_buff *skb,
+               return -1;
+       if (nla_put_be32(skb, NFTA_BITWISE_LEN, htonl(sizeof(u32))))
+               return -1;
+-      if (nla_put_be32(skb, NFTA_BITWISE_OP, htonl(NFT_BITWISE_BOOL)))
++      if (nla_put_be32(skb, NFTA_BITWISE_OP, htonl(NFT_BITWISE_MASK_XOR)))
+               return -1;
+       data.data[0] = priv->mask;
+@@ -502,7 +502,7 @@ nft_bitwise_select_ops(const struct nft_ctx *ctx,
+               return &nft_bitwise_ops;
+       if (tb[NFTA_BITWISE_OP] &&
+-          ntohl(nla_get_be32(tb[NFTA_BITWISE_OP])) != NFT_BITWISE_BOOL)
++          ntohl(nla_get_be32(tb[NFTA_BITWISE_OP])) != NFT_BITWISE_MASK_XOR)
+               return &nft_bitwise_ops;
+       return &nft_bitwise_fast_ops;
+-- 
+2.53.0
+
diff --git a/queue-6.6/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch b/queue-6.6/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
new file mode 100644 (file)
index 0000000..1e5308e
--- /dev/null
@@ -0,0 +1,107 @@
+From fc5e49514b4e5606b577a8262de548f245dbd1da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 22:52:07 +0200
+Subject: netfilter: ebtables: fix OOB read in compat_mtw_from_user
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit f438d1786d657d57790c5d138d6db3fc9fdac392 ]
+
+Luxiao Xu says:
+
+ The function compat_mtw_from_user() converts ebtables extensions from
+ 32-bit user structures to kernel native structures. However, it lacks
+ proper validation of the user-supplied match_size/target_size.
+
+ When certain extensions are processed, the kernel-side translation
+ logic may perform memory accesses based on the extension's expected
+ size. If the user provides a size smaller than what the extension
+ requires, it results in an out-of-bounds read as reported by KASAN.
+
+ This fix introduces a check to ensure match_size is at least as large
+ as the extension's required compatsize. This covers matches, watchers,
+ and targets, while maintaining compatibility with standard targets.
+
+AFAIU this is relevant for matches that need to go though
+match->compat_from_user() call.  Those that use plain memcpy with the
+user-provided size are ok because the caller checks that size vs the
+start of the next rule entry offset (which itself is checked vs. total
+size copied from userspace).
+
+The ->compat_from_user() callbacks assume they can read compatsize bytes,
+so they need this extra check.
+
+Based on an earlier patch from Luxiao Xu.
+
+Fixes: 81e675c227ec ("netfilter: ebtables: add CONFIG_COMPAT support")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/netfilter/ebtables.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
+index f99e348c8f37fa..bc69406d103df6 100644
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1952,6 +1952,25 @@ enum compat_mwt {
+       EBT_COMPAT_TARGET,
+ };
++static bool match_size_ok(const struct xt_match *match, unsigned int match_size)
++{
++      u16 csize;
++
++      if (match->matchsize == -1) /* cannot validate ebt_among */
++              return true;
++
++      csize = match->compatsize ? : match->matchsize;
++
++      return match_size >= csize;
++}
++
++static bool tgt_size_ok(const struct xt_target *tgt, unsigned int tgt_size)
++{
++      u16 csize = tgt->compatsize ? : tgt->targetsize;
++
++      return tgt_size >= csize;
++}
++
+ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                               enum compat_mwt compat_mwt,
+                               struct ebt_entries_buf_state *state,
+@@ -1977,6 +1996,11 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+               if (IS_ERR(match))
+                       return PTR_ERR(match);
++              if (!match_size_ok(match, match_size)) {
++                      module_put(match->me);
++                      return -EINVAL;
++              }
++
+               off = ebt_compat_match_offset(match, match_size);
+               if (dst) {
+                       if (match->compat_from_user)
+@@ -1996,6 +2020,12 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                                           mwt->u.revision);
+               if (IS_ERR(wt))
+                       return PTR_ERR(wt);
++
++              if (!tgt_size_ok(wt, match_size)) {
++                      module_put(wt->me);
++                      return -EINVAL;
++              }
++
+               off = xt_compat_target_offset(wt);
+               if (dst) {
+-- 
+2.53.0
+
diff --git a/queue-6.6/netfilter-nf_tables-fix-dst-corruption-in-same-regis.patch b/queue-6.6/netfilter-nf_tables-fix-dst-corruption-in-same-regis.patch
new file mode 100644 (file)
index 0000000..e321db8
--- /dev/null
@@ -0,0 +1,141 @@
+From 18720c912aa30fbd207aa4bb1952a5aea40f0ff5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 May 2026 16:37:56 +0200
+Subject: netfilter: nf_tables: fix dst corruption in same register operation
+
+From: Fernando Fernandez Mancera <fmancera@suse.de>
+
+[ Upstream commit 18014147d3ee7831dce53fe65d7fc8d428b02552 ]
+
+For lshift and rshift, the shift operations are performed in a loop over
+32-bit words. The loop calculates the shifted value and write it to dst,
+and then immediately reads from src to calculate the carry for the next
+iteration. Because src and dst could point to the same memory location,
+the carry is incorrectly calculated using the newly modified dst value
+instead of the original src value.
+
+Adding a temporary local variable to cache the original value before
+writing to dst and using it for the carry calculation solves the
+problem. In addition, partial overlap is rejected from control plane for
+all kind of operations including byteorder. This was tested with the
+following bytecode:
+
+table test_table ip flags 0 use 1 handle 1
+ip test_table test_chain use 3 type filter hook input prio 0 policy accept packets 0 bytes 0 flags 1
+ip test_table test_chain 2
+  [ immediate reg 1 0x44332211 0x88776655 ]
+  [ bitwise reg 1 = ( reg 1 << 0x08000000 ) ]
+  [ cmp eq reg 1 0x66443322 0x00887766 ]
+  [ counter pkts 0 bytes 0 ]
+ip test_table test_chain 4 3
+  [ immediate reg 1 0x44332211 0x88776655 ]
+  [ bitwise reg 1 = ( reg 1 << 0x08000000 ) ]
+  [ cmp eq reg 1 0x55443322 0x00887766 ]
+  [ counter pkts 21794 bytes 1917798 ]
+
+Fixes: 567d746b55bc ("netfilter: bitwise: add support for shifts.")
+Acked-by: Jeremy Sowden <jeremy@azazel.net>
+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>
+---
+ include/net/netfilter/nf_tables.h |  7 +++++++
+ net/netfilter/nft_bitwise.c       | 18 ++++++++++++++----
+ net/netfilter/nft_byteorder.c     | 13 ++++++++++---
+ 3 files changed, 31 insertions(+), 7 deletions(-)
+
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index ab0567951e3105..a1f828efc9e3de 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -188,6 +188,13 @@ static inline u64 nft_reg_load64(const u32 *sreg)
+       return get_unaligned((u64 *)sreg);
+ }
++static inline bool nft_reg_overlap(u8 src, u8 dst, u32 len)
++{
++      unsigned int n = DIV_ROUND_UP(len, sizeof(u32));
++
++      return src != dst && src < dst + n && dst < src + n;
++}
++
+ static inline void nft_data_copy(u32 *dst, const struct nft_data *src,
+                                unsigned int len)
+ {
+diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
+index af990c600745be..1afb36fb5994db 100644
+--- a/net/netfilter/nft_bitwise.c
++++ b/net/netfilter/nft_bitwise.c
+@@ -43,8 +43,10 @@ static void nft_bitwise_eval_lshift(u32 *dst, const u32 *src,
+       u32 carry = 0;
+       for (i = DIV_ROUND_UP(priv->len, sizeof(u32)); i > 0; i--) {
+-              dst[i - 1] = (src[i - 1] << shift) | carry;
+-              carry = src[i - 1] >> (BITS_PER_TYPE(u32) - shift);
++              u32 tmp_src = src[i - 1];
++
++              dst[i - 1] = (tmp_src << shift) | carry;
++              carry = tmp_src >> (BITS_PER_TYPE(u32) - shift);
+       }
+ }
+@@ -56,8 +58,10 @@ static void nft_bitwise_eval_rshift(u32 *dst, const u32 *src,
+       u32 carry = 0;
+       for (i = 0; i < DIV_ROUND_UP(priv->len, sizeof(u32)); i++) {
+-              dst[i] = carry | (src[i] >> shift);
+-              carry = src[i] << (BITS_PER_TYPE(u32) - shift);
++              u32 tmp_src = src[i];
++
++              dst[i] = carry | (tmp_src >> shift);
++              carry = tmp_src << (BITS_PER_TYPE(u32) - shift);
+       }
+ }
+@@ -235,6 +239,9 @@ static int nft_bitwise_init_bool(const struct nft_ctx *ctx,
+                                             &priv->sreg2, priv->len);
+               if (err < 0)
+                       return err;
++
++              if (nft_reg_overlap(priv->sreg2, priv->dreg, priv->len))
++                      return -EINVAL;
+       }
+       return 0;
+@@ -265,6 +272,9 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
+       if (err < 0)
+               return err;
++      if (nft_reg_overlap(priv->sreg, priv->dreg, priv->len))
++              return -EINVAL;
++
+       if (tb[NFTA_BITWISE_OP]) {
+               priv->op = ntohl(nla_get_be32(tb[NFTA_BITWISE_OP]));
+               switch (priv->op) {
+diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
+index 2f82a444d21bf3..51f5de5c4ca363 100644
+--- a/net/netfilter/nft_byteorder.c
++++ b/net/netfilter/nft_byteorder.c
+@@ -144,9 +144,16 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
+       if (err < 0)
+               return err;
+-      return nft_parse_register_store(ctx, tb[NFTA_BYTEORDER_DREG],
+-                                      &priv->dreg, NULL, NFT_DATA_VALUE,
+-                                      priv->len);
++      err = nft_parse_register_store(ctx, tb[NFTA_BYTEORDER_DREG],
++                                     &priv->dreg, NULL, NFT_DATA_VALUE,
++                                     priv->len);
++      if (err < 0)
++              return err;
++
++      if (nft_reg_overlap(priv->sreg, priv->dreg, priv->len))
++              return -EINVAL;
++
++      return 0;
+ }
+ static int nft_byteorder_dump(struct sk_buff *skb,
+-- 
+2.53.0
+
diff --git a/queue-6.6/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch b/queue-6.6/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
new file mode 100644 (file)
index 0000000..c2d0b03
--- /dev/null
@@ -0,0 +1,68 @@
+From 60f5b7b86f67777d92041c395866c1f3bec484cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 12:36:14 -0700
+Subject: netfilter: synproxy: refresh tcphdr after skb_ensure_writable
+
+From: Chris Mason <clm@meta.com>
+
+[ Upstream commit 92170e6afe927ab2792a3f71902845789c8e31b1 ]
+
+synproxy_tstamp_adjust() rewrites the TCP timestamp option in place
+and then patches the TCP checksum via inet_proto_csum_replace4() on
+the caller-supplied tcphdr pointer.  Both ipv4_synproxy_hook() and
+ipv6_synproxy_hook() obtain that pointer with skb_header_pointer()
+before calling in, so it may either alias skb->head directly or
+point at the caller's on-stack _tcph buffer.
+
+Between obtaining the pointer and using it, the function calls
+skb_ensure_writable(skb, optend), which on a cloned or non-linear
+skb invokes pskb_expand_head() and frees the old skb->head.  After
+that point the cached th is stale:
+
+    caller (ipv[46]_synproxy_hook)
+      th = skb_header_pointer(skb, ..., &_tcph)
+      synproxy_tstamp_adjust(skb, protoff, th, ...)
+        skb_ensure_writable(skb, optend)
+          pskb_expand_head()        /* kfree(old skb->head) */
+        ...
+        inet_proto_csum_replace4(&th->check, ...)
+                                    /* writes into freed head, or
+                                       into the caller's stack copy
+                                       leaving the on-wire checksum
+                                       stale */
+
+The option bytes are written through skb->data and are fine; only
+the checksum update goes through th and so lands in the wrong
+place.  The result is either a write into freed slab memory or a
+packet leaving with a checksum that does not match its payload.
+
+Fix by re-deriving th from skb->data + protoff immediately after
+skb_ensure_writable() succeeds, so the subsequent checksum update
+targets the linear, writable header.
+
+Fixes: 48b1de4c110a ("netfilter: add SYNPROXY core/target")
+Assisted-by: kres (claude-opus-4-7)
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-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_synproxy_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c
+index 16915f8eef2b16..f5a52075691faa 100644
+--- a/net/netfilter/nf_synproxy_core.c
++++ b/net/netfilter/nf_synproxy_core.c
+@@ -199,6 +199,8 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff,
+       if (skb_ensure_writable(skb, optend))
+               return 0;
++      th = (struct tcphdr *)(skb->data + protoff);
++
+       while (optoff < optend) {
+               unsigned char *op = skb->data + optoff;
+-- 
+2.53.0
+
diff --git a/queue-6.6/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch b/queue-6.6/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
new file mode 100644 (file)
index 0000000..fbd0129
--- /dev/null
@@ -0,0 +1,48 @@
+From 4e2a3c94b7263ec961465f8b43e8c84b2ab88f31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 20:10:08 +0200
+Subject: netfilter: xt_cpu: prefer raw_smp_processor_id
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit c376f07e16c02239ed44cabb97145d03f65b4d15 ]
+
+With PREEMPT_RCU we get splat:
+
+BUG: using smp_processor_id() in preemptible [..]
+caller is cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+CPU: 1 .. Comm: syz.3.1377 #0 PREEMPT(full)
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
+ check_preemption_disabled+0xd3/0xe0 lib/smp_processor_id.c:47
+ cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+ [..]
+
+Just use raw version instead.
+This is similar to 14d14a5d2957 ("netfilter: nft_meta: use raw_smp_processor_id()").
+
+Fixes: 0ca743a55991 ("netfilter: nf_tables: add compatibility layer for x_tables")
+Reported-by: syzbot+690d3e3ffa7335ac10eb@syzkaller.appspotmail.com
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_cpu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/xt_cpu.c b/net/netfilter/xt_cpu.c
+index 3bdc302a0f9137..9cb259902a586b 100644
+--- a/net/netfilter/xt_cpu.c
++++ b/net/netfilter/xt_cpu.c
+@@ -34,7 +34,7 @@ static bool cpu_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       const struct xt_cpu_info *info = par->matchinfo;
+-      return (info->cpu == smp_processor_id()) ^ info->invert;
++      return (info->cpu == raw_smp_processor_id()) ^ info->invert;
+ }
+ static struct xt_match cpu_mt_reg __read_mostly = {
+-- 
+2.53.0
+
diff --git a/queue-6.6/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch b/queue-6.6/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
new file mode 100644 (file)
index 0000000..07f19e2
--- /dev/null
@@ -0,0 +1,40 @@
+From a38f68916d1d39d9a3d46c7e2a44629e1273d820 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:41 +0000
+Subject: nfc: llcp: Fix use-after-free in llcp_sock_release()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit f4268b466190dae95a7585f69b4f1f8ad097632c ]
+
+llcp_sock_release() unconditionally unlinks the socket from the local
+sockets list.  However, if the socket is still in connecting state, it
+is on the connecting list.
+
+Fix this by checking the socket state and unlinking from the correct list.
+
+Fixes: b4011239a08e ("NFC: llcp: Fix non blocking sockets connections")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-1-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_sock.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index d5344563e525c9..cd1fdf0beefb6b 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -633,6 +633,8 @@ static int llcp_sock_release(struct socket *sock)
+       if (sock->type == SOCK_RAW)
+               nfc_llcp_sock_unlink(&local->raw_sockets, sk);
++      else if (sk->sk_state == LLCP_CONNECTING)
++              nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       else
+               nfc_llcp_sock_unlink(&local->sockets, sk);
+-- 
+2.53.0
+
diff --git a/queue-6.6/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch b/queue-6.6/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
new file mode 100644 (file)
index 0000000..cb4b990
--- /dev/null
@@ -0,0 +1,67 @@
+From 7b3ff0e2277e1abdc4ea650a01408ec636cd9fd5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:42 +0000
+Subject: nfc: llcp: Fix use-after-free race in nfc_llcp_recv_cc()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit b493ea2765cc17cb8aa7e7544a4b6dcb05b6ed77 ]
+
+A race condition exists in the NFC LLCP connection state machine where
+the connection acceptance packet (CC) can be processed concurrently with
+socket release.  This can lead to a use-after-free of the socket object.
+
+When nfc_llcp_recv_cc() moves the socket from the connecting_sockets
+list to the sockets list, it does so without holding the socket lock.
+If llcp_sock_release() is executing concurrently, it might have already
+unlinked the socket and dropped its references, which can result in
+nfc_llcp_recv_cc() linking a freed socket into the live list.
+
+Fix this by holding lock_sock() during the state transition and list
+movement in nfc_llcp_recv_cc().  After acquiring the lock, check if
+the socket is still hashed to ensure it hasn't already been unlinked
+and marked for destruction by the release path.  This aligns the locking
+pattern with recv_hdlc() and recv_disc().
+
+Fixes: a69f32af86e3 ("NFC: Socket linked list")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-2-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_core.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
+index d9562840fa180b..62b0f2d6686eb8 100644
+--- a/net/nfc/llcp_core.c
++++ b/net/nfc/llcp_core.c
+@@ -1216,6 +1216,15 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk = &llcp_sock->sk;
++      lock_sock(sk);
++
++      /* Check if socket was destroyed whilst waiting for the lock */
++      if (!sk_hashed(sk)) {
++              release_sock(sk);
++              nfc_llcp_sock_put(llcp_sock);
++              return;
++      }
++
+       /* Unlink from connecting and link to the client array */
+       nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       nfc_llcp_sock_link(&local->sockets, sk);
+@@ -1227,6 +1236,8 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk->sk_state = LLCP_CONNECTED;
+       sk->sk_state_change(sk);
++      release_sock(sk);
++
+       nfc_llcp_sock_put(llcp_sock);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.6/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch b/queue-6.6/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
new file mode 100644 (file)
index 0000000..7daf421
--- /dev/null
@@ -0,0 +1,83 @@
+From 65657174e5b814ac4163e28df16fc74f3f61b22c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 May 2026 19:55:18 +0800
+Subject: nfc: nxp-nci: i2c: use rising-edge IRQ on ACPI systems
+
+From: Carl Lee <carl.lee@amd.com>
+
+[ Upstream commit f23bf992d65a42007c517b060ca35cebdea3525a ]
+
+Some ACPI-based platforms report incorrect IRQ trigger types (e.g.
+IRQF_TRIGGER_HIGH), which can lead to interrupt storms.
+
+Use the historically working rising-edge trigger on ACPI systems to
+avoid this regression.
+
+Device Tree-based systems continue to use the firmware-provided
+trigger type.
+
+Fixes: 57be33f85e36 ("nfc: nxp-nci: remove interrupt trigger type")
+Signed-off-by: Carl Lee <carl.lee@amd.com>
+Tested-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Luca Stefani <luca.stefani.ge1@gmail.com>
+Link: https://patch.msgid.link/20260516-nfc-nxp-nci-i2c-restore-irq-trigger-fallback-v3-1-37ba4b6e9086@amd.com
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/nxp-nci/i2c.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c
+index 5ecbf3366a1de4..e80ce1b97bccc9 100644
+--- a/drivers/nfc/nxp-nci/i2c.c
++++ b/drivers/nfc/nxp-nci/i2c.c
+@@ -16,6 +16,7 @@
+ #include <linux/delay.h>
+ #include <linux/i2c.h>
+ #include <linux/interrupt.h>
++#include <linux/irq.h>
+ #include <linux/module.h>
+ #include <linux/nfc.h>
+ #include <linux/gpio/consumer.h>
+@@ -267,6 +268,7 @@ static int nxp_nci_i2c_probe(struct i2c_client *client)
+ {
+       struct device *dev = &client->dev;
+       struct nxp_nci_i2c_phy *phy;
++      unsigned long irqflags;
+       int r;
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+@@ -303,9 +305,26 @@ static int nxp_nci_i2c_probe(struct i2c_client *client)
+       if (r < 0)
+               return r;
++      /*
++       * ACPI platforms may report incorrect IRQ trigger types
++       * (e.g. level-high), which can lead to interrupt storms.
++       *
++       * Use the historically stable rising-edge trigger for ACPI devices.
++       *
++       * On non-ACPI systems (e.g. Device Tree), prefer the firmware-
++       * provided trigger type, falling back to rising-edge if not set.
++       */
++      if (ACPI_COMPANION(dev)) {
++              irqflags = IRQF_TRIGGER_RISING;
++      } else {
++              irqflags = irq_get_trigger_type(client->irq);
++              if (!irqflags)
++                      irqflags = IRQF_TRIGGER_RISING;
++      }
++
+       r = request_threaded_irq(client->irq, NULL,
+                                nxp_nci_i2c_irq_thread_fn,
+-                               IRQF_ONESHOT,
++                               irqflags | IRQF_ONESHOT,
+                                NXP_NCI_I2C_DRIVER_NAME, phy);
+       if (r < 0)
+               nfc_err(&client->dev, "Unable to register IRQ handler\n");
+-- 
+2.53.0
+
diff --git a/queue-6.6/scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch b/queue-6.6/scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch
new file mode 100644 (file)
index 0000000..06cb3ec
--- /dev/null
@@ -0,0 +1,80 @@
+From b2ff862b5bab1cbbb59bea693b346ba075aa8393 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 14:09:41 -0400
+Subject: scsi: core: Run queues for all non-SDEV_DEL devices from
+ scsi_run_host_queues
+
+From: David Jeffery <djeffery@redhat.com>
+
+[ Upstream commit 7205b58702273baf21d6ba7992e6ba15852325f7 ]
+
+While a SCSI host is in a recovery state, scsi_mq_requeue_cmd() will not
+set the requeue list for a requeued command to be kicked in the future.
+The expectation is a call to scsi_run_host_queues() will kick all SCSI
+devices once the recovery state is cleared.
+
+However, scsi_run_host_queues() uses shost_for_each_device() which uses
+scsi_device_get() and so will ignore devices in a partially removed
+state like SDEV_CANCEL. But these devices may also have requeued
+requests, leaving their requests stuck from not being kicked and causing
+the removal process of the device to hang.
+
+scsi_run_host_queues() needs to run against more devices than the macro
+shost_for_each_device() allows. Instead of using the too limiting
+scsi_device_get() state checks, only ignore devices in SDEV_DEL state or
+when unable to acquire a reference. Attempt to run the queues for all
+other devices when scsi_run_host_queues() is called.
+
+Fixes: 8b566edbdbfb ("scsi: core: Only kick the requeue list if necessary")
+Signed-off-by: David Jeffery <djeffery@redhat.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://patch.msgid.link/20260515180941.9698-1-djeffery@redhat.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_lib.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index efd1f1d6e4e9b0..2268e540f28ae6 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -474,10 +474,33 @@ void scsi_requeue_run_queue(struct work_struct *work)
+ void scsi_run_host_queues(struct Scsi_Host *shost)
+ {
+-      struct scsi_device *sdev;
++      struct scsi_device *sdev, *prev = NULL;
++      unsigned long flags;
+-      shost_for_each_device(sdev, shost)
++      spin_lock_irqsave(shost->host_lock, flags);
++      __shost_for_each_device(sdev, shost) {
++              /*
++               * Only skip devices so deep into removal they will never need
++               * another kick to their queues. Thus scsi_device_get() cannot
++               * be used as it would skip devices in SDEV_CANCEL state which
++               * may need a queue kick.
++               */
++              if (sdev->sdev_state == SDEV_DEL ||
++                  !get_device(&sdev->sdev_gendev))
++                      continue;
++              spin_unlock_irqrestore(shost->host_lock, flags);
++
++              if (prev)
++                      put_device(&prev->sdev_gendev);
+               scsi_run_queue(sdev->request_queue);
++
++              prev = sdev;
++
++              spin_lock_irqsave(shost->host_lock, flags);
++      }
++      spin_unlock_irqrestore(shost->host_lock, flags);
++      if (prev)
++              put_device(&prev->sdev_gendev);
+ }
+ static void scsi_uninit_cmd(struct scsi_cmnd *cmd)
+-- 
+2.53.0
+
diff --git a/queue-6.6/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch b/queue-6.6/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
new file mode 100644 (file)
index 0000000..2a35004
--- /dev/null
@@ -0,0 +1,50 @@
+From e9a67f38739eecd796cab49524a8436f3a8679bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 11:24:11 +0800
+Subject: sctp: fix race between sctp_wait_for_connect and peeloff
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit f14fe6395a8b3d961a61e138ad7b36ba3626dd4e ]
+
+sctp_wait_for_connect() drops and re-acquires the socket lock while
+waiting for the association to reach ESTABLISHED state. During this
+window, another thread can peeloff the association to a new socket via
+getsockopt(SCTP_SOCKOPT_PEELOFF), changing asoc->base.sk. After
+re-acquiring the old socket lock, sctp_wait_for_connect() returns
+success without noticing the migration â€” the caller then accesses
+the association under the wrong lock in sctp_datamsg_from_user().
+
+Add the same sk != asoc->base.sk check that sctp_wait_for_sndbuf()
+already has, returning an error if the association was migrated while
+we slept.
+
+Fixes: 668c9beb9020 ("sctp: implement assign_number for sctp_stream_interleave")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260527032411.60959-1-kipreyyy@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/socket.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 98586bcf83cebe..a6a53b0c4ea324 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -9371,6 +9371,8 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p)
+               release_sock(sk);
+               current_timeo = schedule_timeout(current_timeo);
+               lock_sock(sk);
++              if (sk != asoc->base.sk)
++                      goto do_error;
+               *timeo_p = current_timeo;
+       }
+-- 
+2.53.0
+
index 3a056ff01ae266b2ba7a4d1b070e6598047c6587..f28fade55c48dad6694c40316d92031ccb975ea8 100644 (file)
@@ -4,3 +4,45 @@ net-sched-sch_sfb-replace-direct-dequeue-call-with-p.patch
 drm-remove-plane-hsub-vsub-alignment-requirement-for.patch
 bcache-fix-uninitialized-closure-object.patch
 net-cpsw_new-fix-potential-unregister-of-netdev-that.patch
+nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
+nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
+xfrm-check-for-underflow-in-xfrm_state_mtu.patch
+nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
+kernel-fork-validate-exit_signal-in-kernel_clone.patch
+netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
+netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
+netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
+netfilter-bitwise-rename-some-boolean-operation-func.patch
+netfilter-bitwise-add-support-for-doing-and-or-and-x.patch
+netfilter-nf_tables-fix-dst-corruption-in-same-regis.patch
+tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
+tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch
+vsock-keep-poll-shutdown-state-consistent.patch
+net-netlink-fix-sending-unassigned-nsid-after-assign.patch
+net-netlink-don-t-set-nsid-on-local-notifications.patch
+net-smc-do-not-re-initialize-smc-hashtables.patch
+net-iucv-fix-locking-in-.getsockopt.patch
+scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch
+ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
+asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
+net-hsr-fix-potential-oob-access-in-supervision-fram.patch
+gpio-mxc-fix-irq_high-handling.patch
+tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
+vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
+tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
+ksmbd-fix-fsctl-permission-bypass-by-adding-a-permis.patch
+asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
+bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
+bonding-refuse-to-enslave-can-devices.patch
+ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch
+ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
+ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
+net-sched-revert-net-sched-restrict-conditions-for-a.patch
+bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
+bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
+gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
+net-mana-add-null-guards-in-teardown-path-to-prevent.patch
+sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
+ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch
+ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch
+net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch
diff --git a/queue-6.6/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch b/queue-6.6/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch
new file mode 100644 (file)
index 0000000..71d57cc
--- /dev/null
@@ -0,0 +1,47 @@
+From d5da23d77f7e9b7ee19a8b1d038f68204ffd9211 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 09:33:13 -0700
+Subject: tun: free page on build_skb failure in tun_xdp_one()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit aa8963fdce667a42fb7f0bdd2909fadcab02f9a8 ]
+
+When build_skb() fails in tun_xdp_one(), the function sets ret to
+-ENOMEM and jumps to the out label, which returns without freeing the
+page that vhost_net_build_xdp() allocated for the frame. As with the
+short-frame rejection path, tun_sendmsg() discards the per-buffer error
+and still returns total_len, so vhost_tx_batch() takes the success path
+and never frees the page. Each build_skb() failure in a batch leaks one
+page-frag chunk.
+
+Free the page before taking the error path, matching the put_page() the
+other error exits of tun_xdp_one() already perform.
+
+Fixes: 043d222f93ab ("tuntap: accept an array of XDP buffs through sendmsg()")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260521163312.1479805-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 88b704b5d0b26e..9a4192d6a4cabf 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2505,6 +2505,7 @@ static int tun_xdp_one(struct tun_struct *tun,
+ build:
+       skb = build_skb(xdp->data_hard_start, buflen);
+       if (!skb) {
++              put_page(virt_to_head_page(xdp->data));
+               ret = -ENOMEM;
+               goto out;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.6/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch b/queue-6.6/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
new file mode 100644 (file)
index 0000000..3dc4b7a
--- /dev/null
@@ -0,0 +1,54 @@
+From eb77e551673698e972547a5d6b8b5424865bd829 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 09:00:21 -0700
+Subject: tun: free page on short-frame rejection in tun_xdp_one()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f4feb1e20058e407cb00f45aff47f5b7e19a6bbf ]
+
+tun_xdp_one() returns -EINVAL on a frame shorter than ETH_HLEN without
+freeing the page that vhost_net_build_xdp() allocated for it.
+tun_sendmsg() discards that -EINVAL and still returns total_len, so
+vhost_tx_batch() takes the success path and never frees the page; each
+short frame in a batch leaks one page-frag chunk.
+
+A local process that can open /dev/net/tun and /dev/vhost-net can hit
+this path: it attaches a tun/tap device as the vhost-net backend and
+feeds TX descriptors whose length minus the virtio-net header is below
+ETH_HLEN. Each kick leaks the page-frag chunks for that batch, and a
+tight submission loop exhausts host memory and triggers an OOM panic.
+Free the page before returning -EINVAL, matching the XDP-program error
+path in the same function.
+
+Fixes: 049584807f1d ("tun: add missing verification for short frame")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260520160020.375349-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 97dbec8d78077d..88b704b5d0b26e 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2459,8 +2459,10 @@ static int tun_xdp_one(struct tun_struct *tun,
+       bool skb_xdp = false;
+       struct page *page;
+-      if (unlikely(datasize < ETH_HLEN))
++      if (unlikely(datasize < ETH_HLEN)) {
++              put_page(virt_to_head_page(xdp->data));
+               return -EINVAL;
++      }
+       xdp_prog = rcu_dereference(tun->xdp_prog);
+       if (xdp_prog) {
+-- 
+2.53.0
+
diff --git a/queue-6.6/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch b/queue-6.6/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
new file mode 100644 (file)
index 0000000..10cdb21
--- /dev/null
@@ -0,0 +1,67 @@
+From 98d3272a7d817488ae912183d0f8eb90d61d511e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 11:55:12 +0000
+Subject: tunnels: do not assume transport header in
+ iptunnel_pmtud_check_icmp()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 509323077ef79a26ba0c60bb556e45c12c398b2d ]
+
+In some cases, iptunnel_pmtud_check_icmp() can be called while
+skb transport header is not set.
+
+This triggers an out-of-bound access, because
+(typeof(skb->transport_header))~0U is 65535.
+
+Access the icmp header based on IPv4 network header,
+after making sure icmp->type is present in skb linear part.
+
+Note that iptunnel_pmtud_check_icmpv6()) is fine.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Reported-by: Damiano Melotti <melotti@google.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260522115512.1519110-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index 5fb437f040ace7..9f6f1b435d8d72 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -262,7 +262,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct icmphdr *icmph = icmp_hdr(skb);
+       const struct iphdr *iph = ip_hdr(skb);
+       if (mtu < 576 || iph->frag_off != htons(IP_DF))
+@@ -273,9 +272,17 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+           ipv4_is_lbcast(iph->saddr)  || ipv4_is_multicast(iph->saddr))
+               return 0;
+-      if (iph->protocol == IPPROTO_ICMP && icmp_is_err(icmph->type))
+-              return 0;
++      if (iph->protocol == IPPROTO_ICMP) {
++              const struct icmphdr *icmph;
++              if (!pskb_network_may_pull(skb, iph->ihl * 4 +
++                                              offsetofend(struct icmphdr, type)))
++                      return 0;
++              iph = ip_hdr(skb);
++              icmph = (void *)iph + iph->ihl * 4;
++              if (icmp_is_err(icmph->type))
++                      return 0;
++      }
+       return iptunnel_pmtud_build_icmp(skb, mtu);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.6/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch b/queue-6.6/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
new file mode 100644 (file)
index 0000000..7dd1ba6
--- /dev/null
@@ -0,0 +1,87 @@
+From 1025d6fb4e752d1157c1da2f519f180a440a94f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:13:35 +0000
+Subject: tunnels: load network headers after skb_cow() in
+ iptunnel_pmtud_build_icmp[v6]()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b4bc94353050b1fa7b702bd4c6600710dd926cff ]
+
+Sashiko found that iptunnel_pmtud_build_icmp() and
+iptunnel_pmtud_build_icmpv6() were caching ip_hdr() and ipv6_hdr()
+before an skb_cow() call which can reallocate skb->head.
+
+Fix this possible UAF by initializing the local variables
+after the skb_cow() call.
+
+Remove skb_reset_network_header() calls which were not needed.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525201335.2361845-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index 75e3d7501752df..5fb437f040ace7 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -194,7 +194,7 @@ EXPORT_SYMBOL_GPL(iptunnel_handle_offloads);
+  */
+ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct iphdr *iph = ip_hdr(skb);
++      const struct iphdr *iph;
+       struct icmphdr *icmph;
+       struct iphdr *niph;
+       struct ethhdr eh;
+@@ -208,7 +208,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, 576 - sizeof(*niph) - sizeof(*icmph));
+       if (err)
+@@ -218,7 +217,7 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       err = skb_cow(skb, sizeof(*niph) + sizeof(*icmph) + ETH_HLEN);
+       if (err)
+               return err;
+-
++      iph = ip_hdr(skb);
+       icmph = skb_push(skb, sizeof(*icmph));
+       *icmph = (struct icmphdr) {
+               .type                   = ICMP_DEST_UNREACH,
+@@ -290,7 +289,7 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+ {
+-      const struct ipv6hdr *ip6h = ipv6_hdr(skb);
++      const struct ipv6hdr *ip6h;
+       struct icmp6hdr *icmp6h;
+       struct ipv6hdr *nip6h;
+       struct ethhdr eh;
+@@ -305,7 +304,6 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, IPV6_MIN_MTU - sizeof(*nip6h) - sizeof(*icmp6h));
+       if (err)
+@@ -316,6 +314,7 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       if (err)
+               return err;
++      ip6h = ipv6_hdr(skb);
+       icmp6h = skb_push(skb, sizeof(*icmp6h));
+       *icmp6h = (struct icmp6hdr) {
+               .icmp6_type             = ICMPV6_PKT_TOOBIG,
+-- 
+2.53.0
+
diff --git a/queue-6.6/vsock-keep-poll-shutdown-state-consistent.patch b/queue-6.6/vsock-keep-poll-shutdown-state-consistent.patch
new file mode 100644 (file)
index 0000000..f777d8c
--- /dev/null
@@ -0,0 +1,247 @@
+From ac849fac58ec871af3d1e59c66b0a5459f5c24b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 00:56:36 +0800
+Subject: vsock: keep poll shutdown state consistent
+
+From: Ziyu Zhang <ziyuzhang201@gmail.com>
+
+[ Upstream commit aae9d8a5528b8ee9ff8dc5d3558b8a9f852a724a ]
+
+vsock_poll() reads vsk->peer_shutdown before taking the socket lock
+to set EPOLLHUP and EPOLLRDHUP, then reads it again after taking
+the lock to report EOF readability. A shutdown packet can update
+peer_shutdown while poll is waiting for the lock, so one poll invocation
+can report EOF readability without the corresponding HUP/RDHUP bits.
+
+For connectible sockets, take one peer_shutdown snapshot after
+lock_sock() and use it for all peer-shutdown-derived poll bits. For
+datagram sockets, which do not take lock_sock() in poll(), take one
+lockless READ_ONCE() snapshot and pair it with WRITE_ONCE() on the
+writer side.
+
+This keeps the peer-shutdown-derived bits internally consistent for each
+poll pass.
+
+Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
+Signed-off-by: Ziyu Zhang <ziyuzhang201@gmail.com>
+Link: https://patch.msgid.link/20260519165636.62542-1-ziyuzhang201@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/vmw_vsock/af_vsock.c                | 49 ++++++++++++++++---------
+ net/vmw_vsock/hyperv_transport.c        |  9 +++--
+ net/vmw_vsock/virtio_transport_common.c | 14 ++++---
+ net/vmw_vsock/vmci_transport.c          |  8 ++--
+ 4 files changed, 52 insertions(+), 28 deletions(-)
+
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index 187cc259f820b5..a06f708f300c4a 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -522,7 +522,7 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
+                */
+               sock_reset_flag(sk, SOCK_DONE);
+               sk->sk_state = TCP_CLOSE;
+-              vsk->peer_shutdown = 0;
++              WRITE_ONCE(vsk->peer_shutdown, 0);
+       }
+       if (sk->sk_type == SOCK_SEQPACKET) {
+@@ -813,7 +813,7 @@ static struct sock *__vsock_create(struct net *net,
+       vsk->rejected = false;
+       vsk->sent_request = false;
+       vsk->ignore_connecting_rst = false;
+-      vsk->peer_shutdown = 0;
++      WRITE_ONCE(vsk->peer_shutdown, 0);
+       INIT_DELAYED_WORK(&vsk->connect_work, vsock_connect_timeout);
+       INIT_DELAYED_WORK(&vsk->pending_work, vsock_pending_work);
+@@ -1095,6 +1095,25 @@ static int vsock_shutdown(struct socket *sock, int mode)
+       return err;
+ }
++static __poll_t vsock_poll_shutdown(struct sock *sk, u32 peer_shutdown)
++{
++      __poll_t mask = 0;
++
++      /* INET sockets treat local write shutdown and peer write shutdown as a
++       * case of EPOLLHUP set.
++       */
++      if (sk->sk_shutdown == SHUTDOWN_MASK ||
++          ((sk->sk_shutdown & SEND_SHUTDOWN) &&
++           (peer_shutdown & SEND_SHUTDOWN)))
++              mask |= EPOLLHUP;
++
++      if (sk->sk_shutdown & RCV_SHUTDOWN ||
++          peer_shutdown & SEND_SHUTDOWN)
++              mask |= EPOLLRDHUP;
++
++      return mask;
++}
++
+ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+                              poll_table *wait)
+ {
+@@ -1112,24 +1131,17 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+               /* Signify that there has been an error on this socket. */
+               mask |= EPOLLERR;
+-      /* INET sockets treat local write shutdown and peer write shutdown as a
+-       * case of EPOLLHUP set.
+-       */
+-      if ((sk->sk_shutdown == SHUTDOWN_MASK) ||
+-          ((sk->sk_shutdown & SEND_SHUTDOWN) &&
+-           (vsk->peer_shutdown & SEND_SHUTDOWN))) {
+-              mask |= EPOLLHUP;
+-      }
+-
+-      if (sk->sk_shutdown & RCV_SHUTDOWN ||
+-          vsk->peer_shutdown & SEND_SHUTDOWN) {
+-              mask |= EPOLLRDHUP;
+-      }
+-
+       if (sk_is_readable(sk))
+               mask |= EPOLLIN | EPOLLRDNORM;
+       if (sock->type == SOCK_DGRAM) {
++              u32 peer_shutdown = READ_ONCE(vsk->peer_shutdown);
++
++              /* DGRAM sockets do not take lock_sock() in poll(), so use one
++               * lockless snapshot for all shutdown-derived mask bits.
++               */
++              mask |= vsock_poll_shutdown(sk, peer_shutdown);
++
+               /* For datagram sockets we can read if there is something in
+                * the queue and write as long as the socket isn't shutdown for
+                * sending.
+@@ -1144,6 +1156,7 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+       } else if (sock_type_connectible(sk->sk_type)) {
+               const struct vsock_transport *transport;
++              u32 peer_shutdown;
+               lock_sock(sk);
+@@ -1176,8 +1189,10 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+                * terminated should also be considered read, and we check the
+                * shutdown flag for that.
+                */
++              peer_shutdown = READ_ONCE(vsk->peer_shutdown);
++              mask |= vsock_poll_shutdown(sk, peer_shutdown);
+               if (sk->sk_shutdown & RCV_SHUTDOWN ||
+-                  vsk->peer_shutdown & SEND_SHUTDOWN) {
++                  peer_shutdown & SEND_SHUTDOWN) {
+                       mask |= EPOLLIN | EPOLLRDNORM;
+               }
+diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
+index 34871ed1a099c6..865e004ee286f2 100644
+--- a/net/vmw_vsock/hyperv_transport.c
++++ b/net/vmw_vsock/hyperv_transport.c
+@@ -264,7 +264,7 @@ static void hvs_do_close_lock_held(struct vsock_sock *vsk,
+       struct sock *sk = sk_vsock(vsk);
+       sock_set_flag(sk, SOCK_DONE);
+-      vsk->peer_shutdown = SHUTDOWN_MASK;
++      WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+       if (vsock_stream_has_data(vsk) <= 0)
+               sk->sk_state = TCP_CLOSING;
+       sk->sk_state_change(sk);
+@@ -593,7 +593,9 @@ static int hvs_update_recv_data(struct hvsock *hvs)
+               return -EIO;
+       if (payload_len == 0)
+-              hvs->vsk->peer_shutdown |= SEND_SHUTDOWN;
++              WRITE_ONCE(hvs->vsk->peer_shutdown,
++                         READ_ONCE(hvs->vsk->peer_shutdown) |
++                         SEND_SHUTDOWN);
+       hvs->recv_data_len = payload_len;
+       hvs->recv_data_off = 0;
+@@ -704,7 +706,8 @@ static s64 hvs_stream_has_data(struct vsock_sock *vsk)
+               ret = 1;
+               break;
+       case 0:
+-              vsk->peer_shutdown |= SEND_SHUTDOWN;
++              WRITE_ONCE(vsk->peer_shutdown,
++                         READ_ONCE(vsk->peer_shutdown) | SEND_SHUTDOWN);
+               ret = 0;
+               break;
+       default: /* -1 */
+diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
+index d4ff9506eaf6d5..16431ef52799db 100644
+--- a/net/vmw_vsock/virtio_transport_common.c
++++ b/net/vmw_vsock/virtio_transport_common.c
+@@ -1043,7 +1043,7 @@ static void virtio_transport_do_close(struct vsock_sock *vsk,
+       struct sock *sk = sk_vsock(vsk);
+       sock_set_flag(sk, SOCK_DONE);
+-      vsk->peer_shutdown = SHUTDOWN_MASK;
++      WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+       if (vsock_stream_has_data(vsk) <= 0)
+               sk->sk_state = TCP_CLOSING;
+       sk->sk_state_change(sk);
+@@ -1244,12 +1244,15 @@ virtio_transport_recv_connected(struct sock *sk,
+       case VIRTIO_VSOCK_OP_CREDIT_UPDATE:
+               sk->sk_write_space(sk);
+               break;
+-      case VIRTIO_VSOCK_OP_SHUTDOWN:
++      case VIRTIO_VSOCK_OP_SHUTDOWN: {
++              u32 peer_shutdown = READ_ONCE(vsk->peer_shutdown);
++
+               if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SHUTDOWN_RCV)
+-                      vsk->peer_shutdown |= RCV_SHUTDOWN;
++                      peer_shutdown |= RCV_SHUTDOWN;
+               if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SHUTDOWN_SEND)
+-                      vsk->peer_shutdown |= SEND_SHUTDOWN;
+-              if (vsk->peer_shutdown == SHUTDOWN_MASK) {
++                      peer_shutdown |= SEND_SHUTDOWN;
++              WRITE_ONCE(vsk->peer_shutdown, peer_shutdown);
++              if (peer_shutdown == SHUTDOWN_MASK) {
+                       if (vsock_stream_has_data(vsk) <= 0 && !sock_flag(sk, SOCK_DONE)) {
+                               (void)virtio_transport_reset(vsk, NULL);
+                               virtio_transport_do_close(vsk, true);
+@@ -1264,6 +1267,7 @@ virtio_transport_recv_connected(struct sock *sk,
+               if (le32_to_cpu(virtio_vsock_hdr(skb)->flags))
+                       sk->sk_state_change(sk);
+               break;
++      }
+       case VIRTIO_VSOCK_OP_RST:
+               virtio_transport_do_close(vsk, true);
+               break;
+diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
+index 4cd11f355e9d6b..443125e48f2481 100644
+--- a/net/vmw_vsock/vmci_transport.c
++++ b/net/vmw_vsock/vmci_transport.c
+@@ -811,7 +811,7 @@ static void vmci_transport_handle_detach(struct sock *sk)
+               /* On a detach the peer will not be sending or receiving
+                * anymore.
+                */
+-              vsk->peer_shutdown = SHUTDOWN_MASK;
++              WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+               /* We should not be sending anymore since the peer won't be
+                * there to receive, but we can still receive if there is data
+@@ -1534,7 +1534,9 @@ static int vmci_transport_recv_connected(struct sock *sk,
+               if (pkt->u.mode) {
+                       vsk = vsock_sk(sk);
+-                      vsk->peer_shutdown |= pkt->u.mode;
++                      WRITE_ONCE(vsk->peer_shutdown,
++                                 READ_ONCE(vsk->peer_shutdown) |
++                                 pkt->u.mode);
+                       sk->sk_state_change(sk);
+               }
+               break;
+@@ -1551,7 +1553,7 @@ static int vmci_transport_recv_connected(struct sock *sk,
+                * a clean shutdown.
+                */
+               sock_set_flag(sk, SOCK_DONE);
+-              vsk->peer_shutdown = SHUTDOWN_MASK;
++              WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+               if (vsock_stream_has_data(vsk) <= 0)
+                       sk->sk_state = TCP_CLOSING;
+-- 
+2.53.0
+
diff --git a/queue-6.6/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch b/queue-6.6/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
new file mode 100644 (file)
index 0000000..4f9733c
--- /dev/null
@@ -0,0 +1,54 @@
+From 2dd2376124ba04bd65611ef2192912e42c3ca6df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:36:42 +0000
+Subject: vxlan: do not reuse cached ip_hdr() value after
+ skb_tunnel_check_pmtu()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 7d9ef0cb271555d8cf39fefe6c981e1493b25ecf ]
+
+skb_tunnel_check_pmtu() can change skb->head.
+
+Reusing old_iph afer skb_tunnel_check_pmtu() can cause an UAF.
+
+Use instead ip_hdr(skb) as done in drivers/net/bareudp.c
+and drivers/net/geneve.c.
+
+Found by Sashiko.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525203642.2389723-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vxlan/vxlan_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
+index 1a973dcf256127..958d3be4f99086 100644
+--- a/drivers/net/vxlan/vxlan_core.c
++++ b/drivers/net/vxlan/vxlan_core.c
+@@ -2607,7 +2607,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr),
+                                     vni, md, flags, udp_sum);
+@@ -2670,7 +2670,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip6_dst_hoplimit(ndst);
+               skb_scrub_packet(skb, xnet);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
+-- 
+2.53.0
+
diff --git a/queue-6.6/xfrm-check-for-underflow-in-xfrm_state_mtu.patch b/queue-6.6/xfrm-check-for-underflow-in-xfrm_state_mtu.patch
new file mode 100644 (file)
index 0000000..bae8be8
--- /dev/null
@@ -0,0 +1,85 @@
+From cf3c217fc7e297fc037e31a97775ef5f341a6978 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 10:49:14 -0600
+Subject: xfrm: Check for underflow in xfrm_state_mtu
+
+From: David Ahern <dahern@nvidia.com>
+
+[ Upstream commit 742b04d0550b0ec89dcbc99537ec88653bd1ad90 ]
+
+Leo Lin reported OOB write issue in esp component:
+
+  xfrm_state_mtu() returns u32 but performs its arithmetic in unsigned
+  modulo-2^32 space using an attacker-influenced "header_len + authsize +
+  net_adj" subtracted from a small "mtu" argument. A nobody user can
+  install an IPv4 ESP tunnel SA with a large authentication key
+  (XFRMA_ALG_AUTH_TRUNC, e.g. hmac(sha512), 64-byte key, 64-byte trunc),
+  configure a small interface MTU (68 bytes), and set XFRMA_TFCPAD to a
+  large value. When a single UDP datagram is then sent through the
+  tunnel, xfrm_state_mtu() underflows to a near-2^32 value, and
+  esp_output() consumes it as a signed int via:
+
+        padto      = min(x->tfcpad, xfrm_state_mtu(x, mtu_cached))
+        esp.tfclen = padto - skb->len   (assigned to int)
+
+  esp.tfclen ends up negative (e.g. -207). It is sign-extended to size_t
+  when passed to memset() inside esp_output_fill_trailer(), producing a
+  ~16 EB write of zeroes at skb_tail_pointer(skb). KASAN logs it as
+  "Write of size 18446744073709551537 at addr ffff888...".
+
+Check for underflow and return 1. This causes the sendmsg attempt to
+fail with ENETUNREACH.
+
+Fixes: c5c252389374 ("[XFRM]: Optimize MTU calculation")
+Reported-by: Leo Lin <leo@depthfirst.com>
+Assisted-by: Codex:26.506.31004
+Signed-off-by: David Ahern <dahern@nvidia.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 8ba31cf9b31993..6e8860779e2154 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -2860,10 +2860,14 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+       const struct xfrm_type *type = READ_ONCE(x->type);
+       struct crypto_aead *aead;
+       u32 blksize, net_adj = 0;
++      u32 overhead, payload_mtu;
+       if (x->km.state != XFRM_STATE_VALID ||
+-          !type || type->proto != IPPROTO_ESP)
++          !type || type->proto != IPPROTO_ESP) {
++              if (mtu <= x->props.header_len)
++                      return 1;
+               return mtu - x->props.header_len;
++      }
+       aead = x->data;
+       blksize = ALIGN(crypto_aead_blocksize(aead), 4);
+@@ -2883,8 +2887,17 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+               break;
+       }
+-      return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
+-               net_adj) & ~(blksize - 1)) + net_adj - 2;
++      overhead = x->props.header_len + crypto_aead_authsize(aead) + net_adj;
++      if (mtu <= overhead)
++              return 1;
++
++      payload_mtu = mtu - overhead;
++      payload_mtu &= ~(blksize - 1);
++      if (payload_mtu <= 2)
++              return 1;
++
++      return payload_mtu + net_adj - 2;
++
+ }
+ EXPORT_SYMBOL_GPL(xfrm_state_mtu);
+-- 
+2.53.0
+
diff --git a/queue-7.0/accel-ivpu-prevent-uninitialized-data-bug-in-debugfs.patch b/queue-7.0/accel-ivpu-prevent-uninitialized-data-bug-in-debugfs.patch
new file mode 100644 (file)
index 0000000..aa8f015
--- /dev/null
@@ -0,0 +1,40 @@
+From 564b0913fb1d645c6cc17421362708ea1aa98154 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 10:14:42 +0300
+Subject: accel/ivpu: prevent uninitialized data bug in debugfs
+
+From: Dan Carpenter <error27@gmail.com>
+
+[ Upstream commit 44e151be23deb788d9f6124de93823faf6e04e99 ]
+
+The simple_write_to_buffer() will only initialize data starting from
+the *pos offset so if it's non-zero then the first part of the buffer
+uninitialized.  Really, if *pos is non-zero then this code won't work
+so just check for that at the start of the function.
+
+Fixes: 320323d2e545 ("accel/ivpu: Add debugfs interface for setting HWS priority bands")
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Reviewed-by: Karol Wachowski <karol.wachowski@linux.intel.com>
+Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
+Link: https://patch.msgid.link/ahP24m6Mii9EDL7Q@stanley.mountain
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/ivpu/ivpu_debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c
+index a09f54fc430206..e93883914bc274 100644
+--- a/drivers/accel/ivpu/ivpu_debugfs.c
++++ b/drivers/accel/ivpu/ivpu_debugfs.c
+@@ -440,7 +440,7 @@ priority_bands_fops_write(struct file *file, const char __user *user_buf, size_t
+       u32 band;
+       int ret;
+-      if (size >= sizeof(buf))
++      if (*pos != 0 || size >= sizeof(buf))
+               return -EINVAL;
+       ret = simple_write_to_buffer(buf, sizeof(buf) - 1, pos, user_buf, size);
+-- 
+2.53.0
+
diff --git a/queue-7.0/accel-rocket-fix-uaf-via-dangling-gem-handle-in-crea.patch b/queue-7.0/accel-rocket-fix-uaf-via-dangling-gem-handle-in-crea.patch
new file mode 100644 (file)
index 0000000..0de20fa
--- /dev/null
@@ -0,0 +1,86 @@
+From 2bb0f440aee93dcf22269b22a0b3361c206510ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 00:00:00 +0530
+Subject: accel/rocket: fix UAF via dangling GEM handle in create_bo
+
+From: Dhabaleshwar Das <dhabal123@gmail.com>
+
+[ Upstream commit f706e6a4ce75585af979aec3dcbdce68bc76306b ]
+
+rocket_ioctl_create_bo() inserts a GEM handle into the file's IDR via
+drm_gem_handle_create() early on, then performs several operations that
+can fail (sgt allocation, drm_mm insert, iommu_map). If any fail after
+the handle is live, the error path calls drm_gem_shmem_object_free()
+which kfree's the object without removing the handle from the IDR.
+
+This leaves a dangling handle pointing to freed slab memory. Any
+subsequent ioctl using that handle (PREP_BO, FINI_BO, SUBMIT) calls
+drm_gem_object_lookup() and dereferences freed memory (UAF).
+
+Fix by moving drm_gem_handle_create() to after all fallible operations
+succeed, matching the pattern used by panfrost, lima, and etnaviv.
+
+Also fix drm_mm_insert_node_generic() whose return value was silently
+overwritten by iommu_map_sgtable() on the next line. Add the missing
+error check.
+
+[tomeu: Move handle creation to the very end]
+
+Fixes: 658ebeac3351 ("accel/rocket: Add IOCTL for BO creation")
+Reported-by: Dhabaleshwar Das <dhabal123@gmail.com>
+Signed-off-by: Dhabaleshwar Das <dhabal123@gmail.com>
+Reviewed-by: Tomeu Vizoso <tomeu@tomeuvizoso.net>
+Link: https://patch.msgid.link/20260521165720.2113571-1-tomeu@tomeuvizoso.net
+Signed-off-by: Tomeu Vizoso <tomeu@tomeuvizoso.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/rocket/rocket_gem.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/accel/rocket/rocket_gem.c b/drivers/accel/rocket/rocket_gem.c
+index c8084719208a2a..a5fffa51ff3550 100644
+--- a/drivers/accel/rocket/rocket_gem.c
++++ b/drivers/accel/rocket/rocket_gem.c
+@@ -79,11 +79,6 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file *
+       rkt_obj->size = args->size;
+       rkt_obj->offset = 0;
+-      ret = drm_gem_handle_create(file, gem_obj, &args->handle);
+-      drm_gem_object_put(gem_obj);
+-      if (ret)
+-              goto err;
+-
+       sgt = drm_gem_shmem_get_pages_sgt(shmem_obj);
+       if (IS_ERR(sgt)) {
+               ret = PTR_ERR(sgt);
+@@ -95,6 +90,8 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file *
+                                        rkt_obj->size, PAGE_SIZE,
+                                        0, 0);
+       mutex_unlock(&rocket_priv->mm_lock);
++      if (ret)
++              goto err;
+       ret = iommu_map_sgtable(rocket_priv->domain->domain,
+                               rkt_obj->mm.start,
+@@ -112,8 +109,18 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file *
+       args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
+       args->dma_address = rkt_obj->mm.start;
++      ret = drm_gem_handle_create(file, gem_obj, &args->handle);
++      if (ret)
++              goto err_unmap;
++
++      drm_gem_object_put(gem_obj);
++
+       return 0;
++err_unmap:
++      iommu_unmap(rocket_priv->domain->domain,
++                  rkt_obj->mm.start, rkt_obj->size);
++
+ err_remove_node:
+       mutex_lock(&rocket_priv->mm_lock);
+       drm_mm_remove_node(&rkt_obj->mm);
+-- 
+2.53.0
+
diff --git a/queue-7.0/alsa-hda-cs35l56-fix-system-name-string-leaks.patch b/queue-7.0/alsa-hda-cs35l56-fix-system-name-string-leaks.patch
new file mode 100644 (file)
index 0000000..071478c
--- /dev/null
@@ -0,0 +1,92 @@
+From ed968acc372b417b96251efb0f17cb4b2fab8177 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 09:49:30 -0300
+Subject: ALSA: hda: cs35l56: Fix system name string leaks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit a0d9e8df2ebca290c2efff70abc05426e5a476b0 ]
+
+cs35l56_hda_read_acpi() gets an allocated ACPI _SUB string from
+acpi_get_subsystem_id(). On success, that string is used to create the
+firmware system name.
+
+Several error paths after the _SUB lookup can return without releasing
+the allocated string. This includes speaker ID lookup errors other than
+-ENOENT, and errors after a firmware system name has been allocated.
+
+Use scoped cleanup for the temporary _SUB string and make
+cs35l56->system_name device-managed. This releases the temporary _SUB
+string on every error path and lets devres release the firmware system
+name on probe failure and device removal.
+
+Fixes: 6f03b446cbae ("ALSA: hda: cs35l56: Add support for speaker id")
+Fixes: 40b1c2f9b299 ("ALSA: hda/cs35l56: Workaround bad dev-index on Lenovo Yoga Book 9i GenX")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Reviewed-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20260522-alsa-cs35l56-system-name-leak-v4-1-a6154dd09cd9@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/hda/codecs/side-codecs/cs35l56_hda.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/sound/hda/codecs/side-codecs/cs35l56_hda.c b/sound/hda/codecs/side-codecs/cs35l56_hda.c
+index cdbc576569efee..a0ea08eb96a93f 100644
+--- a/sound/hda/codecs/side-codecs/cs35l56_hda.c
++++ b/sound/hda/codecs/side-codecs/cs35l56_hda.c
+@@ -1025,7 +1025,7 @@ static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int hid, int id)
+       u32 values[HDA_MAX_COMPONENTS];
+       char hid_string[8];
+       struct acpi_device *adev;
+-      const char *property, *sub;
++      const char *property;
+       int i, ret;
+       /*
+@@ -1047,7 +1047,8 @@ static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int hid, int id)
+       /* Initialize things that could be overwritten by a fixup */
+       cs35l56->index = -1;
+-      sub = acpi_get_subsystem_id(ACPI_HANDLE(cs35l56->base.dev));
++      const char *sub __free(kfree) = acpi_get_subsystem_id(ACPI_HANDLE(cs35l56->base.dev));
++
+       ret = cs35l56_hda_apply_platform_fixups(cs35l56, sub, &id);
+       if (ret)
+               return ret;
+@@ -1095,15 +1096,16 @@ static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int hid, int id)
+               ret = cirrus_scodec_get_speaker_id(cs35l56->base.dev, cs35l56->index,
+                                                  cs35l56->num_amps, -1);
+               if (ret == -ENOENT) {
+-                      cs35l56->system_name = sub;
++                      cs35l56->system_name = devm_kstrdup(cs35l56->base.dev, sub, GFP_KERNEL);
+               } else if (ret >= 0) {
+-                      cs35l56->system_name = kasprintf(GFP_KERNEL, "%s-spkid%d", sub, ret);
+-                      kfree(sub);
+-                      if (!cs35l56->system_name)
+-                              return -ENOMEM;
++                      cs35l56->system_name = devm_kasprintf(cs35l56->base.dev, GFP_KERNEL,
++                                                            "%s-spkid%d", sub, ret);
+               } else {
+                       return ret;
+               }
++
++              if (!cs35l56->system_name)
++                      return -ENOMEM;
+       }
+       cs35l56->base.reset_gpio = devm_gpiod_get_index_optional(cs35l56->base.dev,
+@@ -1254,7 +1256,6 @@ void cs35l56_hda_remove(struct device *dev)
+       cs_dsp_remove(&cs35l56->cs_dsp);
+-      kfree(cs35l56->system_name);
+       pm_runtime_put_noidle(cs35l56->base.dev);
+       gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
+-- 
+2.53.0
+
diff --git a/queue-7.0/alsa-pcm-oss-fix-setup-list-uaf-on-proc-write-error.patch b/queue-7.0/alsa-pcm-oss-fix-setup-list-uaf-on-proc-write-error.patch
new file mode 100644 (file)
index 0000000..7be990f
--- /dev/null
@@ -0,0 +1,84 @@
+From 8d1a022b4f8644d835bbec9cf08167ad1bd7bc55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 22:09:40 -0300
+Subject: ALSA: pcm: oss: Fix setup list UAF on proc write error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit 4cc54bdd54b337e77115be5b55577d1c58608eae ]
+
+snd_pcm_oss_proc_write() links a newly allocated setup entry into the
+OSS setup list before duplicating the task name. If the task-name
+allocation fails, the error path frees the already linked entry and
+leaves setup_list pointing at freed memory.
+
+A later OSS device open can then walk the stale list entry in
+snd_pcm_oss_look_for_setup() and dereference freed memory.
+
+Allocate the task name and initialize the setup entry before publishing
+the entry on setup_list. Also fetch the initial proc read iterator only
+after taking setup_mutex, so all setup_list traversal follows the same
+list lifetime rules.
+
+Reported-by: syzbot+8e498074a794999eb41c@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/6a1062b7.170a0220.35b2b7.0003.GAE@google.com
+Closes: https://syzkaller.appspot.com/bug?extid=8e498074a794999eb41c
+Fixes: 060d77b9c04a ("[ALSA] Fix / clean up PCM-OSS setup hooks")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260522-alsa-pcm-oss-setup-uaf-v1-1-40bdcc4d17e8@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/oss/pcm_oss.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
+index 6af26ec2ecfd59..b1b4c7d017beea 100644
+--- a/sound/core/oss/pcm_oss.c
++++ b/sound/core/oss/pcm_oss.c
+@@ -2968,8 +2968,10 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
+                                 struct snd_info_buffer *buffer)
+ {
+       struct snd_pcm_str *pstr = entry->private_data;
+-      struct snd_pcm_oss_setup *setup = pstr->oss.setup_list;
++      struct snd_pcm_oss_setup *setup;
++
+       guard(mutex)(&pstr->oss.setup_mutex);
++      setup = pstr->oss.setup_list;
+       while (setup) {
+               snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n",
+                           setup->task_name,
+@@ -3054,6 +3056,13 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
+                               buffer->error = -ENOMEM;
+                               return;
+                       }
++                      template.task_name = kstrdup(task_name, GFP_KERNEL);
++                      if (!template.task_name) {
++                              kfree(setup);
++                              buffer->error = -ENOMEM;
++                              return;
++                      }
++                      *setup = template;
+                       if (pstr->oss.setup_list == NULL)
+                               pstr->oss.setup_list = setup;
+                       else {
+@@ -3061,12 +3070,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
+                                    setup1->next; setup1 = setup1->next);
+                               setup1->next = setup;
+                       }
+-                      template.task_name = kstrdup(task_name, GFP_KERNEL);
+-                      if (! template.task_name) {
+-                              kfree(setup);
+-                              buffer->error = -ENOMEM;
+-                              return;
+-                      }
++                      continue;
+               }
+               *setup = template;
+       }
+-- 
+2.53.0
+
diff --git a/queue-7.0/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch b/queue-7.0/asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
new file mode 100644 (file)
index 0000000..c8b3bf5
--- /dev/null
@@ -0,0 +1,47 @@
+From 959828173499d1f14b397934a4dca342be225927 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 09:24:00 -0300
+Subject: ASoC: codecs: simple-mux: Fix enum control bounds check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit f63ad68e18d774a5d15cd7e405ead63f6b322679 ]
+
+simple_mux_control_put() rejects values greater than e->items, but
+enum control values are zero based. For the two-entry mux used by this
+driver, valid values are 0 and 1, so value 2 must be rejected as well.
+
+Accepting e->items can store an invalid mux state, pass it to the GPIO
+setter, and pass it on to the DAPM mux update path where it is used as
+an index into the enum text array.
+
+Use the same >= e->items check used by the ASoC enum helpers.
+
+Fixes: 342fbb7578d1 ("ASoC: add simple-mux")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260527-asoc-simple-mux-enum-bounds-v1-1-3f805b9fc671@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/simple-mux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/simple-mux.c b/sound/soc/codecs/simple-mux.c
+index 069555f35f7359..c2f906a3f074ce 100644
+--- a/sound/soc/codecs/simple-mux.c
++++ b/sound/soc/codecs/simple-mux.c
+@@ -51,7 +51,7 @@ static int simple_mux_control_put(struct snd_kcontrol *kcontrol,
+       struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
+       struct simple_mux *priv = snd_soc_component_get_drvdata(c);
+-      if (ucontrol->value.enumerated.item[0] > e->items)
++      if (ucontrol->value.enumerated.item[0] >= e->items)
+               return -EINVAL;
+       if (priv->mux == ucontrol->value.enumerated.item[0])
+-- 
+2.53.0
+
diff --git a/queue-7.0/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch b/queue-7.0/asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
new file mode 100644 (file)
index 0000000..b3a023e
--- /dev/null
@@ -0,0 +1,112 @@
+From 99ceb52e3882357e2d6ce74a52d86a113fb6159a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 13:51:47 -0300
+Subject: ASoC: Intel: bytcht_es8316: Fix MCLK leak on init errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit afb2a3a9d8369d18122a0d7cd294eba9a98259c6 ]
+
+byt_cht_es8316_init() enables MCLK before configuring the codec sysclk
+and creating the headset jack. If either of those later steps fails, the
+function returns without disabling MCLK, leaving the clock enabled after
+card registration fails.
+
+Track whether this driver enabled MCLK and disable it on the init error
+paths. Add the matching DAI link exit callback so the same clock enable
+is also balanced when ASoC cleans up a successfully initialized link.
+
+Fixes: a03bdaa565cb ("ASoC: Intel: add machine driver for BYT/CHT + ES8316")
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260519-asoc-bytcht-es8316-mclk-leak-v1-1-b4a11cdc2afd@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcht_es8316.c | 29 ++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
+index 192e2a394ff3d0..ea387dc7427382 100644
+--- a/sound/soc/intel/boards/bytcht_es8316.c
++++ b/sound/soc/intel/boards/bytcht_es8316.c
+@@ -40,6 +40,7 @@ struct byt_cht_es8316_private {
+       struct gpio_desc *speaker_en_gpio;
+       struct device *codec_dev;
+       bool speaker_en;
++      bool mclk_enabled;
+ };
+ enum {
+@@ -170,6 +171,15 @@ static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
+       },
+ };
++static void byt_cht_es8316_disable_mclk(struct byt_cht_es8316_private *priv)
++{
++      if (!priv->mclk_enabled)
++              return;
++
++      clk_disable_unprepare(priv->mclk);
++      priv->mclk_enabled = false;
++}
++
+ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+ {
+       struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component;
+@@ -227,12 +237,14 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+       ret = clk_prepare_enable(priv->mclk);
+       if (ret)
+               dev_err(card->dev, "unable to enable MCLK\n");
++      else
++              priv->mclk_enabled = true;
+       ret = snd_soc_dai_set_sysclk(snd_soc_rtd_to_codec(runtime, 0), 0, 19200000,
+                                    SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               dev_err(card->dev, "can't set codec clock %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       ret = snd_soc_card_jack_new_pins(card, "Headset",
+@@ -241,13 +253,25 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
+                                        ARRAY_SIZE(byt_cht_es8316_jack_pins));
+       if (ret) {
+               dev_err(card->dev, "jack creation failed %d\n", ret);
+-              return ret;
++              goto err_disable_mclk;
+       }
+       snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+       snd_soc_component_set_jack(codec, &priv->jack, NULL);
+       return 0;
++
++err_disable_mclk:
++      byt_cht_es8316_disable_mclk(priv);
++      return ret;
++}
++
++static void byt_cht_es8316_exit(struct snd_soc_pcm_runtime *runtime)
++{
++      struct snd_soc_card *card = runtime->card;
++      struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
++
++      byt_cht_es8316_disable_mclk(priv);
+ }
+ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
+@@ -353,6 +377,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
+                                               | SND_SOC_DAIFMT_CBC_CFC,
+               .be_hw_params_fixup = byt_cht_es8316_codec_fixup,
+               .init = byt_cht_es8316_init,
++              .exit = byt_cht_es8316_exit,
+               SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
+       },
+ };
+-- 
+2.53.0
+
diff --git a/queue-7.0/blk-mq-reinsert-cached-request-to-the-list.patch b/queue-7.0/blk-mq-reinsert-cached-request-to-the-list.patch
new file mode 100644 (file)
index 0000000..cfc7dc3
--- /dev/null
@@ -0,0 +1,44 @@
+From a227639fbfd866fd17e126e0ff263df8ff8893fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:31 -0700
+Subject: blk-mq: reinsert cached request to the list
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ Upstream commit b051bb6bf0a231117036aa607cadf55be8e63910 ]
+
+A previous commit removed an optimization out of caution for a scenario
+that turns out not to be real: all the "queue_exit" goto's are safe to
+reinsert the request into the cached_rq's plug list as they are either
+from a non-blocking path, or a successful merge that already holds the
+queue reference. This optimization is most needed for small sequential
+workloads that successfully merge into larger requests.
+
+Fixes: dc278e9bf2b9 ("blk-mq: pop cached request if it is usable")
+Suggested-by: Ming Lei <tom.leiming@gmail.com>
+Suggested-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Link: https://patch.msgid.link/20260526153531.2365935-1-kbusch@meta.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 39986a742b981a..061c8ef4484a25 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -3244,7 +3244,7 @@ void blk_mq_submit_bio(struct bio *bio)
+       if (!rq)
+               blk_queue_exit(q);
+       else
+-              blk_mq_free_request(rq);
++              rq_list_add_head(&plug->cached_rqs, rq);
+ }
+ #ifdef CONFIG_BLK_MQ_STACKING
+-- 
+2.53.0
+
diff --git a/queue-7.0/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch b/queue-7.0/bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
new file mode 100644 (file)
index 0000000..8375d50
--- /dev/null
@@ -0,0 +1,40 @@
+From c8907a61c18236cd18ddd34f089d2635478d3ab6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 11:21:39 +0800
+Subject: Bluetooth: 6lowpan: check skb_clone() return value in
+ send_mcast_pkt()
+
+From: Zhao Dongdong <zhaodongdong@kylinos.cn>
+
+[ Upstream commit 3c40d381ce04f9575a5d8b542898183c3b4b38dc ]
+
+The skb_clone() function can return NULL if memory allocation fails.
+send_mcast_pkt() calls skb_clone() without checking the return value, which
+can lead to a NULL pointer dereference in send_pkt() when it dereferences
+skb->data.
+Add a NULL check after skb_clone() and skip the peer if the clone fails.
+
+Fixes: 18722c247023 ("Bluetooth: Enable 6LoWPAN support for BT LE devices")
+Signed-off-by: Zhao Dongdong <zhaodongdong@kylinos.cn>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/6lowpan.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 2f03b780b40d84..960a19b3e26da1 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -486,6 +486,8 @@ static int send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
+                       int ret;
+                       local_skb = skb_clone(skb, GFP_ATOMIC);
++                      if (!local_skb)
++                              continue;
+                       BT_DBG("xmit %s to %pMR type %u IP %pI6c chan %p",
+                              netdev->name,
+-- 
+2.53.0
+
diff --git a/queue-7.0/bluetooth-hci_sync-reset-device-counters-in-hci_dev_.patch b/queue-7.0/bluetooth-hci_sync-reset-device-counters-in-hci_dev_.patch
new file mode 100644 (file)
index 0000000..c0a4a46
--- /dev/null
@@ -0,0 +1,38 @@
+From 0b8f63d390a8819be50aa98f2fdcdcf0c1bf635b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 10:50:59 -0300
+Subject: Bluetooth: hci_sync: Reset device counters in hci_dev_close_sync()
+
+From: Heitor Alves de Siqueira <halves@igalia.com>
+
+[ Upstream commit cdf88b35e06f1b385f7f6228060ae541d44fbb72 ]
+
+Before resetting or closing the device, protocol counters should also be
+zeroed.
+
+Fixes: d0b137062b2d ("Bluetooth: hci_sync: Rework init stages")
+Signed-off-by: Heitor Alves de Siqueira <halves@igalia.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 80b71e39656faf..35988eace9e4f4 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -5393,6 +5393,10 @@ int hci_dev_close_sync(struct hci_dev *hdev)
+       /* Reset device */
+       skb_queue_purge(&hdev->cmd_q);
+       atomic_set(&hdev->cmd_cnt, 1);
++      hdev->acl_cnt = 0;
++      hdev->sco_cnt = 0;
++      hdev->le_cnt = 0;
++      hdev->iso_cnt = 0;
+       if (hci_test_quirk(hdev, HCI_QUIRK_RESET_ON_CLOSE) &&
+           !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
+               set_bit(HCI_INIT, &hdev->flags);
+-- 
+2.53.0
+
diff --git a/queue-7.0/bluetooth-hci_sync-set-hci_cmd_drain_workqueue-durin.patch b/queue-7.0/bluetooth-hci_sync-set-hci_cmd_drain_workqueue-durin.patch
new file mode 100644 (file)
index 0000000..d97a10c
--- /dev/null
@@ -0,0 +1,57 @@
+From 35a912c06c6b00ef57e1ae9934c2f76dccd70f43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 10:50:58 -0300
+Subject: Bluetooth: hci_sync: Set HCI_CMD_DRAIN_WORKQUEUE during device close
+
+From: Heitor Alves de Siqueira <halves@igalia.com>
+
+[ Upstream commit 525daaea459fc215f432de1b8debbd9144bf97b0 ]
+
+Since hci_dev_close_sync() can now be called during the reset path, we
+should also set HCI_CMD_DRAIN_WORKQUEUE. This avoids queuing timeouts
+while the hdev workqueue is being drained.
+
+Fixes: 877afadad2dc ("Bluetooth: When HCI work queue is drained, only queue chained work")
+Signed-off-by: Heitor Alves de Siqueira <halves@igalia.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 426f465be35533..80b71e39656faf 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -5301,6 +5301,12 @@ int hci_dev_close_sync(struct hci_dev *hdev)
+       bt_dev_dbg(hdev, "");
++      /* Set HCI_DRAIN_WORKQUEUE flag to prevent queuing work during
++       * reset/close. See hci_cmd_work() and handle_cmd_cnt_and_timer().
++       */
++      hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
++      synchronize_rcu();
++
+       if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
+               disable_delayed_work(&hdev->power_off);
+               disable_delayed_work(&hdev->ncmd_timer);
+@@ -5324,6 +5330,7 @@ int hci_dev_close_sync(struct hci_dev *hdev)
+       if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
+               cancel_delayed_work_sync(&hdev->cmd_timer);
++              hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
+               return err;
+       }
+@@ -5423,6 +5430,7 @@ int hci_dev_close_sync(struct hci_dev *hdev)
+       /* Clear flags */
+       hdev->flags &= BIT(HCI_RAW);
+       hci_dev_clear_volatile_flags(hdev);
++      hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
+       memset(hdev->eir, 0, sizeof(hdev->eir));
+       memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
+-- 
+2.53.0
+
diff --git a/queue-7.0/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch b/queue-7.0/bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
new file mode 100644 (file)
index 0000000..be62366
--- /dev/null
@@ -0,0 +1,62 @@
+From 1471327a723ed39148ab4b7d9408cf2f29fb3a25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 18:51:52 +0800
+Subject: Bluetooth: l2cap: clear chan->ident on ECRED reconfiguration success
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit 00e1950716c6ed67d74777b2db286b0fa23b4be9 ]
+
+l2cap_ecred_reconf_rsp() returns early on success without clearing
+chan->ident. Every other L2CAP response handler (l2cap_ecred_conn_rsp,
+l2cap_le_connect_rsp, l2cap_config_rsp) clears chan->ident after a
+successful transaction to prevent the channel from matching subsequent
+responses with the recycled ident value.
+
+A remote attacker that completed a reconfiguration as the peer can
+replay a failure response with the stale ident, causing the kernel to
+match and destroy the already-established channel via
+l2cap_chan_del(chan, ECONNRESET).
+
+Clear chan->ident for all matching channels on success, and harden the
+failure path by using l2cap_chan_hold_unless_zero() consistent with
+other L2CAP handlers (l2cap_le_command_rej, __l2cap_get_chan_by_ident).
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 99297d8f2c1f34..83ea31926bd0f8 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -5466,14 +5466,20 @@ static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
+       BT_DBG("result 0x%4.4x", result);
+-      if (!result)
++      if (!result) {
++              list_for_each_entry(chan, &conn->chan_l, list) {
++                      if (chan->ident == cmd->ident)
++                              chan->ident = 0;
++              }
+               return 0;
++      }
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
+               if (chan->ident != cmd->ident)
+                       continue;
+-              l2cap_chan_hold(chan);
++              if (!l2cap_chan_hold_unless_zero(chan))
++                      continue;
+               l2cap_chan_lock(chan);
+               l2cap_chan_del(chan, ECONNRESET);
+-- 
+2.53.0
+
diff --git a/queue-7.0/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch b/queue-7.0/bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
new file mode 100644 (file)
index 0000000..60e06c8
--- /dev/null
@@ -0,0 +1,82 @@
+From cc27c20a01b88f545defdcdf3fe543d332ec7ffc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 May 2026 12:09:42 -0400
+Subject: Bluetooth: L2CAP: Fix possible crash on l2cap_ecred_conn_rsp
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 41c2713b204e6cb6a94587bc6bf6935107df5479 ]
+
+If dcid is received for an already-assigned destination CID the spec
+requires that both channels to be discarded, but calling l2cap_chan_del
+may invalidate the tmp cursor created by list_for_each_entry_safe and
+in fact it is the wrong procedure as the chan->dcid may be assigned
+previously it really needs to be disconnected.
+
+Calling l2cap_chan_clone directly may still lead to l2cap_chan_del so
+instead schedule l2cap_chan_timeout with delay 0 to close the channel
+asynchronously.
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 27 ++++++++++++++++++++++-----
+ 1 file changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 83ea31926bd0f8..27b5d459e1217c 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -5268,6 +5268,7 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+       cmd_len -= sizeof(*rsp);
+       list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
++              struct l2cap_chan *orig;
+               u16 dcid;
+               if (chan->ident != cmd->ident ||
+@@ -5289,8 +5290,10 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+               BT_DBG("dcid[%d] 0x%4.4x", i, dcid);
++              orig = __l2cap_get_chan_by_dcid(conn, dcid);
++
+               /* Check if dcid is already in use */
+-              if (dcid && __l2cap_get_chan_by_dcid(conn, dcid)) {
++              if (dcid && orig) {
+                       /* If a device receives a
+                        * L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an
+                        * already-assigned Destination CID, then both the
+@@ -5299,10 +5302,24 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
+                        */
+                       l2cap_chan_del(chan, ECONNREFUSED);
+                       l2cap_chan_unlock(chan);
+-                      chan = __l2cap_get_chan_by_dcid(conn, dcid);
+-                      l2cap_chan_lock(chan);
+-                      l2cap_chan_del(chan, ECONNRESET);
+-                      l2cap_chan_unlock(chan);
++
++                      /* Check that the dcid channel mode is
++                       * L2CAP_MODE_EXT_FLOWCTL since this procedure is only
++                       * valid for that mode and shouldn't disconnect a dcid
++                       * in other modes.
++                       */
++                      if (orig->mode == L2CAP_MODE_EXT_FLOWCTL) {
++                              l2cap_chan_lock(orig);
++                              /* Disconnect the original channel as it may be
++                               * considered connected since dcid has already
++                               * been assigned; don't call l2cap_chan_close
++                               * directly since that could lead to
++                               * l2cap_chan_del and then removing the channel
++                               * from the list while we're iterating over it.
++                               */
++                              __set_chan_timer(orig, 0);
++                              l2cap_chan_unlock(orig);
++                      }
+                       continue;
+               }
+-- 
+2.53.0
+
diff --git a/queue-7.0/bonding-refuse-to-enslave-can-devices.patch b/queue-7.0/bonding-refuse-to-enslave-can-devices.patch
new file mode 100644 (file)
index 0000000..48b434a
--- /dev/null
@@ -0,0 +1,74 @@
+From e456d6c0731704887d708fcb72791b742b7f6683 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 21:33:19 +0200
+Subject: bonding: refuse to enslave CAN devices
+
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+
+[ Upstream commit 8ba68464e4787b6a7ec938826e16124df20fd23d ]
+
+syzbot reported a kernel paging request crash in
+can_rx_unregister() inside net/can/af_can.c. The crash occurs
+because a virtual CAN device (vxcan) is being enslaved to a
+bonding master.
+
+During the enslavement process, the bonding driver mutates
+and modifies the network device states to fit an Ethernet-like
+aggregation model. However, CAN devices operate on a completely
+different Layer 2 architecture, relying on the CAN mid-layer
+private data structure (can_ml_priv) instead of standard
+Ethernet structures. Since bonding does not initialize or
+maintain these CAN structures, subsequent operations on the
+half-enslaved interface (such as closing associated sockets
+via isotp_release) lead to a null-pointer dereference when
+accessing the CAN receiver lists.
+
+Bonding CAN interfaces is architecturally invalid as CAN lacks
+MAC addresses, ARP capabilities, and standard Ethernet
+link-layer mechanisms. While generic loopback devices are
+blocked globally in net/core/dev.c, virtual CAN devices
+bypass this check because they do not carry the IFF_LOOPBACK
+flag, despite acting as local software-loopbacks.
+
+Fix this by explicitly blocking network devices of type
+ARPHRD_CAN from being enslaved at the very beginning of
+bond_enslave(). This prevents illegal state mutations,
+eliminates the resulting KASAN crashes, and avoids potential
+memory leaks from incomplete socket cleanups.
+
+As the CAN support has been added a long time after bonding
+the Fixes-tag points to the introduction of ARPHRD_CAN that
+would have needed a specific handling in bonding_main.c.
+
+Fixes: cd05acfe65ed ("[CAN]: Allocate protocol numbers for PF_CAN")
+Reported-by: syzbot+8ed98cbd0161632bce95@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=8ed98cbd0161632bce95
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Link: https://patch.msgid.link/20260526-bonding-candev-v1-1-ba1df400918a@hartkopp.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index eb49ce486992de..d6a1e814878f28 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1892,6 +1892,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
+       struct sockaddr_storage ss;
+       int res = 0, i;
++      if (slave_dev->type == ARPHRD_CAN) {
++              BOND_NL_ERR(bond_dev, extack,
++                          "CAN devices cannot be enslaved");
++              return -EPERM;
++      }
++
+       if (slave_dev->flags & IFF_MASTER &&
+           !netif_is_bond_master(slave_dev)) {
+               BOND_NL_ERR(bond_dev, extack,
+-- 
+2.53.0
+
diff --git a/queue-7.0/bridge-fix-sleep-in-atomic-context-in-netlink-path.patch b/queue-7.0/bridge-fix-sleep-in-atomic-context-in-netlink-path.patch
new file mode 100644 (file)
index 0000000..66db3a4
--- /dev/null
@@ -0,0 +1,149 @@
+From 178c953d89bb7ce63cdd15e6f1e3a6bc32f7c5ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 09:48:16 +0300
+Subject: bridge: Fix sleep in atomic context in netlink path
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 5eec4427b89c2fb2beac54920101e55a2f1c0c21 ]
+
+Since the introduction of the netlink configuration path for bridge
+ports in commit 25c71c75ac87 ("bridge: bridge port parameters over
+netlink"), br_setport() was always called with the bridge lock held
+around it. Back then this decision made sense: The bridge lock protects
+the STP state of the bridge and its ports and at that time the function
+only processed three STP related netlink attributes (cost, priority and
+state).
+
+Nowadays, br_setport() processes a lot more attributes and most of them
+do not need the bridge lock:
+
+* Bridge flags: Only require RTNL. Read locklessly by the data path.
+  Annotations can be added in net-next.
+
+* FDB port flushing: Only requires the FDB lock.
+
+* Multicast attributes: Only require the multicast lock.
+
+* Group forward mask: Only requires RTNL. Read locklessly by the data
+  path. Annotations can be added in net-next.
+
+* Backup port and NHID: Only require RTNL. Read locklessly by the data
+  path.
+
+This is a problem as the bridge calls dev_set_promiscuity() when certain
+bridge port flags change and this function can sleep since the commit
+cited below, resulting in a splat such as [1].
+
+Fix this by reducing the scope of the bridge lock and only take it when
+processing the three STP related attributes that require it. This is
+consistent with the multicast attributes where each attribute acquires
+the multicast lock instead of having one critical section for all
+relevant attributes.
+
+[1]
+BUG: sleeping function called from invalid context at net/core/dev_addr_lists.c:1262
+in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 356, name: bridge
+preempt_count: 201, expected: 0
+RCU nest depth: 0, expected: 0
+2 locks held by bridge/356:
+#0: ffffffff919473a0 (rtnl_mutex){+.+.}-{4:4}, at: rtnetlink_rcv_msg (net/core/rtnetlink.c:80 net/core/rtnetlink.c:7002)
+#1: ffff888115072d58 (&br->lock){+...}-{3:3}, at: br_setlink (./include/linux/spinlock.h:348 net/bridge/br_netlink.c:1117)
+Preemption disabled at:
+ 0x0
+Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+Call Trace:
+<TASK>
+dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120)
+__might_resched.cold (kernel/sched/core.c:9163)
+netif_rx_mode_run (net/core/dev_addr_lists.c:1262)
+netif_rx_mode_sync (net/core/dev_addr_lists.c:1428)
+dev_set_promiscuity (net/core/dev_api.c:289)
+br_manage_promisc (net/bridge/br_if.c:135 net/bridge/br_if.c:172)
+br_port_flags_change (net/bridge/br_if.c:242 net/bridge/br_if.c:747)
+br_setport (net/bridge/br_netlink.c:1000)
+br_setlink (net/bridge/br_netlink.c:1118)
+rtnl_bridge_setlink (net/core/rtnetlink.c:5572)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:7005)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1318 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sock_sendmsg (net/socket.c:787 (discriminator 4) net/socket.c:802 (discriminator 4))
+____sys_sendmsg (net/socket.c:2698)
+___sys_sendmsg (net/socket.c:2752)
+__sys_sendmsg (net/socket.c:2784)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+Fixes: 78cd408356fe ("net: add missing instance lock to dev_set_promiscuity")
+Reviewed-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260526064818.272516-2-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/br_netlink.c | 17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
+index 0264730938f4b2..2ad502bfbd55e5 100644
+--- a/net/bridge/br_netlink.c
++++ b/net/bridge/br_netlink.c
+@@ -1000,19 +1000,25 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[],
+       br_port_flags_change(p, changed_mask);
+       if (tb[IFLA_BRPORT_COST]) {
++              spin_lock_bh(&p->br->lock);
+               err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST]));
++              spin_unlock_bh(&p->br->lock);
+               if (err)
+                       return err;
+       }
+       if (tb[IFLA_BRPORT_PRIORITY]) {
++              spin_lock_bh(&p->br->lock);
+               err = br_stp_set_port_priority(p, nla_get_u16(tb[IFLA_BRPORT_PRIORITY]));
++              spin_unlock_bh(&p->br->lock);
+               if (err)
+                       return err;
+       }
+       if (tb[IFLA_BRPORT_STATE]) {
++              spin_lock_bh(&p->br->lock);
+               err = br_set_port_state(p, nla_get_u8(tb[IFLA_BRPORT_STATE]));
++              spin_unlock_bh(&p->br->lock);
+               if (err)
+                       return err;
+       }
+@@ -1114,9 +1120,7 @@ int br_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags,
+                       if (err)
+                               return err;
+-                      spin_lock_bh(&p->br->lock);
+                       err = br_setport(p, tb, extack);
+-                      spin_unlock_bh(&p->br->lock);
+               } else {
+                       /* Binary compatibility with old RSTP */
+                       if (nla_len(protinfo) < sizeof(u8))
+@@ -1203,17 +1207,10 @@ static int br_port_slave_changelink(struct net_device *brdev,
+                                   struct nlattr *data[],
+                                   struct netlink_ext_ack *extack)
+ {
+-      struct net_bridge *br = netdev_priv(brdev);
+-      int ret;
+-
+       if (!data)
+               return 0;
+-      spin_lock_bh(&br->lock);
+-      ret = br_setport(br_port_get_rtnl(dev), data, extack);
+-      spin_unlock_bh(&br->lock);
+-
+-      return ret;
++      return br_setport(br_port_get_rtnl(dev), data, extack);
+ }
+ static int br_port_fill_slave_info(struct sk_buff *skb,
+-- 
+2.53.0
+
diff --git a/queue-7.0/bridge-fix-sleep-in-atomic-context-in-sysfs-path.patch b/queue-7.0/bridge-fix-sleep-in-atomic-context-in-sysfs-path.patch
new file mode 100644 (file)
index 0000000..e1e015c
--- /dev/null
@@ -0,0 +1,158 @@
+From 1c6f20508c064b8161efaa8ba4f9ef3b551f5752 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 09:48:17 +0300
+Subject: bridge: Fix sleep in atomic context in sysfs path
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 6d34594cc619d0d4b07d5afcad8b5984f3526dcf ]
+
+Since the start of the git history, brport_store() always acquired the
+bridge lock. Back then this decision made sense: The bridge lock
+protects the STP state of the bridge and its ports and at that time the
+function was only used by two STP related attributes (cost and
+priority).
+
+Nowadays, brport_store() processes a lot more attributes and most of
+them do not need the bridge lock:
+
+* Bridge flags: Only require RTNL. Read locklessly by the data path.
+  Annotations can be added in net-next.
+
+* FDB port flushing: Only requires the FDB lock.
+
+* Multicast attributes: Only require the multicast lock.
+
+* Group forward mask: Only requires RTNL. Read locklessly by the data
+  path. Annotations can be added in net-next.
+
+* Backup port: Only requires RTNL. Read locklessly by the data path.
+
+This is a problem as the bridge calls dev_set_promiscuity() when certain
+bridge port flags change and this function can sleep since the commit
+cited below, resulting in a splat such as [1].
+
+Fix this by reducing the scope of the bridge lock and only take it when
+processing the two STP related attributes that require it. Remove the
+now stale comment from br_switchdev_set_port_flag(). The
+SWITCHDEV_F_DEFER flag can be removed in net-next.
+
+[1]
+BUG: sleeping function called from invalid context at net/core/dev_addr_lists.c:1262
+in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 372, name: bash
+preempt_count: 201, expected: 0
+RCU nest depth: 0, expected: 0
+5 locks held by bash/372:
+#0: ffff88810c51c3f0 (sb_writers#7){.+.+}-{0:0}, at: ksys_write (fs/read_write.c:740)
+#1: ffff888115ce9480 (&of->mutex){+.+.}-{4:4}, at: kernfs_fop_write_iter (fs/kernfs/file.c:343)
+#2: ffff88810b9fd330 (kn->active#37){.+.+}-{0:0}, at: kernfs_fop_write_iter (fs/kernfs/file.c:80 fs/kernfs/file.c:344)
+#3: ffffffffa59473a0 (rtnl_mutex){+.+.}-{4:4}, at: brport_store (net/bridge/br_sysfs_if.c:326)
+#4: ffff8881099d2d58 (&br->lock){+...}-{3:3}, at: brport_store (./include/linux/spinlock.h:348 net/bridge/br_sysfs_if.c:345)
+Preemption disabled at:
+ 0x0
+Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+Call Trace:
+<TASK>
+dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120)
+__might_resched.cold (kernel/sched/core.c:9163)
+netif_rx_mode_run (net/core/dev_addr_lists.c:1262)
+netif_rx_mode_sync (net/core/dev_addr_lists.c:1428)
+dev_set_promiscuity (net/core/dev_api.c:289)
+br_manage_promisc (net/bridge/br_if.c:135 net/bridge/br_if.c:172)
+br_port_flags_change (net/bridge/br_if.c:242 net/bridge/br_if.c:747)
+store_learning (net/bridge/br_sysfs_if.c:79 net/bridge/br_sysfs_if.c:235)
+brport_store (net/bridge/br_sysfs_if.c:346)
+kernfs_fop_write_iter (fs/kernfs/file.c:352)
+new_sync_write (fs/read_write.c:595)
+vfs_write (fs/read_write.c:688)
+ksys_write (fs/read_write.c:740)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+Fixes: 78cd408356fe ("net: add missing instance lock to dev_set_promiscuity")
+Reviewed-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260526064818.272516-3-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/br_switchdev.c |  1 -
+ net/bridge/br_sysfs_if.c  | 30 ++++++++++++++++++++++--------
+ 2 files changed, 22 insertions(+), 9 deletions(-)
+
+diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
+index 4fac002922d22a..58257e9e9d30b6 100644
+--- a/net/bridge/br_switchdev.c
++++ b/net/bridge/br_switchdev.c
+@@ -99,7 +99,6 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
+       attr.u.brport_flags.val = flags;
+       attr.u.brport_flags.mask = mask;
+-      /* We run from atomic context here */
+       err = call_switchdev_notifiers(SWITCHDEV_PORT_ATTR_SET, p->dev,
+                                      &info.info, extack);
+       err = notifier_to_errno(err);
+diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
+index 1f57c36a7fc097..d6df81fa0d13fe 100644
+--- a/net/bridge/br_sysfs_if.c
++++ b/net/bridge/br_sysfs_if.c
+@@ -86,16 +86,34 @@ static ssize_t show_path_cost(struct net_bridge_port *p, char *buf)
+       return sysfs_emit(buf, "%d\n", p->path_cost);
+ }
+-static BRPORT_ATTR(path_cost, 0644,
+-                 show_path_cost, br_stp_set_path_cost);
++static int store_path_cost(struct net_bridge_port *p, unsigned long v)
++{
++      int ret;
++
++      spin_lock_bh(&p->br->lock);
++      ret = br_stp_set_path_cost(p, v);
++      spin_unlock_bh(&p->br->lock);
++      return ret;
++}
++
++static BRPORT_ATTR(path_cost, 0644, show_path_cost, store_path_cost);
+ static ssize_t show_priority(struct net_bridge_port *p, char *buf)
+ {
+       return sysfs_emit(buf, "%d\n", p->priority);
+ }
+-static BRPORT_ATTR(priority, 0644,
+-                       show_priority, br_stp_set_port_priority);
++static int store_priority(struct net_bridge_port *p, unsigned long v)
++{
++      int ret;
++
++      spin_lock_bh(&p->br->lock);
++      ret = br_stp_set_port_priority(p, v);
++      spin_unlock_bh(&p->br->lock);
++      return ret;
++}
++
++static BRPORT_ATTR(priority, 0644, show_priority, store_priority);
+ static ssize_t show_designated_root(struct net_bridge_port *p, char *buf)
+ {
+@@ -334,17 +352,13 @@ static ssize_t brport_store(struct kobject *kobj,
+                       ret = -ENOMEM;
+                       goto out_unlock;
+               }
+-              spin_lock_bh(&p->br->lock);
+               ret = brport_attr->store_raw(p, buf_copy);
+-              spin_unlock_bh(&p->br->lock);
+               kfree(buf_copy);
+       } else if (brport_attr->store) {
+               val = simple_strtoul(buf, &endp, 0);
+               if (endp == buf)
+                       goto out_unlock;
+-              spin_lock_bh(&p->br->lock);
+               ret = brport_attr->store(p, val);
+-              spin_unlock_bh(&p->br->lock);
+       }
+       if (!ret) {
+-- 
+2.53.0
+
diff --git a/queue-7.0/cxl-test-update-mock-dev-array-before-calling-platfo.patch b/queue-7.0/cxl-test-update-mock-dev-array-before-calling-platfo.patch
new file mode 100644 (file)
index 0000000..2b7a9d6
--- /dev/null
@@ -0,0 +1,272 @@
+From 1b8694628317ca2d2a903b454e4aa534458f9c2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 20:14:57 +0800
+Subject: cxl/test: Update mock dev array before calling platform_device_add()
+
+From: Li Ming <ming.li@zohomail.com>
+
+[ Upstream commit d90f236f8b9e354848bd226f581db27755ab901d ]
+
+CXL test environment hits the following error sometimes.
+
+ cxl_mem mem9: endpoint7 failed probe
+
+All mock memdevs are platform firmware devices added by cxl_test module,
+and cxl_test module also provides a platform device driver for them to
+create a memdev device to CXL subsystem. cxl_test module uses
+cxl_rcd/mem_single/mem arrays to store different types of mock memdevs.
+CXL drivers calls registered mock functions for a mock memdev by
+checking if a given memdev is in these arrays.
+
+When cxl_test module adds these mock memdevs, it always calls
+platform_device_add() before adding them to a suitable mock memdev
+array. However, there is a small window where CXL drivers calls mock
+function for a added memdev before it added to a mock memdev array. In
+above case, cxl endpoint driver considers a added memdev was not a mock
+memdev, then calling devm_cxl_endpoint_decoders_setup() for it rather
+than mock_endpoint_decoders_setup().
+
+An appropriate solution is that adding a new mock device to a mock
+device array before calling platform_device_add() for it. It can
+guarantee the new mock device is visible to CXL subsystem.
+
+This patch introduces a new helped called cxl_mock_platform_device_add()
+to handle the issue, and uses the function for all mock devices addition.
+
+Fixes: 3a2b97b3210b ("cxl/test: Improve init-order fidelity relative to real-world systems")
+Signed-off-by: Li Ming <ming.li@zohomail.com>
+Tested-by: Alison Schofield <alison.schofield@intel.com>
+Reviewed-by: Alison Schofield <alison.schofield@intel.com>
+Link: https://patch.msgid.link/20260520121457.234404-1-ming.li@zohomail.com
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/cxl/test/cxl.c | 105 ++++++++++++++---------------------
+ 1 file changed, 43 insertions(+), 62 deletions(-)
+
+diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
+index 81e2aef3627a44..f4c26441fc41af 100644
+--- a/tools/testing/cxl/test/cxl.c
++++ b/tools/testing/cxl/test/cxl.c
+@@ -1144,6 +1144,23 @@ static void mock_companion(struct acpi_device *adev, struct device *dev)
+ #define SZ_64G (SZ_32G * 2)
+ #endif
++static int cxl_mock_platform_device_add(struct platform_device *pdev,
++                                      struct platform_device **ppdev)
++{
++      int rc;
++
++      if (ppdev)
++              *ppdev = pdev;
++      rc = platform_device_add(pdev);
++      if (rc) {
++              platform_device_put(pdev);
++              if (ppdev)
++                      *ppdev = NULL;
++      }
++
++      return rc;
++}
++
+ static __init int cxl_rch_topo_init(void)
+ {
+       int rc, i;
+@@ -1158,13 +1175,10 @@ static __init int cxl_rch_topo_init(void)
+                       goto err_bridge;
+               mock_companion(adev, &pdev->dev);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_rch[i]);
++              if (rc)
+                       goto err_bridge;
+-              }
+-              cxl_rch[i] = pdev;
+               mock_pci_bus[idx].bridge = &pdev->dev;
+               rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
+                                      "firmware_node");
+@@ -1216,13 +1230,10 @@ static __init int cxl_single_topo_init(void)
+                       goto err_bridge;
+               mock_companion(adev, &pdev->dev);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_hb_single[i]);
++              if (rc)
+                       goto err_bridge;
+-              }
+-              cxl_hb_single[i] = pdev;
+               mock_pci_bus[i + NR_CXL_HOST_BRIDGES].bridge = &pdev->dev;
+               rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
+                                      "physical_node");
+@@ -1241,12 +1252,9 @@ static __init int cxl_single_topo_init(void)
+                       goto err_port;
+               pdev->dev.parent = &bridge->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_root_single[i]);
++              if (rc)
+                       goto err_port;
+-              }
+-              cxl_root_single[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_swu_single); i++) {
+@@ -1259,12 +1267,9 @@ static __init int cxl_single_topo_init(void)
+                       goto err_uport;
+               pdev->dev.parent = &root_port->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_swu_single[i]);
++              if (rc)
+                       goto err_uport;
+-              }
+-              cxl_swu_single[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_swd_single); i++) {
+@@ -1278,12 +1283,9 @@ static __init int cxl_single_topo_init(void)
+                       goto err_dport;
+               pdev->dev.parent = &uport->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_swd_single[i]);
++              if (rc)
+                       goto err_dport;
+-              }
+-              cxl_swd_single[i] = pdev;
+       }
+       return 0;
+@@ -1356,12 +1358,9 @@ static int cxl_mem_init(void)
+               pdev->dev.parent = &dport->dev;
+               set_dev_node(&pdev->dev, i % 2);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_mem[i]);
++              if (rc)
+                       goto err_mem;
+-              }
+-              cxl_mem[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_mem_single); i++) {
+@@ -1374,12 +1373,9 @@ static int cxl_mem_init(void)
+               pdev->dev.parent = &dport->dev;
+               set_dev_node(&pdev->dev, i % 2);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_mem_single[i]);
++              if (rc)
+                       goto err_single;
+-              }
+-              cxl_mem_single[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_rcd); i++) {
+@@ -1393,12 +1389,9 @@ static int cxl_mem_init(void)
+               pdev->dev.parent = &rch->dev;
+               set_dev_node(&pdev->dev, i % 2);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_rcd[i]);
++              if (rc)
+                       goto err_rcd;
+-              }
+-              cxl_rcd[i] = pdev;
+       }
+       return 0;
+@@ -1463,13 +1456,10 @@ static __init int cxl_test_init(void)
+                       goto err_bridge;
+               mock_companion(adev, &pdev->dev);
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_host_bridge[i]);
++              if (rc)
+                       goto err_bridge;
+-              }
+-              cxl_host_bridge[i] = pdev;
+               mock_pci_bus[i].bridge = &pdev->dev;
+               rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
+                                      "physical_node");
+@@ -1487,12 +1477,9 @@ static __init int cxl_test_init(void)
+                       goto err_port;
+               pdev->dev.parent = &bridge->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_root_port[i]);
++              if (rc)
+                       goto err_port;
+-              }
+-              cxl_root_port[i] = pdev;
+       }
+       BUILD_BUG_ON(ARRAY_SIZE(cxl_switch_uport) != ARRAY_SIZE(cxl_root_port));
+@@ -1505,12 +1492,9 @@ static __init int cxl_test_init(void)
+                       goto err_uport;
+               pdev->dev.parent = &root_port->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_switch_uport[i]);
++              if (rc)
+                       goto err_uport;
+-              }
+-              cxl_switch_uport[i] = pdev;
+       }
+       for (i = 0; i < ARRAY_SIZE(cxl_switch_dport); i++) {
+@@ -1523,12 +1507,9 @@ static __init int cxl_test_init(void)
+                       goto err_dport;
+               pdev->dev.parent = &uport->dev;
+-              rc = platform_device_add(pdev);
+-              if (rc) {
+-                      platform_device_put(pdev);
++              rc = cxl_mock_platform_device_add(pdev, &cxl_switch_dport[i]);
++              if (rc)
+                       goto err_dport;
+-              }
+-              cxl_switch_dport[i] = pdev;
+       }
+       rc = cxl_single_topo_init();
+@@ -1546,9 +1527,9 @@ static __init int cxl_test_init(void)
+       mock_companion(&acpi0017_mock, &cxl_acpi->dev);
+       acpi0017_mock.dev.bus = &platform_bus_type;
+-      rc = platform_device_add(cxl_acpi);
++      rc = cxl_mock_platform_device_add(cxl_acpi, NULL);
+       if (rc)
+-              goto err_root;
++              goto err_rch;
+       rc = cxl_mem_init();
+       if (rc)
+-- 
+2.53.0
+
diff --git a/queue-7.0/dpll-export-__dpll_device_change_ntf-for-use-under-d.patch b/queue-7.0/dpll-export-__dpll_device_change_ntf-for-use-under-d.patch
new file mode 100644 (file)
index 0000000..0acb948
--- /dev/null
@@ -0,0 +1,70 @@
+From e1fc70f17d041e2f925e9ce9ac9e1151af5b103b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 09:45:23 +0200
+Subject: dpll: export __dpll_device_change_ntf() for use under dpll_lock
+
+From: Ivan Vecera <ivecera@redhat.com>
+
+[ Upstream commit 20040b2a3cb992f84d3db4c086b909eb9b906b31 ]
+
+Export __dpll_device_change_ntf() so that drivers can send device
+change notifications from within device callbacks, which are already
+called under dpll_lock. Using dpll_device_change_ntf() in that
+context would deadlock.
+
+Add lockdep_assert_held() to catch misuse without the lock held.
+
+Signed-off-by: Ivan Vecera <ivecera@redhat.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://patch.msgid.link/20260526074525.1451008-2-ivecera@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: d733f519f644 ("dpll: zl3073x: use __dpll_device_change_ntf() and remove change_work")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dpll/dpll_netlink.c | 13 +++++++++++--
+ include/linux/dpll.h        |  1 +
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
+index 95ae786e98aab3..72aa5f4d5d3114 100644
+--- a/drivers/dpll/dpll_netlink.c
++++ b/drivers/dpll/dpll_netlink.c
+@@ -771,12 +771,21 @@ int dpll_device_delete_ntf(struct dpll_device *dpll)
+       return dpll_device_event_send(DPLL_CMD_DEVICE_DELETE_NTF, dpll);
+ }
+-static int
+-__dpll_device_change_ntf(struct dpll_device *dpll)
++/**
++ * __dpll_device_change_ntf - notify that the dpll device has been changed
++ * @dpll: registered dpll pointer
++ *
++ * Context: caller must hold dpll_lock. Suitable for use inside device
++ *          callbacks which are already invoked under dpll_lock.
++ * Return: 0 if succeeds, error code otherwise.
++ */
++int __dpll_device_change_ntf(struct dpll_device *dpll)
+ {
++      lockdep_assert_held(&dpll_lock);
+       dpll_device_notify(dpll, DPLL_DEVICE_CHANGED);
+       return dpll_device_event_send(DPLL_CMD_DEVICE_CHANGE_NTF, dpll);
+ }
++EXPORT_SYMBOL_GPL(__dpll_device_change_ntf);
+ /**
+  * dpll_device_change_ntf - notify that the dpll device has been changed
+diff --git a/include/linux/dpll.h b/include/linux/dpll.h
+index 8f97120ee7b37d..a77d5741dd3932 100644
+--- a/include/linux/dpll.h
++++ b/include/linux/dpll.h
+@@ -274,6 +274,7 @@ void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin,
+ int dpll_pin_ref_sync_pair_add(struct dpll_pin *pin,
+                              struct dpll_pin *ref_sync_pin);
++int __dpll_device_change_ntf(struct dpll_device *dpll);
+ int dpll_device_change_ntf(struct dpll_device *dpll);
+ int __dpll_pin_change_ntf(struct dpll_pin *pin);
+-- 
+2.53.0
+
diff --git a/queue-7.0/dpll-zl3073x-add-die-temperature-reporting-for-suppo.patch b/queue-7.0/dpll-zl3073x-add-die-temperature-reporting-for-suppo.patch
new file mode 100644 (file)
index 0000000..215e923
--- /dev/null
@@ -0,0 +1,183 @@
+From 85afbb582fa268e65be2e196f1179b169301526a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Feb 2026 11:53:00 +0100
+Subject: dpll: zl3073x: add die temperature reporting for supported chips
+
+From: Ivan Vecera <ivecera@redhat.com>
+
+[ Upstream commit 3a97e02b3e91e4d40095ad9bb6e466d8d7c1a1bc ]
+
+Some zl3073x chip variants (0x1Exx, 0x2Exx and 0x3FC4) provide a die
+temperature status register with 0.1 C resolution.
+
+Add a ZL3073X_FLAG_DIE_TEMP chip flag to identify these variants and
+implement zl3073x_dpll_temp_get() as the dpll_device_ops.temp_get
+callback. The register value is converted from 0.1 C units to
+millidegrees as expected by the DPLL subsystem.
+
+To support per-instance ops selection, copy the base dpll_device_ops
+into struct zl3073x_dpll and conditionally set .temp_get during device
+registration based on the chip flag.
+
+Signed-off-by: Ivan Vecera <ivecera@redhat.com>
+Link: https://patch.msgid.link/20260227105300.710272-3-ivecera@redhat.com
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: d733f519f644 ("dpll: zl3073x: use __dpll_device_change_ntf() and remove change_work")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dpll/zl3073x/core.c | 22 +++++++++++-----------
+ drivers/dpll/zl3073x/core.h |  2 ++
+ drivers/dpll/zl3073x/dpll.c | 28 +++++++++++++++++++++++++---
+ drivers/dpll/zl3073x/dpll.h |  2 ++
+ drivers/dpll/zl3073x/regs.h |  2 ++
+ 5 files changed, 42 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c
+index c8af3430104505..10e036ccf08f05 100644
+--- a/drivers/dpll/zl3073x/core.c
++++ b/drivers/dpll/zl3073x/core.c
+@@ -30,18 +30,18 @@ static const struct zl3073x_chip_info zl3073x_chip_ids[] = {
+       ZL_CHIP_INFO(0x0E95, 3, ZL3073X_FLAG_REF_PHASE_COMP_32),
+       ZL_CHIP_INFO(0x0E96, 4, ZL3073X_FLAG_REF_PHASE_COMP_32),
+       ZL_CHIP_INFO(0x0E97, 5, ZL3073X_FLAG_REF_PHASE_COMP_32),
+-      ZL_CHIP_INFO(0x1E93, 1, 0),
+-      ZL_CHIP_INFO(0x1E94, 2, 0),
+-      ZL_CHIP_INFO(0x1E95, 3, 0),
+-      ZL_CHIP_INFO(0x1E96, 4, 0),
+-      ZL_CHIP_INFO(0x1E97, 5, 0),
++      ZL_CHIP_INFO(0x1E93, 1, ZL3073X_FLAG_DIE_TEMP),
++      ZL_CHIP_INFO(0x1E94, 2, ZL3073X_FLAG_DIE_TEMP),
++      ZL_CHIP_INFO(0x1E95, 3, ZL3073X_FLAG_DIE_TEMP),
++      ZL_CHIP_INFO(0x1E96, 4, ZL3073X_FLAG_DIE_TEMP),
++      ZL_CHIP_INFO(0x1E97, 5, ZL3073X_FLAG_DIE_TEMP),
+       ZL_CHIP_INFO(0x1F60, 2, ZL3073X_FLAG_REF_PHASE_COMP_32),
+-      ZL_CHIP_INFO(0x2E93, 1, 0),
+-      ZL_CHIP_INFO(0x2E94, 2, 0),
+-      ZL_CHIP_INFO(0x2E95, 3, 0),
+-      ZL_CHIP_INFO(0x2E96, 4, 0),
+-      ZL_CHIP_INFO(0x2E97, 5, 0),
+-      ZL_CHIP_INFO(0x3FC4, 2, 0),
++      ZL_CHIP_INFO(0x2E93, 1, ZL3073X_FLAG_DIE_TEMP),
++      ZL_CHIP_INFO(0x2E94, 2, ZL3073X_FLAG_DIE_TEMP),
++      ZL_CHIP_INFO(0x2E95, 3, ZL3073X_FLAG_DIE_TEMP),
++      ZL_CHIP_INFO(0x2E96, 4, ZL3073X_FLAG_DIE_TEMP),
++      ZL_CHIP_INFO(0x2E97, 5, ZL3073X_FLAG_DIE_TEMP),
++      ZL_CHIP_INFO(0x3FC4, 2, ZL3073X_FLAG_DIE_TEMP),
+ };
+ #define ZL_RANGE_OFFSET               0x80
+diff --git a/drivers/dpll/zl3073x/core.h b/drivers/dpll/zl3073x/core.h
+index fde5c8371fbd28..b6f22ee1c0bd1b 100644
+--- a/drivers/dpll/zl3073x/core.h
++++ b/drivers/dpll/zl3073x/core.h
+@@ -32,11 +32,13 @@ struct zl3073x_dpll;
+ enum zl3073x_flags {
+       ZL3073X_FLAG_REF_PHASE_COMP_32_BIT,
++      ZL3073X_FLAG_DIE_TEMP_BIT,
+       ZL3073X_FLAGS_NBITS /* must be last */
+ };
+ #define __ZL3073X_FLAG(name)  BIT(ZL3073X_FLAG_ ## name ## _BIT)
+ #define ZL3073X_FLAG_REF_PHASE_COMP_32        __ZL3073X_FLAG(REF_PHASE_COMP_32)
++#define ZL3073X_FLAG_DIE_TEMP         __ZL3073X_FLAG(DIE_TEMP)
+ /**
+  * struct zl3073x_chip_info - chip variant identification
+diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c
+index aaa14ea5e670fd..c201c974a7f9a4 100644
+--- a/drivers/dpll/zl3073x/dpll.c
++++ b/drivers/dpll/zl3073x/dpll.c
+@@ -1065,6 +1065,25 @@ zl3073x_dpll_output_pin_state_on_dpll_get(const struct dpll_pin *dpll_pin,
+       return 0;
+ }
++static int
++zl3073x_dpll_temp_get(const struct dpll_device *dpll, void *dpll_priv,
++                    s32 *temp, struct netlink_ext_ack *extack)
++{
++      struct zl3073x_dpll *zldpll = dpll_priv;
++      struct zl3073x_dev *zldev = zldpll->dev;
++      u16 val;
++      int rc;
++
++      rc = zl3073x_read_u16(zldev, ZL_REG_DIE_TEMP_STATUS, &val);
++      if (rc)
++              return rc;
++
++      /* Register value is in units of 0.1 C, convert to millidegrees */
++      *temp = (s16)val * 100;
++
++      return 0;
++}
++
+ static int
+ zl3073x_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv,
+                            enum dpll_lock_status *status,
+@@ -1671,6 +1690,10 @@ zl3073x_dpll_device_register(struct zl3073x_dpll *zldpll)
+       zldpll->forced_ref = FIELD_GET(ZL_DPLL_MODE_REFSEL_REF,
+                                      dpll_mode_refsel);
++      zldpll->ops = zl3073x_dpll_device_ops;
++      if (zldev->info->flags & ZL3073X_FLAG_DIE_TEMP)
++              zldpll->ops.temp_get = zl3073x_dpll_temp_get;
++
+       zldpll->dpll_dev = dpll_device_get(zldev->clock_id, zldpll->id,
+                                          THIS_MODULE, &zldpll->tracker);
+       if (IS_ERR(zldpll->dpll_dev)) {
+@@ -1682,7 +1705,7 @@ zl3073x_dpll_device_register(struct zl3073x_dpll *zldpll)
+       rc = dpll_device_register(zldpll->dpll_dev,
+                                 zl3073x_prop_dpll_type_get(zldev, zldpll->id),
+-                                &zl3073x_dpll_device_ops, zldpll);
++                                &zldpll->ops, zldpll);
+       if (rc) {
+               dpll_device_put(zldpll->dpll_dev, &zldpll->tracker);
+               zldpll->dpll_dev = NULL;
+@@ -1705,8 +1728,7 @@ zl3073x_dpll_device_unregister(struct zl3073x_dpll *zldpll)
+       cancel_work_sync(&zldpll->change_work);
+-      dpll_device_unregister(zldpll->dpll_dev, &zl3073x_dpll_device_ops,
+-                             zldpll);
++      dpll_device_unregister(zldpll->dpll_dev, &zldpll->ops, zldpll);
+       dpll_device_put(zldpll->dpll_dev, &zldpll->tracker);
+       zldpll->dpll_dev = NULL;
+ }
+diff --git a/drivers/dpll/zl3073x/dpll.h b/drivers/dpll/zl3073x/dpll.h
+index c65c798c37927f..278a24f357c9bd 100644
+--- a/drivers/dpll/zl3073x/dpll.h
++++ b/drivers/dpll/zl3073x/dpll.h
+@@ -17,6 +17,7 @@
+  * @forced_ref: selected reference in forced reference lock mode
+  * @check_count: periodic check counter
+  * @phase_monitor: is phase offset monitor enabled
++ * @ops: DPLL device operations for this instance
+  * @dpll_dev: pointer to registered DPLL device
+  * @tracker: tracking object for the acquired reference
+  * @lock_status: last saved DPLL lock status
+@@ -31,6 +32,7 @@ struct zl3073x_dpll {
+       u8                              forced_ref;
+       u8                              check_count;
+       bool                            phase_monitor;
++      struct dpll_device_ops          ops;
+       struct dpll_device              *dpll_dev;
+       dpll_tracker                    tracker;
+       enum dpll_lock_status           lock_status;
+diff --git a/drivers/dpll/zl3073x/regs.h b/drivers/dpll/zl3073x/regs.h
+index 5573d7188406bb..19c598daa784ca 100644
+--- a/drivers/dpll/zl3073x/regs.h
++++ b/drivers/dpll/zl3073x/regs.h
+@@ -78,6 +78,8 @@
+ #define ZL_REG_RESET_STATUS                   ZL_REG(0, 0x18, 1)
+ #define ZL_REG_RESET_STATUS_RESET             BIT(0)
++#define ZL_REG_DIE_TEMP_STATUS                        ZL_REG(0, 0x44, 2)
++
+ /*************************
+  * Register Page 2, Status
+  *************************/
+-- 
+2.53.0
+
diff --git a/queue-7.0/dpll-zl3073x-detect-dpll-channel-count-from-chip-id-.patch b/queue-7.0/dpll-zl3073x-detect-dpll-channel-count-from-chip-id-.patch
new file mode 100644 (file)
index 0000000..73646f5
--- /dev/null
@@ -0,0 +1,425 @@
+From 3dac0b76c78970a25972d9e63870f94dbfed9ba6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Feb 2026 11:52:59 +0100
+Subject: dpll: zl3073x: detect DPLL channel count from chip ID at runtime
+
+From: Ivan Vecera <ivecera@redhat.com>
+
+[ Upstream commit 4845f2fff730f0cdf8f7fe6401c8b871891cf1cb ]
+
+Replace the five per-variant zl3073x_chip_info structures and their
+exported symbol definitions with a single consolidated chip ID lookup
+table. The chip variant is now detected at runtime by reading the chip
+ID register from hardware and looking it up in the table, rather than
+being selected at compile time via the bus driver match data.
+
+Repurpose struct zl3073x_chip_info to hold a single chip ID, its
+channel count, and a flags field. Introduce enum zl3073x_flags with
+ZL3073X_FLAG_REF_PHASE_COMP_32 to replace the chip_id switch statement
+in zl3073x_dev_is_ref_phase_comp_32bit(). Store a pointer to the
+detected chip_info entry in struct zl3073x_dev for runtime access.
+
+This simplifies the bus drivers by removing per-variant .data and
+.driver_data references from the I2C/SPI match tables, and makes
+adding support for new chip variants a single-line table addition.
+
+Signed-off-by: Ivan Vecera <ivecera@redhat.com>
+Link: https://patch.msgid.link/20260227105300.710272-2-ivecera@redhat.com
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: d733f519f644 ("dpll: zl3073x: use __dpll_device_change_ntf() and remove change_work")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dpll/zl3073x/core.c | 118 ++++++++++--------------------------
+ drivers/dpll/zl3073x/core.h |  57 +++++++++--------
+ drivers/dpll/zl3073x/i2c.c  |  37 ++++-------
+ drivers/dpll/zl3073x/spi.c  |  37 ++++-------
+ 4 files changed, 82 insertions(+), 167 deletions(-)
+
+diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c
+index 37f3c33570eef2..c8af3430104505 100644
+--- a/drivers/dpll/zl3073x/core.c
++++ b/drivers/dpll/zl3073x/core.c
+@@ -20,79 +20,30 @@
+ #include "dpll.h"
+ #include "regs.h"
+-/* Chip IDs for zl30731 */
+-static const u16 zl30731_ids[] = {
+-      0x0E93,
+-      0x1E93,
+-      0x2E93,
++#define ZL_CHIP_INFO(_id, _nchannels, _flags)                         \
++      { .id = (_id), .num_channels = (_nchannels), .flags = (_flags) }
++
++static const struct zl3073x_chip_info zl3073x_chip_ids[] = {
++      ZL_CHIP_INFO(0x0E30, 2, ZL3073X_FLAG_REF_PHASE_COMP_32),
++      ZL_CHIP_INFO(0x0E93, 1, ZL3073X_FLAG_REF_PHASE_COMP_32),
++      ZL_CHIP_INFO(0x0E94, 2, ZL3073X_FLAG_REF_PHASE_COMP_32),
++      ZL_CHIP_INFO(0x0E95, 3, ZL3073X_FLAG_REF_PHASE_COMP_32),
++      ZL_CHIP_INFO(0x0E96, 4, ZL3073X_FLAG_REF_PHASE_COMP_32),
++      ZL_CHIP_INFO(0x0E97, 5, ZL3073X_FLAG_REF_PHASE_COMP_32),
++      ZL_CHIP_INFO(0x1E93, 1, 0),
++      ZL_CHIP_INFO(0x1E94, 2, 0),
++      ZL_CHIP_INFO(0x1E95, 3, 0),
++      ZL_CHIP_INFO(0x1E96, 4, 0),
++      ZL_CHIP_INFO(0x1E97, 5, 0),
++      ZL_CHIP_INFO(0x1F60, 2, ZL3073X_FLAG_REF_PHASE_COMP_32),
++      ZL_CHIP_INFO(0x2E93, 1, 0),
++      ZL_CHIP_INFO(0x2E94, 2, 0),
++      ZL_CHIP_INFO(0x2E95, 3, 0),
++      ZL_CHIP_INFO(0x2E96, 4, 0),
++      ZL_CHIP_INFO(0x2E97, 5, 0),
++      ZL_CHIP_INFO(0x3FC4, 2, 0),
+ };
+-const struct zl3073x_chip_info zl30731_chip_info = {
+-      .ids = zl30731_ids,
+-      .num_ids = ARRAY_SIZE(zl30731_ids),
+-      .num_channels = 1,
+-};
+-EXPORT_SYMBOL_NS_GPL(zl30731_chip_info, "ZL3073X");
+-
+-/* Chip IDs for zl30732 */
+-static const u16 zl30732_ids[] = {
+-      0x0E30,
+-      0x0E94,
+-      0x1E94,
+-      0x1F60,
+-      0x2E94,
+-      0x3FC4,
+-};
+-
+-const struct zl3073x_chip_info zl30732_chip_info = {
+-      .ids = zl30732_ids,
+-      .num_ids = ARRAY_SIZE(zl30732_ids),
+-      .num_channels = 2,
+-};
+-EXPORT_SYMBOL_NS_GPL(zl30732_chip_info, "ZL3073X");
+-
+-/* Chip IDs for zl30733 */
+-static const u16 zl30733_ids[] = {
+-      0x0E95,
+-      0x1E95,
+-      0x2E95,
+-};
+-
+-const struct zl3073x_chip_info zl30733_chip_info = {
+-      .ids = zl30733_ids,
+-      .num_ids = ARRAY_SIZE(zl30733_ids),
+-      .num_channels = 3,
+-};
+-EXPORT_SYMBOL_NS_GPL(zl30733_chip_info, "ZL3073X");
+-
+-/* Chip IDs for zl30734 */
+-static const u16 zl30734_ids[] = {
+-      0x0E96,
+-      0x1E96,
+-      0x2E96,
+-};
+-
+-const struct zl3073x_chip_info zl30734_chip_info = {
+-      .ids = zl30734_ids,
+-      .num_ids = ARRAY_SIZE(zl30734_ids),
+-      .num_channels = 4,
+-};
+-EXPORT_SYMBOL_NS_GPL(zl30734_chip_info, "ZL3073X");
+-
+-/* Chip IDs for zl30735 */
+-static const u16 zl30735_ids[] = {
+-      0x0E97,
+-      0x1E97,
+-      0x2E97,
+-};
+-
+-const struct zl3073x_chip_info zl30735_chip_info = {
+-      .ids = zl30735_ids,
+-      .num_ids = ARRAY_SIZE(zl30735_ids),
+-      .num_channels = 5,
+-};
+-EXPORT_SYMBOL_NS_GPL(zl30735_chip_info, "ZL3073X");
+-
+ #define ZL_RANGE_OFFSET               0x80
+ #define ZL_PAGE_SIZE          0x80
+ #define ZL_NUM_PAGES          256
+@@ -942,7 +893,7 @@ static void zl3073x_dev_dpll_fini(void *ptr)
+ }
+ static int
+-zl3073x_devm_dpll_init(struct zl3073x_dev *zldev, u8 num_dplls)
++zl3073x_devm_dpll_init(struct zl3073x_dev *zldev)
+ {
+       struct kthread_worker *kworker;
+       struct zl3073x_dpll *zldpll;
+@@ -952,7 +903,7 @@ zl3073x_devm_dpll_init(struct zl3073x_dev *zldev, u8 num_dplls)
+       INIT_LIST_HEAD(&zldev->dplls);
+       /* Allocate all DPLLs */
+-      for (i = 0; i < num_dplls; i++) {
++      for (i = 0; i < zldev->info->num_channels; i++) {
+               zldpll = zl3073x_dpll_alloc(zldev, i);
+               if (IS_ERR(zldpll)) {
+                       dev_err_probe(zldev->dev, PTR_ERR(zldpll),
+@@ -992,14 +943,12 @@ zl3073x_devm_dpll_init(struct zl3073x_dev *zldev, u8 num_dplls)
+ /**
+  * zl3073x_dev_probe - initialize zl3073x device
+  * @zldev: pointer to zl3073x device
+- * @chip_info: chip info based on compatible
+  *
+  * Common initialization of zl3073x device structure.
+  *
+  * Returns: 0 on success, <0 on error
+  */
+-int zl3073x_dev_probe(struct zl3073x_dev *zldev,
+-                    const struct zl3073x_chip_info *chip_info)
++int zl3073x_dev_probe(struct zl3073x_dev *zldev)
+ {
+       u16 id, revision, fw_ver;
+       unsigned int i;
+@@ -1011,18 +960,17 @@ int zl3073x_dev_probe(struct zl3073x_dev *zldev,
+       if (rc)
+               return rc;
+-      /* Check it matches */
+-      for (i = 0; i < chip_info->num_ids; i++) {
+-              if (id == chip_info->ids[i])
++      /* Detect chip variant */
++      for (i = 0; i < ARRAY_SIZE(zl3073x_chip_ids); i++) {
++              if (zl3073x_chip_ids[i].id == id)
+                       break;
+       }
+-      if (i == chip_info->num_ids) {
++      if (i == ARRAY_SIZE(zl3073x_chip_ids))
+               return dev_err_probe(zldev->dev, -ENODEV,
+-                                   "Unknown or non-match chip ID: 0x%0x\n",
+-                                   id);
+-      }
+-      zldev->chip_id = id;
++                                   "Unknown chip ID: 0x%04x\n", id);
++
++      zldev->info = &zl3073x_chip_ids[i];
+       /* Read revision, firmware version and custom config version */
+       rc = zl3073x_read_u16(zldev, ZL_REG_REVISION, &revision);
+@@ -1061,7 +1009,7 @@ int zl3073x_dev_probe(struct zl3073x_dev *zldev,
+                                    "Failed to initialize mutex\n");
+       /* Register DPLL channels */
+-      rc = zl3073x_devm_dpll_init(zldev, chip_info->num_channels);
++      rc = zl3073x_devm_dpll_init(zldev);
+       if (rc)
+               return rc;
+diff --git a/drivers/dpll/zl3073x/core.h b/drivers/dpll/zl3073x/core.h
+index fd2af3c62a7d5c..fde5c8371fbd28 100644
+--- a/drivers/dpll/zl3073x/core.h
++++ b/drivers/dpll/zl3073x/core.h
+@@ -30,12 +30,32 @@ struct zl3073x_dpll;
+ #define ZL3073X_NUM_PINS      (ZL3073X_NUM_INPUT_PINS + \
+                                ZL3073X_NUM_OUTPUT_PINS)
++enum zl3073x_flags {
++      ZL3073X_FLAG_REF_PHASE_COMP_32_BIT,
++      ZL3073X_FLAGS_NBITS /* must be last */
++};
++
++#define __ZL3073X_FLAG(name)  BIT(ZL3073X_FLAG_ ## name ## _BIT)
++#define ZL3073X_FLAG_REF_PHASE_COMP_32        __ZL3073X_FLAG(REF_PHASE_COMP_32)
++
++/**
++ * struct zl3073x_chip_info - chip variant identification
++ * @id: chip ID
++ * @num_channels: number of DPLL channels supported by this variant
++ * @flags: chip variant flags
++ */
++struct zl3073x_chip_info {
++      u16             id;
++      u8              num_channels;
++      unsigned long   flags;
++};
++
+ /**
+  * struct zl3073x_dev - zl3073x device
+  * @dev: pointer to device
+  * @regmap: regmap to access device registers
++ * @info: detected chip info
+  * @multiop_lock: to serialize multiple register operations
+- * @chip_id: chip ID read from hardware
+  * @ref: array of input references' invariants
+  * @out: array of outs' invariants
+  * @synth: array of synths' invariants
+@@ -46,10 +66,10 @@ struct zl3073x_dpll;
+  * @phase_avg_factor: phase offset measurement averaging factor
+  */
+ struct zl3073x_dev {
+-      struct device           *dev;
+-      struct regmap           *regmap;
+-      struct mutex            multiop_lock;
+-      u16                     chip_id;
++      struct device                   *dev;
++      struct regmap                   *regmap;
++      const struct zl3073x_chip_info  *info;
++      struct mutex                    multiop_lock;
+       /* Invariants */
+       struct zl3073x_ref      ref[ZL3073X_NUM_REFS];
+@@ -68,22 +88,10 @@ struct zl3073x_dev {
+       u8                      phase_avg_factor;
+ };
+-struct zl3073x_chip_info {
+-      const u16       *ids;
+-      size_t          num_ids;
+-      int             num_channels;
+-};
+-
+-extern const struct zl3073x_chip_info zl30731_chip_info;
+-extern const struct zl3073x_chip_info zl30732_chip_info;
+-extern const struct zl3073x_chip_info zl30733_chip_info;
+-extern const struct zl3073x_chip_info zl30734_chip_info;
+-extern const struct zl3073x_chip_info zl30735_chip_info;
+ extern const struct regmap_config zl3073x_regmap_config;
+ struct zl3073x_dev *zl3073x_devm_alloc(struct device *dev);
+-int zl3073x_dev_probe(struct zl3073x_dev *zldev,
+-                    const struct zl3073x_chip_info *chip_info);
++int zl3073x_dev_probe(struct zl3073x_dev *zldev);
+ int zl3073x_dev_start(struct zl3073x_dev *zldev, bool full);
+ void zl3073x_dev_stop(struct zl3073x_dev *zldev);
+@@ -158,18 +166,7 @@ int zl3073x_ref_phase_offsets_update(struct zl3073x_dev *zldev, int channel);
+ static inline bool
+ zl3073x_dev_is_ref_phase_comp_32bit(struct zl3073x_dev *zldev)
+ {
+-      switch (zldev->chip_id) {
+-      case 0x0E30:
+-      case 0x0E93:
+-      case 0x0E94:
+-      case 0x0E95:
+-      case 0x0E96:
+-      case 0x0E97:
+-      case 0x1F60:
+-              return true;
+-      default:
+-              return false;
+-      }
++      return zldev->info->flags & ZL3073X_FLAG_REF_PHASE_COMP_32;
+ }
+ static inline bool
+diff --git a/drivers/dpll/zl3073x/i2c.c b/drivers/dpll/zl3073x/i2c.c
+index 7bbfdd4ed8671d..979df85826abcc 100644
+--- a/drivers/dpll/zl3073x/i2c.c
++++ b/drivers/dpll/zl3073x/i2c.c
+@@ -22,40 +22,25 @@ static int zl3073x_i2c_probe(struct i2c_client *client)
+               return dev_err_probe(dev, PTR_ERR(zldev->regmap),
+                                    "Failed to initialize regmap\n");
+-      return zl3073x_dev_probe(zldev, i2c_get_match_data(client));
++      return zl3073x_dev_probe(zldev);
+ }
+ static const struct i2c_device_id zl3073x_i2c_id[] = {
+-      {
+-              .name = "zl30731",
+-              .driver_data = (kernel_ulong_t)&zl30731_chip_info,
+-      },
+-      {
+-              .name = "zl30732",
+-              .driver_data = (kernel_ulong_t)&zl30732_chip_info,
+-      },
+-      {
+-              .name = "zl30733",
+-              .driver_data = (kernel_ulong_t)&zl30733_chip_info,
+-      },
+-      {
+-              .name = "zl30734",
+-              .driver_data = (kernel_ulong_t)&zl30734_chip_info,
+-      },
+-      {
+-              .name = "zl30735",
+-              .driver_data = (kernel_ulong_t)&zl30735_chip_info,
+-      },
++      { "zl30731" },
++      { "zl30732" },
++      { "zl30733" },
++      { "zl30734" },
++      { "zl30735" },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(i2c, zl3073x_i2c_id);
+ static const struct of_device_id zl3073x_i2c_of_match[] = {
+-      { .compatible = "microchip,zl30731", .data = &zl30731_chip_info },
+-      { .compatible = "microchip,zl30732", .data = &zl30732_chip_info },
+-      { .compatible = "microchip,zl30733", .data = &zl30733_chip_info },
+-      { .compatible = "microchip,zl30734", .data = &zl30734_chip_info },
+-      { .compatible = "microchip,zl30735", .data = &zl30735_chip_info },
++      { .compatible = "microchip,zl30731" },
++      { .compatible = "microchip,zl30732" },
++      { .compatible = "microchip,zl30733" },
++      { .compatible = "microchip,zl30734" },
++      { .compatible = "microchip,zl30735" },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, zl3073x_i2c_of_match);
+diff --git a/drivers/dpll/zl3073x/spi.c b/drivers/dpll/zl3073x/spi.c
+index af901b4d6dda06..f024f42b78d05f 100644
+--- a/drivers/dpll/zl3073x/spi.c
++++ b/drivers/dpll/zl3073x/spi.c
+@@ -22,40 +22,25 @@ static int zl3073x_spi_probe(struct spi_device *spi)
+               return dev_err_probe(dev, PTR_ERR(zldev->regmap),
+                                    "Failed to initialize regmap\n");
+-      return zl3073x_dev_probe(zldev, spi_get_device_match_data(spi));
++      return zl3073x_dev_probe(zldev);
+ }
+ static const struct spi_device_id zl3073x_spi_id[] = {
+-      {
+-              .name = "zl30731",
+-              .driver_data = (kernel_ulong_t)&zl30731_chip_info
+-      },
+-      {
+-              .name = "zl30732",
+-              .driver_data = (kernel_ulong_t)&zl30732_chip_info,
+-      },
+-      {
+-              .name = "zl30733",
+-              .driver_data = (kernel_ulong_t)&zl30733_chip_info,
+-      },
+-      {
+-              .name = "zl30734",
+-              .driver_data = (kernel_ulong_t)&zl30734_chip_info,
+-      },
+-      {
+-              .name = "zl30735",
+-              .driver_data = (kernel_ulong_t)&zl30735_chip_info,
+-      },
++      { "zl30731" },
++      { "zl30732" },
++      { "zl30733" },
++      { "zl30734" },
++      { "zl30735" },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(spi, zl3073x_spi_id);
+ static const struct of_device_id zl3073x_spi_of_match[] = {
+-      { .compatible = "microchip,zl30731", .data = &zl30731_chip_info },
+-      { .compatible = "microchip,zl30732", .data = &zl30732_chip_info },
+-      { .compatible = "microchip,zl30733", .data = &zl30733_chip_info },
+-      { .compatible = "microchip,zl30734", .data = &zl30734_chip_info },
+-      { .compatible = "microchip,zl30735", .data = &zl30735_chip_info },
++      { .compatible = "microchip,zl30731" },
++      { .compatible = "microchip,zl30732" },
++      { .compatible = "microchip,zl30733" },
++      { .compatible = "microchip,zl30734" },
++      { .compatible = "microchip,zl30735" },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, zl3073x_spi_of_match);
+-- 
+2.53.0
+
diff --git a/queue-7.0/dpll-zl3073x-use-__dpll_device_change_ntf-and-remove.patch b/queue-7.0/dpll-zl3073x-use-__dpll_device_change_ntf-and-remove.patch
new file mode 100644 (file)
index 0000000..109001a
--- /dev/null
@@ -0,0 +1,114 @@
+From 9087e846d722a4fba9f263ff9430a9f19be5c7cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 09:45:24 +0200
+Subject: dpll: zl3073x: use __dpll_device_change_ntf() and remove change_work
+
+From: Ivan Vecera <ivecera@redhat.com>
+
+[ Upstream commit d733f519f6443540f8359461a34e3b0042099bbe ]
+
+The change_work was introduced to send device change notifications
+from DPLL device callbacks without deadlocking on dpll_lock, since
+the callbacks are already invoked under that lock. Now that
+__dpll_device_change_ntf() is exported for callers that already
+hold dpll_lock, use it directly and remove the change_work
+infrastructure entirely.
+
+This eliminates a race condition where change_work could be
+re-scheduled after cancel_work_sync() during device teardown,
+potentially causing the handler to dereference a freed or NULL
+dpll_dev pointer.
+
+Fixes: 9363b4837659 ("dpll: zl3073x: Allow to configure phase offset averaging factor")
+Signed-off-by: Ivan Vecera <ivecera@redhat.com>
+Link: https://patch.msgid.link/20260526074525.1451008-3-ivecera@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dpll/zl3073x/dpll.c | 26 +++++++++-----------------
+ drivers/dpll/zl3073x/dpll.h |  2 --
+ 2 files changed, 9 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c
+index c201c974a7f9a4..70c91948c7da8d 100644
+--- a/drivers/dpll/zl3073x/dpll.c
++++ b/drivers/dpll/zl3073x/dpll.c
+@@ -1193,15 +1193,6 @@ zl3073x_dpll_phase_offset_avg_factor_get(const struct dpll_device *dpll,
+       return 0;
+ }
+-static void
+-zl3073x_dpll_change_work(struct work_struct *work)
+-{
+-      struct zl3073x_dpll *zldpll;
+-
+-      zldpll = container_of(work, struct zl3073x_dpll, change_work);
+-      dpll_device_change_ntf(zldpll->dpll_dev);
+-}
+-
+ static int
+ zl3073x_dpll_phase_offset_avg_factor_set(const struct dpll_device *dpll,
+                                        void *dpll_priv, u32 factor,
+@@ -1227,8 +1218,10 @@ zl3073x_dpll_phase_offset_avg_factor_set(const struct dpll_device *dpll,
+        * we have to send a notification for other DPLL devices.
+        */
+       list_for_each_entry(item, &zldpll->dev->dplls, list) {
+-              if (item != zldpll)
+-                      schedule_work(&item->change_work);
++              struct dpll_device *dpll_dev = READ_ONCE(item->dpll_dev);
++
++              if (item != zldpll && dpll_dev)
++                      __dpll_device_change_ntf(dpll_dev);
+       }
+       return 0;
+@@ -1724,13 +1717,13 @@ zl3073x_dpll_device_register(struct zl3073x_dpll *zldpll)
+ static void
+ zl3073x_dpll_device_unregister(struct zl3073x_dpll *zldpll)
+ {
+-      WARN(!zldpll->dpll_dev, "DPLL device is not registered\n");
++      struct dpll_device *dpll_dev = READ_ONCE(zldpll->dpll_dev);
+-      cancel_work_sync(&zldpll->change_work);
++      WARN(!dpll_dev, "DPLL device is not registered\n");
+-      dpll_device_unregister(zldpll->dpll_dev, &zldpll->ops, zldpll);
+-      dpll_device_put(zldpll->dpll_dev, &zldpll->tracker);
+-      zldpll->dpll_dev = NULL;
++      WRITE_ONCE(zldpll->dpll_dev, NULL);
++      dpll_device_unregister(dpll_dev, &zldpll->ops, zldpll);
++      dpll_device_put(dpll_dev, &zldpll->tracker);
+ }
+ /**
+@@ -1976,7 +1969,6 @@ zl3073x_dpll_alloc(struct zl3073x_dev *zldev, u8 ch)
+       zldpll->dev = zldev;
+       zldpll->id = ch;
+       INIT_LIST_HEAD(&zldpll->pins);
+-      INIT_WORK(&zldpll->change_work, zl3073x_dpll_change_work);
+       return zldpll;
+ }
+diff --git a/drivers/dpll/zl3073x/dpll.h b/drivers/dpll/zl3073x/dpll.h
+index 278a24f357c9bd..241253212f7d57 100644
+--- a/drivers/dpll/zl3073x/dpll.h
++++ b/drivers/dpll/zl3073x/dpll.h
+@@ -22,7 +22,6 @@
+  * @tracker: tracking object for the acquired reference
+  * @lock_status: last saved DPLL lock status
+  * @pins: list of pins
+- * @change_work: device change notification work
+  */
+ struct zl3073x_dpll {
+       struct list_head                list;
+@@ -37,7 +36,6 @@ struct zl3073x_dpll {
+       dpll_tracker                    tracker;
+       enum dpll_lock_status           lock_status;
+       struct list_head                pins;
+-      struct work_struct              change_work;
+ };
+ struct zl3073x_dpll *zl3073x_dpll_alloc(struct zl3073x_dev *zldev, u8 ch);
+-- 
+2.53.0
+
diff --git a/queue-7.0/drm-i915-aux-use-polling-when-irqs-are-unavailable.patch b/queue-7.0/drm-i915-aux-use-polling-when-irqs-are-unavailable.patch
new file mode 100644 (file)
index 0000000..db40a2b
--- /dev/null
@@ -0,0 +1,85 @@
+From 1306c5b24b5b65cb690ad7ce8f3be661f2c1b5aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Apr 2026 18:37:44 +0200
+Subject: drm/i915/aux: use polling when irqs are unavailable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: MichaÅ‚ Grzelak <michal.grzelak@intel.com>
+
+[ Upstream commit 202e77cf2e839e1adc804433322dc5c9ee511c9f ]
+
+PTL with physically disconnected display was observed to have 40s longer
+execution time when testing xe_fault_injection@xe_guc_mmio_send_recv.
+The issue has not been seen when reverting commit 40a9f77a28fa ("Revert
+"drm/i915/dp: change aux_ctl reg read to polling read"").
+
+Apparently the configuration suffers from not having AUX enabled when
+using interrupts. One probable cause can be xe enabling interrupts too
+late: interrupts need memory allocations which currently can't be done
+before the display FB takeover is done.
+
+As for now, use polling for AUX in case interrupts are unavailable.
+
+Fixes: 40a9f77a28fa ("Revert "drm/i915/dp: change aux_ctl reg read to polling read"")
+Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Signed-off-by: MichaÅ‚ Grzelak <michal.grzelak@intel.com>
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patch.msgid.link/20260416163744.288107-1-michal.grzelak@intel.com
+(cherry picked from commit 05e0550b65cd1604bd515fbc65f522bce4c10a87)
+Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_dp_aux.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c
+index b20ec3e589fadc..9c9b6410366d5c 100644
+--- a/drivers/gpu/drm/i915/display/intel_dp_aux.c
++++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c
+@@ -12,6 +12,7 @@
+ #include "intel_dp.h"
+ #include "intel_dp_aux.h"
+ #include "intel_dp_aux_regs.h"
++#include "intel_parent.h"
+ #include "intel_pps.h"
+ #include "intel_quirks.h"
+ #include "intel_tc.h"
+@@ -60,18 +61,29 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp)
+       struct intel_display *display = to_intel_display(intel_dp);
+       i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp);
+       const unsigned int timeout_ms = 10;
++      bool done = true;
+       u32 status;
+-      bool done;
++      int ret;
++      if (intel_parent_irq_enabled(display)) {
+ #define C (((status = intel_de_read_notrace(display, ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0)
+-      done = wait_event_timeout(display->gmbus.wait_queue, C,
+-                                msecs_to_jiffies_timeout(timeout_ms));
++              done = wait_event_timeout(display->gmbus.wait_queue, C,
++                                        msecs_to_jiffies_timeout(timeout_ms));
++
++#undef C
++      } else {
++              ret = intel_de_wait_ms(display, ch_ctl,
++                                     DP_AUX_CH_CTL_SEND_BUSY, 0,
++                                     timeout_ms, &status);
++
++              if (ret == -ETIMEDOUT)
++                      done = false;
++      }
+       if (!done)
+               drm_err(display->drm,
+                       "%s: did not complete or timeout within %ums (status 0x%08x)\n",
+                       intel_dp->aux.name, timeout_ms, status);
+-#undef C
+       return status;
+ }
+-- 
+2.53.0
+
diff --git a/queue-7.0/drm-xe-restore-idledly-regiter-on-engine-reset.patch b/queue-7.0/drm-xe-restore-idledly-regiter-on-engine-reset.patch
new file mode 100644 (file)
index 0000000..df3f11c
--- /dev/null
@@ -0,0 +1,43 @@
+From a1a6c6d3e5d15f7e92b8c260bcf13e3cfff779fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 22:05:32 +0530
+Subject: drm/xe: Restore IDLEDLY regiter on engine reset
+
+From: Balasubramani Vivekanandan <balasubramani.vivekanandan@intel.com>
+
+[ Upstream commit f657a6a3ba4c20bc01f5be3752d53498ee1bfe35 ]
+
+Wa_16023105232 programs the register IDLEDLY. The register is reset
+whenever the engine is reset. Therefore it should be added to the GuC
+save-restore register list for it to be restored after reset.
+
+Fixes: 7c53ff050ba8 ("drm/xe: Apply Wa_16023105232")
+Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patch.msgid.link/20260522163531.1365540-2-balasubramani.vivekanandan@intel.com
+Signed-off-by: Balasubramani Vivekanandan <balasubramani.vivekanandan@intel.com>
+(cherry picked from commit df1cfe24743a93b71eab27687e148ab8ae9b69e3)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_ads.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_ads.c b/drivers/gpu/drm/xe/xe_guc_ads.c
+index f4cbc030f4c81b..904225cbff0d8a 100644
+--- a/drivers/gpu/drm/xe/xe_guc_ads.c
++++ b/drivers/gpu/drm/xe/xe_guc_ads.c
+@@ -770,6 +770,11 @@ static unsigned int guc_mmio_regset_write(struct xe_guc_ads *ads,
+               }
+       }
++      if (XE_GT_WA(hwe->gt, 16023105232))
++              guc_mmio_regset_write_one(ads, regset_map,
++                                        RING_IDLEDLY(hwe->mmio_base),
++                                        count++);
++
+       return count;
+ }
+-- 
+2.53.0
+
diff --git a/queue-7.0/esp-fix-page-frag-reference-leak-on-skb_to_sgvec-fai.patch b/queue-7.0/esp-fix-page-frag-reference-leak-on-skb_to_sgvec-fai.patch
new file mode 100644 (file)
index 0000000..cbb4be9
--- /dev/null
@@ -0,0 +1,152 @@
+From e3d5ae76091ea58f31ca35eee643a7f009d535da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 09:27:17 +0200
+Subject: esp: fix page frag reference leak on skb_to_sgvec failure
+
+From: e521588 <alessandro.schino@sbb.ch>
+
+[ Upstream commit 2982e599fff6faa21c8df147d96fc7af6c1a2f24 ]
+
+In esp_output_tail(), when esp->inplace is false, the old skb page frags
+are replaced with a new page from the xfrm page_frag cache. The source
+scatterlist (sg) is built from the old frags before the replacement, and
+esp_ssg_unref() is responsible for releasing the old page references
+after the crypto operation completes.
+
+However, if the second skb_to_sgvec() call (which builds the destination
+scatterlist from the new page) fails, the code jumps to error_free which
+only calls kfree(tmp). The old page frag references captured in the
+source scatterlist are never released:
+
+  1. sg[] is built from old frags via skb_to_sgvec() (no extra get_page)
+  2. nr_frags is set to 1 and frag[0] is replaced with the new page
+  3. Second skb_to_sgvec() fails -> goto error_free
+  4. kfree(tmp) frees the sg[] memory but old frags are not unref'd
+  5. kfree_skb() only releases frag[0] (the new page), not the old ones
+
+Fix this by adding a bool parameter to esp_ssg_unref() that, when true,
+unconditionally unrefs the source scatterlist frags without checking
+req->src and req->dst, since those fields are not yet initialized by
+aead_request_set_crypt() at the point of the error. Existing callers
+pass false to preserve the original behavior.
+
+The same issue exists in both esp4 and esp6 as the code is identical.
+
+Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible")
+Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible")
+
+Signed-off-by: Alessandro Schino <7991aleschino@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/esp4.c | 12 +++++++-----
+ net/ipv6/esp6.c | 12 +++++++-----
+ 2 files changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
+index 6a5febbdbee493..8314d7bddcb715 100644
+--- a/net/ipv4/esp4.c
++++ b/net/ipv4/esp4.c
+@@ -96,7 +96,7 @@ static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
+                            __alignof__(struct scatterlist));
+ }
+-static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
++static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb, bool already_unref)
+ {
+       struct crypto_aead *aead = x->data;
+       int extralen = 0;
+@@ -113,7 +113,7 @@ static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
+       /* Unref skb_frag_pages in the src scatterlist if necessary.
+        * Skip the first sg which comes from skb->data.
+        */
+-      if (req->src != req->dst)
++      if (already_unref || req->src != req->dst)
+               for (sg = sg_next(req->src); sg; sg = sg_next(sg))
+                       skb_page_unref(page_to_netmem(sg_page(sg)),
+                                      skb->pp_recycle);
+@@ -220,7 +220,7 @@ static void esp_output_done(void *data, int err)
+       }
+       tmp = ESP_SKB_CB(skb)->tmp;
+-      esp_ssg_unref(x, tmp, skb);
++      esp_ssg_unref(x, tmp, skb, false);
+       kfree(tmp);
+       if (xo && (xo->flags & XFRM_DEV_RESUME)) {
+@@ -569,8 +569,10 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
+               err = skb_to_sgvec(skb, dsg,
+                                  (unsigned char *)esph - skb->data,
+                                  assoclen + ivlen + esp->clen + alen);
+-              if (unlikely(err < 0))
++              if (unlikely(err < 0)) {
++                      esp_ssg_unref(x, tmp, skb, true);
+                       goto error_free;
++              }
+       }
+       if ((x->props.flags & XFRM_STATE_ESN))
+@@ -602,7 +604,7 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
+       }
+       if (sg != dsg)
+-              esp_ssg_unref(x, tmp, skb);
++              esp_ssg_unref(x, tmp, skb, false);
+       if (!err && x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
+               err = esp_output_tail_tcp(x, skb);
+diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
+index 9c06c5a1419dc4..9d0c4957ac6276 100644
+--- a/net/ipv6/esp6.c
++++ b/net/ipv6/esp6.c
+@@ -113,7 +113,7 @@ static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
+                            __alignof__(struct scatterlist));
+ }
+-static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
++static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb, bool already_unref)
+ {
+       struct crypto_aead *aead = x->data;
+       int extralen = 0;
+@@ -130,7 +130,7 @@ static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
+       /* Unref skb_frag_pages in the src scatterlist if necessary.
+        * Skip the first sg which comes from skb->data.
+        */
+-      if (req->src != req->dst)
++      if (already_unref || req->src != req->dst)
+               for (sg = sg_next(req->src); sg; sg = sg_next(sg))
+                       skb_page_unref(page_to_netmem(sg_page(sg)),
+                                      skb->pp_recycle);
+@@ -254,7 +254,7 @@ static void esp_output_done(void *data, int err)
+       }
+       tmp = ESP_SKB_CB(skb)->tmp;
+-      esp_ssg_unref(x, tmp, skb);
++      esp_ssg_unref(x, tmp, skb, false);
+       kfree(tmp);
+       esp_output_encap_csum(skb);
+@@ -600,8 +600,10 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
+               err = skb_to_sgvec(skb, dsg,
+                                  (unsigned char *)esph - skb->data,
+                                  assoclen + ivlen + esp->clen + alen);
+-              if (unlikely(err < 0))
++              if (unlikely(err < 0)) {
++                      esp_ssg_unref(x, tmp, skb, true);
+                       goto error_free;
++              }
+       }
+       if ((x->props.flags & XFRM_STATE_ESN))
+@@ -634,7 +636,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
+       }
+       if (sg != dsg)
+-              esp_ssg_unref(x, tmp, skb);
++              esp_ssg_unref(x, tmp, skb, false);
+       if (!err && x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
+               err = esp_output_tail_tcp(x, skb);
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-cmis-fix-u16-to-u8-truncation-of-msleep_pre_.patch b/queue-7.0/ethtool-cmis-fix-u16-to-u8-truncation-of-msleep_pre_.patch
new file mode 100644 (file)
index 0000000..b584473
--- /dev/null
@@ -0,0 +1,52 @@
+From 2dca642becb9dc2f2f618672bf5b8224075c5055 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:10 -0700
+Subject: ethtool: cmis: fix u16-to-u8 truncation of msleep_pre_rpl
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 3e8c3d464c36bb342fe377b026577c7ec27fdbb4 ]
+
+ethtool_cmis_cdb_compose_args() accepts msleep_pre_rpl as u16 but stores
+it into the u8 field ethtool_cmis_cdb_cmd_args::msleep_pre_rpl, silently
+truncating values >= 256. Seven of the nine call sites pass 1000 ms
+(it's the third argument from the end).
+
+Fixes: a39c84d79625 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-8-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
+index 4a9a946cabf05d..778783a0f23c0b 100644
+--- a/net/ethtool/cmis.h
++++ b/net/ethtool/cmis.h
+@@ -63,9 +63,9 @@ struct ethtool_cmis_cdb_request {
+  * struct ethtool_cmis_cdb_cmd_args - CDB commands execution arguments
+  * @req: CDB command fields as described in the CMIS standard.
+  * @max_duration: Maximum duration time for command completion in msec.
++ * @msleep_pre_rpl: Waiting time before checking reply in msec.
+  * @read_write_len_ext: Allowable additional number of byte octets to the LPL
+  *                    in a READ or a WRITE commands.
+- * @msleep_pre_rpl: Waiting time before checking reply in msec.
+  * @rpl_exp_len: Expected reply length in bytes.
+  * @flags: Validation flags for CDB commands.
+  * @err_msg: Error message to be sent to user space.
+@@ -73,8 +73,8 @@ struct ethtool_cmis_cdb_request {
+ struct ethtool_cmis_cdb_cmd_args {
+       struct ethtool_cmis_cdb_request req;
+       u16                             max_duration;
++      u16                             msleep_pre_rpl;
+       u8                              read_write_len_ext;
+-      u8                              msleep_pre_rpl;
+       u8                              rpl_exp_len;
+       u8                              flags;
+       char                            *err_msg;
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-cmis-require-exact-cdb-reply-length.patch b/queue-7.0/ethtool-cmis-require-exact-cdb-reply-length.patch
new file mode 100644 (file)
index 0000000..4f8fb6a
--- /dev/null
@@ -0,0 +1,70 @@
+From e87c6d88d165888efbf2a4d6902294a2b5646f7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:09 -0700
+Subject: ethtool: cmis: require exact CDB reply length
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 6c3f999a9d1338c6c89a9ff4549eafe72bc2e7b1 ]
+
+Malicious SFP module could respond with rpl_len longer than
+what cmis_cdb_process_reply() expected, leading to OOB writes.
+Malicious HW is a bit theoretical but some modules may just
+be buggy and/or the reads may occasionally get corrupted,
+so let's protect the kernel.
+
+The existing check protects from short replies. We need to
+protect from long ones, too. All callers that pass a non-zero
+rpl_exp_len cast the reply payload to a fixed-layout struct
+and read fields at fixed offsets, with no version negotiation
+or short-reply handling:
+
+  - cmis_cdb_validate_password()
+  - cmis_cdb_module_features_get()
+  - cmis_fw_update_fw_mng_features_get()
+
+so let's assume that responses longer than expected do not
+have to be handled gracefully here. Add a warning message
+to make the debug easier in case my understanding is wrong...
+
+Note that page_data->length (argument of kmalloc) comes from
+last arg to ethtool_cmis_page_init() which is rpl_exp_len.
+
+Note2 that AIs also like to point out overflows in args->req.payload
+itself (which is a fixed-size 120 B buffer, on the stack),
+but callers should be reading structs defined by the standard,
+so protecting from requests for more data than max seem like
+defensive programming.
+
+Fixes: a39c84d79625 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands")
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-7-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis_cdb.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
+index 3670ca42dd403e..f3a53a98446099 100644
+--- a/net/ethtool/cmis_cdb.c
++++ b/net/ethtool/cmis_cdb.c
+@@ -513,8 +513,13 @@ static int cmis_cdb_process_reply(struct net_device *dev,
+       }
+       rpl = (struct ethtool_cmis_cdb_rpl *)page_data->data;
+-      if ((args->rpl_exp_len > rpl->hdr.rpl_len + rpl_hdr_len) ||
+-          !rpl->hdr.rpl_chk_code) {
++      if (rpl->hdr.rpl_len != args->rpl_exp_len) {
++              netdev_warn(dev, "CDB reply length mismatch, expected %u got %u\n",
++                          args->rpl_exp_len, rpl->hdr.rpl_len);
++              err = -EIO;
++              goto out;
++      }
++      if (!rpl->hdr.rpl_chk_code) {
+               err = -EIO;
+               goto out;
+       }
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-cmis-validate-fw-size-against-start_cmd_payl.patch b/queue-7.0/ethtool-cmis-validate-fw-size-against-start_cmd_payl.patch
new file mode 100644 (file)
index 0000000..3330382
--- /dev/null
@@ -0,0 +1,48 @@
+From ce13c0943b6b3e93ab040edd59c762a758768d88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:12 -0700
+Subject: ethtool: cmis: validate fw->size against start_cmd_payload_size
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit d5551f4c1800dc714cec86647bdd651ae0de923e ]
+
+cmis_fw_update_start_download() copies start_cmd_payload_size bytes
+from the firmware blob into the CDB LPL vendor_data[] payload without
+validating that the FW has enough data.
+
+Since the start_cmd_payload_size can only be ~120B an image too short
+is most likely corrupted, so reject it.
+
+Fixes: c4f78134d45c ("ethtool: cmis_fw_update: add a layer for supporting firmware update using CDB")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-10-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis_fw_update.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/ethtool/cmis_fw_update.c b/net/ethtool/cmis_fw_update.c
+index 16190c97e1f78c..291d04d2776a5c 100644
+--- a/net/ethtool/cmis_fw_update.c
++++ b/net/ethtool/cmis_fw_update.c
+@@ -130,6 +130,14 @@ cmis_fw_update_start_download(struct ethtool_cmis_cdb *cdb,
+       u8 lpl_len;
+       int err;
++      if (fw_update->fw->size < vendor_data_size) {
++              ethnl_module_fw_flash_ntf_err(fw_update->dev,
++                                            &fw_update->ntf_params,
++                                            "Firmware image too small for module's start payload",
++                                            NULL);
++              return -EINVAL;
++      }
++
+       pl.image_size = cpu_to_be32(fw_update->fw->size);
+       memcpy(pl.vendor_data, fw_update->fw->data, vendor_data_size);
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-cmis-validate-start_cmd_payload_size-from-mo.patch b/queue-7.0/ethtool-cmis-validate-start_cmd_payload_size-from-mo.patch
new file mode 100644 (file)
index 0000000..51741e2
--- /dev/null
@@ -0,0 +1,96 @@
+From a627e6e43c8d38d63fb877ea6d251fb1e058b668 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:11 -0700
+Subject: ethtool: cmis: validate start_cmd_payload_size from module
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 12c2496a71f82f63617971ca9b730dffa05cf58b ]
+
+The CMIS firmware update code reads start_cmd_payload_size from
+the module's FW Management Features CDB reply and uses it directly
+as the byte count for memcpy. The destination buffer is 112 bytes
+(ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH - 8). So a malicious
+module (or corrupted response) can cause a OOB write later on in
+cmis_fw_update_start_download().
+
+Let's error out. If modules that expect longer LPL writes actually
+exist we should revisit.
+
+struct cmis_cdb_start_fw_download_pl's definition has to move,
+no change there.
+
+Fixes: c4f78134d45c ("ethtool: cmis_fw_update: add a layer for supporting firmware update using CDB")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-9-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis_fw_update.c | 36 ++++++++++++++++++++++--------------
+ 1 file changed, 22 insertions(+), 14 deletions(-)
+
+diff --git a/net/ethtool/cmis_fw_update.c b/net/ethtool/cmis_fw_update.c
+index df5f344209c47b..16190c97e1f78c 100644
+--- a/net/ethtool/cmis_fw_update.c
++++ b/net/ethtool/cmis_fw_update.c
+@@ -44,6 +44,20 @@ enum cmis_cdb_fw_write_mechanism {
+       CMIS_CDB_FW_WRITE_MECHANISM_BOTH        = 0x11,
+ };
++/* See section 9.7.2 "CMD 0101h: Start Firmware Download" in CMIS standard
++ * revision 5.2.
++ * struct cmis_cdb_start_fw_download_pl is a structured layout of the
++ * flat array, ethtool_cmis_cdb_request::payload.
++ */
++struct cmis_cdb_start_fw_download_pl {
++      __struct_group(cmis_cdb_start_fw_download_pl_h, head, /* no attrs */,
++                      __be32  image_size;
++                      __be32  resv1;
++      );
++      u8 vendor_data[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH -
++              sizeof(struct cmis_cdb_start_fw_download_pl_h)];
++};
++
+ static int
+ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
+                                  struct net_device *dev,
+@@ -86,6 +100,14 @@ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
+        */
+       cdb->read_write_len_ext = rpl->read_write_len_ext;
+       fw_mng->start_cmd_payload_size = rpl->start_cmd_payload_size;
++      if (fw_mng->start_cmd_payload_size >
++          sizeof_field(struct cmis_cdb_start_fw_download_pl, vendor_data)) {
++              ethnl_module_fw_flash_ntf_err(dev, ntf_params,
++                                            "Start cmd payload size exceeds max LPL payload",
++                                            NULL);
++              return -EINVAL;
++      }
++
+       fw_mng->write_mechanism =
+               rpl->write_mechanism == CMIS_CDB_FW_WRITE_MECHANISM_LPL ?
+               CMIS_CDB_FW_WRITE_MECHANISM_LPL :
+@@ -97,20 +119,6 @@ cmis_fw_update_fw_mng_features_get(struct ethtool_cmis_cdb *cdb,
+       return 0;
+ }
+-/* See section 9.7.2 "CMD 0101h: Start Firmware Download" in CMIS standard
+- * revision 5.2.
+- * struct cmis_cdb_start_fw_download_pl is a structured layout of the
+- * flat array, ethtool_cmis_cdb_request::payload.
+- */
+-struct cmis_cdb_start_fw_download_pl {
+-      __struct_group(cmis_cdb_start_fw_download_pl_h, head, /* no attrs */,
+-                      __be32  image_size;
+-                      __be32  resv1;
+-      );
+-      u8 vendor_data[ETHTOOL_CMIS_CDB_LPL_MAX_PL_LENGTH -
+-              sizeof(struct cmis_cdb_start_fw_download_pl_h)];
+-};
+-
+ static int
+ cmis_fw_update_start_download(struct ethtool_cmis_cdb *cdb,
+                             struct ethtool_cmis_fw_update_params *fw_update,
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-coalesce-cap-profile-updates-at-net_dim_para.patch b/queue-7.0/ethtool-coalesce-cap-profile-updates-at-net_dim_para.patch
new file mode 100644 (file)
index 0000000..21c8cf6
--- /dev/null
@@ -0,0 +1,45 @@
+From bd28fbf9a69ba891490fd79cce95a1d2a0987637 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:24 -0700
+Subject: ethtool: coalesce: cap profile updates at NET_DIM_PARAMS_NUM_PROFILES
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 7281b096b072f6c6e30420e3467d738f2e4c4b57 ]
+
+ethnl_update_profile() walks the ETHTOOL_A_PROFILE_IRQ_MODERATION
+nest list with an index 'i' and writes new_profile[i++] without
+bounding i. The destination is kmemdup()'d at NET_DIM_PARAMS_NUM_PROFILES
+entries (5), but the Netlink nest count is entirely user-controlled.
+Netlink policies do not have support for constraining the number
+of nested entries (or number of multi-attr entries).
+
+Fixes: f750dfe825b9 ("ethtool: provide customized dim profile management")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-2-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/coalesce.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/ethtool/coalesce.c b/net/ethtool/coalesce.c
+index 3e18ca1ccc5ef6..cace02d964cb21 100644
+--- a/net/ethtool/coalesce.c
++++ b/net/ethtool/coalesce.c
+@@ -463,6 +463,12 @@ static int ethnl_update_profile(struct net_device *dev,
+       nla_for_each_nested_type(nest, ETHTOOL_A_PROFILE_IRQ_MODERATION,
+                                nests, rem) {
++              if (i >= NET_DIM_PARAMS_NUM_PROFILES) {
++                      NL_SET_BAD_ATTR(extack, nest);
++                      ret = -E2BIG;
++                      goto err_out;
++              }
++
+               ret = nla_parse_nested(tb, len_irq_moder - 1, nest,
+                                      coalesce_irq_moderation_policy,
+                                      extack);
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch b/queue-7.0/ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch
new file mode 100644 (file)
index 0000000..896cc7a
--- /dev/null
@@ -0,0 +1,48 @@
+From ee819def2d239de46f6048a568fe4038f25855b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:32 -0700
+Subject: ethtool: eeprom: add missing ethnl_ops_begin() / _complete() during
+ fallback
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 2376586f85f972fefe701f095bb37dcfe7405d21 ]
+
+All ethtool driver op calls should be sandwiched between
+ethnl_ops_begin() / ethnl_ops_complete(). In Netlink eeprom code,
+if the paged access failed we fall back to old API, but we
+first call _complete() and the fallback never does its own
+ethnl_ops_begin(). Move the fallback into the _begin() / _complete()
+section.
+
+Fixes: 96d971e307cc ("ethtool: Add fallback to get_module_eeprom from netlink command")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-10-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/eeprom.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c
+index 3b8209e930fd3a..03cb418a15823b 100644
+--- a/net/ethtool/eeprom.c
++++ b/net/ethtool/eeprom.c
+@@ -140,12 +140,11 @@ static int eeprom_prepare_data(const struct ethnl_req_info *req_base,
+       return 0;
+ err_ops:
++      if (ret == -EOPNOTSUPP)
++              ret = eeprom_fallback(request, reply);
+       ethnl_ops_complete(dev);
+ err_free:
+       kfree(page_data.data);
+-
+-      if (ret == -EOPNOTSUPP)
+-              return eeprom_fallback(request, reply);
+       return ret;
+ }
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch b/queue-7.0/ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
new file mode 100644 (file)
index 0000000..ebbada3
--- /dev/null
@@ -0,0 +1,62 @@
+From 037295e26c47f64f130ff17a0f629a7bd1724b2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:33 -0700
+Subject: ethtool: eeprom: add more safeties to EEPROM Netlink fallback
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 67cfdd9210b99f260b3e0afeb9525e0acc7be31e ]
+
+The Netlink fallback path for reading module EEPROM
+(fallback_set_params()) validates that offset < eeprom_len,
+but does not check that offset + length stays within eeprom_len.
+The ioctl equivalent (ethtool_get_any_eeprom() in ioctl.c) has
+always enforced both bounds:
+
+  if (eeprom.offset + eeprom.len > total_len)
+      return -EINVAL;
+
+This could lead to surprises in both drivers and device FW.
+Add the missing offset + length validation to fallback_set_params(),
+mirroring the ioctl.
+
+Similarly - ethtool core in general, and ethtool_get_any_eeprom()
+in particular tries to zero-init all buffers passed to the drivers
+to avoid any extra work of zeroing things out. eeprom_fallback()
+uses a plain kmalloc(), change it to zalloc.
+
+Fixes: 96d971e307cc ("ethtool: Add fallback to get_module_eeprom from netlink command")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-11-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/eeprom.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c
+index 03cb418a15823b..80af38a6c76acf 100644
+--- a/net/ethtool/eeprom.c
++++ b/net/ethtool/eeprom.c
+@@ -43,6 +43,9 @@ static int fallback_set_params(struct eeprom_req_info *request,
+       if (offset >= modinfo->eeprom_len)
+               return -EINVAL;
++      if (length > modinfo->eeprom_len - offset)
++              return -EINVAL;
++
+       eeprom->cmd = ETHTOOL_GMODULEEEPROM;
+       eeprom->len = length;
+       eeprom->offset = offset;
+@@ -68,7 +71,7 @@ static int eeprom_fallback(struct eeprom_req_info *request,
+       if (err < 0)
+               return err;
+-      data = kmalloc(eeprom.len, GFP_KERNEL);
++      data = kzalloc(eeprom.len, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+       err = ethtool_get_module_eeprom_call(dev, &eeprom, data);
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-linkstate-fix-unbalanced-ethnl_ops_complete-.patch b/queue-7.0/ethtool-linkstate-fix-unbalanced-ethnl_ops_complete-.patch
new file mode 100644 (file)
index 0000000..0546f2b
--- /dev/null
@@ -0,0 +1,43 @@
+From 38b98152586b77499f2df4274075e6648caa4c24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:26 -0700
+Subject: ethtool: linkstate: fix unbalanced ethnl_ops_complete() on PHY lookup
+ error
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 596c51ed9e125b12c4d85b4530dfd4c7847634b7 ]
+
+linkstate_prepare_data() calls ethnl_req_get_phydev() before
+ethnl_ops_begin(), but routes its error path through "goto out"
+which calls ethnl_ops_complete().
+
+Fixes: fe55b1d401c6 ("ethtool: linkstate: migrate linkstate functions to support multi-PHY setups")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-4-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/linkstate.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/net/ethtool/linkstate.c b/net/ethtool/linkstate.c
+index 05a5f72c99fab1..3dc52a39d34525 100644
+--- a/net/ethtool/linkstate.c
++++ b/net/ethtool/linkstate.c
+@@ -105,10 +105,8 @@ static int linkstate_prepare_data(const struct ethnl_req_info *req_base,
+       phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_LINKSTATE_HEADER,
+                                     info->extack);
+-      if (IS_ERR(phydev)) {
+-              ret = PTR_ERR(phydev);
+-              goto out;
+-      }
++      if (IS_ERR(phydev))
++              return PTR_ERR(phydev);
+       ret = ethnl_ops_begin(dev);
+       if (ret < 0)
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-module-avoid-leaking-a-netdev-ref-on-module-.patch b/queue-7.0/ethtool-module-avoid-leaking-a-netdev-ref-on-module-.patch
new file mode 100644 (file)
index 0000000..f7aab92
--- /dev/null
@@ -0,0 +1,50 @@
+From 23c8dba54d8c60b29d05026c25a7fc2f1a7ff465 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:05 -0700
+Subject: ethtool: module: avoid leaking a netdev ref on module flash errors
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit fb7f511d62692661846c47f199e0afe25c2982db ]
+
+module_flash_fw_schedule() is missing undo for setting
+the "in_progress" flag and taking the netdev reference.
+Delay taking these, the device can't disappear while
+we are holding rtnl_lock.
+
+Fixes: 32b4c8b53ee7 ("ethtool: Add ability to flash transceiver modules' firmware")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-3-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/module.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/module.c b/net/ethtool/module.c
+index 8047c14f7ee370..594a49fdd7fd06 100644
+--- a/net/ethtool/module.c
++++ b/net/ethtool/module.c
+@@ -319,8 +319,6 @@ module_flash_fw_schedule(struct net_device *dev, const char *file_name,
+       if (err < 0)
+               goto err_release_firmware;
+-      dev->ethtool->module_fw_flash_in_progress = true;
+-      netdev_hold(dev, &module_fw->dev_tracker, GFP_KERNEL);
+       fw_update->dev = dev;
+       fw_update->ntf_params.portid = info->snd_portid;
+       fw_update->ntf_params.seq = info->snd_seq;
+@@ -335,6 +333,9 @@ module_flash_fw_schedule(struct net_device *dev, const char *file_name,
+       if (err < 0)
+               goto err_release_firmware;
++      dev->ethtool->module_fw_flash_in_progress = true;
++      netdev_hold(dev, &module_fw->dev_tracker, GFP_KERNEL);
++
+       schedule_work(&module_fw->work);
+       return 0;
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-module-avoid-racy-updates-to-dev-ethtool-bit.patch b/queue-7.0/ethtool-module-avoid-racy-updates-to-dev-ethtool-bit.patch
new file mode 100644 (file)
index 0000000..e6b2050
--- /dev/null
@@ -0,0 +1,64 @@
+From c324e0df6028d324a1c09461e852bf53e0450e7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:06 -0700
+Subject: ethtool: module: avoid racy updates to dev->ethtool bitfield
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 7a84b965ffc12030af63cd10a8f3a1123ff39b7a ]
+
+When reviewing other changes Gemini points out that we currently
+update module_fw_flash_in_progress without holding any locks.
+Since module_fw_flash_in_progress is part of a bitfield this
+is not great, updates to other fields may be lost.
+
+We could use a bool and sprinkle some READ_ONCE/WRITE_ONCE here
+but seems like the issue is rather than the work is an unusual
+writer. The other writers already hold the right locks. So just
+very briefly take these locks when the work completes.
+
+Note that nothing ever cancels the FW update work, so there's
+no concern with deadlocks vs cancel.
+
+Fixes: 32b4c8b53ee7 ("ethtool: Add ability to flash transceiver modules' firmware")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-4-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/module.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/module.c b/net/ethtool/module.c
+index 594a49fdd7fd06..ce4ce514edca89 100644
+--- a/net/ethtool/module.c
++++ b/net/ethtool/module.c
+@@ -221,14 +221,22 @@ static void module_flash_fw_work_list_del(struct list_head *list)
+ static void module_flash_fw_work(struct work_struct *work)
+ {
+       struct ethtool_module_fw_flash *module_fw;
++      struct net_device *dev;
+       module_fw = container_of(work, struct ethtool_module_fw_flash, work);
++      dev = module_fw->fw_update.dev;
+       ethtool_cmis_fw_update(&module_fw->fw_update);
+       module_flash_fw_work_list_del(&module_fw->list);
+-      module_fw->fw_update.dev->ethtool->module_fw_flash_in_progress = false;
+-      netdev_put(module_fw->fw_update.dev, &module_fw->dev_tracker);
++
++      rtnl_lock();
++      netdev_lock_ops(dev);
++      dev->ethtool->module_fw_flash_in_progress = false;
++      netdev_unlock_ops(dev);
++      rtnl_unlock();
++
++      netdev_put(dev, &module_fw->dev_tracker);
+       release_firmware(module_fw->fw_update.fw);
+       kfree(module_fw);
+ }
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-module-call-ethnl_ops_complete-on-module-fla.patch b/queue-7.0/ethtool-module-call-ethnl_ops_complete-on-module-fla.patch
new file mode 100644 (file)
index 0000000..05aa68b
--- /dev/null
@@ -0,0 +1,42 @@
+From 435553a917bdaa1dfc9469d8cdc1e4140d3100b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:04 -0700
+Subject: ethtool: module: call ethnl_ops_complete() on module flash errors
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 84371fb58423f997939aacdcbc02d128d76a54e5 ]
+
+When validate() fails we are skipping over ethnl_ops_complete()
+even tho we already called ethnl_ops_begin().
+
+Fixes: 32b4c8b53ee7 ("ethtool: Add ability to flash transceiver modules' firmware")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-2-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/module.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/module.c b/net/ethtool/module.c
+index 0a761bf4771e11..8047c14f7ee370 100644
+--- a/net/ethtool/module.c
++++ b/net/ethtool/module.c
+@@ -427,10 +427,11 @@ int ethnl_act_module_fw_flash(struct sk_buff *skb, struct genl_info *info)
+       ret = ethnl_module_fw_flash_validate(dev, info->extack);
+       if (ret < 0)
+-              goto out_unlock;
++              goto out_complete;
+       ret = module_flash_fw(dev, tb, skb, info);
++out_complete:
+       ethnl_ops_complete(dev);
+ out_unlock:
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-module-check-fw_flash_in_progress-under-rtnl.patch b/queue-7.0/ethtool-module-check-fw_flash_in_progress-under-rtnl.patch
new file mode 100644 (file)
index 0000000..7c86018
--- /dev/null
@@ -0,0 +1,56 @@
+From 6fd890d3905671ca0d32603e23f02426807a819f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:07 -0700
+Subject: ethtool: module: check fw_flash_in_progress under rtnl_lock
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 504eaefa44c8dec50f7499edcb36d24f3aefab2a ]
+
+ethnl_set_module_validate() inspects module_fw_flash_in_progress
+but validate is meant for _input_ validation, not state validation.
+rtnl_lock is not held, yet. Move the check into ethnl_set_module().
+
+Fixes: 32b4c8b53ee7 ("ethtool: Add ability to flash transceiver modules' firmware")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-5-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/module.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/net/ethtool/module.c b/net/ethtool/module.c
+index ce4ce514edca89..373326e49d150e 100644
+--- a/net/ethtool/module.c
++++ b/net/ethtool/module.c
+@@ -120,12 +120,6 @@ ethnl_set_module_validate(struct ethnl_req_info *req_info,
+       if (!tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY])
+               return 0;
+-      if (req_info->dev->ethtool->module_fw_flash_in_progress) {
+-              NL_SET_ERR_MSG(info->extack,
+-                             "Module firmware flashing is in progress");
+-              return -EBUSY;
+-      }
+-
+       if (!ops->get_module_power_mode || !ops->set_module_power_mode) {
+               NL_SET_ERR_MSG_ATTR(info->extack,
+                                   tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY],
+@@ -148,6 +142,12 @@ ethnl_set_module(struct ethnl_req_info *req_info, struct genl_info *info)
+       ops = dev->ethtool_ops;
++      if (dev->ethtool->module_fw_flash_in_progress) {
++              NL_SET_ERR_MSG(info->extack,
++                             "Module firmware flashing is in progress");
++              return -EBUSY;
++      }
++
+       power_new.policy = nla_get_u8(tb[ETHTOOL_A_MODULE_POWER_MODE_POLICY]);
+       ret = ops->get_module_power_mode(dev, &power, info->extack);
+       if (ret < 0)
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-module-fix-cleanup-if-socket-used-for-flashi.patch b/queue-7.0/ethtool-module-fix-cleanup-if-socket-used-for-flashi.patch
new file mode 100644 (file)
index 0000000..9473de3
--- /dev/null
@@ -0,0 +1,105 @@
+From 4277857e3371b603b23d436a698c1fd550a6f91b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:13:08 -0700
+Subject: ethtool: module: fix cleanup if socket used for flashing multiple
+ devices
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 760d04ebad5c4304f22c0d2251c9623b87a117c8 ]
+
+When a single Netlink socket issues MODULE_FW_FLASH_ACT against multiple
+devices, ethnl_sock_priv_set() overwrites sk_priv->dev on each call,
+retaining only the last one. The socket priv is used on socket close,
+to walk the global work list and mark the uncompleted flashing work
+as "orphaned". Otherwise if another socket reuses the PID it will
+unexpectedly receive the flashing notifications.
+
+Don't record the device, record net pointer instead. The purpose of
+the dev is to scope the work to a netns, anyway. If we store netns
+the overrides are safe/a nop since all flashed devices must be in
+the same netns as the socket.
+
+Fixes: 32b4c8b53ee7 ("ethtool: Add ability to flash transceiver modules' firmware")
+Reviewed-by: Danielle Ratson <danieller@nvidia.com>
+Link: https://patch.msgid.link/20260522231312.1710836-6-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/module.c  | 9 ++++-----
+ net/ethtool/netlink.c | 4 ++--
+ net/ethtool/netlink.h | 4 ++--
+ 3 files changed, 8 insertions(+), 9 deletions(-)
+
+diff --git a/net/ethtool/module.c b/net/ethtool/module.c
+index 373326e49d150e..6eb83f6b3d267c 100644
+--- a/net/ethtool/module.c
++++ b/net/ethtool/module.c
+@@ -291,11 +291,9 @@ void ethnl_module_fw_flash_sock_destroy(struct ethnl_sock_priv *sk_priv)
+       spin_lock(&module_fw_flash_work_list_lock);
+       list_for_each_entry(work, &module_fw_flash_work_list, list) {
+-              if (work->fw_update.dev == sk_priv->dev &&
+-                  work->fw_update.ntf_params.portid == sk_priv->portid) {
++              if (work->fw_update.ntf_params.portid == sk_priv->portid &&
++                  dev_net(work->fw_update.dev) == sk_priv->net)
+                       work->fw_update.ntf_params.closed_sock = true;
+-                      break;
+-              }
+       }
+       spin_unlock(&module_fw_flash_work_list_lock);
+ }
+@@ -332,7 +330,8 @@ module_flash_fw_schedule(struct net_device *dev, const char *file_name,
+       fw_update->ntf_params.seq = info->snd_seq;
+       fw_update->ntf_params.closed_sock = false;
+-      err = ethnl_sock_priv_set(skb, dev, fw_update->ntf_params.portid,
++      err = ethnl_sock_priv_set(skb, dev_net(dev),
++                                fw_update->ntf_params.portid,
+                                 ETHTOOL_SOCK_TYPE_MODULE_FW_FLASH);
+       if (err < 0)
+               goto err_release_firmware;
+diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
+index 6e5f0f4f815a1a..4cf928da607252 100644
+--- a/net/ethtool/netlink.c
++++ b/net/ethtool/netlink.c
+@@ -52,7 +52,7 @@ const struct nla_policy ethnl_header_policy_phy_stats[] = {
+       [ETHTOOL_A_HEADER_PHY_INDEX]            = NLA_POLICY_MIN(NLA_U32, 1),
+ };
+-int ethnl_sock_priv_set(struct sk_buff *skb, struct net_device *dev, u32 portid,
++int ethnl_sock_priv_set(struct sk_buff *skb, struct net *net, u32 portid,
+                       enum ethnl_sock_type type)
+ {
+       struct ethnl_sock_priv *sk_priv;
+@@ -61,7 +61,7 @@ int ethnl_sock_priv_set(struct sk_buff *skb, struct net_device *dev, u32 portid,
+       if (IS_ERR(sk_priv))
+               return PTR_ERR(sk_priv);
+-      sk_priv->dev = dev;
++      sk_priv->net = net;
+       sk_priv->portid = portid;
+       sk_priv->type = type;
+diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h
+index 89010eaa67dfcd..65c24f627b218f 100644
+--- a/net/ethtool/netlink.h
++++ b/net/ethtool/netlink.h
+@@ -318,12 +318,12 @@ enum ethnl_sock_type {
+ };
+ struct ethnl_sock_priv {
+-      struct net_device *dev;
++      struct net *net;
+       u32 portid;
+       enum ethnl_sock_type type;
+ };
+-int ethnl_sock_priv_set(struct sk_buff *skb, struct net_device *dev, u32 portid,
++int ethnl_sock_priv_set(struct sk_buff *skb, struct net *net, u32 portid,
+                       enum ethnl_sock_type type);
+ /**
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-pse-pd-fix-missing-ethnl_ops_complete.patch b/queue-7.0/ethtool-pse-pd-fix-missing-ethnl_ops_complete.patch
new file mode 100644 (file)
index 0000000..268e600
--- /dev/null
@@ -0,0 +1,59 @@
+From e789513d907129b0d1859ee78bd50288aa380a53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:27 -0700
+Subject: ethtool: pse-pd: fix missing ethnl_ops_complete()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit ab5bf428fb6bd361163c7247b92750d1d24ca2ed ]
+
+pse_prepare_data() is missing ethnl_ops_complete() if
+ethnl_req_get_phydev() returned an error. Move getting
+phydev up so that we don't have to worry about this
+(similar order to linkstate_prepare_data()).
+
+Note that phydev may still be NULL (this is checked in
+pse_get_pse_attributes()), the goal isn't really to avoid
+the _begin() / _complete() calls, only to simplify the error
+handling.
+
+While at it propagate the original error. Why this code
+overrides the error with -ENODEV but !phydev generates
+-EOPNOTSUPP is unclear to me...
+
+Fixes: 31748765bed3 ("net: ethtool: pse-pd: Target the command to the requested PHY")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-5-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/pse-pd.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
+index 24def9c9dd54bf..aa4514333d13bd 100644
+--- a/net/ethtool/pse-pd.c
++++ b/net/ethtool/pse-pd.c
+@@ -61,14 +61,14 @@ static int pse_prepare_data(const struct ethnl_req_info *req_base,
+       struct phy_device *phydev;
+       int ret;
+-      ret = ethnl_ops_begin(dev);
+-      if (ret < 0)
+-              return ret;
+-
+       phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_PSE_HEADER,
+                                     info->extack);
+       if (IS_ERR(phydev))
+-              return -ENODEV;
++              return PTR_ERR(phydev);
++
++      ret = ethnl_ops_begin(dev);
++      if (ret < 0)
++              return ret;
+       ret = pse_get_pse_attributes(phydev, info->extack, data);
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-rss-add-missing-errno-on-rss-context-delete.patch b/queue-7.0/ethtool-rss-add-missing-errno-on-rss-context-delete.patch
new file mode 100644 (file)
index 0000000..caabd3b
--- /dev/null
@@ -0,0 +1,40 @@
+From 0d6d66ae9eacc703a24f730adde29fbfb418e267 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:06:43 -0700
+Subject: ethtool: rss: add missing errno on RSS context delete
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 3e6c6e9782ff8a8d8ded774b07ad4590cd61d04c ]
+
+Remember to set ret before jumping out if someone tries
+to delete a context on a device which doesn't support
+contexts.
+
+Fixes: fbe09277fa63 ("ethtool: rss: support removing contexts via Netlink")
+Link: https://patch.msgid.link/20260522230647.1705600-3-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/rss.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
+index 926be5698ba4cc..688c0e4bba69db 100644
+--- a/net/ethtool/rss.c
++++ b/net/ethtool/rss.c
+@@ -1160,8 +1160,10 @@ int ethnl_rss_delete_doit(struct sk_buff *skb, struct genl_info *info)
+       dev = req.dev;
+       ops = dev->ethtool_ops;
+-      if (!ops->create_rxfh_context)
++      if (!ops->create_rxfh_context) {
++              ret = -EOPNOTSUPP;
+               goto exit_free_dev;
++      }
+       rtnl_lock();
+       netdev_lock_ops(dev);
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-rss-avoid-device-context-leak-on-reply-build.patch b/queue-7.0/ethtool-rss-avoid-device-context-leak-on-reply-build.patch
new file mode 100644 (file)
index 0000000..70992c7
--- /dev/null
@@ -0,0 +1,55 @@
+From fd7cb3983dc035e257226b2029edba581e951a02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:06:47 -0700
+Subject: ethtool: rss: avoid device context leak on reply-build failure
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 32a9ecde62731c9f7412507709192c84dafc38d1 ]
+
+We wait with filling the reply for new RSS context creation
+until after the driver ->create_rxfh_context call. The driver
+needs to fill some of the defaults in the context. The failure
+of rss_fill_reply() is somewhat theoretical, but doesn't take
+much effort to handle it properly. Call ->remove_rxfh_context().
+
+If the driver's remove callback fails (some implementations like sfc
+can return real command errors from firmware RPCs) - skip the xa_erase
+and kfree, leaving the context in the xarray. This matches how
+ethnl_rss_delete_doit() behaves.
+
+Fixes: a166ab7816c5 ("ethtool: rss: support creating contexts via Netlink")
+Link: https://patch.msgid.link/20260522230647.1705600-7-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/rss.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
+index f745ddec6fbab8..b122f67dbde1d6 100644
+--- a/net/ethtool/rss.c
++++ b/net/ethtool/rss.c
+@@ -1096,7 +1096,7 @@ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
+       ntf_fail |= rss_fill_reply(rsp, &req.base, &data.base);
+       if (WARN_ON(!hdr || ntf_fail)) {
+               ret = -EMSGSIZE;
+-              goto exit_unlock;
++              goto err_remove_ctx;
+       }
+       genlmsg_end(rsp, hdr);
+@@ -1124,6 +1124,10 @@ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
+       nlmsg_free(rsp);
+       return ret;
++err_remove_ctx:
++      if (ops->remove_rxfh_context(dev, ctx, req.rss_context, NULL))
++              /* leave the context on failure, like ethnl_rss_delete_doit() */
++              goto exit_unlock;
+ err_ctx_id_free:
+       xa_erase(&dev->ethtool->rss_ctx, req.rss_context);
+ err_unlock_free_ctx:
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-rss-avoid-modifying-the-rss-context-response.patch b/queue-7.0/ethtool-rss-avoid-modifying-the-rss-context-response.patch
new file mode 100644 (file)
index 0000000..f186a33
--- /dev/null
@@ -0,0 +1,73 @@
+From faa3701e72e78b2298ea270b053dac19c6203082 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:06:42 -0700
+Subject: ethtool: rss: avoid modifying the RSS context response
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit c75b6f6eaacd0b74b832414cc3b9289c3686e941 ]
+
+Gemini says that we're modifying the RSS_CREATE response skb.
+I think it's right, the comment says that unicast() should
+unshare the skb but I'm not entirely sure what I meant there.
+netlink_trim() does a copy but only if skb is not well sized
+(it's at least 2x larger than necessary for the payload).
+
+Fixes: a166ab7816c5 ("ethtool: rss: support creating contexts via Netlink")
+Link: https://patch.msgid.link/20260522230647.1705600-2-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/rss.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
+index da5934cceb0757..926be5698ba4cc 100644
+--- a/net/ethtool/rss.c
++++ b/net/ethtool/rss.c
+@@ -974,11 +974,17 @@ ethnl_rss_create_validate(struct net_device *dev, struct genl_info *info)
+ }
+ static void
+-ethnl_rss_create_send_ntf(struct sk_buff *rsp, struct net_device *dev)
++ethnl_rss_create_send_ntf(const struct sk_buff *rsp, struct net_device *dev)
+ {
+-      struct nlmsghdr *nlh = (void *)rsp->data;
+       struct genlmsghdr *genl_hdr;
++      struct nlmsghdr *nlh;
++      struct sk_buff *ntf;
++
++      ntf = skb_copy_expand(rsp, 0, 0, GFP_KERNEL);
++      if (!ntf)
++              return;
++      nlh = nlmsg_hdr(ntf);
+       /* Convert the reply into a notification */
+       nlh->nlmsg_pid = 0;
+       nlh->nlmsg_seq = ethnl_bcast_seq_next();
+@@ -986,7 +992,7 @@ ethnl_rss_create_send_ntf(struct sk_buff *rsp, struct net_device *dev)
+       genl_hdr = nlmsg_data(nlh);
+       genl_hdr->cmd = ETHTOOL_MSG_RSS_CREATE_NTF;
+-      ethnl_multicast(rsp, dev);
++      ethnl_multicast(ntf, dev);
+ }
+ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
+@@ -1094,12 +1100,8 @@ int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
+       genlmsg_end(rsp, hdr);
+-      /* Use the same skb for the response and the notification,
+-       * genlmsg_reply() will copy the skb if it has elevated user count.
+-       */
+-      skb_get(rsp);
+-      ret = genlmsg_reply(rsp, info);
+       ethnl_rss_create_send_ntf(rsp, dev);
++      ret = genlmsg_reply(rsp, info);
+       rsp = NULL;
+ exit_unlock:
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-rss-fix-falsely-ignoring-indir-table-updates.patch b/queue-7.0/ethtool-rss-fix-falsely-ignoring-indir-table-updates.patch
new file mode 100644 (file)
index 0000000..698c065
--- /dev/null
@@ -0,0 +1,38 @@
+From 197579e2f979fa3bfbe5847727d195a1ee8fbcce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:06:44 -0700
+Subject: ethtool: rss: fix falsely ignoring indir table updates
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 8d60141a32875248ef71d49c9920fa5e2aa40b29 ]
+
+rss_set_prep_indir() compares the new indirection table against the
+current one to determine whether any update is needed. The memcmp
+call passes data->indir_size as the length argument, but indir_size
+is the number of u32 entries, not the byte count.
+
+Fixes: c0ae03588bbb ("ethtool: rss: initial RSS_SET (indirection table handling)")
+Link: https://patch.msgid.link/20260522230647.1705600-4-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/rss.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
+index 688c0e4bba69db..4877655f724419 100644
+--- a/net/ethtool/rss.c
++++ b/net/ethtool/rss.c
+@@ -684,7 +684,7 @@ rss_set_prep_indir(struct net_device *dev, struct genl_info *info,
+                               ethtool_rxfh_indir_default(i, num_rx_rings);
+       }
+-      *mod |= memcmp(rxfh->indir, data->indir_table, data->indir_size);
++      *mod |= memcmp(rxfh->indir, data->indir_table, alloc_size);
+       return 0;
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-rss-fix-hkey-leak-when-indir_size-is-0.patch b/queue-7.0/ethtool-rss-fix-hkey-leak-when-indir_size-is-0.patch
new file mode 100644 (file)
index 0000000..00a23fd
--- /dev/null
@@ -0,0 +1,47 @@
+From ffe42842b2d707cb7f5e1be7355fc9bfd39a509f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:06:46 -0700
+Subject: ethtool: rss: fix hkey leak when indir_size is 0
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 78ccf1a70c6378e1f5073a8c2209b5129067b925 ]
+
+rss_get_data_alloc() allocates a single buffer that backs both the
+indirection table and the hash key, but only assigned data->indir_table
+when indir_size was nonzero. The expectation was that no driver
+implements RSS without supporting indirection table but apparently
+enic does just that (it's the only such in-tree driver).
+enic has get_rxfh_key_size but no get_rxfh_indir_size.
+data->indir_table stays as NULL, hkey gets set but rss_get_data_free()
+kfree(data->indir_table) is a nop and the allocation leaks.
+
+Always store the allocation base in data->indir_table so the free path
+is unambiguous. No caller treats indir_table as a sentinel; everything
+keys off indir_size.
+
+Fixes: 7112a04664bf ("ethtool: add netlink based get rss support")
+Link: https://patch.msgid.link/20260522230647.1705600-6-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/rss.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
+index 5416aec13b7fe7..f745ddec6fbab8 100644
+--- a/net/ethtool/rss.c
++++ b/net/ethtool/rss.c
+@@ -132,8 +132,7 @@ rss_get_data_alloc(struct net_device *dev, struct rss_reply_data *data)
+       if (!rss_config)
+               return -ENOMEM;
+-      if (data->indir_size)
+-              data->indir_table = (u32 *)rss_config;
++      data->indir_table = (u32 *)rss_config;
+       if (data->hkey_size)
+               data->hkey = rss_config + indir_bytes;
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-rss-fix-indir_table-and-hkey-leak-on-get_rxf.patch b/queue-7.0/ethtool-rss-fix-indir_table-and-hkey-leak-on-get_rxf.patch
new file mode 100644 (file)
index 0000000..591786f
--- /dev/null
@@ -0,0 +1,41 @@
+From 364ef4eb6b6a58d4d0b4e4a5485b5dc28890262c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:06:45 -0700
+Subject: ethtool: rss: fix indir_table and hkey leak on get_rxfh failure
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 266297692f97008ca48bc311775c087c59bd7fe3 ]
+
+rss_prepare_get() allocates the indirection table and hash key buffer
+via rss_get_data_alloc(), then calls ops->get_rxfh() to populate them.
+If get_rxfh() fails, the function returns an error without freeing
+the allocation.
+
+Fixes: 4f038a6a02d2 ("net: ethtool: Don't call .cleanup_data when prepare_data fails")
+Link: https://patch.msgid.link/20260522230647.1705600-5-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/rss.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c
+index 4877655f724419..5416aec13b7fe7 100644
+--- a/net/ethtool/rss.c
++++ b/net/ethtool/rss.c
+@@ -168,8 +168,10 @@ rss_prepare_get(const struct rss_req_info *request, struct net_device *dev,
+       rxfh.key = data->hkey;
+       ret = ops->get_rxfh(dev, &rxfh);
+-      if (ret)
++      if (ret) {
++              rss_get_data_free(data);
+               goto out_unlock;
++      }
+       data->hfunc = rxfh.hfunc;
+       data->input_xfrm = rxfh.input_xfrm;
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-strset-fix-header-attribute-index-in-ethnl_r.patch b/queue-7.0/ethtool-strset-fix-header-attribute-index-in-ethnl_r.patch
new file mode 100644 (file)
index 0000000..e6cb326
--- /dev/null
@@ -0,0 +1,42 @@
+From c9d696dd1160472043a4c815b1e36b10d5e4ff95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:31 -0700
+Subject: ethtool: strset: fix header attribute index in ethnl_req_get_phydev()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit a8d8bef6b45bf7cc0b1f6110c5cd8d0160a9bad7 ]
+
+strset_prepare_data() passes ETHTOOL_A_HEADER_FLAGS (3) as the header
+attribute to ethnl_req_get_phydev(). This is incorrect, in the main
+attr space 3 is ETHTOOL_A_STRSET_COUNTS_ONLY, not the request
+header attr. The correct constant is ETHTOOL_A_STRSET_HEADER (1).
+
+ethnl_req_get_phydev() only uses this value for the extack,
+so this is not a "functionally visible"(?) bug.
+
+Fixes: e96c93aa4be9 ("net: ethtool: strset: Allow querying phy stats by index")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-9-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/strset.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ethtool/strset.c b/net/ethtool/strset.c
+index f6a67109beda1b..872ca593b97668 100644
+--- a/net/ethtool/strset.c
++++ b/net/ethtool/strset.c
+@@ -309,7 +309,7 @@ static int strset_prepare_data(const struct ethnl_req_info *req_base,
+               return 0;
+       }
+-      phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_HEADER_FLAGS,
++      phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_STRSET_HEADER,
+                                     info->extack);
+       /* phydev can be NULL, check for errors only */
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-tsconfig-fix-missing-ethnl_ops_complete.patch b/queue-7.0/ethtool-tsconfig-fix-missing-ethnl_ops_complete.patch
new file mode 100644 (file)
index 0000000..84cd3ac
--- /dev/null
@@ -0,0 +1,42 @@
+From fe14dfb0cbc18ca6a70b022e3896c127a0a45bde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:28 -0700
+Subject: ethtool: tsconfig: fix missing ethnl_ops_complete()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 6386bd772de64e6760306eb91c7e86163af6c22f ]
+
+tsconfig_prepare_data() calls ethnl_ops_begin(), we need to call
+ethnl_ops_complete() before returning the error.
+
+Fixes: 6e9e2eed4f39 ("net: ethtool: Add support for tsconfig command to get/set hwtstamp config")
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-6-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/tsconfig.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/tsconfig.c b/net/ethtool/tsconfig.c
+index 966c769c72677f..990dca9a3fc564 100644
+--- a/net/ethtool/tsconfig.c
++++ b/net/ethtool/tsconfig.c
+@@ -69,8 +69,10 @@ static int tsconfig_prepare_data(const struct ethnl_req_info *req_base,
+               if (ret)
+                       goto out;
+-              if (ts_info.phc_index == -1)
+-                      return -ENODEV;
++              if (ts_info.phc_index == -1) {
++                      ret = -ENODEV;
++                      goto out;
++              }
+               data->hwprov_desc.index = ts_info.phc_index;
+               data->hwprov_desc.qualifier = ts_info.phc_qualifier;
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-tsconfig-fix-reply-error-handling.patch b/queue-7.0/ethtool-tsconfig-fix-reply-error-handling.patch
new file mode 100644 (file)
index 0000000..52d8300
--- /dev/null
@@ -0,0 +1,55 @@
+From 4819737df5bdc3ca659a57227aa2933bf504fc91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:25 -0700
+Subject: ethtool: tsconfig: fix reply error handling
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit a888bbd43940cada72f7686337741ce86d1cf869 ]
+
+A couple of trivial bugs in error handling in tsconfig_send_reply().
+If we failed to allocate rskb we need to set the error.
+If we did allocate it but failed to send it - we need to remember
+to free it.
+
+Fixes: 6e9e2eed4f39 ("net: ethtool: Add support for tsconfig command to get/set hwtstamp config")
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-3-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/tsconfig.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/tsconfig.c b/net/ethtool/tsconfig.c
+index e49e612a68c2c0..966c769c72677f 100644
+--- a/net/ethtool/tsconfig.c
++++ b/net/ethtool/tsconfig.c
+@@ -224,16 +224,21 @@ static int tsconfig_send_reply(struct net_device *dev, struct genl_info *info)
+       reply_len = ret + ethnl_reply_header_size();
+       rskb = ethnl_reply_init(reply_len, dev, ETHTOOL_MSG_TSCONFIG_SET_REPLY,
+                               ETHTOOL_A_TSCONFIG_HEADER, info, &reply_payload);
+-      if (!rskb)
++      if (!rskb) {
++              ret = -ENOMEM;
+               goto err_cleanup;
++      }
+       ret = tsconfig_fill_reply(rskb, &req_info->base, &reply_data->base);
+       if (ret < 0)
+-              goto err_cleanup;
++              goto err_free_msg;
+       genlmsg_end(rskb, reply_payload);
+       ret = genlmsg_reply(rskb, info);
++      rskb = NULL;
++err_free_msg:
++      nlmsg_free(rskb);
+ err_cleanup:
+       kfree(reply_data);
+       kfree(req_info);
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-tsinfo-don-t-pass-err_ptr-to-genlmsg_cancel-.patch b/queue-7.0/ethtool-tsinfo-don-t-pass-err_ptr-to-genlmsg_cancel-.patch
new file mode 100644 (file)
index 0000000..8a9fdb9
--- /dev/null
@@ -0,0 +1,49 @@
+From c3bc87e1fee5346980304db27bf47d63b2ae47af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:30 -0700
+Subject: ethtool: tsinfo: don't pass ERR_PTR to genlmsg_cancel on prepare
+ failure
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit c3fc9976f686f9a95baf87db9d387f218fd65394 ]
+
+The goto err label leads to:
+
+       genlmsg_cancel(skb, ehdr);
+       return ret;
+
+If ethnl_tsinfo_prepare_dump() failed, it has not started a genlmsg.
+There's nothing to cancel, and passing an error pointer to
+genlmsg_cancel() would cause a crash.
+
+Fixes: b9e3f7dc9ed9 ("net: ethtool: tsinfo: Enhance tsinfo to support several hwtstamp by net topology")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-8-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/tsinfo.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/net/ethtool/tsinfo.c b/net/ethtool/tsinfo.c
+index cb1491e0a28bac..64e6016a7a1772 100644
+--- a/net/ethtool/tsinfo.c
++++ b/net/ethtool/tsinfo.c
+@@ -405,10 +405,8 @@ static int ethnl_tsinfo_dump_one_netdev(struct sk_buff *skb,
+                       continue;
+               ehdr = ethnl_tsinfo_prepare_dump(skb, dev, reply_data, cb);
+-              if (IS_ERR(ehdr)) {
+-                      ret = PTR_ERR(ehdr);
+-                      goto err;
+-              }
++              if (IS_ERR(ehdr))
++                      return PTR_ERR(ehdr);
+               reply_data->ts_info.phc_qualifier = ctx->pos_phcqualifier;
+               ret = ops->get_ts_info(dev, &reply_data->ts_info);
+-- 
+2.53.0
+
diff --git a/queue-7.0/ethtool-tsinfo-fix-uninitialized-stats-on-the-by-phc.patch b/queue-7.0/ethtool-tsinfo-fix-uninitialized-stats-on-the-by-phc.patch
new file mode 100644 (file)
index 0000000..008dbf6
--- /dev/null
@@ -0,0 +1,75 @@
+From 547d8b6755488b890f877b151b8f04890c537bea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:29 -0700
+Subject: ethtool: tsinfo: fix uninitialized stats on the by-PHC path
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 1de405699c62c3a9544bcdcfb9eff8a01cfc7582 ]
+
+tsinfo_prepare_data() has two code paths: a "by-PHC" path for
+user-specified hardware timestamping providers, and the old path.
+Commit 89e281ebff72 ("ethtool: init tsinfo stats if requested") added
+ethtool_stats_init() to mark stat slots as ETHTOOL_STAT_NOT_SET before
+the driver callback populates them, but placed the call inside the
+old-path block.
+
+When commit b9e3f7dc9ed9 ("net: ethtool: tsinfo: Enhance tsinfo to
+support several hwtstamp by net topology") added the by-PHC early
+return, it landed above the stats initialization. On that path
+the stats array retains the zero-fill from ethnl_init_reply_data()'s
+zalloc. This leads to the reply including a stats nest with four
+zero-valued attributes that should have been absent.
+
+Reject GET requests for stats with HWTSTAMP_PROVIDER or dump.
+
+Fixes: b9e3f7dc9ed9 ("net: ethtool: tsinfo: Enhance tsinfo to support several hwtstamp by net topology")
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260526153533.2779187-7-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/tsinfo.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/net/ethtool/tsinfo.c b/net/ethtool/tsinfo.c
+index c0145c752d2f8b..cb1491e0a28bac 100644
+--- a/net/ethtool/tsinfo.c
++++ b/net/ethtool/tsinfo.c
+@@ -81,6 +81,11 @@ tsinfo_parse_request(struct ethnl_req_info *req_base, struct nlattr **tb,
+       if (!tb[ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER])
+               return 0;
++      if (req_base->flags & ETHTOOL_FLAG_STATS) {
++              NL_SET_ERR_MSG(extack, "can't query statistics for a provider");
++              return -EOPNOTSUPP;
++      }
++
+       return ts_parse_hwtst_provider(tb[ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER],
+                                      &req->hwprov_desc, extack, &mod);
+ }
+@@ -521,6 +526,12 @@ int ethnl_tsinfo_start(struct netlink_callback *cb)
+       if (ret < 0)
+               goto free_reply_data;
++      if (req_info->base.flags & ETHTOOL_FLAG_STATS) {
++              NL_SET_ERR_MSG(cb->extack, "stats not supported in dump");
++              ret = -EOPNOTSUPP;
++              goto err_dev_put;
++      }
++
+       ctx->req_info = req_info;
+       ctx->reply_data = reply_data;
+       ctx->pos_ifindex = 0;
+@@ -530,6 +541,8 @@ int ethnl_tsinfo_start(struct netlink_callback *cb)
+       return 0;
++err_dev_put:
++      ethnl_parse_header_dev_put(&req_info->base);
+ free_reply_data:
+       kfree(reply_data);
+ free_req_info:
+-- 
+2.53.0
+
diff --git a/queue-7.0/gpio-adnp-fix-flow-control-regression-caused-by-scop.patch b/queue-7.0/gpio-adnp-fix-flow-control-regression-caused-by-scop.patch
new file mode 100644 (file)
index 0000000..4296edc
--- /dev/null
@@ -0,0 +1,43 @@
+From e4087ffb82072afe9d635ba50f4bae9e67a6fc05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 09:35:27 +0200
+Subject: gpio: adnp: fix flow control regression caused by scoped_guard()
+
+From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+
+[ Upstream commit a5c627d90809b793fc053849b3a00609db305776 ]
+
+scoped_guard() is implemented as a for loop. Using it to protect code
+using the continue statement changes the flow as we now only break out
+of the hidden loop inside scoped_guard(), not the original for loop. Use
+a regular code block instead.
+
+Fixes: c7fe19ed3973 ("gpio: adnp: use lock guards for the I2C lock")
+Reported-by: David Lechner <dlechner@baylibre.com>
+Closes: https://lore.kernel.org/all/cde2abb2-4cc8-4fc9-b34a-0c5d2b95779f@baylibre.com/
+Reviewed-by: Linus Walleij <linusw@kernel.org>
+Link: https://patch.msgid.link/20260522073527.9812-1-bartosz.golaszewski@oss.qualcomm.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-adnp.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c
+index e5ac2d2110137f..fe5bcaa90496aa 100644
+--- a/drivers/gpio/gpio-adnp.c
++++ b/drivers/gpio/gpio-adnp.c
+@@ -237,7 +237,9 @@ static irqreturn_t adnp_irq(int irq, void *data)
+               unsigned long pending;
+               int err;
+-              scoped_guard(mutex, &adnp->i2c_lock) {
++              {
++                      guard(mutex)(&adnp->i2c_lock);
++
+                       err = adnp_read(adnp, GPIO_PLR(adnp) + i, &level);
+                       if (err < 0)
+                               continue;
+-- 
+2.53.0
+
diff --git a/queue-7.0/gpio-mxc-fix-irq_high-handling.patch b/queue-7.0/gpio-mxc-fix-irq_high-handling.patch
new file mode 100644 (file)
index 0000000..9aa0277
--- /dev/null
@@ -0,0 +1,38 @@
+From 9aff72d05d5c0f628301257534f677cbd8c5085c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 08:35:01 +0200
+Subject: gpio: mxc: fix irq_high handling
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit dac917ed5aead741004db8d0d5151dd577802df8 ]
+
+If port->irq_high is -1 (fsl,imx21-gpio compatible) and gpio_idx is >= 16
+enable_irq_wake() is called with -1 which is wrong.
+
+Fixes: 5f6d1998adeb ("gpio: mxc: release the parent IRQ in runtime suspend")
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260526063504.25916-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-mxc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
+index 647b6f4861b744..12f11a6c96653c 100644
+--- a/drivers/gpio/gpio-mxc.c
++++ b/drivers/gpio/gpio-mxc.c
+@@ -469,7 +469,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
+                * the handler is needed only once, but doing it for every port
+                * is more robust and easier.
+                */
+-              port->irq_high = -1;
++              port->irq_high = 0;
+               port->mx_irq_handler = mx2_gpio_irq_handler;
+       } else
+               port->mx_irq_handler = mx3_gpio_irq_handler;
+-- 
+2.53.0
+
diff --git a/queue-7.0/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch b/queue-7.0/gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
new file mode 100644 (file)
index 0000000..ac8b1b3
--- /dev/null
@@ -0,0 +1,78 @@
+From 5984d5b25d011db16b6c794b47f97aed9636d7ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:02:45 +0200
+Subject: gpio: rockchip: convert bank->clk to devm_clk_get_enabled()
+
+From: Marco Scardovi <scardracs@disroot.org>
+
+[ Upstream commit 3e46c18d5d87f063a93ae0fe7662fbf6660459d5 ]
+
+The bank->clk was previously obtained via of_clk_get() and manually
+prepared/enabled. However, it was missing a corresponding clk_put() in
+both the error paths and the remove function, leading to a reference leak.
+
+Convert the allocation to devm_clk_get_enabled(), which also properly
+propagates failures from clk_prepare_enable() that were previously ignored.
+
+The GPIO bank device uses the same OF node as the previous of_clk_get()
+call, so devm_clk_get_enabled(dev, NULL) correctly resolves the same
+clock provider entry.
+
+Fix the reference leak and simplify the code by removing the manual
+clk_disable_unprepare() calls in the probe error paths and in the
+remove function.
+
+Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
+Assisted-by: Antigravity:gemini-3.5-flash
+Signed-off-by: Marco Scardovi <scardracs@disroot.org>
+Link: https://patch.msgid.link/20260526171050.12785-2-scardracs@disroot.org
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-rockchip.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index 0fff4a699f12d1..f910220141f712 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -656,11 +656,10 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+       if (!bank->irq)
+               return -EINVAL;
+-      bank->clk = of_clk_get(bank->of_node, 0);
++      bank->clk = devm_clk_get_enabled(bank->dev, NULL);
+       if (IS_ERR(bank->clk))
+               return PTR_ERR(bank->clk);
+-      clk_prepare_enable(bank->clk);
+       id = readl(bank->reg_base + gpio_regs_v2.version_id);
+       switch (id) {
+@@ -672,7 +671,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+               bank->db_clk = of_clk_get(bank->of_node, 1);
+               if (IS_ERR(bank->db_clk)) {
+                       dev_err(bank->dev, "cannot find debounce clk\n");
+-                      clk_disable_unprepare(bank->clk);
+                       return -EINVAL;
+               }
+               break;
+@@ -751,7 +749,6 @@ static int rockchip_gpio_probe(struct platform_device *pdev)
+       ret = rockchip_gpiolib_register(bank);
+       if (ret) {
+-              clk_disable_unprepare(bank->clk);
+               mutex_unlock(&bank->deferred_lock);
+               return ret;
+       }
+@@ -792,7 +789,6 @@ static void rockchip_gpio_remove(struct platform_device *pdev)
+ {
+       struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);
+-      clk_disable_unprepare(bank->clk);
+       gpiochip_remove(&bank->gpio_chip);
+ }
+-- 
+2.53.0
+
diff --git a/queue-7.0/gpio-rockchip-teardown-bugs-and-resource-leaks.patch b/queue-7.0/gpio-rockchip-teardown-bugs-and-resource-leaks.patch
new file mode 100644 (file)
index 0000000..d637509
--- /dev/null
@@ -0,0 +1,88 @@
+From 6b190e68f9aa881bd5f5a82a7c5f19062d079730 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:02:46 +0200
+Subject: gpio: rockchip: teardown bugs and resource leaks
+
+From: Marco Scardovi <scardracs@disroot.org>
+
+[ Upstream commit 9500077678230e36d22bf16d2b9539c13e59a801 ]
+
+Address several teardown issues and resource leaks in the driver's remove
+path and error handling:
+
+1. Debounce clock reference leak: The debounce clock (bank->db_clk) is
+   obtained using of_clk_get() which increments the clock's reference
+   count, but clk_put() is never called. Register a devm action to
+   cleanly release it on unbind. Note that of_clk_get(..., 1) remains
+   necessary over devm_clk_get() because the DT binding does not define
+   clock-names, precluding name-based lookup.
+
+2. Unregistered chained IRQ handler: The chained IRQ handler is not
+   disconnected in remove(). If a stray interrupt fires after the driver
+   is removed, the kernel attempts to execute a stale handler, leading
+   to a panic. Fix this by clearing the handler in remove().
+
+3. IRQ domain leak: The linear IRQ domain and its generic chips are
+   allocated manually during probe but never removed. Remove the IRQ
+   domain during driver teardown to free the associated generic chips
+   and mappings.
+
+Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
+Assisted-by: Antigravity:gemini-3.5-flash
+Signed-off-by: Marco Scardovi <scardracs@disroot.org>
+Link: https://patch.msgid.link/20260526171050.12785-3-scardracs@disroot.org
+[Bartosz: don't emit an error message on devres allocation failure]
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-rockchip.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index f910220141f712..1ef0ba956cfd8c 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -638,10 +638,17 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
+       return ret;
+ }
++static void rockchip_clk_put(void *data)
++{
++      struct clk *clk = data;
++
++      clk_put(clk);
++}
++
+ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+ {
+       struct resource res;
+-      int id = 0;
++      int id = 0, ret;
+       if (of_address_to_resource(bank->of_node, 0, &res)) {
+               dev_err(bank->dev, "cannot find IO resource for bank\n");
+@@ -673,6 +680,11 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
+                       dev_err(bank->dev, "cannot find debounce clk\n");
+                       return -EINVAL;
+               }
++
++              ret = devm_add_action_or_reset(bank->dev, rockchip_clk_put,
++                                             bank->db_clk);
++              if (ret)
++                      return ret;
+               break;
+       case GPIO_TYPE_V1:
+               bank->gpio_regs = &gpio_regs_v1;
+@@ -789,6 +801,9 @@ static void rockchip_gpio_remove(struct platform_device *pdev)
+ {
+       struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);
++      irq_set_chained_handler_and_data(bank->irq, NULL, NULL);
++      if (bank->domain)
++              irq_domain_remove(bank->domain);
+       gpiochip_remove(&bank->gpio_chip);
+ }
+-- 
+2.53.0
+
diff --git a/queue-7.0/gpio-virtuser-fix-uninitialized-data-bug-in-gpio_vir.patch b/queue-7.0/gpio-virtuser-fix-uninitialized-data-bug-in-gpio_vir.patch
new file mode 100644 (file)
index 0000000..41d8449
--- /dev/null
@@ -0,0 +1,49 @@
+From 15f2fc579a4fb8ff836c58cfc9d011b7828e3add Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 10:15:16 +0300
+Subject: gpio: virtuser: Fix uninitialized data bug in
+ gpio_virtuser_direction_do_write()
+
+From: Dan Carpenter <error27@gmail.com>
+
+[ Upstream commit 8a122b5e72cc0043705f0d524bcd15f0c0b3ec15 ]
+
+If *ppos is non-zero (user-space write split over multiple calls to
+write()) then simple_write_to_buffer() won't initialize the start of the
+buffer. Really, non-zero values for *ppos aren't going to work at all.
+Check for that and return -EINVAL at the start of the function.
+
+Fixes: 91581c4b3f29 ("gpio: virtuser: new virtual testing driver for the GPIO API")
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Link: https://patch.msgid.link/ahP3BJWWy-m_qI0X@stanley.mountain
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-virtuser.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpio/gpio-virtuser.c b/drivers/gpio/gpio-virtuser.c
+index 955b5efc283ef5..c6f16cb02bf6b8 100644
+--- a/drivers/gpio/gpio-virtuser.c
++++ b/drivers/gpio/gpio-virtuser.c
+@@ -399,7 +399,7 @@ static ssize_t gpio_virtuser_direction_do_write(struct file *file,
+       char buf[32], *trimmed;
+       int ret, dir, val = 0;
+-      if (count >= sizeof(buf))
++      if (*ppos != 0 || count >= sizeof(buf))
+               return -EINVAL;
+       ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
+@@ -624,7 +624,7 @@ static ssize_t gpio_virtuser_consumer_write(struct file *file,
+       char buf[GPIO_VIRTUSER_NAME_BUF_LEN + 2];
+       int ret;
+-      if (count >= sizeof(buf))
++      if (*ppos != 0 || count >= sizeof(buf))
+               return -EINVAL;
+       ret = simple_write_to_buffer(buf, GPIO_VIRTUSER_NAME_BUF_LEN, ppos,
+-- 
+2.53.0
+
diff --git a/queue-7.0/hid-remove-duplicate-hid_warn_ratelimited-definition.patch b/queue-7.0/hid-remove-duplicate-hid_warn_ratelimited-definition.patch
new file mode 100644 (file)
index 0000000..344d5b8
--- /dev/null
@@ -0,0 +1,43 @@
+From c978f9e8dfcc900acff83041b76d773ac13e293a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 16:32:04 +0800
+Subject: HID: remove duplicate hid_warn_ratelimited definition
+
+From: Liu Kai <lukace97@outlook.com>
+
+[ Upstream commit dd2147375a8fe7c5bc3f1f1b1d3a9567c26faefa ]
+
+The hid_warn_ratelimited macro is defined twice in include/linux/hid.h:
+- first one added by commit 4051ead99888 ("HID: rate-limit hid_warn to
+  prevent log flooding")
+- second one added by commit 1d64624243af ("HID: core: Add
+  printk_ratelimited variants to hid_warn() etc")).
+
+The second definition is correctly grouped with other ratelimited macros.
+Remove the duplicate definition.
+
+Fixes: 1d64624243af ("HID: core: Add printk_ratelimited variants to hid_warn() etc")
+Signed-off-by: Liu Kai <lukace97@outlook.com>
+[bentiss: edited commit message]
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/hid.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/include/linux/hid.h b/include/linux/hid.h
+index 101e05acf931a5..c9e0ebe9c75270 100644
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -1284,8 +1284,6 @@ void hid_quirks_exit(__u16 bus);
+       dev_notice(&(hid)->dev, fmt, ##__VA_ARGS__)
+ #define hid_warn(hid, fmt, ...)                               \
+       dev_warn(&(hid)->dev, fmt, ##__VA_ARGS__)
+-#define hid_warn_ratelimited(hid, fmt, ...)                           \
+-      dev_warn_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__)
+ #define hid_info(hid, fmt, ...)                               \
+       dev_info(&(hid)->dev, fmt, ##__VA_ARGS__)
+ #define hid_dbg(hid, fmt, ...)                                \
+-- 
+2.53.0
+
diff --git a/queue-7.0/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch b/queue-7.0/ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
new file mode 100644 (file)
index 0000000..d8dddc6
--- /dev/null
@@ -0,0 +1,48 @@
+From 55c128606073a42ce30811703a73053e46d35a53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 12:21:47 +0000
+Subject: ipv4: free net->ipv4.sysctl_local_reserved_ports after
+ unregister_net_sysctl_table()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 87a1e0fe7776da7ab411be332b4be58ac8840d10 ]
+
+ipv4_sysctl_exit_net() is currently freeing net->ipv4.sysctl_local_reserved_ports
+too soon.
+
+Only after unregister_net_sysctl_table() we can be sure no threads can possibly
+use the sysctls, including /proc/sys/net/ipv4/ip_local_reserved_ports.
+
+Fixes: 122ff243f5f1 ("ipv4: make ip_local_reserved_ports per netns")
+Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Link: https://patch.msgid.link/20260521122147.3584624-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/sysctl_net_ipv4.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 5654cc9c8a0b9e..e47df4d706a9cd 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -1698,10 +1698,10 @@ static __net_exit void ipv4_sysctl_exit_net(struct net *net)
+ {
+       const struct ctl_table *table;
+-      kfree(net->ipv4.sysctl_local_reserved_ports);
+       table = net->ipv4.ipv4_hdr->ctl_table_arg;
+       unregister_net_sysctl_table(net->ipv4.ipv4_hdr);
+       kfree(table);
++      kfree(net->ipv4.sysctl_local_reserved_ports);
+ }
+ static __net_initdata struct pernet_operations ipv4_sysctl_ops = {
+-- 
+2.53.0
+
diff --git a/queue-7.0/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch b/queue-7.0/ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch
new file mode 100644 (file)
index 0000000..bcdcda4
--- /dev/null
@@ -0,0 +1,49 @@
+From 0e9f2f0f7b61ab6f16e0d83d28aa893042404627 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 13:31:31 +0800
+Subject: ipv6: fix possible infinite loop in fib6_select_path()
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 9c7da87c2dc860bb17ca1ece942495d28b1ce3b9 ]
+
+Found while auditing the same pattern Sashiko reported in
+rt6_fill_node() [1]. Apply the same fix as
+commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").
+
+Writers holding tb6_lock can list_del_rcu(&first->fib6_siblings)
+without waiting for RCU readers; first->fib6_siblings.next then
+still points into the old ring and this softirq-side walker never
+reaches &first->fib6_siblings as its terminator. fib6_purge_rt()
+always WRITE_ONCE()s first->fib6_nsiblings to 0 before
+list_del_rcu(), so an inside-loop check is a reliable detach signal.
+
+[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev
+
+Fixes: d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260527053133.180695-2-jiayuan.chen@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 398e873072bbfb..9a45ecdd7b853c 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -481,6 +481,9 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
+               const struct fib6_nh *nh = sibling->fib6_nh;
+               int nh_upper_bound;
++              if (!READ_ONCE(first->fib6_nsiblings))
++                      break;
++
+               nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);
+               if (hash > nh_upper_bound)
+                       continue;
+-- 
+2.53.0
+
diff --git a/queue-7.0/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch b/queue-7.0/ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch
new file mode 100644 (file)
index 0000000..a7a7700
--- /dev/null
@@ -0,0 +1,47 @@
+From 165f5786a691227b7d6197905485bc0395eab4ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 13:31:30 +0800
+Subject: ipv6: fix possible infinite loop in rt6_fill_node()
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 9f72412bcf60144f252b0d6205106abf14344abc ]
+
+Sashiko reported this issue [1]. Apply the same fix as
+commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").
+
+Writers holding tb6_lock can list_del_rcu(&rt->fib6_siblings)
+without waiting for RCU readers; rt->fib6_siblings.next then still
+points into the old ring and this softirq-side walker never reaches
+&rt->fib6_siblings, causing a CPU stall. fib6_del_route() always
+WRITE_ONCE()s rt->fib6_nsiblings to 0 before list_del_rcu(), so an
+inside-loop check is a reliable detach signal.
+
+[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev
+
+Fixes: d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260527053133.180695-1-jiayuan.chen@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index cb521700cee7ed..398e873072bbfb 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -5891,6 +5891,8 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
+                               goto nla_put_failure;
+                       }
++                      if (!READ_ONCE(rt->fib6_nsiblings))
++                              break;
+               }
+               rcu_read_unlock();
+-- 
+2.53.0
+
diff --git a/queue-7.0/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch b/queue-7.0/ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
new file mode 100644 (file)
index 0000000..31f7623
--- /dev/null
@@ -0,0 +1,62 @@
+From 13865a97cf43376e9c365cc3602035cc0d13b553 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 21:10:31 +0530
+Subject: ipv6: rpl: fix hdrlen overflow in ipv6_rpl_srh_decompress()
+
+From: Rahul Chandelkar <rc@rexion.ai>
+
+[ Upstream commit 9d5e7a46a9f6d8f503b41bfefef70659845f1679 ]
+
+ipv6_rpl_srh_decompress() computes:
+
+    outhdr->hdrlen = (((n + 1) * sizeof(struct in6_addr)) >> 3);
+
+hdrlen is __u8. For n >= 127 the result exceeds 255 and silently
+truncates. With n=127 (cmpri=15, cmpre=15, pad=0, hdrlen=16):
+
+    (128 * 16) >> 3 = 256, truncated to 0 as __u8
+
+The caller in ipv6_rpl_srh_rcv() then places the compressed header
+at buf + ((ohdr->hdrlen + 1) << 3). With hdrlen=0 this is buf + 8,
+but the decompressed region occupies buf[0..2055] (8-byte header
+plus 128 full addresses). The compressed header overlaps the
+decompressed data, and ipv6_rpl_srh_compress() writes into this
+overlap, corrupting the routing header of the forwarded packet.
+
+The existing guard at exthdrs.c:546 checks (n + 1) > 255, which
+prevents n+1 from overflowing unsigned char (the segments_left
+field), but does not prevent the computed hdrlen from overflowing
+__u8. n=127 passes because 128 <= 255, yet hdrlen=256 does not
+fit.
+
+Tighten the bound to (n + 1) > 127. This caps n at 126, giving
+hdrlen = (127 * 16) >> 3 = 254, which fits in __u8. The compressed
+header then lands at buf + ((254 + 1) << 3) = buf + 2040, exactly
+past the decompressed region (buf[0..2039]). No overlap. 127
+segments is well beyond any realistic RPL deployment.
+
+Fixes: 8610c7c6e3bd ("net: ipv6: add support for rpl sr exthdr")
+Signed-off-by: Rahul Chandelkar <rc@rexion.ai>
+Link: https://patch.msgid.link/20260525154031.2290876-1-rc@rexion.ai
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index cf90f933ca1ada..3757317e8151e0 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -544,7 +544,7 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
+        * unsigned char which is segments_left field. Should not be
+        * higher than that.
+        */
+-      if (r || (n + 1) > 255) {
++      if (r || (n + 1) > 127) {
+               kfree_skb(skb);
+               return -1;
+       }
+-- 
+2.53.0
+
diff --git a/queue-7.0/kernel-fork-validate-exit_signal-in-kernel_clone.patch b/queue-7.0/kernel-fork-validate-exit_signal-in-kernel_clone.patch
new file mode 100644 (file)
index 0000000..0e037b6
--- /dev/null
@@ -0,0 +1,116 @@
+From 8e2042f9ba5741e337370a16551934b0f431b7b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Mar 2026 20:49:56 +0530
+Subject: kernel/fork: validate exit_signal in kernel_clone()
+
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+
+[ Upstream commit 09e7827e785729f391c8d46dc71becce70d296ab ]
+
+When a child process exits, it sends exit_signal to its parent via
+do_notify_parent().  The clone() syscall constructs exit_signal as:
+
+(lower_32_bits(clone_flags) & CSIGNAL)
+
+CSIGNAL is 0xff, so values in the range 65-255 are possible.  However,
+valid_signal() only accepts signals up to _NSIG (64 on x86_64).  A
+non-zero non-valid exit_signal acts the same as exit_signal == 0: the
+parent process is not signaled when the child terminates.
+
+The syzkaller reproducer triggers this by calling clone() with flags=0x80,
+resulting in exit_signal = (0x80 & CSIGNAL) = 128, which exceeds _NSIG and
+is not a valid signal.
+
+The v1 of this patch added the check only in the clone() syscall handler,
+which is incomplete.  kernel_clone() has other callers such as
+sys_ia32_clone() which would remain unprotected.  Move the check to
+kernel_clone() to cover all callers.
+
+Since the valid_signal() check is now in kernel_clone() and covers all
+callers including clone3(), the same check in copy_clone_args_from_user()
+becomes redundant and is removed.  The higher 32bits check for clone3() is
+kept as it is clone3() specific.
+
+Note that this is a user-visible change: previously, passing an invalid
+exit_signal to clone() was silently accepted.  The man page for clone()
+does not document any defined behavior for invalid exit_signal values, so
+rejecting them with -EINVAL is the correct behavior.  It is unlikely that
+any sane application relies on passing an invalid exit_signal.
+
+[oleg@redhat.com: the comment above kernel_clone() should be updated]
+  Link: https://lore.kernel.org/abwvgU17W8wuW2-J@redhat.com
+Link: https://lore.kernel.org/20260316151956.563558-1-kartikey406@gmail.com
+Fixes: 3f2c788a1314 ("fork: prevent accidental access to clone3 features")
+Signed-off-by: Deepanshu Kartikey <Kartikey406@gmail.com>
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Reported-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bbe6b99feefc3a0842de
+Tested-by: syzbot+bbe6b99feefc3a0842de@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/20260307064202.353405-1-kartikey406@gmail.com/T/ [v1]
+Link: https://lore.kernel.org/all/20260316104536.558108-1-kartikey406@gmail.com/T/ [v2]
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Ben Segall <bsegall@google.com>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Juri Lelli <juri.lelli@redhat.com>
+Cc: Kees Cook <kees@kernel.org>
+Cc: Liam Howlett <liam@infradead.org>
+Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Valentin Schneider <vschneid@redhat.com>
+Cc: Vincent Guittot <vincent.guittot@linaro.org>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/fork.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 73622ad0665a07..bcde8e2843fb97 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -2606,8 +2606,6 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
+  *
+  * It copies the process, and if successful kick-starts
+  * it and waits for it to finish using the VM if required.
+- *
+- * args->exit_signal is expected to be checked for sanity by the caller.
+  */
+ pid_t kernel_clone(struct kernel_clone_args *args)
+ {
+@@ -2632,6 +2630,9 @@ pid_t kernel_clone(struct kernel_clone_args *args)
+           (args->pidfd == args->parent_tid))
+               return -EINVAL;
++      if (!valid_signal(args->exit_signal))
++              return -EINVAL;
++
+       /*
+        * Determine whether and which event to report to ptracer.  When
+        * called from kernel_thread or CLONE_UNTRACED is explicitly
+@@ -2830,11 +2831,9 @@ static noinline int copy_clone_args_from_user(struct kernel_clone_args *kargs,
+               return -EINVAL;
+       /*
+-       * Verify that higher 32bits of exit_signal are unset and that
+-       * it is a valid signal
++       * Verify that higher 32bits of exit_signal are unset
+        */
+-      if (unlikely((args.exit_signal & ~((u64)CSIGNAL)) ||
+-                   !valid_signal(args.exit_signal)))
++      if (unlikely(args.exit_signal & ~((u64)CSIGNAL)))
+               return -EINVAL;
+       if ((args.flags & CLONE_INTO_CGROUP) &&
+-- 
+2.53.0
+
diff --git a/queue-7.0/ksmbd-fix-fsctl-permission-bypass-by-adding-a-permis.patch b/queue-7.0/ksmbd-fix-fsctl-permission-bypass-by-adding-a-permis.patch
new file mode 100644 (file)
index 0000000..b78794a
--- /dev/null
@@ -0,0 +1,69 @@
+From 3cf7fd18201f3829d9b400331cd5dd626d1e0142 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 22:07:16 +0900
+Subject: ksmbd: fix FSCTL permission bypass by adding a permission check for
+ FSCTL_SET_SPARSE
+
+From: Sean Shen <grayhat@foxmail.com>
+
+[ Upstream commit cc57232cae23c0df91b4a59d0f519141ce9b5b02 ]
+
+FSCTL_SET_SPARSE in fsctl_set_sparse() modifies the file's sparse
+attribute and saves it through xattr without any permission checks.
+
+This exposes two issues:
+
+1) A client on a read-only share can change the sparse attribute
+   on files it opened, even though the share is read-only.
+   Other FSCTL write operations already check
+   test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE),
+   but FSCTL_SET_SPARSE does not.
+
+2) Even on writable shares, clients without FILE_WRITE_DATA or
+   FILE_WRITE_ATTRIBUTES access should not modify the sparse
+   attribute. Similar handle-level checks exist in other functions
+   but are missing here.
+
+Add both share-level writable check and per-handle access check.
+Use goto out on error to avoid leaking file references.
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Cc: Namjae Jeon <linkinjeon@kernel.org>
+Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Cc: Steve French <smfrench@gmail.com>
+Signed-off-by: Sean Shen <grayhat@foxmail.com>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/smb2pdu.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
+index 3a8a739c025fb7..64ef1b8b37f8ad 100644
+--- a/fs/smb/server/smb2pdu.c
++++ b/fs/smb/server/smb2pdu.c
+@@ -8202,9 +8202,20 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id,
+       int ret = 0;
+       __le32 old_fattr;
++      if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
++              ksmbd_debug(SMB, "User does not have write permission\n");
++              return -EACCES;
++      }
++
+       fp = ksmbd_lookup_fd_fast(work, id);
+       if (!fp)
+               return -ENOENT;
++
++      if (!(fp->daccess & (FILE_WRITE_DATA_LE | FILE_WRITE_ATTRIBUTES_LE))) {
++              ret = -EACCES;
++              goto out;
++      }
++
+       idmap = file_mnt_idmap(fp->filp);
+       old_fattr = fp->f_ci->m_fattr;
+-- 
+2.53.0
+
diff --git a/queue-7.0/kunit-fix-use-after-free-in-debugfs-when-using-kunit.patch b/queue-7.0/kunit-fix-use-after-free-in-debugfs-when-using-kunit.patch
new file mode 100644 (file)
index 0000000..53067ab
--- /dev/null
@@ -0,0 +1,110 @@
+From 24af084aa70b0ebc3ba5365f20e1b0815dd3fbb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 May 2026 10:48:54 +0200
+Subject: kunit: fix use-after-free in debugfs when using kunit.filter
+
+From: Florian Schmaus <florian.schmaus@codasip.com>
+
+[ Upstream commit fb6988b83b4cafe8db63999c1ddff1b7c66d2ff5 ]
+
+When the kernel is booted with a kunit filter (e.g.,
+kunit.filter="speed!=slow"), the kunit executor dynamically allocates
+copies of the filtered test suites using kmalloc/kmemdup.
+
+During the initial boot execution, kunit_debugfs_create_suite() creates
+debugfs files (such as /sys/kernel/debug/kunit/<suite>/run) and
+permanently stores a pointer to the dynamically allocated suite in the
+inode's i_private field.
+
+Previously, the executor freed this dynamically allocated suite_set
+immediately after executing the boot-time tests. Because the debugfs
+nodes were not destroyed, any subsequent interaction with the debugfs
+`run` file from userspace triggered a use-after-free (UAF). On systems
+with architectural capabilities, like CHERI RISC-V, this resulted in
+an immediate fatal hardware exception due to the invalidation of the
+capability tags on the reclaimed memory. On other architectures, it
+resulted in silent memory corruption.
+
+Fix this UAF by properly coupling the lifetime of the filtered suite
+memory allocation to the lifetime of the kunit subsystem and its
+associated VFS nodes. Ownership of the boot-time suite_set is now
+transferred to a global tracker ('kunit_boot_suites'), and the memory
+is cleanly released in kunit_exit() during module teardown.
+
+Link: https://lore.kernel.org/r/20260507084854.233984-1-florian.schmaus@codasip.com
+Fixes: e2219db280e3 ("kunit: add debugfs /sys/kernel/debug/kunit/<suite>/results display")
+Signed-off-by: Florian Schmaus <florian.schmaus@codasip.com>
+Reviewed-by: Martin Kaiser <martin@kaiser.cx>
+Reviewed-by: David Gow <david@davidgow.net>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/kunit/test.h |  1 +
+ lib/kunit/executor.c | 19 ++++++++++++++++---
+ lib/kunit/test.c     |  1 +
+ 3 files changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/include/kunit/test.h b/include/kunit/test.h
+index 9cd1594ab697d9..ce0573e196ce75 100644
+--- a/include/kunit/test.h
++++ b/include/kunit/test.h
+@@ -613,6 +613,7 @@ unsigned long kunit_vm_mmap(struct kunit *test, struct file *file,
+                           unsigned long offset);
+ void kunit_cleanup(struct kunit *test);
++void kunit_free_boot_suites(void);
+ void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt, ...);
+diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c
+index 1fef217de11db1..b0f8a41d61d367 100644
+--- a/lib/kunit/executor.c
++++ b/lib/kunit/executor.c
+@@ -15,6 +15,16 @@ extern struct kunit_suite * const __kunit_suites_end[];
+ extern struct kunit_suite * const __kunit_init_suites_start[];
+ extern struct kunit_suite * const __kunit_init_suites_end[];
++static struct kunit_suite_set kunit_boot_suites;
++
++void kunit_free_boot_suites(void)
++{
++      if (kunit_boot_suites.start) {
++              kunit_free_suite_set(kunit_boot_suites);
++              kunit_boot_suites = (struct kunit_suite_set){ NULL, NULL };
++      }
++}
++
+ static char *action_param;
+ module_param_named(action, action_param, charp, 0400);
+@@ -411,9 +421,12 @@ int kunit_run_all_tests(void)
+               pr_err("kunit executor: unknown action '%s'\n", action_param);
+ free_out:
+-      if (filter_glob_param || filter_param)
+-              kunit_free_suite_set(suite_set);
+-      else if (init_num_suites > 0)
++      if (filter_glob_param || filter_param) {
++              if (err)
++                      kunit_free_suite_set(suite_set);
++              else
++                      kunit_boot_suites = suite_set;
++      } else if (init_num_suites > 0)
+               /* Don't use kunit_free_suite_set because suites aren't individually allocated */
+               kfree(suite_set.start);
+diff --git a/lib/kunit/test.c b/lib/kunit/test.c
+index 41e1c89799b6a7..99773e000e1b77 100644
+--- a/lib/kunit/test.c
++++ b/lib/kunit/test.c
+@@ -1075,6 +1075,7 @@ static void __exit kunit_exit(void)
+       kunit_bus_shutdown();
+       kunit_debugfs_cleanup();
++      kunit_free_boot_suites();
+ }
+ module_exit(kunit_exit);
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-avoid-checksumming-unreadable-skb-tail-on-trim.patch b/queue-7.0/net-avoid-checksumming-unreadable-skb-tail-on-trim.patch
new file mode 100644 (file)
index 0000000..87076ca
--- /dev/null
@@ -0,0 +1,102 @@
+From a7143d3ec18f53d308b13cd88e690526a14c8e59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 14:06:40 +0200
+Subject: net: Avoid checksumming unreadable skb tail on trim
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Björn Töpel <bjorn@kernel.org>
+
+[ Upstream commit 2e357f002c61fd76fd8f12468744a06a5ec48eaa ]
+
+pskb_trim_rcsum_slow() keeps CHECKSUM_COMPLETE valid by subtracting
+the checksum of the bytes removed from the skb tail. That assumes the
+removed bytes can be read.
+
+io_uring zcrx skbs may contain unreadable net_iov frags. With fbnic
+header/data split, small TCP/IPv4 packets can carry Ethernet padding
+in such a frag. ip_rcv_core() trims the skb to iph->tot_len before TCP
+sees it, and the CHECKSUM_COMPLETE adjustment then calls
+skb_checksum() on the padding.
+
+This is exposed by IPv4 because small TCP/IPv4 frames can be shorter
+than the Ethernet minimum payload. TCP/IPv6 frames are large enough in
+the normal zcrx path, so they do not hit the same padding trim.
+
+Keep the existing checksum adjustment for readable skbs. If the
+remaining packet is fully linear, drop CHECKSUM_COMPLETE and let the
+stack validate the packet after trimming. If unreadable payload would
+remain, fail the trim; the checksum cannot be adjusted without reading
+the trimmed tail.
+
+Also clear skb->unreadable when trimming removes all frags.
+
+Fixes: 65249feb6b3d ("net: add support for skbs with unreadable frags")
+Signed-off-by: Björn Töpel <bjorn@kernel.org>
+Reviewed-by: Breno Leitao <leitao@debian.org>
+Link: https://patch.msgid.link/20260522120643.242974-1-bjorn@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 31 +++++++++++++++++++++++++++----
+ 1 file changed, 27 insertions(+), 4 deletions(-)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 28bd8304796d7a..13af6f35428d52 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -2811,6 +2811,8 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len)
+               skb->data_len  = 0;
+               skb_set_tail_pointer(skb, len);
+       }
++      if (!skb_shinfo(skb)->nr_frags && !skb_has_frag_list(skb))
++              skb->unreadable = 0;
+       if (!skb->sk || skb->destructor == sock_edemux)
+               skb_condense(skb);
+@@ -2818,16 +2820,37 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len)
+ }
+ EXPORT_SYMBOL(___pskb_trim);
++static int pskb_trim_rcsum_complete(struct sk_buff *skb, unsigned int len)
++{
++      int delta = skb->len - len;
++
++      if (skb_frags_readable(skb)) {
++              skb->csum = csum_block_sub(skb->csum,
++                                         skb_checksum(skb, len, delta, 0),
++                                         len);
++              return 0;
++      }
++
++      if (len > skb_headlen(skb))
++              return -EFAULT;
++
++      /* The trimmed bytes are unreadable, but the remaining packet can be
++       * checksummed by software after trimming.
++       */
++      skb->ip_summed = CHECKSUM_NONE;
++      return 0;
++}
++
+ /* Note : use pskb_trim_rcsum() instead of calling this directly
+  */
+ int pskb_trim_rcsum_slow(struct sk_buff *skb, unsigned int len)
+ {
+       if (skb->ip_summed == CHECKSUM_COMPLETE) {
+-              int delta = skb->len - len;
++              int err;
+-              skb->csum = csum_block_sub(skb->csum,
+-                                         skb_checksum(skb, len, delta, 0),
+-                                         len);
++              err = pskb_trim_rcsum_complete(skb, len);
++              if (err)
++                      return err;
+       } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               int hdlen = (len > skb_headlen(skb)) ? skb_headlen(skb) : len;
+               int offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-handshake-drain-pending-requests-at-net-namespac.patch b/queue-7.0/net-handshake-drain-pending-requests-at-net-namespac.patch
new file mode 100644 (file)
index 0000000..93b148c
--- /dev/null
@@ -0,0 +1,112 @@
+From 0931ecae42ad61cc1eddcb4ad81df6fa680a1311 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:22 -0400
+Subject: net/handshake: Drain pending requests at net namespace exit
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit ea5fe6a73ca57e5150b8a38b341aef2636eb72f0 ]
+
+The arguments to list_splice_init() in handshake_net_exit() are
+reversed. The call moves the local empty "requests" list onto
+hn->hn_requests, leaving the local list empty, so the subsequent
+drain loop runs zero iterations. Pending handshake requests that
+had not yet been accepted are not torn down when the net namespace
+is destroyed; each one keeps a reference on a socket file and on
+the handshake_req allocation.
+
+Pass the source and destination in the documented order
+(list_splice_init(list, head) moves list onto head) so the pending
+list is transferred to the local scratch list and drained through
+handshake_complete().
+
+Fixing the splice direction exposes a list-corruption race. After
+the splice each req->hr_list still has non-empty link pointers,
+threading the stack-local scratch list rather than hn_requests.
+A concurrent handshake_req_cancel() -- for example, from sunrpc's
+TLS timeout on a kernel socket whose netns reference was not
+taken -- finds the request through the rhashtable, calls
+remove_pending(), and sees !list_empty(&req->hr_list).
+__remove_pending_locked() then list_del_init()s an entry off the
+scratch list while the drain iterates, corrupting it. The same
+call arriving after the drain loop has run list_del() on an
+entry hits LIST_POISON instead.
+
+Have remove_pending() check HANDSHAKE_F_NET_DRAINING under
+hn_lock and report not-found when drain is in progress. The
+drain has already taken ownership; handshake_complete()'s existing
+test_and_set on HANDSHAKE_F_REQ_COMPLETED still arbitrates
+between drain and cancel for who calls the consumer's hp_done. Use
+list_del_init() rather than list_del() in the drain so req->hr_list
+does not carry LIST_POISON after drain releases the entry.
+
+The DRAINING guard in remove_pending() makes cancel return false,
+but cancel still falls through to test_and_set_bit on
+HANDSHAKE_F_REQ_COMPLETED and drops the request's hr_file reference.
+Without another pin, if that is the last reference, sk_destruct frees
+the request while it is still linked on the drain loop's local list.
+Pin each request's hr_file under hn_lock before releasing the list,
+and drop that drain pin after the loop finishes with the request.
+
+Fixes: 3b3009ea8abb ("net/handshake: Create a NETLINK service for handling handshake requests")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-8-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/netlink.c | 10 ++++++++--
+ net/handshake/request.c |  5 ++++-
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/net/handshake/netlink.c b/net/handshake/netlink.c
+index 21d6cbd52fcdb6..3fd4fef9bab1a4 100644
+--- a/net/handshake/netlink.c
++++ b/net/handshake/netlink.c
+@@ -201,13 +201,19 @@ static void __net_exit handshake_net_exit(struct net *net)
+        */
+       spin_lock_bh(&hn->hn_lock);
+       set_bit(HANDSHAKE_F_NET_DRAINING, &hn->hn_flags);
+-      list_splice_init(&requests, &hn->hn_requests);
++      list_splice_init(&hn->hn_requests, &requests);
++      list_for_each_entry(req, &requests, hr_list)
++              get_file(req->hr_file);
+       spin_unlock_bh(&hn->hn_lock);
+       while (!list_empty(&requests)) {
++              struct file *file;
++
+               req = list_first_entry(&requests, struct handshake_req, hr_list);
+-              list_del(&req->hr_list);
++              file = req->hr_file;
++              list_del_init(&req->hr_list);
+               handshake_complete(req, -ETIMEDOUT, NULL);
++              fput(file);
+       }
+ }
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index e2d7ee7ce6e0e0..2f1ab6eb9538c5 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -163,13 +163,16 @@ static void __remove_pending_locked(struct handshake_net *hn,
+  * otherwise %false.
+  *
+  * If @req was on a pending list, it has not yet been accepted.
++ * Returns %false when the net namespace is draining; the drain
++ * loop has taken ownership of the pending list.
+  */
+ static bool remove_pending(struct handshake_net *hn, struct handshake_req *req)
+ {
+       bool ret = false;
+       spin_lock_bh(&hn->hn_lock);
+-      if (!list_empty(&req->hr_list)) {
++      if (!test_bit(HANDSHAKE_F_NET_DRAINING, &hn->hn_flags) &&
++          !list_empty(&req->hr_list)) {
+               __remove_pending_locked(hn, req);
+               ret = true;
+       }
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-handshake-hand-off-the-pinned-file-reference-to-.patch b/queue-7.0/net-handshake-hand-off-the-pinned-file-reference-to-.patch
new file mode 100644 (file)
index 0000000..7423d3c
--- /dev/null
@@ -0,0 +1,151 @@
+From 3ad739a55523fe3e66ddedbf7bf5782ecc3ccb0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:19 -0400
+Subject: net/handshake: hand off the pinned file reference to accept_doit
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit f4251190e58b209999c1ba9e6d2976136a1be055 ]
+
+handshake_req_next() removes the request from the per-net
+pending list and drops hn_lock before handshake_nl_accept_doit()
+reads req->hr_sk->sk_socket and dereferences sock->file (once in
+FD_PREPARE() and again in get_file()).  In that window a
+consumer running tls_handshake_cancel() followed by sockfd_put()
+(svc_sock_free) or __fput_sync() (xs_reset_transport) releases
+sock->file.  sock_release() then runs sock_orphan(), zeroing
+sk_socket, and frees the struct socket.  The accept-side code
+either reads NULL through sk_socket or chases freed memory.
+
+The submit-side sock_hold() does not prevent this.  sk_refcnt
+protects struct sock, but struct socket and sock->file are
+independently refcounted via the file descriptor the consumer
+owns.  Pinning sk leaves sock and sock->file unprotected.
+
+Retarget the accept-side dereferences at req->hr_file, which was
+pinned at submit time, instead of req->hr_sk->sk_socket->file.
+Pinning on its own is not sufficient: a consumer that cancels
+between handshake_req_next() returning and accept_doit reaching
+FD_PREPARE() takes the !remove_pending() branch in
+handshake_req_cancel() and drops hr_file before the accept side
+takes its own reference.  Hand off an additional file reference
+inside handshake_req_next(), under hn_lock, so the accept side
+operates on a reference that no concurrent handshake_req_cancel()
+can revoke.  FD_PREPARE() consumes that handed-off reference,
+either by transferring it to the new fd in fd_publish() or by
+dropping it in the cleanup destructor on error; the explicit
+get_file() that previously balanced FD_PREPARE() is therefore
+redundant and goes away.
+
+Update handshake_req_cancel_test2 and _test3 to simulate the
+FD_PREPARE() consumption with an fput() so the kunit file-count
+assertions stay balanced.
+
+Reported-by: Chris Mason <clm@meta.com>
+Fixes: 3b3009ea8abb ("net/handshake: Create a NETLINK service for handling handshake requests")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-5-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/handshake-test.c |  8 ++++++++
+ net/handshake/netlink.c        |  7 ++-----
+ net/handshake/request.c        | 18 ++++++++++++++++++
+ 3 files changed, 28 insertions(+), 5 deletions(-)
+
+diff --git a/net/handshake/handshake-test.c b/net/handshake/handshake-test.c
+index df3948e807a0fd..9cc7a95f41207e 100644
+--- a/net/handshake/handshake-test.c
++++ b/net/handshake/handshake-test.c
+@@ -375,6 +375,10 @@ static void handshake_req_cancel_test2(struct kunit *test)
+       /* Pretend to accept this request */
+       next = handshake_req_next(hn, HANDSHAKE_HANDLER_CLASS_TLSHD);
+       KUNIT_ASSERT_PTR_EQ(test, req, next);
++      /* Simulate FD_PREPARE() consuming the file reference handed
++       * off by handshake_req_next(); see handshake_nl_accept_doit().
++       */
++      fput(filp);
+       /* Act */
+       result = handshake_req_cancel(sock->sk);
+@@ -417,6 +421,10 @@ static void handshake_req_cancel_test3(struct kunit *test)
+       /* Pretend to accept this request */
+       next = handshake_req_next(hn, HANDSHAKE_HANDLER_CLASS_TLSHD);
+       KUNIT_ASSERT_PTR_EQ(test, req, next);
++      /* Simulate FD_PREPARE() consuming the file reference handed
++       * off by handshake_req_next(); see handshake_nl_accept_doit().
++       */
++      fput(filp);
+       /* Pretend to complete this request */
+       handshake_complete(next, -ETIMEDOUT, NULL);
+diff --git a/net/handshake/netlink.c b/net/handshake/netlink.c
+index 039344979de934..561dfa6fa7711a 100644
+--- a/net/handshake/netlink.c
++++ b/net/handshake/netlink.c
+@@ -92,7 +92,6 @@ int handshake_nl_accept_doit(struct sk_buff *skb, struct genl_info *info)
+       struct net *net = sock_net(skb->sk);
+       struct handshake_net *hn = handshake_pernet(net);
+       struct handshake_req *req = NULL;
+-      struct socket *sock;
+       int class, err;
+       err = -EOPNOTSUPP;
+@@ -107,15 +106,13 @@ int handshake_nl_accept_doit(struct sk_buff *skb, struct genl_info *info)
+       err = -EAGAIN;
+       req = handshake_req_next(hn, class);
+       if (req) {
+-              sock = req->hr_sk->sk_socket;
+-
+-              FD_PREPARE(fdf, O_CLOEXEC, sock->file);
++              FD_PREPARE(fdf, O_CLOEXEC, req->hr_file);
+               if (fdf.err) {
++                      fput(req->hr_file); /* drop ref from handshake_req_next() */
+                       err = fdf.err;
+                       goto out_complete;
+               }
+-              get_file(sock->file); /* FD_PREPARE() consumes a reference. */
+               err = req->hr_proto->hp_accept(req, info, fd_prepare_fd(fdf));
+               if (err)
+                       goto out_complete; /* Automatic cleanup handles fput */
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 97f9f823994994..22e4b414ad1d7f 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -177,6 +177,17 @@ static bool remove_pending(struct handshake_net *hn, struct handshake_req *req)
+       return ret;
+ }
++/**
++ * handshake_req_next - Return the next queued handshake request
++ * @hn: per-net handshake state
++ * @class: handler class to match
++ *
++ * On a non-NULL return, the caller owns an extra reference
++ * on @req->hr_file.  FD_PREPARE() consumes it on success; on
++ * the FD_PREPARE() failure path the caller must fput() it.
++ *
++ * Return: pointer to a removed handshake_req, or NULL.
++ */
+ struct handshake_req *handshake_req_next(struct handshake_net *hn, int class)
+ {
+       struct handshake_req *req, *pos;
+@@ -187,6 +198,13 @@ struct handshake_req *handshake_req_next(struct handshake_net *hn, int class)
+               if (pos->hr_proto->hp_handler_class != class)
+                       continue;
+               __remove_pending_locked(hn, pos);
++              /* Hand off a file reference to the accept side under
++               * hn_lock.  A concurrent handshake_req_cancel() can drop
++               * hr_file before accept reaches FD_PREPARE(); this extra
++               * reference keeps the file alive until FD_PREPARE() takes
++               * ownership.
++               */
++              get_file(pos->hr_file);
+               req = pos;
+               break;
+       }
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-handshake-pass-negative-errno-through-handshake_.patch b/queue-7.0/net-handshake-pass-negative-errno-through-handshake_.patch
new file mode 100644 (file)
index 0000000..f4b3d33
--- /dev/null
@@ -0,0 +1,212 @@
+From 72d8327f969d3d48e94f6823e951024e4ae84577 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:17 -0400
+Subject: net/handshake: Pass negative errno through handshake_complete()
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 6b22d433aa13f68e3cd9534ca9a5f4277bfa01c2 ]
+
+handshake_complete() declares status as unsigned int and
+tls_handshake_done() negates that value (-status) before handing
+it to the TLS consumer. Consumers match on negative errno
+constants -- xs_tls_handshake_done() has
+
+       switch (status) {
+       case 0:
+       case -EACCES:
+       case -ETIMEDOUT:
+               lower_transport->xprt_err = status;
+               break;
+       default:
+               lower_transport->xprt_err = -EACCES;
+       }
+
+so the API as designed expects callers to pass positive errno
+values that the tlshd shim then negates.
+
+Three internal callers in handshake_nl_accept_doit(), the
+net-exit drain, and a kunit test follow kernel convention and
+pass negative errnos -- -EIO, -ETIMEDOUT, -ETIMEDOUT. The
+implicit conversion to unsigned int turns -ETIMEDOUT into
+0xFFFFFF92; the subsequent -status in tls_handshake_done()
+wraps back to 110, the consumer's switch falls through, and
+the xprt reports -EACCES on what should be -ETIMEDOUT or -EIO.
+
+Fix the API rather than the call sites. The natural kernel
+convention is negative errno in, negative errno out. Change
+handshake_complete() and hp_done to take int status, drop the
+negation in tls_handshake_done(), and negate once in
+handshake_nl_done_doit() where status arrives from the wire
+as an unsigned netlink attribute. The three internal callers
+were already correct under that convention and need no change.
+
+At the same wire boundary, declare MAX_ERRNO as the netlink
+policy upper bound for HANDSHAKE_A_DONE_STATUS. Attribute
+validation rejects out-of-range values before
+handshake_nl_done_doit() runs, and negating a bounded u32 there
+stays within int range -- closing the UBSAN-visible signed-
+integer overflow that an unconstrained u32 would invoke.
+
+Fixes: 3b3009ea8abb ("net/handshake: Create a NETLINK service for handling handshake requests")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-3-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/netlink/specs/handshake.yaml | 8 ++++++++
+ net/handshake/genl.c                       | 3 ++-
+ net/handshake/genl.h                       | 1 +
+ net/handshake/handshake-test.c             | 2 +-
+ net/handshake/handshake.h                  | 4 ++--
+ net/handshake/netlink.c                    | 2 +-
+ net/handshake/request.c                    | 2 +-
+ net/handshake/tlshd.c                      | 4 ++--
+ 8 files changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/Documentation/netlink/specs/handshake.yaml b/Documentation/netlink/specs/handshake.yaml
+index 95c3fade7a8d7b..1024297b38513a 100644
+--- a/Documentation/netlink/specs/handshake.yaml
++++ b/Documentation/netlink/specs/handshake.yaml
+@@ -12,6 +12,12 @@ protocol: genetlink
+ doc: Netlink protocol to request a transport layer security handshake.
+ definitions:
++  -
++    type: const
++    name: max-errno
++    value: 4095
++    header: linux/err.h
++    scope: kernel
+   -
+     type: enum
+     name: handler-class
+@@ -80,6 +86,8 @@ attribute-sets:
+       -
+         name: status
+         type: u32
++        checks:
++          max: max-errno
+       -
+         name: sockfd
+         type: s32
+diff --git a/net/handshake/genl.c b/net/handshake/genl.c
+index 8706126094915d..4b20cd9cdd0e09 100644
+--- a/net/handshake/genl.c
++++ b/net/handshake/genl.c
+@@ -10,6 +10,7 @@
+ #include "genl.h"
+ #include <uapi/linux/handshake.h>
++#include <linux/err.h>
+ /* HANDSHAKE_CMD_ACCEPT - do */
+ static const struct nla_policy handshake_accept_nl_policy[HANDSHAKE_A_ACCEPT_HANDLER_CLASS + 1] = {
+@@ -18,7 +19,7 @@ static const struct nla_policy handshake_accept_nl_policy[HANDSHAKE_A_ACCEPT_HAN
+ /* HANDSHAKE_CMD_DONE - do */
+ static const struct nla_policy handshake_done_nl_policy[HANDSHAKE_A_DONE_REMOTE_AUTH + 1] = {
+-      [HANDSHAKE_A_DONE_STATUS] = { .type = NLA_U32, },
++      [HANDSHAKE_A_DONE_STATUS] = NLA_POLICY_MAX(NLA_U32, MAX_ERRNO),
+       [HANDSHAKE_A_DONE_SOCKFD] = { .type = NLA_S32, },
+       [HANDSHAKE_A_DONE_REMOTE_AUTH] = { .type = NLA_U32, },
+ };
+diff --git a/net/handshake/genl.h b/net/handshake/genl.h
+index 8d3e18672dafcf..46b65f131669a6 100644
+--- a/net/handshake/genl.h
++++ b/net/handshake/genl.h
+@@ -11,6 +11,7 @@
+ #include <net/genetlink.h>
+ #include <uapi/linux/handshake.h>
++#include <linux/err.h>
+ int handshake_nl_accept_doit(struct sk_buff *skb, struct genl_info *info);
+ int handshake_nl_done_doit(struct sk_buff *skb, struct genl_info *info);
+diff --git a/net/handshake/handshake-test.c b/net/handshake/handshake-test.c
+index 55442b2f518afb..df3948e807a0fd 100644
+--- a/net/handshake/handshake-test.c
++++ b/net/handshake/handshake-test.c
+@@ -25,7 +25,7 @@ static int test_accept_func(struct handshake_req *req, struct genl_info *info,
+       return 0;
+ }
+-static void test_done_func(struct handshake_req *req, unsigned int status,
++static void test_done_func(struct handshake_req *req, int status,
+                          struct genl_info *info)
+ {
+ }
+diff --git a/net/handshake/handshake.h b/net/handshake/handshake.h
+index a48163765a7a1d..2289b0e274f40a 100644
+--- a/net/handshake/handshake.h
++++ b/net/handshake/handshake.h
+@@ -57,7 +57,7 @@ struct handshake_proto {
+       int                     (*hp_accept)(struct handshake_req *req,
+                                            struct genl_info *info, int fd);
+       void                    (*hp_done)(struct handshake_req *req,
+-                                         unsigned int status,
++                                         int status,
+                                          struct genl_info *info);
+       void                    (*hp_destroy)(struct handshake_req *req);
+ };
+@@ -86,7 +86,7 @@ struct handshake_req *handshake_req_hash_lookup(struct sock *sk);
+ struct handshake_req *handshake_req_next(struct handshake_net *hn, int class);
+ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+                        gfp_t flags);
+-void handshake_complete(struct handshake_req *req, unsigned int status,
++void handshake_complete(struct handshake_req *req, int status,
+                       struct genl_info *info);
+ bool handshake_req_cancel(struct sock *sk);
+diff --git a/net/handshake/netlink.c b/net/handshake/netlink.c
+index 97114ec8027a5a..039344979de934 100644
+--- a/net/handshake/netlink.c
++++ b/net/handshake/netlink.c
+@@ -160,7 +160,7 @@ int handshake_nl_done_doit(struct sk_buff *skb, struct genl_info *info)
+       status = -EIO;
+       if (info->attrs[HANDSHAKE_A_DONE_STATUS])
+-              status = nla_get_u32(info->attrs[HANDSHAKE_A_DONE_STATUS]);
++              status = -(int)nla_get_u32(info->attrs[HANDSHAKE_A_DONE_STATUS]);
+       handshake_complete(req, status, info);
+       sockfd_put(sock);
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 5d4a17f902d201..97f9f823994994 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -284,7 +284,7 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+ }
+ EXPORT_SYMBOL(handshake_req_submit);
+-void handshake_complete(struct handshake_req *req, unsigned int status,
++void handshake_complete(struct handshake_req *req, int status,
+                       struct genl_info *info)
+ {
+       struct sock *sk = req->hr_sk;
+diff --git a/net/handshake/tlshd.c b/net/handshake/tlshd.c
+index af294c6cc71731..7567150c2a4f95 100644
+--- a/net/handshake/tlshd.c
++++ b/net/handshake/tlshd.c
+@@ -93,7 +93,7 @@ static void tls_handshake_remote_peerids(struct tls_handshake_req *treq,
+  *
+  */
+ static void tls_handshake_done(struct handshake_req *req,
+-                             unsigned int status, struct genl_info *info)
++                             int status, struct genl_info *info)
+ {
+       struct tls_handshake_req *treq = handshake_req_private(req);
+@@ -104,7 +104,7 @@ static void tls_handshake_done(struct handshake_req *req,
+       if (!status)
+               set_bit(HANDSHAKE_F_REQ_SESSION, &req->hr_flags);
+-      treq->th_consumer_done(treq->th_consumer_data, -status,
++      treq->th_consumer_done(treq->th_consumer_data, status,
+                              treq->th_peerid[0]);
+ }
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-handshake-take-a-long-lived-file-reference-at-su.patch b/queue-7.0/net-handshake-take-a-long-lived-file-reference-at-su.patch
new file mode 100644 (file)
index 0000000..e028b3c
--- /dev/null
@@ -0,0 +1,187 @@
+From 86969bc5abab447646c757cfd5030956913cbd9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:18 -0400
+Subject: net/handshake: Take a long-lived file reference at submit
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 09dba37eee70d0596e26645015f1aa95a9848e9d ]
+
+handshake_nl_accept_doit() needs the file pointer backing
+req->hr_sk->sk_socket to survive the window between
+handshake_req_next() and the subsequent FD_PREPARE() and get_file().
+The submit-side sock_hold() does not provide that.  sk_refcnt keeps
+struct sock alive, but struct socket is owned by sock->file: when
+the consumer fputs the last file reference, sock_release() tears
+the socket down regardless of any sock_hold.
+
+Add an hr_file pointer to struct handshake_req and acquire an
+explicit reference on sock->file during handshake_req_submit().
+handshake_complete() and handshake_req_cancel() release the
+reference on the completion-bit-winning path.
+
+The submit error path must also release the file reference, but
+after rhashtable insertion a concurrent handshake_req_cancel() can
+discover the request and race the error path.  Gate the error-path
+cleanup -- sk_destruct restoration, fput, and request destruction
+-- with test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED), the same
+serialization handshake_complete() and handshake_req_cancel()
+already use.  When cancel has already claimed ownership, the submit
+error path returns without touching the request; socket teardown
+handles final destruction.
+
+The accept-side dereferences are not yet retargeted; that change
+comes in the next patch.
+
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-4-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: ea5fe6a73ca5 ("net/handshake: Drain pending requests at net namespace exit")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/handshake.h |  2 ++
+ net/handshake/netlink.c   |  6 ------
+ net/handshake/request.c   | 42 ++++++++++++++++++++++++++++++++-------
+ 3 files changed, 37 insertions(+), 13 deletions(-)
+
+diff --git a/net/handshake/handshake.h b/net/handshake/handshake.h
+index 2289b0e274f40a..da61cadd1ad3e7 100644
+--- a/net/handshake/handshake.h
++++ b/net/handshake/handshake.h
+@@ -24,6 +24,7 @@ enum hn_flags_bits {
+       HANDSHAKE_F_NET_DRAINING,
+ };
++struct file;
+ struct handshake_proto;
+ /* One handshake request */
+@@ -32,6 +33,7 @@ struct handshake_req {
+       struct rhash_head               hr_rhash;
+       unsigned long                   hr_flags;
+       const struct handshake_proto    *hr_proto;
++      struct file                     *hr_file;
+       struct sock                     *hr_sk;
+       void                            (*hr_odestruct)(struct sock *sk);
+diff --git a/net/handshake/netlink.c b/net/handshake/netlink.c
+index 561dfa6fa7711a..21d6cbd52fcdb6 100644
+--- a/net/handshake/netlink.c
++++ b/net/handshake/netlink.c
+@@ -207,12 +207,6 @@ static void __net_exit handshake_net_exit(struct net *net)
+       while (!list_empty(&requests)) {
+               req = list_first_entry(&requests, struct handshake_req, hr_list);
+               list_del(&req->hr_list);
+-
+-              /*
+-               * Requests on this list have not yet been
+-               * accepted, so they do not have an fd to put.
+-               */
+-
+               handshake_complete(req, -ETIMEDOUT, NULL);
+       }
+ }
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 22e4b414ad1d7f..e2d7ee7ce6e0e0 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -13,6 +13,7 @@
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/inet.h>
++#include <linux/file.h>
+ #include <linux/rhashtable.h>
+ #include <net/sock.h>
+@@ -233,9 +234,16 @@ EXPORT_SYMBOL_IF_KUNIT(handshake_req_next);
+  * A zero return value from handshake_req_submit() means that
+  * exactly one subsequent completion callback is guaranteed.
+  *
+- * A negative return value from handshake_req_submit() means that
+- * no completion callback will be done and that @req has been
+- * destroyed.
++ * A negative return value from handshake_req_submit() guarantees that
++ * no completion callback will occur and that @req is no longer owned by
++ * the caller. If cancellation wins the completion race after the request
++ * has been published, final destruction is deferred until socket teardown.
++ *
++ * The caller must hold a reference on @sock->file for the duration
++ * of this call. Once the request is published to the accept side, a
++ * concurrent completion or cancellation may release the request's pin on
++ * @sock->file; the caller's reference is what keeps @sock->sk valid until
++ * handshake_req_submit() returns.
+  */
+ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+                        gfp_t flags)
+@@ -254,6 +262,14 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+               kfree(req);
+               return -EINVAL;
+       }
++
++      /*
++       * Pin sock->file for the lifetime of the request so the
++       * accept side does not race a consumer that releases the
++       * socket while a handshake is pending.
++       */
++      req->hr_file = get_file(sock->file);
++
+       req->hr_odestruct = req->hr_sk->sk_destruct;
+       req->hr_sk->sk_destruct = handshake_sk_destruct;
+@@ -285,7 +301,11 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+                       goto out_err;
+       }
+-      /* Prevent socket release while a handshake request is pending */
++      /*
++       * Pin struct sock so sk_destruct does not run until the
++       * handshake completion path releases it; struct socket is
++       * held separately via hr_file above.
++       */
+       sock_hold(req->hr_sk);
+       trace_handshake_submit(net, req, req->hr_sk);
+@@ -294,10 +314,13 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+ out_unlock:
+       spin_unlock_bh(&hn->hn_lock);
+ out_err:
+-      /* Restore original destructor so socket teardown still runs on failure */
+-      req->hr_sk->sk_destruct = req->hr_odestruct;
+       trace_handshake_submit_err(net, req, req->hr_sk, ret);
+-      handshake_req_destroy(req);
++      if (!test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) {
++              /* Restore original destructor so socket teardown still runs. */
++              req->hr_sk->sk_destruct = req->hr_odestruct;
++              fput(req->hr_file);
++              handshake_req_destroy(req);
++      }
+       return ret;
+ }
+ EXPORT_SYMBOL(handshake_req_submit);
+@@ -309,11 +332,15 @@ void handshake_complete(struct handshake_req *req, int status,
+       struct net *net = sock_net(sk);
+       if (!test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) {
++              struct file *file = req->hr_file;
++
+               trace_handshake_complete(net, req, sk, status);
+               req->hr_proto->hp_done(req, status, info);
+               /* Handshake request is no longer pending */
+               sock_put(sk);
++
++              fput(file);
+       }
+ }
+ EXPORT_SYMBOL_IF_KUNIT(handshake_complete);
+@@ -362,6 +389,7 @@ bool handshake_req_cancel(struct sock *sk)
+       /* Handshake request is no longer pending */
+       sock_put(sk);
++      fput(req->hr_file);
+       return true;
+ }
+ EXPORT_SYMBOL(handshake_req_cancel);
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-handshake-use-spin_lock_bh-for-hn_lock.patch b/queue-7.0/net-handshake-use-spin_lock_bh-for-hn_lock.patch
new file mode 100644 (file)
index 0000000..a2d2ddc
--- /dev/null
@@ -0,0 +1,138 @@
+From 752b199c12287a17ee46b936125afd25c4f1e549 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:15 -0400
+Subject: net/handshake: Use spin_lock_bh for hn_lock
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit cc993e0927ec8bd98ea33377ada03295fcda0f24 ]
+
+nvmet_tcp_state_change(), a socket callback that runs in BH context,
+can reach handshake_req_cancel() via nvmet_tcp_schedule_release_queue()
+and tls_handshake_cancel().  handshake_req_cancel() acquires
+hn->hn_lock with plain spin_lock().  If a process-context thread on
+the same CPU holds hn->hn_lock when a softirq invokes the cancel path,
+the lock attempt deadlocks.  This is the only caller that invokes
+tls_handshake_cancel() from BH context; every other consumer calls it
+from process context.
+
+Deferring the cancel to process context in the NVMe target is not
+straightforward: nvmet_tcp_schedule_release_queue() must call
+tls_handshake_cancel() atomically with its state transition to
+DISCONNECTING.  If the cancel were deferred, the handshake completion
+callback could fire in the window before the cancel runs, observe the
+unexpected state, and return without dropping its kref on the queue.
+Reworking that interlock is considerably more invasive than hardening
+the handshake lock.  Convert all hn->hn_lock acquisitions from
+spin_lock/spin_unlock to spin_lock_bh/spin_unlock_bh so the lock is
+never taken with softirqs enabled.
+
+Fixes: 675b453e0241 ("nvmet-tcp: enable TLS handshake upcall")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-1-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/handshake/netlink.c |  4 ++--
+ net/handshake/request.c | 14 +++++++-------
+ net/handshake/tlshd.c   |  2 ++
+ 3 files changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/net/handshake/netlink.c b/net/handshake/netlink.c
+index b989456fc4c5ff..97114ec8027a5a 100644
+--- a/net/handshake/netlink.c
++++ b/net/handshake/netlink.c
+@@ -202,10 +202,10 @@ static void __net_exit handshake_net_exit(struct net *net)
+        * accepted and are in progress will be destroyed when
+        * the socket is closed.
+        */
+-      spin_lock(&hn->hn_lock);
++      spin_lock_bh(&hn->hn_lock);
+       set_bit(HANDSHAKE_F_NET_DRAINING, &hn->hn_flags);
+       list_splice_init(&requests, &hn->hn_requests);
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+       while (!list_empty(&requests)) {
+               req = list_first_entry(&requests, struct handshake_req, hr_list);
+diff --git a/net/handshake/request.c b/net/handshake/request.c
+index 2829adbeb149b0..5d4a17f902d201 100644
+--- a/net/handshake/request.c
++++ b/net/handshake/request.c
+@@ -167,12 +167,12 @@ static bool remove_pending(struct handshake_net *hn, struct handshake_req *req)
+ {
+       bool ret = false;
+-      spin_lock(&hn->hn_lock);
++      spin_lock_bh(&hn->hn_lock);
+       if (!list_empty(&req->hr_list)) {
+               __remove_pending_locked(hn, req);
+               ret = true;
+       }
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+       return ret;
+ }
+@@ -182,7 +182,7 @@ struct handshake_req *handshake_req_next(struct handshake_net *hn, int class)
+       struct handshake_req *req, *pos;
+       req = NULL;
+-      spin_lock(&hn->hn_lock);
++      spin_lock_bh(&hn->hn_lock);
+       list_for_each_entry(pos, &hn->hn_requests, hr_list) {
+               if (pos->hr_proto->hp_handler_class != class)
+                       continue;
+@@ -190,7 +190,7 @@ struct handshake_req *handshake_req_next(struct handshake_net *hn, int class)
+               req = pos;
+               break;
+       }
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+       return req;
+ }
+@@ -249,7 +249,7 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+       if (READ_ONCE(hn->hn_pending) >= hn->hn_pending_max)
+               goto out_err;
+-      spin_lock(&hn->hn_lock);
++      spin_lock_bh(&hn->hn_lock);
+       ret = -EOPNOTSUPP;
+       if (test_bit(HANDSHAKE_F_NET_DRAINING, &hn->hn_flags))
+               goto out_unlock;
+@@ -258,7 +258,7 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+               goto out_unlock;
+       if (!__add_pending_locked(hn, req))
+               goto out_unlock;
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+       ret = handshake_genl_notify(net, req->hr_proto, flags);
+       if (ret) {
+@@ -274,7 +274,7 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
+       return 0;
+ out_unlock:
+-      spin_unlock(&hn->hn_lock);
++      spin_unlock_bh(&hn->hn_lock);
+ out_err:
+       /* Restore original destructor so socket teardown still runs on failure */
+       req->hr_sk->sk_destruct = req->hr_odestruct;
+diff --git a/net/handshake/tlshd.c b/net/handshake/tlshd.c
+index 8f9532a15f43f9..af294c6cc71731 100644
+--- a/net/handshake/tlshd.c
++++ b/net/handshake/tlshd.c
+@@ -425,6 +425,8 @@ EXPORT_SYMBOL(tls_server_hello_psk);
+  * Request cancellation races with request completion. To determine
+  * who won, callers examine the return value from this function.
+  *
++ * Context: May be called from process or softirq context.
++ *
+  * Return values:
+  *   %true - Uncompleted handshake request was canceled
+  *   %false - Handshake request already completed or not found
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-hibmcge-disable-relaxed-ordering-to-fix-rx-packe.patch b/queue-7.0/net-hibmcge-disable-relaxed-ordering-to-fix-rx-packe.patch
new file mode 100644 (file)
index 0000000..1eab6be
--- /dev/null
@@ -0,0 +1,45 @@
+From cfeae8c251efba00e11719a40afda675842367c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 22:45:24 +0800
+Subject: net: hibmcge: disable Relaxed Ordering to fix RX packet corruption
+
+From: Jijie Shao <shaojijie@huawei.com>
+
+[ Upstream commit 463a1271aa26eac992851b9d98cc75bc3cd4a1ed ]
+
+When SMMU is disabled, the hibmcge driver may receive corrupted packets.
+The hardware writes packet data and descriptors to the same page, but
+with Relaxed Ordering enabled, PCI write transactions may not be
+strictly ordered. This can cause the driver to observe a valid
+descriptor before the corresponding packet data is fully written.
+
+Fix this by clearing PCI_EXP_DEVCTL_RELAX_EN in the PCI bridge control
+register to ensure strict write ordering between packet data and
+descriptors.
+
+Fixes: f72e25594061 ("net: hibmcge: Implement rx_poll function to receive packets")
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Link: https://patch.msgid.link/20260525144525.94884-2-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c
+index 068da2fd1fea83..f721e98938049e 100644
+--- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c
++++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c
+@@ -420,6 +420,9 @@ static int hbg_pci_init(struct pci_dev *pdev)
+               return -ENOMEM;
+       pci_set_master(pdev);
++      pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL,
++                                 PCI_EXP_DEVCTL_RELAX_EN);
++      pci_save_state(pdev);
+       return 0;
+ }
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-hibmcge-move-dma_rmb-after-dma_sync_single_for_c.patch b/queue-7.0/net-hibmcge-move-dma_rmb-after-dma_sync_single_for_c.patch
new file mode 100644 (file)
index 0000000..519c6fe
--- /dev/null
@@ -0,0 +1,51 @@
+From 1eef5b200c5a704fe170ed657d7149524f46cc1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 22:45:25 +0800
+Subject: net: hibmcge: move dma_rmb() after dma_sync_single_for_cpu() in RX
+ path
+
+From: Jijie Shao <shaojijie@huawei.com>
+
+[ Upstream commit b545b6ea1802b32436fa97f1d2918718212cc831 ]
+
+The dma_rmb() barrier was placed before dma_sync_single_for_cpu(), which
+is incorrect. DMA sync must complete first to make the buffer accessible
+to the CPU, then the rmb barrier ensures subsequent descriptor reads
+observe the latest data written by the hardware.
+
+Reorder the operations so dma_sync_single_for_cpu() is called before
+dma_rmb() to guarantee the driver reads consistent data from the DMA
+buffer.
+
+Fixes: f72e25594061 ("net: hibmcge: Implement rx_poll function to receive packets")
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Link: https://patch.msgid.link/20260525144525.94884-3-shaojijie@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
+index a4ea92c31c2fea..0ae31499467693 100644
+--- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
++++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c
+@@ -452,12 +452,12 @@ static bool hbg_sync_data_from_hw(struct hbg_priv *priv,
+ {
+       struct hbg_rx_desc *rx_desc;
+-      /* make sure HW write desc complete */
+-      dma_rmb();
+-
+       dma_sync_single_for_cpu(&priv->pdev->dev, buffer->page_dma,
+                               buffer->page_size, DMA_FROM_DEVICE);
++      /* make sure HW write desc complete */
++      dma_rmb();
++
+       rx_desc = (struct hbg_rx_desc *)buffer->page_addr;
+       return FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, rx_desc->word2) != 0;
+ }
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-hsr-fix-potential-oob-access-in-supervision-fram.patch b/queue-7.0/net-hsr-fix-potential-oob-access-in-supervision-fram.patch
new file mode 100644 (file)
index 0000000..8713e5c
--- /dev/null
@@ -0,0 +1,48 @@
+From 46edc11fffee29f552edb03be622b536bfa94855 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 May 2026 15:03:30 +0200
+Subject: net: hsr: fix potential OOB access in supervision frame handling
+
+From: Luka Gejak <luka.gejak@linux.dev>
+
+[ Upstream commit f229426072fc865654a60978bb7fda790a051ff3 ]
+
+Ensure the entire TLV header is linearized before access by adding
+sizeof(struct hsr_sup_tlv) to the pskb_may_pull() calls. Without this,
+a truncated frame could cause an out-of-bounds access.
+
+Fixes: eafaa88b3eb7 ("net: hsr: Add support for redbox supervision frames")
+Signed-off-by: Luka Gejak <luka.gejak@linux.dev>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260523130330.61880-1-luka.gejak@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_forward.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index aefc9b6936ba0c..299de290ddaa5c 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -84,7 +84,7 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb)
+       /* Get next tlv */
+       total_length += hsr_sup_tag->tlv.HSR_TLV_length;
+-      if (!pskb_may_pull(skb, total_length))
++      if (!pskb_may_pull(skb, total_length + sizeof(struct hsr_sup_tlv)))
+               return false;
+       skb_pull(skb, total_length);
+       hsr_sup_tlv = (struct hsr_sup_tlv *)skb->data;
+@@ -100,7 +100,7 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb)
+               /* make sure another tlv follows */
+               total_length += sizeof(struct hsr_sup_tlv) + hsr_sup_tlv->HSR_TLV_length;
+-              if (!pskb_may_pull(skb, total_length))
++              if (!pskb_may_pull(skb, total_length + sizeof(struct hsr_sup_tlv)))
+                       return false;
+               /* get next tlv */
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-introduce-skb-tc-depth-field-to-track-packet-loo.patch b/queue-7.0/net-introduce-skb-tc-depth-field-to-track-packet-loo.patch
new file mode 100644 (file)
index 0000000..e8a632c
--- /dev/null
@@ -0,0 +1,95 @@
+From bb7061e5395e889293daffb386f50a6838e46097 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:48 -0400
+Subject: net: Introduce skb tc depth field to track packet loops
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit 98b34f3e8c3492cfc89ff943c9d92b4d52863d1d ]
+
+Add a 2-bit per-skb tc depth field to track packet loops across the stack.
+
+The previous per-CPU loop counters like MIRRED_NEST_LIMIT
+assume a single call stack and lose state in two cases:
+1) When a packet is queued and reprocessed later (e.g., egress->ingress
+   via backlog), the per-cpu state is gone by the time it is dequeued.
+2) With XPS/RPS a packet may arrive on one CPU and be processed on
+   another.
+
+A per-skb field solves both by travelling with the packet itself.
+
+The field fits in existing padding, using 2 bits that were previously a
+hole:
+
+pahole before(-) and after (+) diff looks like:
+   __u8       slow_gro:1;           /*   132: 3  1 */
+   __u8       csum_not_inet:1;      /*   132: 4  1 */
+   __u8       unreadable:1;         /*   132: 5  1 */
+ + __u8       tc_depth:2;           /*   132: 6  1 */
+
+ - /* XXX 2 bits hole, try to pack */
+   /* XXX 1 byte hole, try to pack */
+
+   __u16      tc_index;             /*   134     2 */
+
+There used to be a ttl field which was removed as part of tc_verd in commit
+aec745e2c520 ("net-tc: remove unused tc_verd fields").  It was already
+unused by that time, due to remove earlier in commit c19ae86a510c ("tc: remove
+unused redirect ttl").
+
+The first user of this field is netem, which increments tc_depth on
+duplicated packets before re-enqueueing them at the root qdisc.  On
+re-entry, netem skips duplication for any skb with tc_depth already set,
+bounding recursion to a single level regardless of tree topology.
+
+The other user is mirred which increments it on each pass
+and limits to depth to MIRRED_DEFER_LIMIT (3).
+
+The new field was called ttl in earlier versions of this patch
+but renamed to tc_depth to avoid confusion with IP ttl.
+
+Note (looking at you Sashiko! Dont ignore me and continue bringing this up):
+1. Since both mirred and netem utilize the same 2-bit tc_depth field it is
+   possible when netem and mirred are used together that netem qdisc to skip
+   the duplication step. This is a known trade-off, as a 2-bit field cannot
+   independently track both features' recursion depths and it is not considered
+   sane to have a setup that addresses both features on at the same time.
+
+2. skb_scrub_packet does not clear tc_depth. This means a packet's loop history
+  is preserved even across namespaces. While this might be restrictive for
+  some topologies, it is also design intent to provide robustness against loops
+  across namespaces.
+
+Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-2-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: db875221ab08 ("net/sched: Fix ethx:ingress -> ethy:egress -> ethx:ingress mirred loop")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/skbuff.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 2f278ce376b7ed..a58ff8903e536e 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -821,6 +821,7 @@ enum skb_tstamp_type {
+  *    @_sk_redir: socket redirection information for skmsg
+  *    @_nfct: Associated connection, if any (with nfctinfo bits)
+  *    @skb_iif: ifindex of device we arrived on
++ *    @tc_depth: counter for packet duplication
+  *    @tc_index: Traffic control index
+  *    @hash: the packet hash
+  *    @queue_mapping: Queue mapping for multiqueue devices
+@@ -1030,6 +1031,7 @@ struct sk_buff {
+       __u8                    csum_not_inet:1;
+ #endif
+       __u8                    unreadable:1;
++      __u8                    tc_depth:2;
+ #if defined(CONFIG_NET_SCHED) || defined(CONFIG_NET_XGRESS)
+       __u16                   tc_index;       /* traffic control index */
+ #endif
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-iucv-fix-locking-in-.getsockopt.patch b/queue-7.0/net-iucv-fix-locking-in-.getsockopt.patch
new file mode 100644 (file)
index 0000000..1cde028
--- /dev/null
@@ -0,0 +1,87 @@
+From b2ffd478825809dcaaacb0279519368df3385a11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 07:11:45 -0700
+Subject: net/iucv: fix locking in .getsockopt
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 3589d20a666caf30ad100c960a2de7de390fce88 ]
+
+Mirror iucv_sock_setsockopt() and wrap the whole switch in
+lock_sock()/release_sock(). The pre-existing SO_MSGLIMIT-only lock
+becomes redundant and is removed.
+
+Any AF_IUCV HIPER user can potentially crash the kernel by racing
+recvmsg() with getsockopt(SO_MSGSIZE): the SO_MSGSIZE arm dereferences
+iucv->hs_dev->mtu after iucv_sock_close() (called from the racing
+recvmsg()) has set hs_dev to NULL, producing a NULL pointer dereference
+oops.
+
+Suggested-by: Stanislav Fomichev <sdf.kernel@gmail.com>
+Fixes: 51363b8751a6 ("af_iucv: allow retrieval of maximum message size")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Tested-by: Alexandra Winter <wintera@linux.ibm.com>
+Link: https://patch.msgid.link/20260521-af_iucv_fix2-v1-1-f16b1c510aa9@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/iucv/af_iucv.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index 6554d2cffc1961..30cbd98f941a98 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -1538,7 +1538,7 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       struct sock *sk = sock->sk;
+       struct iucv_sock *iucv = iucv_sk(sk);
+       unsigned int val;
+-      int len;
++      int len, rc;
+       if (level != SOL_IUCV)
+               return -ENOPROTOOPT;
+@@ -1551,26 +1551,34 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+       len = min_t(unsigned int, len, sizeof(int));
++      rc = 0;
++
++      lock_sock(sk);
+       switch (optname) {
+       case SO_IPRMDATA_MSG:
+               val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0;
+               break;
+       case SO_MSGLIMIT:
+-              lock_sock(sk);
+               val = (iucv->path != NULL) ? iucv->path->msglim /* connected */
+                                          : iucv->msglimit;    /* default */
+-              release_sock(sk);
+               break;
+       case SO_MSGSIZE:
+-              if (sk->sk_state == IUCV_OPEN)
+-                      return -EBADFD;
++              if (sk->sk_state == IUCV_OPEN) {
++                      rc = -EBADFD;
++                      break;
++              }
+               val = (iucv->hs_dev) ? iucv->hs_dev->mtu -
+                               sizeof(struct af_iucv_trans_hdr) - ETH_HLEN :
+                               0x7fffffff;
+               break;
+       default:
+-              return -ENOPROTOOPT;
++              rc = -ENOPROTOOPT;
++              break;
+       }
++      release_sock(sk);
++
++      if (rc)
++              return rc;
+       if (put_user(len, optlen))
+               return -EFAULT;
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-mana-add-null-guards-in-teardown-path-to-prevent.patch b/queue-7.0/net-mana-add-null-guards-in-teardown-path-to-prevent.patch
new file mode 100644 (file)
index 0000000..59b48bf
--- /dev/null
@@ -0,0 +1,148 @@
+From ae0d68b335ffad3e1e24a238363c50cdc850204e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 01:08:24 -0700
+Subject: net: mana: Add NULL guards in teardown path to prevent panic on
+ attach failure
+
+From: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+
+[ Upstream commit 17bfe0a8c014ee1d542ad352cd6a0a505361664a ]
+
+When queue allocation fails partway through, the error cleanup frees
+and NULLs apc->tx_qp and apc->rxqs. Multiple teardown paths such as
+mana_remove(), mana_change_mtu() recovery, and internal error handling
+in mana_alloc_queues() can subsequently call into functions that
+dereference these pointers without NULL checks:
+
+- mana_chn_setxdp() dereferences apc->rxqs[0], causing a NULL pointer
+  dereference panic (CR2: 0000000000000000 at mana_chn_setxdp+0x26).
+- mana_destroy_vport() iterates apc->rxqs without a NULL check.
+- mana_fence_rqs() iterates apc->rxqs without a NULL check.
+- mana_dealloc_queues() iterates apc->tx_qp without a NULL check.
+
+Add NULL guards for apc->rxqs in mana_fence_rqs(),
+mana_destroy_vport(), and before the mana_chn_setxdp() call. Add a
+NULL guard for apc->tx_qp in mana_dealloc_queues() to skip TX queue
+draining when TX queues were never allocated or already freed.
+
+Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
+Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+Link: https://patch.msgid.link/20260525081129.1230035-2-dipayanroy@linux.microsoft.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microsoft/mana/mana_en.c | 70 +++++++++++--------
+ 1 file changed, 41 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
+index 14d6f68eaa6958..3ddbf3b9a76501 100644
+--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
+@@ -1713,6 +1713,9 @@ static void mana_fence_rqs(struct mana_port_context *apc)
+       struct mana_rxq *rxq;
+       int err;
++      if (!apc->rxqs)
++              return;
++
+       for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
+               rxq = apc->rxqs[rxq_idx];
+               err = mana_fence_rq(apc, rxq);
+@@ -2821,13 +2824,16 @@ static void mana_destroy_vport(struct mana_port_context *apc)
+       struct mana_rxq *rxq;
+       u32 rxq_idx;
+-      for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
+-              rxq = apc->rxqs[rxq_idx];
+-              if (!rxq)
+-                      continue;
++      if (apc->rxqs) {
+-              mana_destroy_rxq(apc, rxq, true);
+-              apc->rxqs[rxq_idx] = NULL;
++              for (rxq_idx = 0; rxq_idx < apc->num_queues; rxq_idx++) {
++                      rxq = apc->rxqs[rxq_idx];
++                      if (!rxq)
++                              continue;
++
++                      mana_destroy_rxq(apc, rxq, true);
++                      apc->rxqs[rxq_idx] = NULL;
++              }
+       }
+       mana_destroy_txq(apc);
+@@ -3232,7 +3238,8 @@ static int mana_dealloc_queues(struct net_device *ndev)
+       if (apc->port_is_up)
+               return -EINVAL;
+-      mana_chn_setxdp(apc, NULL);
++      if (apc->rxqs)
++              mana_chn_setxdp(apc, NULL);
+       if (gd->gdma_context->is_pf && !apc->ac->bm_hostmode)
+               mana_pf_deregister_filter(apc);
+@@ -3250,33 +3257,38 @@ static int mana_dealloc_queues(struct net_device *ndev)
+        * number of queues.
+        */
+-      for (i = 0; i < apc->num_queues; i++) {
+-              txq = &apc->tx_qp[i].txq;
+-              tsleep = 1000;
+-              while (atomic_read(&txq->pending_sends) > 0 &&
+-                     time_before(jiffies, timeout)) {
+-                      usleep_range(tsleep, tsleep + 1000);
+-                      tsleep <<= 1;
+-              }
+-              if (atomic_read(&txq->pending_sends)) {
+-                      err = pcie_flr(to_pci_dev(gd->gdma_context->dev));
+-                      if (err) {
+-                              netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
+-                                         err, atomic_read(&txq->pending_sends),
+-                                         txq->gdma_txq_id);
++      if (apc->tx_qp) {
++              for (i = 0; i < apc->num_queues; i++) {
++                      txq = &apc->tx_qp[i].txq;
++                      tsleep = 1000;
++                      while (atomic_read(&txq->pending_sends) > 0 &&
++                             time_before(jiffies, timeout)) {
++                              usleep_range(tsleep, tsleep + 1000);
++                              tsleep <<= 1;
++                      }
++                      if (atomic_read(&txq->pending_sends)) {
++                              err =
++                                  pcie_flr(to_pci_dev(gd->gdma_context->dev));
++                              if (err) {
++                                      netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
++                                                 err,
++                                          atomic_read(&txq->pending_sends),
++                                          txq->gdma_txq_id);
++                              }
++                              break;
+                       }
+-                      break;
+               }
+-      }
+-      for (i = 0; i < apc->num_queues; i++) {
+-              txq = &apc->tx_qp[i].txq;
+-              while ((skb = skb_dequeue(&txq->pending_skbs))) {
+-                      mana_unmap_skb(skb, apc);
+-                      dev_kfree_skb_any(skb);
++              for (i = 0; i < apc->num_queues; i++) {
++                      txq = &apc->tx_qp[i].txq;
++                      while ((skb = skb_dequeue(&txq->pending_skbs))) {
++                              mana_unmap_skb(skb, apc);
++                              dev_kfree_skb_any(skb);
++                      }
++                      atomic_set(&txq->pending_sends, 0);
+               }
+-              atomic_set(&txq->pending_sends, 0);
+       }
++
+       /* We're 100% sure the queues can no longer be woken up, because
+        * we're sure now mana_poll_tx_cq() can't be running.
+        */
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-mana-skip-redundant-detach-on-already-detached-p.patch b/queue-7.0/net-mana-skip-redundant-detach-on-already-detached-p.patch
new file mode 100644 (file)
index 0000000..05c8f81
--- /dev/null
@@ -0,0 +1,51 @@
+From 4bdb09f16d22a76ac25db360d5cfbd8dcb341672 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 01:08:25 -0700
+Subject: net: mana: Skip redundant detach on already-detached port
+
+From: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+
+[ Upstream commit 5b05aa36ee24297d7296ca58dfd8c448d0e4cda3 ]
+
+When mana_per_port_queue_reset_work_handler() runs after a previous
+detach succeeded but attach failed, the port is left in a detached
+state with apc->tx_qp and apc->rxqs already freed. Calling
+mana_detach() again unconditionally leads to NULL pointer dereferences
+during queue teardown.
+
+Add an early exit in mana_detach() when the port is already in
+detached state (!netif_device_present) for non-close callers, making
+it safe to call idempotently. This allows the queue reset handler and
+other recovery paths to simply retry mana_attach() without redundant
+teardown.
+
+Fixes: 3b194343c250 ("net: mana: Implement ndo_tx_timeout and serialize queue resets per port.")
+Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+Link: https://patch.msgid.link/20260525081129.1230035-3-dipayanroy@linux.microsoft.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microsoft/mana/mana_en.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
+index 3ddbf3b9a76501..13a0af0456c9e3 100644
+--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
+@@ -3313,6 +3313,12 @@ int mana_detach(struct net_device *ndev, bool from_close)
+       ASSERT_RTNL();
++      /* If already detached (indicates detach succeeded but attach failed
++       * previously). Now skip mana detach and just retry mana_attach.
++       */
++      if (!from_close && !netif_device_present(ndev))
++              return 0;
++
+       apc->port_st_save = apc->port_is_up;
+       apc->port_is_up = false;
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-mlx5-hws-reject-unsupported-remove-header-action.patch b/queue-7.0/net-mlx5-hws-reject-unsupported-remove-header-action.patch
new file mode 100644 (file)
index 0000000..8db678a
--- /dev/null
@@ -0,0 +1,50 @@
+From 29a39d1a8e1fa1b8d48f7beacafdc71bb4d79068 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 May 2026 01:00:31 +0100
+Subject: net/mlx5: HWS: Reject unsupported remove-header action
+
+From: Prathamesh Deshpande <prathameshdeshpande7@gmail.com>
+
+[ Upstream commit 86f1d0f063e423a5c1982db1e5e7a8eac511e603 ]
+
+mlx5_cmd_hws_packet_reformat_alloc() handles
+MLX5_REFORMAT_TYPE_REMOVE_HDR by looking up a matching HWS remove-header
+action.
+
+If mlx5_fs_get_action_remove_header_vlan() returns NULL, the code only
+logs an error and continues. The function then returns success with a NULL
+HWS action stored in the packet-reformat object.
+
+Return an error when no matching remove-header action is available.
+
+Fixes: aecd9d1020e3 ("net/mlx5: fs, add HWS packet reformat API function")
+Signed-off-by: Prathamesh Deshpande <prathameshdeshpande7@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
+Acked-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20260506000054.51797-1-prathameshdeshpande7@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c
+index aca77853abb81b..5a172c572a68f5 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c
+@@ -1320,8 +1320,10 @@ mlx5_cmd_hws_packet_reformat_alloc(struct mlx5_flow_root_namespace *ns,
+               break;
+       case MLX5_REFORMAT_TYPE_REMOVE_HDR:
+               hws_action = mlx5_fs_get_action_remove_header_vlan(fs_ctx, params);
+-              if (!hws_action)
++              if (!hws_action) {
+                       mlx5_core_err(dev, "Only vlan remove header supported\n");
++                      return -EOPNOTSUPP;
++              }
+               break;
+       default:
+               mlx5_core_err(ns->dev, "Packet-reformat not supported(%d)\n",
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-netlink-don-t-set-nsid-on-local-notifications.patch b/queue-7.0/net-netlink-don-t-set-nsid-on-local-notifications.patch
new file mode 100644 (file)
index 0000000..f995c27
--- /dev/null
@@ -0,0 +1,82 @@
+From c02be8ca232955dabaaefb486e7a15ee59720851 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:36 +0200
+Subject: net: netlink: don't set nsid on local notifications
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 88b126b39f9757e9debc322d4679239e9af089c7 ]
+
+In most cases, notifications on sockets with NETLINK_LISTEN_ALL_NSID
+do not contain NSID in their ancillary data in case the event is local
+to the listener.
+
+However, when a self-referential NSID is allocated for a namespace,
+every local notification starts sending this ID to the user space.
+
+This is problematic, because the listener cannot tell if those
+notifications are local or not anymore without making extra requests
+to figure out if the provided NSID is local or not.  The listener
+can also not figure out the local NSID beforehand as it can be
+allocated at any point in time by other processes, changing the
+structure of the future notifications for everyone.
+
+The value is practically not useful, since it's the namespace's own
+ID that the application has to obtain from other sources in order to
+figure out if it's the same or not.  So, for the application it's
+just an extra busy work with no benefits.  Moreover, applications
+that do not know about this quirk may be mishandling notifications
+with NSID set as notifications from remote namespaces.  This is the
+case for ovs-vswitchd and the iproute2's 'ip monitor' that stops
+printing 'current' and starts printing the nsid number mid-session.
+
+Lack of clear documentation for this behavior is also not helping.
+
+A search though open-source projects doesn't reveal any projects
+that use NETNSA_NSID_NOT_ASSIGNED and rely on metadata to contain
+self-referential NSIDs (expected, since the value is not useful).
+Quite the opposite, as already mentioned, there are few applications
+that rely on NSID to not be present in local events.
+
+Since the value is not useful and actively harmful in some cases,
+let's not report it for local events, making the notifications more
+consistent.
+
+Also adding some blank lines for readability.
+
+Fixes: 59324cf35aba ("netlink: allow to listen "all" netns")
+Reported-by: Matteo Perin <matteo.perin@canonical.com>
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-3-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 441c9852b25714..c47f530b9ff7d9 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1482,10 +1482,14 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++
+       NETLINK_CB(p->skb2).nsid_is_set = false;
+-      NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+-      if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+-              NETLINK_CB(p->skb2).nsid_is_set = true;
++      if (!net_eq(sock_net(sk), p->net)) {
++              NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
++              if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
++                      NETLINK_CB(p->skb2).nsid_is_set = true;
++      }
++
+       val = netlink_broadcast_deliver(sk, p->skb2);
+       if (val < 0) {
+               netlink_overrun(sk);
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-netlink-fix-sending-unassigned-nsid-after-assign.patch b/queue-7.0/net-netlink-fix-sending-unassigned-nsid-after-assign.patch
new file mode 100644 (file)
index 0000000..6dd5953
--- /dev/null
@@ -0,0 +1,45 @@
+From d7e12a472a7a13f826bf9f11ea71e8732568776e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 19:22:35 +0200
+Subject: net: netlink: fix sending unassigned nsid after assigned one
+
+From: Ilya Maximets <i.maximets@ovn.org>
+
+[ Upstream commit 70f8592ee90585272018a725054b6eb2ab7e99ca ]
+
+If the current skb is not shared, it is re-used directly for all the
+sockets subscribed to the notification.  If we have remote all-nsid
+socket receiving a message first, then the 'nsid_is_set' will be
+set to 'true'.  If the nsid is NOT_ASSIGNED for the next socket in
+the list, the 'nsid_is_set' will remain 'true' and the negative value
+is be delivered to the user space.  All subsequent nsid values will be
+delivered as well, since there is no code path that sets the flag
+back to 'false'.
+
+Fix that by always dropping the flag to 'false' first.
+
+Fixes: 7212462fa6fd ("netlink: don't send unknown nsid")
+Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Link: https://patch.msgid.link/20260520172317.175168-2-i.maximets@ovn.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 4d609d5cf40653..441c9852b25714 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1482,6 +1482,7 @@ static void do_one_broadcast(struct sock *sk,
+               p->skb2 = NULL;
+               goto out;
+       }
++      NETLINK_CB(p->skb2).nsid_is_set = false;
+       NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
+       if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+               NETLINK_CB(p->skb2).nsid_is_set = true;
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-pcs-pcs-mtk-lynxi-fix-bpi-r3-serdes-configuratio.patch b/queue-7.0/net-pcs-pcs-mtk-lynxi-fix-bpi-r3-serdes-configuratio.patch
new file mode 100644 (file)
index 0000000..25d4966
--- /dev/null
@@ -0,0 +1,63 @@
+From 68d43e79c75d51bed77ed440241f848e044c5ae8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 17:32:38 +0200
+Subject: net: pcs: pcs-mtk-lynxi: fix bpi-r3 serdes configuration
+
+From: Frank Wunderlich <frank-w@public-files.de>
+
+[ Upstream commit 422b5233b607476ac7176bfa2a101b9a103d7653 ]
+
+Commit 8871389da151 introduces common pcs dts properties which writes
+rx=normal,tx=normal polarity to register SGMSYS_QPHY_WRAP_CTRL of switch.
+This is initialized with tx-bit set and so change inverts polarity
+compared to before.
+
+It looks like mt7531 has tx polarity inverted in hardware and set tx-bit
+by default to restore the normal polarity.
+
+The MT7531 datasheet quite clearly states:
+Register 000050EC QPHY_WRAP_CTRL -- QPHY wrapper control
+Reset value: 0x00000501
+
+BIT 1 RX_BIT_POLARITY -- RX bit polarity control
+ 1'b0: normal
+ 1'b1: inverted
+
+BIT 0 TX_BIT_POLARITY -- TX bit polarity control (TX default inversed
+in MT7531)
+ 1'b0: normal
+ 1'b1: inverted
+
+Till this patch the register write was only called when mediatek,pnswap
+property was set which cannot be done for switch because the fw-node param
+was always NULL from switch driver in the mtk_pcs_lynxi_create call.
+
+Do not configure switch side like it's done before.
+
+Fixes: 8871389da151 ("net: pcs: pcs-mtk-lynxi: deprecate "mediatek,pnswap"")
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260526153239.30194-1-linux@fw-web.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/pcs/pcs-mtk-lynxi.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
+index c12f8087af9be5..a753bd88cbc223 100644
+--- a/drivers/net/pcs/pcs-mtk-lynxi.c
++++ b/drivers/net/pcs/pcs-mtk-lynxi.c
+@@ -129,6 +129,9 @@ static int mtk_pcs_config_polarity(struct mtk_pcs_lynxi *mpcs,
+       unsigned int val = 0;
+       int ret;
++      if (!fwnode)
++              return 0;
++
+       if (fwnode_property_read_bool(fwnode, "mediatek,pnswap"))
+               default_pol = PHY_POL_INVERT;
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-sched-act_mirred-fix-blockcast-recursion-bypass-.patch b/queue-7.0/net-sched-act_mirred-fix-blockcast-recursion-bypass-.patch
new file mode 100644 (file)
index 0000000..6fa82ea
--- /dev/null
@@ -0,0 +1,114 @@
+From 47d74a925129f0f80822a799be3a6404b4bf8be9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:53 -0400
+Subject: net/sched: act_mirred: Fix blockcast recursion bypass leading to
+ stack overflow
+
+From: Kito Xu (veritas501) <hxzene@gmail.com>
+
+[ Upstream commit a005fa5d7502eefec7ee6e1c01adadc06de2f9ad ]
+
+tcf_mirred_act() checks sched_mirred_nest against MIRRED_NEST_LIMIT (4)
+to prevent deep recursion.  However, when the action uses blockcast
+(tcfm_blockid != 0), the function returns at the tcf_blockcast() call
+BEFORE reaching the counter increment.  As a result, the recursion
+counter never advances and the limit check is entirely bypassed.
+
+When two devices share a TC egress block with a mirred blockcast rule,
+a packet egressing on device A is mirrored to device B via blockcast;
+device B's egress TC re-enters tcf_mirred_act() via blockcast and
+mirrors back to A, creating an unbounded recursion loop:
+
+  tcf_mirred_act -> tcf_blockcast -> tcf_mirred_to_dev -> dev_queue_xmit
+  -> sch_handle_egress -> tcf_classify -> tcf_mirred_act -> (repeat)
+
+This recursion continues until the kernel stack overflows.
+
+The bug is reachable from an unprivileged user via
+unshare(CLONE_NEWUSER | CLONE_NEWNET): user namespaces grant
+CAP_NET_ADMIN in the new network namespace, which is sufficient to
+create dummy devices, attach clsact qdiscs with shared blocks, and
+install mirred blockcast filters.
+
+ BUG: TASK stack guard page was hit at ffffc90000b7fff8
+ Oops: stack guard page: 0000 [#1] SMP KASAN NOPTI
+ CPU: 2 UID: 1000 PID: 169 Comm: poc Not tainted 7.0.0-rc7-next-20260410
+ RIP: 0010:xas_find+0x17/0x480
+ Call Trace:
+  xa_find+0x17b/0x1d0
+  tcf_mirred_act+0x640/0x1060
+  tcf_action_exec+0x400/0x530
+  basic_classify+0x128/0x1d0
+  tcf_classify+0xd83/0x1150
+  tc_run+0x328/0x620
+  __dev_queue_xmit+0x797/0x3100
+  tcf_mirred_to_dev+0x7b1/0xf70
+  tcf_mirred_act+0x68a/0x1060
+  [repeating ~30+ times until stack overflow]
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Fix this by incrementing sched_mirred_nest before calling
+tcf_blockcast() and decrementing it on return, mirroring the
+non-blockcast path.  This ensures subsequent recursive entries see the
+updated counter and are correctly limited by MIRRED_NEST_LIMIT.
+
+Fixes: fe946a751d9b ("net/sched: act_mirred: add loop detection")
+Signed-off-by: Kito Xu (veritas501) <hxzene@gmail.com>
+Link: https://patch.msgid.link/20260525122556.973584-7-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_mirred.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
+index dd5e7ea7ef2652..dbe4a4ff3e08b8 100644
+--- a/net/sched/act_mirred.c
++++ b/net/sched/act_mirred.c
+@@ -396,14 +396,12 @@ static int tcf_blockcast_mirror(struct sk_buff *skb, struct tcf_mirred *m,
+ static int tcf_blockcast(struct sk_buff *skb, struct tcf_mirred *m,
+                        const u32 blockid, struct tcf_result *res,
+-                       int retval)
++                       int m_eaction, int retval)
+ {
+       const u32 exception_ifindex = skb->dev->ifindex;
+       struct tcf_block *block;
+       bool is_redirect;
+-      int m_eaction;
+-      m_eaction = READ_ONCE(m->tcfm_eaction);
+       is_redirect = tcf_mirred_is_act_redirect(m_eaction);
+       /* we are already under rcu protection, so can call block lookup
+@@ -453,8 +451,16 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+       tcf_action_update_bstats(&m->common, skb);
+       blockid = READ_ONCE(m->tcfm_blockid);
+-      if (blockid)
+-              return tcf_blockcast(skb, m, blockid, res, retval);
++      m_eaction = READ_ONCE(m->tcfm_eaction);
++      want_ingress = tcf_mirred_act_wants_ingress(m_eaction);
++      if (blockid) {
++              if (!want_ingress)
++                      xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = NULL;
++              retval = tcf_blockcast(skb, m, blockid, res, m_eaction, retval);
++              if (!want_ingress)
++                      xmit->sched_mirred_nest--;
++              return retval;
++      }
+       dev = rcu_dereference_bh(m->tcfm_dev);
+       if (unlikely(!dev)) {
+@@ -463,8 +469,6 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+               return retval;
+       }
+-      m_eaction = READ_ONCE(m->tcfm_eaction);
+-      want_ingress = tcf_mirred_act_wants_ingress(m_eaction);
+       if (!want_ingress) {
+               for (i = 0; i < xmit->sched_mirred_nest; i++) {
+                       if (xmit->sched_mirred_dev[i] != dev)
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-sched-act_mirred-fix-return-code-in-early-mirred.patch b/queue-7.0/net-sched-act_mirred-fix-return-code-in-early-mirred.patch
new file mode 100644 (file)
index 0000000..46dcc79
--- /dev/null
@@ -0,0 +1,99 @@
+From e2675e84594fb8dfef530667a43734a445885b56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:54 -0400
+Subject: net/sched: act_mirred: Fix return code in early mirred redirect error
+ paths
+
+From: Victor Nogueira <victor@mojatatu.com>
+
+[ Upstream commit e80ad525fc7e8c933ad78478c5dda286cfd55c60 ]
+
+Since retval is set as TC_ACT_STOLEN in the mirred redirect case, returning
+retval in cases where redirect failed will make the callers not register
+the skb as being dropped.
+
+Fix this by returning TC_ACT_SHOT instead in such scenarios.
+
+Fixes: 16085e48cb48 ("net/sched: act_mirred: Create function tcf_mirred_to_dev and improve readability")
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Closes: https://sashiko.dev/#/patchset/20260413082027.2244884-1-hxzene%40gmail.com
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-8-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_mirred.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
+index dbe4a4ff3e08b8..553342c55cf7c6 100644
+--- a/net/sched/act_mirred.c
++++ b/net/sched/act_mirred.c
+@@ -372,7 +372,8 @@ static int tcf_blockcast_redir(struct sk_buff *skb, struct tcf_mirred *m,
+                                        dev_is_mac_header_xmit(dev_prev),
+                                        m_eaction, retval);
+-      return retval;
++      /* If the packet wasn't redirected, we have to register as a drop */
++      return TC_ACT_SHOT;
+ }
+ static int tcf_blockcast_mirror(struct sk_buff *skb, struct tcf_mirred *m,
+@@ -410,7 +411,7 @@ static int tcf_blockcast(struct sk_buff *skb, struct tcf_mirred *m,
+       block = tcf_block_lookup(dev_net(skb->dev), blockid);
+       if (!block || xa_empty(&block->ports)) {
+               tcf_action_inc_overlimit_qstats(&m->common);
+-              return retval;
++              return is_redirect ? TC_ACT_SHOT : retval;
+       }
+       if (is_redirect)
+@@ -428,8 +429,8 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+ {
+       struct tcf_mirred *m = to_mirred(a);
+       int retval = READ_ONCE(m->tcf_action);
++      bool m_mac_header_xmit, is_redirect;
+       struct netdev_xmit *xmit;
+-      bool m_mac_header_xmit;
+       struct net_device *dev;
+       bool want_ingress;
+       int i, m_eaction;
+@@ -462,11 +463,13 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+               return retval;
+       }
++      is_redirect = tcf_mirred_is_act_redirect(m_eaction);
++
+       dev = rcu_dereference_bh(m->tcfm_dev);
+       if (unlikely(!dev)) {
+               pr_notice_once("tc mirred: target device is gone\n");
+               tcf_action_inc_overlimit_qstats(&m->common);
+-              return retval;
++              goto err_out;
+       }
+       if (!want_ingress) {
+@@ -476,7 +479,7 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+                       pr_notice_once("tc mirred: loop on device %s\n",
+                                      netdev_name(dev));
+                       tcf_action_inc_overlimit_qstats(&m->common);
+-                      return retval;
++                      goto err_out;
+               }
+               xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = dev;
+       }
+@@ -489,6 +492,11 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+               xmit->sched_mirred_nest--;
+       return retval;
++
++err_out:
++      if (is_redirect)
++              retval = TC_ACT_SHOT;
++      return retval;
+ }
+ static void tcf_stats_update(struct tc_action *a, u64 bytes, u64 packets,
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-sched-fix-ethx-ingress-ethy-egress-ethx-ingress-.patch b/queue-7.0/net-sched-fix-ethx-ingress-ethy-egress-ethx-ingress-.patch
new file mode 100644 (file)
index 0000000..584e3dd
--- /dev/null
@@ -0,0 +1,135 @@
+From f2941f2de613209607df02d329c266682fa59d59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:52 -0400
+Subject: net/sched: Fix ethx:ingress -> ethy:egress -> ethx:ingress mirred
+ loop
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit db875221ab08d213a83bf30196ae8b64d55a3403 ]
+
+When mirred redirects to ingress (from either ingress or egress) the loop
+state from sched_mirred_dev array dev is lost because of 1) the packet
+deferral into the backlog and 2) the fact the sched_mirred_dev array is
+cleared. In such cases, if there was a loop we won't discover it.
+
+Here's a simple test to reproduce:
+ip a add dev port0 10.10.10.11/24
+
+tc qdisc add dev port0 clsact
+tc filter add dev port0 egress protocol ip \
+   prio 10 matchall action mirred ingress redirect dev port1
+
+tc qdisc add dev port1 clsact
+tc filter add dev port1 ingress protocol ip \
+   prio 10 matchall action mirred egress redirect dev port0
+
+ping -c 1 -W0.01 10.10.10.10
+
+Fixes: fe946a751d9b ("net/sched: act_mirred: add loop detection")
+Tested-by: Victor Nogueira <victor@mojatatu.com>
+Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-6-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_mirred.c | 47 +++++++++++++++++++++++++++---------------
+ 1 file changed, 30 insertions(+), 17 deletions(-)
+
+diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
+index 2c5a7a321a9438..dd5e7ea7ef2652 100644
+--- a/net/sched/act_mirred.c
++++ b/net/sched/act_mirred.c
+@@ -26,6 +26,10 @@
+ #include <net/tc_act/tc_mirred.h>
+ #include <net/tc_wrapper.h>
++#define MIRRED_DEFER_LIMIT 3
++_Static_assert(MIRRED_DEFER_LIMIT <= 3,
++             "MIRRED_DEFER_LIMIT exceeds tc_depth bitfield width");
++
+ static LIST_HEAD(mirred_list);
+ static DEFINE_SPINLOCK(mirred_list_lock);
+@@ -234,12 +238,15 @@ tcf_mirred_forward(bool at_ingress, bool want_ingress, struct sk_buff *skb)
+ {
+       int err;
+-      if (!want_ingress)
++      if (!want_ingress) {
+               err = tcf_dev_queue_xmit(skb, dev_queue_xmit);
+-      else if (!at_ingress)
+-              err = netif_rx(skb);
+-      else
+-              err = netif_receive_skb(skb);
++      } else {
++              skb->tc_depth++;
++              if (!at_ingress)
++                      err = netif_rx(skb);
++              else
++                      err = netif_receive_skb(skb);
++      }
+       return err;
+ }
+@@ -426,6 +433,7 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+       struct netdev_xmit *xmit;
+       bool m_mac_header_xmit;
+       struct net_device *dev;
++      bool want_ingress;
+       int i, m_eaction;
+       u32 blockid;
+@@ -434,7 +442,8 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+ #else
+       xmit = this_cpu_ptr(&softnet_data.xmit);
+ #endif
+-      if (unlikely(xmit->sched_mirred_nest >= MIRRED_NEST_LIMIT)) {
++      if (unlikely(xmit->sched_mirred_nest >= MIRRED_NEST_LIMIT ||
++                   skb->tc_depth >= MIRRED_DEFER_LIMIT)) {
+               net_warn_ratelimited("Packet exceeded mirred recursion limit on dev %s\n",
+                                    netdev_name(skb->dev));
+               return TC_ACT_SHOT;
+@@ -453,23 +462,27 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(struct sk_buff *skb,
+               tcf_action_inc_overlimit_qstats(&m->common);
+               return retval;
+       }
+-      for (i = 0; i < xmit->sched_mirred_nest; i++) {
+-              if (xmit->sched_mirred_dev[i] != dev)
+-                      continue;
+-              pr_notice_once("tc mirred: loop on device %s\n",
+-                             netdev_name(dev));
+-              tcf_action_inc_overlimit_qstats(&m->common);
+-              return retval;
+-      }
+-      xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = dev;
++      m_eaction = READ_ONCE(m->tcfm_eaction);
++      want_ingress = tcf_mirred_act_wants_ingress(m_eaction);
++      if (!want_ingress) {
++              for (i = 0; i < xmit->sched_mirred_nest; i++) {
++                      if (xmit->sched_mirred_dev[i] != dev)
++                              continue;
++                      pr_notice_once("tc mirred: loop on device %s\n",
++                                     netdev_name(dev));
++                      tcf_action_inc_overlimit_qstats(&m->common);
++                      return retval;
++              }
++              xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = dev;
++      }
+       m_mac_header_xmit = READ_ONCE(m->tcfm_mac_header_xmit);
+-      m_eaction = READ_ONCE(m->tcfm_eaction);
+       retval = tcf_mirred_to_dev(skb, m, dev, m_mac_header_xmit, m_eaction,
+                                  retval);
+-      xmit->sched_mirred_nest--;
++      if (!want_ingress)
++              xmit->sched_mirred_nest--;
+       return retval;
+ }
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-sched-fix-packet-loop-on-netem-when-duplicate-is.patch b/queue-7.0/net-sched-fix-packet-loop-on-netem-when-duplicate-is.patch
new file mode 100644 (file)
index 0000000..10180cb
--- /dev/null
@@ -0,0 +1,71 @@
+From c4011f23f07b6f676e2c8a8786db346fe0baf900 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:51 -0400
+Subject: net/sched: fix packet loop on netem when duplicate is on
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit 9552b11e3edabc97cfcd9f29103d5afbce7ae183 ]
+
+When netem duplicates a packet it re-enqueues the copy at the root qdisc.
+If another netem sits in the tree the copy can be duplicated
+again, recursing until the stack or memory is exhausted.
+
+The original duplication guard temporarily zeroed q->duplicate around
+the re-enqueue, but that does not cover all cases because it is
+per-qdisc state shared across all concurrent enqueue paths
+and is not safe without additional locking.
+
+Use the skb tc_depth field introduced in an earlier patch:
+ - increment it on the duplicate before re-enqueue
+ - skip duplication for any skb whose tc_depth is already non-zero.
+
+This marks the packet itself rather than mutating qdisc state,
+therefore it is safe regardless of tree topology or concurrency.
+
+Fixes: 0afb51e72855 ("[PKT_SCHED]: netem: reinsert for duplication")
+Reported-by: William Liu <will@willsroot.io>
+Reported-by: Savino Dicanosa <savy@syst3mfailure.io>
+Closes: https://lore.kernel.org/netdev/8DuRWwfqjoRDLDmBMlIfbrsZg9Gx50DHJc1ilxsEBNe2D6NMoigR_eIRIG0LOjMc3r10nUUZtArXx4oZBIdUfZQrwjcQhdinnMis_0G7VEk=@willsroot.io/
+Co-developed-by: Victor Nogueira <victor@mojatatu.com>
+Signed-off-by: Victor Nogueira <victor@mojatatu.com>
+Reviewed-by: William Liu <will@willsroot.io>
+Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-5-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_netem.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
+index d97acd2f392346..17a79fe2f0911d 100644
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -461,7 +461,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+       skb->prev = NULL;
+       /* Random duplication */
+-      if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor, &q->prng))
++      if (q->duplicate && skb->tc_depth == 0 &&
++          q->duplicate >= get_crandom(&q->dup_cor, &q->prng))
+               ++count;
+       /* Drop packet? */
+@@ -540,11 +541,9 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+        */
+       if (skb2) {
+               struct Qdisc *rootq = qdisc_root_bh(sch);
+-              u32 dupsave = q->duplicate; /* prevent duplicating a dup... */
+-              q->duplicate = 0;
++              skb2->tc_depth++; /* prevent duplicating a dup... */
+               rootq->enqueue(skb2, rootq, to_free);
+-              q->duplicate = dupsave;
+               skb2 = NULL;
+       }
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-sched-revert-net-sched-restrict-conditions-for-a.patch b/queue-7.0/net-sched-revert-net-sched-restrict-conditions-for-a.patch
new file mode 100644 (file)
index 0000000..0b10b14
--- /dev/null
@@ -0,0 +1,102 @@
+From 9e979a4d13b2b7675c50cff8ecd323d91f115356 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 08:25:49 -0400
+Subject: net/sched: Revert "net/sched: Restrict conditions for adding
+ duplicating netems to qdisc tree"
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit eda0b7f203bb166c98d1418b204135bd566ac83b ]
+
+This reverts commit ec8e0e3d7adef940cdf9475e2352c0680189d14e.
+
+The original patch rejects any tree containing two netems when
+either has duplication set, even when they sit on unrelated classes
+of the same classful parent. That broke configurations that have
+worked since netem was introduced.
+
+The re-entrancy problem the original commit was trying to solve is
+handled by later patch using tc_depth flag.
+
+Doing this revert will (re)expose the original bug with multiple
+netem duplication. When this patch is backported make sure
+and get the full series.
+
+Fixes: ec8e0e3d7ade ("net/sched: Restrict conditions for adding duplicating netems to qdisc tree")
+Reported-by: Ji-Soo Chung <jschung2@proton.me>
+Reported-by: Gerlinde <lrGerlinde@mailfence.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220774
+Reported-by: zyc zyc <zyc199902@zohomail.cn>
+Closes: https://lore.kernel.org/all/19adda5a1e2.12410b78222774.9191120410578703463@zohomail.cn/
+Reported-by: Manas Ghandat <ghandatmanas@gmail.com>
+Closes: https://lore.kernel.org/netdev/f69b2c8f-8325-4c2e-a011-6dbc089f30e4@gmail.com/
+Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://patch.msgid.link/20260525122556.973584-3-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_netem.c | 40 ----------------------------------------
+ 1 file changed, 40 deletions(-)
+
+diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
+index bc18e1976b6e07..d97acd2f392346 100644
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -1007,41 +1007,6 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
+       return 0;
+ }
+-static const struct Qdisc_class_ops netem_class_ops;
+-
+-static int check_netem_in_tree(struct Qdisc *sch, bool duplicates,
+-                             struct netlink_ext_ack *extack)
+-{
+-      struct Qdisc *root, *q;
+-      unsigned int i;
+-
+-      root = qdisc_root_sleeping(sch);
+-
+-      if (sch != root && root->ops->cl_ops == &netem_class_ops) {
+-              if (duplicates ||
+-                  ((struct netem_sched_data *)qdisc_priv(root))->duplicate)
+-                      goto err;
+-      }
+-
+-      if (!qdisc_dev(root))
+-              return 0;
+-
+-      hash_for_each(qdisc_dev(root)->qdisc_hash, i, q, hash) {
+-              if (sch != q && q->ops->cl_ops == &netem_class_ops) {
+-                      if (duplicates ||
+-                          ((struct netem_sched_data *)qdisc_priv(q))->duplicate)
+-                              goto err;
+-              }
+-      }
+-
+-      return 0;
+-
+-err:
+-      NL_SET_ERR_MSG(extack,
+-                     "netem: cannot mix duplicating netems with other netems in tree");
+-      return -EINVAL;
+-}
+-
+ /* Parse netlink message to set options */
+ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+                       struct netlink_ext_ack *extack)
+@@ -1118,11 +1083,6 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+       q->gap = qopt->gap;
+       q->counter = 0;
+       q->loss = qopt->loss;
+-
+-      ret = check_netem_in_tree(sch, qopt->duplicate, extack);
+-      if (ret)
+-              goto unlock;
+-
+       q->duplicate = qopt->duplicate;
+       /* for compatibility with earlier versions.
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch b/queue-7.0/net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch
new file mode 100644 (file)
index 0000000..e30c56e
--- /dev/null
@@ -0,0 +1,64 @@
+From 486561b89e9f97c15e8cd6e953d924fd86826871 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 May 2026 19:43:53 +0100
+Subject: net: skbuff: fix pskb_carve leaking zcopy pages
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit ff6e798c2eac3ebd0501ad7e796f583fab928de8 ]
+
+When SKBFL_MANAGED_FRAG_REFS is set, frag pages are not refcounted but
+their lifetime is controlled by the attached ubuf_info. To make a copy
+of the skb_shared_info, we either should clear the flag and reference
+the frags, or keep the flag and have frags unreferenced.
+
+pskb_carve_inside_header() and pskb_carve_inside_nonlinear() don't
+follow the rule and thus can leak page references. Let's clear
+SKBFL_MANAGED_FRAG_REFS from the original skb to fix it. It's the
+simplest way to address it, but there are more performant ways to do
+that if it ever becomes a problem.
+
+Link: https://lore.kernel.org/all/20260523085809.26331-1-nvminh232@clc.fitus.edu.vn/
+Fixes: 753f1ca4e1e50 ("net: introduce managed frags infrastructure")
+Reported-by: Minh Nguyen <minhnguyen.080505@gmail.com>
+Reported-by: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/1e2086aa69217d7f9c8da3d38f5be7160f1b4cd1.1779993185.git.asml.silence@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 13af6f35428d52..95ef64fad657d3 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -6847,6 +6847,11 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
+       skb_copy_from_linear_data_offset(skb, off, data, new_hlen);
+       skb->len -= off;
++      /* Remove SKBFL_MANAGED_FRAG_REFS instead of trying to honour it
++       * while refcounting frags below.
++       */
++      skb_zcopy_downgrade_managed(skb);
++
+       memcpy((struct skb_shared_info *)(data + size),
+              skb_shinfo(skb),
+              offsetof(struct skb_shared_info,
+@@ -6958,6 +6963,11 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,
+               return -ENOMEM;
+       size = SKB_WITH_OVERHEAD(size);
++      /* Remove SKBFL_MANAGED_FRAG_REFS instead of trying to honour it
++       * while refcounting frags below.
++       */
++      skb_zcopy_downgrade_managed(skb);
++
+       memcpy((struct skb_shared_info *)(data + size),
+              skb_shinfo(skb), offsetof(struct skb_shared_info, frags[0]));
+       if (skb_orphan_frags(skb, gfp_mask)) {
+-- 
+2.53.0
+
diff --git a/queue-7.0/net-smc-do-not-re-initialize-smc-hashtables.patch b/queue-7.0/net-smc-do-not-re-initialize-smc-hashtables.patch
new file mode 100644 (file)
index 0000000..9fd7830
--- /dev/null
@@ -0,0 +1,59 @@
+From 6137ada3d0ec0ca3637d283839198f46d1936a01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 16:56:39 +0200
+Subject: net/smc: Do not re-initialize smc hashtables
+
+From: Alexandra Winter <wintera@linux.ibm.com>
+
+[ Upstream commit 9e4389b0038781f19f97895186ed941ff8ac1678 ]
+
+INIT_HLIST_HEAD(&smc_v*_hashinfo.ht) are called after smc_nl_init(),
+proto_register() and sock_register(). This can lead to smc_v*_hashinfo.ht
+being reset even though hash entries already exist and are being used,
+possibly resulting in a corrupted list.
+
+Remove unnecessary and dangerous re-initialisation of smc_v*_hashinfo.ht in
+smc_init(); it is implicitly initialised to zero anyhow. Add
+HLIST_HEAD_INIT to the definitions for clarity.
+
+Fixes: f16a7dd5cf27 ("smc: netlink interface for SMC sockets")
+Suggested-by: Halil Pasic <pasic@linux.ibm.com>
+Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
+Acked-by: Halil Pasic <pasic@linux.ibm.com>
+Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
+Link: https://patch.msgid.link/20260521145639.10317-1-wintera@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index f744f791121776..de034a3e5d801f 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -188,10 +188,12 @@ static bool smc_hs_congested(const struct sock *sk)
+ struct smc_hashinfo smc_v4_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v4_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ struct smc_hashinfo smc_v6_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v6_hashinfo.lock),
++      .ht = HLIST_HEAD_INIT,
+ };
+ int smc_hash_sk(struct sock *sk)
+@@ -3522,8 +3524,6 @@ static int __init smc_init(void)
+               pr_err("%s: sock_register fails with %d\n", __func__, rc);
+               goto out_proto6;
+       }
+-      INIT_HLIST_HEAD(&smc_v4_hashinfo.ht);
+-      INIT_HLIST_HEAD(&smc_v6_hashinfo.ht);
+       rc = smc_ib_register_client();
+       if (rc) {
+-- 
+2.53.0
+
diff --git a/queue-7.0/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch b/queue-7.0/netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
new file mode 100644 (file)
index 0000000..48abe7a
--- /dev/null
@@ -0,0 +1,107 @@
+From 0639455d3782e3bfd34565125f2225b8bfc5f607 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 22:52:07 +0200
+Subject: netfilter: ebtables: fix OOB read in compat_mtw_from_user
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit f438d1786d657d57790c5d138d6db3fc9fdac392 ]
+
+Luxiao Xu says:
+
+ The function compat_mtw_from_user() converts ebtables extensions from
+ 32-bit user structures to kernel native structures. However, it lacks
+ proper validation of the user-supplied match_size/target_size.
+
+ When certain extensions are processed, the kernel-side translation
+ logic may perform memory accesses based on the extension's expected
+ size. If the user provides a size smaller than what the extension
+ requires, it results in an out-of-bounds read as reported by KASAN.
+
+ This fix introduces a check to ensure match_size is at least as large
+ as the extension's required compatsize. This covers matches, watchers,
+ and targets, while maintaining compatibility with standard targets.
+
+AFAIU this is relevant for matches that need to go though
+match->compat_from_user() call.  Those that use plain memcpy with the
+user-provided size are ok because the caller checks that size vs the
+start of the next rule entry offset (which itself is checked vs. total
+size copied from userspace).
+
+The ->compat_from_user() callbacks assume they can read compatsize bytes,
+so they need this extra check.
+
+Based on an earlier patch from Luxiao Xu.
+
+Fixes: 81e675c227ec ("netfilter: ebtables: add CONFIG_COMPAT support")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/netfilter/ebtables.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
+index b9f4daac09af36..8a6a069329d21d 100644
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1956,6 +1956,25 @@ enum compat_mwt {
+       EBT_COMPAT_TARGET,
+ };
++static bool match_size_ok(const struct xt_match *match, unsigned int match_size)
++{
++      u16 csize;
++
++      if (match->matchsize == -1) /* cannot validate ebt_among */
++              return true;
++
++      csize = match->compatsize ? : match->matchsize;
++
++      return match_size >= csize;
++}
++
++static bool tgt_size_ok(const struct xt_target *tgt, unsigned int tgt_size)
++{
++      u16 csize = tgt->compatsize ? : tgt->targetsize;
++
++      return tgt_size >= csize;
++}
++
+ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                               enum compat_mwt compat_mwt,
+                               struct ebt_entries_buf_state *state,
+@@ -1981,6 +2000,11 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+               if (IS_ERR(match))
+                       return PTR_ERR(match);
++              if (!match_size_ok(match, match_size)) {
++                      module_put(match->me);
++                      return -EINVAL;
++              }
++
+               off = ebt_compat_match_offset(match, match_size);
+               if (dst) {
+                       if (match->compat_from_user)
+@@ -2000,6 +2024,12 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
+                                           mwt->u.revision);
+               if (IS_ERR(wt))
+                       return PTR_ERR(wt);
++
++              if (!tgt_size_ok(wt, match_size)) {
++                      module_put(wt->me);
++                      return -EINVAL;
++              }
++
+               off = xt_compat_target_offset(wt);
+               if (dst) {
+-- 
+2.53.0
+
diff --git a/queue-7.0/netfilter-nf_tables-fix-dst-corruption-in-same-regis.patch b/queue-7.0/netfilter-nf_tables-fix-dst-corruption-in-same-regis.patch
new file mode 100644 (file)
index 0000000..95ab120
--- /dev/null
@@ -0,0 +1,141 @@
+From b0318bf07d4088b57acb7db0c691bb4f038eeeb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 May 2026 16:37:56 +0200
+Subject: netfilter: nf_tables: fix dst corruption in same register operation
+
+From: Fernando Fernandez Mancera <fmancera@suse.de>
+
+[ Upstream commit 18014147d3ee7831dce53fe65d7fc8d428b02552 ]
+
+For lshift and rshift, the shift operations are performed in a loop over
+32-bit words. The loop calculates the shifted value and write it to dst,
+and then immediately reads from src to calculate the carry for the next
+iteration. Because src and dst could point to the same memory location,
+the carry is incorrectly calculated using the newly modified dst value
+instead of the original src value.
+
+Adding a temporary local variable to cache the original value before
+writing to dst and using it for the carry calculation solves the
+problem. In addition, partial overlap is rejected from control plane for
+all kind of operations including byteorder. This was tested with the
+following bytecode:
+
+table test_table ip flags 0 use 1 handle 1
+ip test_table test_chain use 3 type filter hook input prio 0 policy accept packets 0 bytes 0 flags 1
+ip test_table test_chain 2
+  [ immediate reg 1 0x44332211 0x88776655 ]
+  [ bitwise reg 1 = ( reg 1 << 0x08000000 ) ]
+  [ cmp eq reg 1 0x66443322 0x00887766 ]
+  [ counter pkts 0 bytes 0 ]
+ip test_table test_chain 4 3
+  [ immediate reg 1 0x44332211 0x88776655 ]
+  [ bitwise reg 1 = ( reg 1 << 0x08000000 ) ]
+  [ cmp eq reg 1 0x55443322 0x00887766 ]
+  [ counter pkts 21794 bytes 1917798 ]
+
+Fixes: 567d746b55bc ("netfilter: bitwise: add support for shifts.")
+Acked-by: Jeremy Sowden <jeremy@azazel.net>
+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>
+---
+ include/net/netfilter/nf_tables.h |  7 +++++++
+ net/netfilter/nft_bitwise.c       | 18 ++++++++++++++----
+ net/netfilter/nft_byteorder.c     | 13 ++++++++++---
+ 3 files changed, 31 insertions(+), 7 deletions(-)
+
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index 3ec41574af776c..668b401f5147b4 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -187,6 +187,13 @@ static inline u64 nft_reg_load64(const u32 *sreg)
+       return get_unaligned((u64 *)sreg);
+ }
++static inline bool nft_reg_overlap(u8 src, u8 dst, u32 len)
++{
++      unsigned int n = DIV_ROUND_UP(len, sizeof(u32));
++
++      return src != dst && src < dst + n && dst < src + n;
++}
++
+ static inline void nft_data_copy(u32 *dst, const struct nft_data *src,
+                                unsigned int len)
+ {
+diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
+index af990c600745be..1afb36fb5994db 100644
+--- a/net/netfilter/nft_bitwise.c
++++ b/net/netfilter/nft_bitwise.c
+@@ -43,8 +43,10 @@ static void nft_bitwise_eval_lshift(u32 *dst, const u32 *src,
+       u32 carry = 0;
+       for (i = DIV_ROUND_UP(priv->len, sizeof(u32)); i > 0; i--) {
+-              dst[i - 1] = (src[i - 1] << shift) | carry;
+-              carry = src[i - 1] >> (BITS_PER_TYPE(u32) - shift);
++              u32 tmp_src = src[i - 1];
++
++              dst[i - 1] = (tmp_src << shift) | carry;
++              carry = tmp_src >> (BITS_PER_TYPE(u32) - shift);
+       }
+ }
+@@ -56,8 +58,10 @@ static void nft_bitwise_eval_rshift(u32 *dst, const u32 *src,
+       u32 carry = 0;
+       for (i = 0; i < DIV_ROUND_UP(priv->len, sizeof(u32)); i++) {
+-              dst[i] = carry | (src[i] >> shift);
+-              carry = src[i] << (BITS_PER_TYPE(u32) - shift);
++              u32 tmp_src = src[i];
++
++              dst[i] = carry | (tmp_src >> shift);
++              carry = tmp_src << (BITS_PER_TYPE(u32) - shift);
+       }
+ }
+@@ -235,6 +239,9 @@ static int nft_bitwise_init_bool(const struct nft_ctx *ctx,
+                                             &priv->sreg2, priv->len);
+               if (err < 0)
+                       return err;
++
++              if (nft_reg_overlap(priv->sreg2, priv->dreg, priv->len))
++                      return -EINVAL;
+       }
+       return 0;
+@@ -265,6 +272,9 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
+       if (err < 0)
+               return err;
++      if (nft_reg_overlap(priv->sreg, priv->dreg, priv->len))
++              return -EINVAL;
++
+       if (tb[NFTA_BITWISE_OP]) {
+               priv->op = ntohl(nla_get_be32(tb[NFTA_BITWISE_OP]));
+               switch (priv->op) {
+diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
+index af9206a3afd181..5e7a7841b789b0 100644
+--- a/net/netfilter/nft_byteorder.c
++++ b/net/netfilter/nft_byteorder.c
+@@ -144,9 +144,16 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
+       if (err < 0)
+               return err;
+-      return nft_parse_register_store(ctx, tb[NFTA_BYTEORDER_DREG],
+-                                      &priv->dreg, NULL, NFT_DATA_VALUE,
+-                                      priv->len);
++      err = nft_parse_register_store(ctx, tb[NFTA_BYTEORDER_DREG],
++                                     &priv->dreg, NULL, NFT_DATA_VALUE,
++                                     priv->len);
++      if (err < 0)
++              return err;
++
++      if (nft_reg_overlap(priv->sreg, priv->dreg, priv->len))
++              return -EINVAL;
++
++      return 0;
+ }
+ static int nft_byteorder_dump(struct sk_buff *skb,
+-- 
+2.53.0
+
diff --git a/queue-7.0/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch b/queue-7.0/netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
new file mode 100644 (file)
index 0000000..83279b2
--- /dev/null
@@ -0,0 +1,68 @@
+From 3785b183ff1f658fab7f65a5e55794ca86ec561a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 12:36:14 -0700
+Subject: netfilter: synproxy: refresh tcphdr after skb_ensure_writable
+
+From: Chris Mason <clm@meta.com>
+
+[ Upstream commit 92170e6afe927ab2792a3f71902845789c8e31b1 ]
+
+synproxy_tstamp_adjust() rewrites the TCP timestamp option in place
+and then patches the TCP checksum via inet_proto_csum_replace4() on
+the caller-supplied tcphdr pointer.  Both ipv4_synproxy_hook() and
+ipv6_synproxy_hook() obtain that pointer with skb_header_pointer()
+before calling in, so it may either alias skb->head directly or
+point at the caller's on-stack _tcph buffer.
+
+Between obtaining the pointer and using it, the function calls
+skb_ensure_writable(skb, optend), which on a cloned or non-linear
+skb invokes pskb_expand_head() and frees the old skb->head.  After
+that point the cached th is stale:
+
+    caller (ipv[46]_synproxy_hook)
+      th = skb_header_pointer(skb, ..., &_tcph)
+      synproxy_tstamp_adjust(skb, protoff, th, ...)
+        skb_ensure_writable(skb, optend)
+          pskb_expand_head()        /* kfree(old skb->head) */
+        ...
+        inet_proto_csum_replace4(&th->check, ...)
+                                    /* writes into freed head, or
+                                       into the caller's stack copy
+                                       leaving the on-wire checksum
+                                       stale */
+
+The option bytes are written through skb->data and are fine; only
+the checksum update goes through th and so lands in the wrong
+place.  The result is either a write into freed slab memory or a
+packet leaving with a checksum that does not match its payload.
+
+Fix by re-deriving th from skb->data + protoff immediately after
+skb_ensure_writable() succeeds, so the subsequent checksum update
+targets the linear, writable header.
+
+Fixes: 48b1de4c110a ("netfilter: add SYNPROXY core/target")
+Assisted-by: kres (claude-opus-4-7)
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-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_synproxy_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c
+index 57f57e2fc80a8f..036c8586f49b75 100644
+--- a/net/netfilter/nf_synproxy_core.c
++++ b/net/netfilter/nf_synproxy_core.c
+@@ -200,6 +200,8 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff,
+       if (skb_ensure_writable(skb, optend))
+               return 0;
++      th = (struct tcphdr *)(skb->data + protoff);
++
+       while (optoff < optend) {
+               unsigned char *op = skb->data + optoff;
+-- 
+2.53.0
+
diff --git a/queue-7.0/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch b/queue-7.0/netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
new file mode 100644 (file)
index 0000000..fb162bb
--- /dev/null
@@ -0,0 +1,48 @@
+From 64d259f9aff2371b33a3782e01d2a5a6db547288 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 20:10:08 +0200
+Subject: netfilter: xt_cpu: prefer raw_smp_processor_id
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit c376f07e16c02239ed44cabb97145d03f65b4d15 ]
+
+With PREEMPT_RCU we get splat:
+
+BUG: using smp_processor_id() in preemptible [..]
+caller is cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+CPU: 1 .. Comm: syz.3.1377 #0 PREEMPT(full)
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
+ check_preemption_disabled+0xd3/0xe0 lib/smp_processor_id.c:47
+ cpu_mt+0x53/0xd0 net/netfilter/xt_cpu.c:37
+ [..]
+
+Just use raw version instead.
+This is similar to 14d14a5d2957 ("netfilter: nft_meta: use raw_smp_processor_id()").
+
+Fixes: 0ca743a55991 ("netfilter: nf_tables: add compatibility layer for x_tables")
+Reported-by: syzbot+690d3e3ffa7335ac10eb@syzkaller.appspotmail.com
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_cpu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/xt_cpu.c b/net/netfilter/xt_cpu.c
+index 3bdc302a0f9137..9cb259902a586b 100644
+--- a/net/netfilter/xt_cpu.c
++++ b/net/netfilter/xt_cpu.c
+@@ -34,7 +34,7 @@ static bool cpu_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       const struct xt_cpu_info *info = par->matchinfo;
+-      return (info->cpu == smp_processor_id()) ^ info->invert;
++      return (info->cpu == raw_smp_processor_id()) ^ info->invert;
+ }
+ static struct xt_match cpu_mt_reg __read_mostly = {
+-- 
+2.53.0
+
diff --git a/queue-7.0/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch b/queue-7.0/nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
new file mode 100644 (file)
index 0000000..a252d90
--- /dev/null
@@ -0,0 +1,40 @@
+From 57f7005d37edd17fb90150d2bbe5146cdfc5a0a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:41 +0000
+Subject: nfc: llcp: Fix use-after-free in llcp_sock_release()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit f4268b466190dae95a7585f69b4f1f8ad097632c ]
+
+llcp_sock_release() unconditionally unlinks the socket from the local
+sockets list.  However, if the socket is still in connecting state, it
+is on the connecting list.
+
+Fix this by checking the socket state and unlinking from the correct list.
+
+Fixes: b4011239a08e ("NFC: llcp: Fix non blocking sockets connections")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-1-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_sock.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index f1be1e84f66537..feab29fc62f44b 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -633,6 +633,8 @@ static int llcp_sock_release(struct socket *sock)
+       if (sock->type == SOCK_RAW)
+               nfc_llcp_sock_unlink(&local->raw_sockets, sk);
++      else if (sk->sk_state == LLCP_CONNECTING)
++              nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       else
+               nfc_llcp_sock_unlink(&local->sockets, sk);
+-- 
+2.53.0
+
diff --git a/queue-7.0/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch b/queue-7.0/nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
new file mode 100644 (file)
index 0000000..457c39d
--- /dev/null
@@ -0,0 +1,67 @@
+From 6a7ed01eb4ecf4efdae29a44fd4ded9f6176a9dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 13:40:42 +0000
+Subject: nfc: llcp: Fix use-after-free race in nfc_llcp_recv_cc()
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit b493ea2765cc17cb8aa7e7544a4b6dcb05b6ed77 ]
+
+A race condition exists in the NFC LLCP connection state machine where
+the connection acceptance packet (CC) can be processed concurrently with
+socket release.  This can lead to a use-after-free of the socket object.
+
+When nfc_llcp_recv_cc() moves the socket from the connecting_sockets
+list to the sockets list, it does so without holding the socket lock.
+If llcp_sock_release() is executing concurrently, it might have already
+unlinked the socket and dropped its references, which can result in
+nfc_llcp_recv_cc() linking a freed socket into the live list.
+
+Fix this by holding lock_sock() during the state transition and list
+movement in nfc_llcp_recv_cc().  After acquiring the lock, check if
+the socket is still hashed to ensure it hasn't already been unlinked
+and marked for destruction by the release path.  This aligns the locking
+pattern with recv_hdlc() and recv_disc().
+
+Fixes: a69f32af86e3 ("NFC: Socket linked list")
+Signed-off-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260429134115.3558604-2-lee@kernel.org
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_core.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
+index db5bc6a878ddb0..dc65c719f35f2e 100644
+--- a/net/nfc/llcp_core.c
++++ b/net/nfc/llcp_core.c
+@@ -1218,6 +1218,15 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk = &llcp_sock->sk;
++      lock_sock(sk);
++
++      /* Check if socket was destroyed whilst waiting for the lock */
++      if (!sk_hashed(sk)) {
++              release_sock(sk);
++              nfc_llcp_sock_put(llcp_sock);
++              return;
++      }
++
+       /* Unlink from connecting and link to the client array */
+       nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+       nfc_llcp_sock_link(&local->sockets, sk);
+@@ -1229,6 +1238,8 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
+       sk->sk_state = LLCP_CONNECTED;
+       sk->sk_state_change(sk);
++      release_sock(sk);
++
+       nfc_llcp_sock_put(llcp_sock);
+ }
+-- 
+2.53.0
+
diff --git a/queue-7.0/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch b/queue-7.0/nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
new file mode 100644 (file)
index 0000000..4449a2e
--- /dev/null
@@ -0,0 +1,83 @@
+From 2ebff846067468486d15be8295548ed5de7caaa5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 May 2026 19:55:18 +0800
+Subject: nfc: nxp-nci: i2c: use rising-edge IRQ on ACPI systems
+
+From: Carl Lee <carl.lee@amd.com>
+
+[ Upstream commit f23bf992d65a42007c517b060ca35cebdea3525a ]
+
+Some ACPI-based platforms report incorrect IRQ trigger types (e.g.
+IRQF_TRIGGER_HIGH), which can lead to interrupt storms.
+
+Use the historically working rising-edge trigger on ACPI systems to
+avoid this regression.
+
+Device Tree-based systems continue to use the firmware-provided
+trigger type.
+
+Fixes: 57be33f85e36 ("nfc: nxp-nci: remove interrupt trigger type")
+Signed-off-by: Carl Lee <carl.lee@amd.com>
+Tested-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Tested-by: Luca Stefani <luca.stefani.ge1@gmail.com>
+Link: https://patch.msgid.link/20260516-nfc-nxp-nci-i2c-restore-irq-trigger-fallback-v3-1-37ba4b6e9086@amd.com
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/nxp-nci/i2c.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c
+index b3d34433bd14a0..a6c08175d9dd93 100644
+--- a/drivers/nfc/nxp-nci/i2c.c
++++ b/drivers/nfc/nxp-nci/i2c.c
+@@ -16,6 +16,7 @@
+ #include <linux/delay.h>
+ #include <linux/i2c.h>
+ #include <linux/interrupt.h>
++#include <linux/irq.h>
+ #include <linux/module.h>
+ #include <linux/nfc.h>
+ #include <linux/gpio/consumer.h>
+@@ -267,6 +268,7 @@ static int nxp_nci_i2c_probe(struct i2c_client *client)
+ {
+       struct device *dev = &client->dev;
+       struct nxp_nci_i2c_phy *phy;
++      unsigned long irqflags;
+       int r;
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+@@ -303,9 +305,26 @@ static int nxp_nci_i2c_probe(struct i2c_client *client)
+       if (r < 0)
+               return r;
++      /*
++       * ACPI platforms may report incorrect IRQ trigger types
++       * (e.g. level-high), which can lead to interrupt storms.
++       *
++       * Use the historically stable rising-edge trigger for ACPI devices.
++       *
++       * On non-ACPI systems (e.g. Device Tree), prefer the firmware-
++       * provided trigger type, falling back to rising-edge if not set.
++       */
++      if (ACPI_COMPANION(dev)) {
++              irqflags = IRQF_TRIGGER_RISING;
++      } else {
++              irqflags = irq_get_trigger_type(client->irq);
++              if (!irqflags)
++                      irqflags = IRQF_TRIGGER_RISING;
++      }
++
+       r = request_threaded_irq(client->irq, NULL,
+                                nxp_nci_i2c_irq_thread_fn,
+-                               IRQF_ONESHOT,
++                               irqflags | IRQF_ONESHOT,
+                                NXP_NCI_I2C_DRIVER_NAME, phy);
+       if (r < 0)
+               nfc_err(&client->dev, "Unable to register IRQ handler\n");
+-- 
+2.53.0
+
diff --git a/queue-7.0/nvme-tcp-store-negative-errno-in-queue-tls_err.patch b/queue-7.0/nvme-tcp-store-negative-errno-in-queue-tls_err.patch
new file mode 100644 (file)
index 0000000..88c0865
--- /dev/null
@@ -0,0 +1,52 @@
+From 9ccafa4254a63ef89313fd285189fef0703166dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 12:51:16 -0400
+Subject: nvme-tcp: store negative errno in queue->tls_err
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 9015985b5eb1a90eb86caf5bce1dfcf1aa38f8ad ]
+
+nvme_tcp_tls_done() assigns queue->tls_err in three branches.  The
+ENOKEY lookup failure and the EOPNOTSUPP initializer both store
+negative errnos.  The third branch, reached when the handshake
+layer reports a non-zero status, stores -status.
+
+The handshake layer delivers status to the consumer callback as a
+negative errno; the other in-tree consumers --
+xs_tls_handshake_done() and the nvmet target callback -- treat
+their status argument that way.  The extra negation in
+nvme_tcp_tls_done() flips the sign, leaving tls_err as a positive
+value (for instance, +EIO), which nvme_tcp_start_tls() then
+returns to its caller.
+
+Drop the extra negation so queue->tls_err uniformly carries a
+negative errno on failure.
+
+Fixes: be8e82caa685 ("nvme-tcp: enable TLS handshake upcall")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
+Link: https://patch.msgid.link/20260525-handshake-file-pin-v3-2-66c616906ead@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/tcp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
+index 243dab830dc84f..29f9ba0bdd3f1e 100644
+--- a/drivers/nvme/host/tcp.c
++++ b/drivers/nvme/host/tcp.c
+@@ -1688,7 +1688,7 @@ static void nvme_tcp_tls_done(void *data, int status, key_serial_t pskid)
+               qid, pskid, status);
+       if (status) {
+-              queue->tls_err = -status;
++              queue->tls_err = status;
+               goto out_complete;
+       }
+-- 
+2.53.0
+
diff --git a/queue-7.0/revert-ipv6-preserve-insertion-order-for-same-scope-.patch b/queue-7.0/revert-ipv6-preserve-insertion-order-for-same-scope-.patch
new file mode 100644 (file)
index 0000000..9020aff
--- /dev/null
@@ -0,0 +1,67 @@
+From 7f947d9ded5a08fd174b0011c86c6f8daa2afba8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 13:23:57 +0200
+Subject: Revert "ipv6: preserve insertion order for same-scope addresses"
+
+From: Fernando Fernandez Mancera <fmancera@suse.de>
+
+[ Upstream commit 072aa0f5c3d8f11f3159037418ec45edce7440b8 ]
+
+Chris Adams reported that preserving insertion order for same-scope
+addresses is causing SSH connections to be dropped after stopping a VM
+while running NetworkManager.
+
+NetworkManager caches the IPv6 address configuration, when a RA arrives,
+it determines the list of addresses to configure and checks if the
+addresses are already in the right order in the kernel. If they aren't,
+NetworkManager removes and re-adds them to achieve the desired order.
+
+As the order changes, NetworkManager is confused and reconfigures the
+addresses on every update. In addition, this would also affect to cloud
+tooling that relies on IPv6 addresses order to identify primary and
+secondaries addresses.
+
+This reverts commit cb3de96eea66f5e4a580086c6a1be46e765f97f4.
+
+Fixes: cb3de96eea66 ("ipv6: preserve insertion order for same-scope addresses")
+Reported-by: Chris Adams <linux@cmadams.net>
+Closes: https://lore.kernel.org/netdev/20260521135310.GC977@cmadams.net/
+Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260529112357.5079-1-fmancera@suse.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/addrconf.c                  | 2 +-
+ tools/testing/selftests/net/ioam6.sh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index dd0b4d80e0f84d..e5276be71062a3 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1012,7 +1012,7 @@ ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp)
+       list_for_each(p, &idev->addr_list) {
+               struct inet6_ifaddr *ifa
+                       = list_entry(p, struct inet6_ifaddr, if_list);
+-              if (ifp_scope > ipv6_addr_src_scope(&ifa->addr))
++              if (ifp_scope >= ipv6_addr_src_scope(&ifa->addr))
+                       break;
+       }
+diff --git a/tools/testing/selftests/net/ioam6.sh b/tools/testing/selftests/net/ioam6.sh
+index b2b99889942f75..845c26dd01a932 100755
+--- a/tools/testing/selftests/net/ioam6.sh
++++ b/tools/testing/selftests/net/ioam6.sh
+@@ -273,8 +273,8 @@ setup()
+   ip -netns $ioam_node_beta link set ioam-veth-betaR name veth1 &>/dev/null
+   ip -netns $ioam_node_gamma link set ioam-veth-gamma name veth0 &>/dev/null
+-  ip -netns $ioam_node_alpha addr add 2001:db8:1::2/64 dev veth0 &>/dev/null
+   ip -netns $ioam_node_alpha addr add 2001:db8:1::50/64 dev veth0 &>/dev/null
++  ip -netns $ioam_node_alpha addr add 2001:db8:1::2/64 dev veth0 &>/dev/null
+   ip -netns $ioam_node_alpha link set veth0 up &>/dev/null
+   ip -netns $ioam_node_alpha link set lo up &>/dev/null
+   ip -netns $ioam_node_alpha route add 2001:db8:2::/64 \
+-- 
+2.53.0
+
diff --git a/queue-7.0/scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch b/queue-7.0/scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch
new file mode 100644 (file)
index 0000000..cfccb90
--- /dev/null
@@ -0,0 +1,80 @@
+From ada4b76d8603ae226ddb79d6f868822cb9969dd2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 14:09:41 -0400
+Subject: scsi: core: Run queues for all non-SDEV_DEL devices from
+ scsi_run_host_queues
+
+From: David Jeffery <djeffery@redhat.com>
+
+[ Upstream commit 7205b58702273baf21d6ba7992e6ba15852325f7 ]
+
+While a SCSI host is in a recovery state, scsi_mq_requeue_cmd() will not
+set the requeue list for a requeued command to be kicked in the future.
+The expectation is a call to scsi_run_host_queues() will kick all SCSI
+devices once the recovery state is cleared.
+
+However, scsi_run_host_queues() uses shost_for_each_device() which uses
+scsi_device_get() and so will ignore devices in a partially removed
+state like SDEV_CANCEL. But these devices may also have requeued
+requests, leaving their requests stuck from not being kicked and causing
+the removal process of the device to hang.
+
+scsi_run_host_queues() needs to run against more devices than the macro
+shost_for_each_device() allows. Instead of using the too limiting
+scsi_device_get() state checks, only ignore devices in SDEV_DEL state or
+when unable to acquire a reference. Attempt to run the queues for all
+other devices when scsi_run_host_queues() is called.
+
+Fixes: 8b566edbdbfb ("scsi: core: Only kick the requeue list if necessary")
+Signed-off-by: David Jeffery <djeffery@redhat.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://patch.msgid.link/20260515180941.9698-1-djeffery@redhat.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_lib.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index d3a8cd4166f92f..1da52f07d299b5 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -574,10 +574,33 @@ void scsi_requeue_run_queue(struct work_struct *work)
+ void scsi_run_host_queues(struct Scsi_Host *shost)
+ {
+-      struct scsi_device *sdev;
++      struct scsi_device *sdev, *prev = NULL;
++      unsigned long flags;
+-      shost_for_each_device(sdev, shost)
++      spin_lock_irqsave(shost->host_lock, flags);
++      __shost_for_each_device(sdev, shost) {
++              /*
++               * Only skip devices so deep into removal they will never need
++               * another kick to their queues. Thus scsi_device_get() cannot
++               * be used as it would skip devices in SDEV_CANCEL state which
++               * may need a queue kick.
++               */
++              if (sdev->sdev_state == SDEV_DEL ||
++                  !get_device(&sdev->sdev_gendev))
++                      continue;
++              spin_unlock_irqrestore(shost->host_lock, flags);
++
++              if (prev)
++                      put_device(&prev->sdev_gendev);
+               scsi_run_queue(sdev->request_queue);
++
++              prev = sdev;
++
++              spin_lock_irqsave(shost->host_lock, flags);
++      }
++      spin_unlock_irqrestore(shost->host_lock, flags);
++      if (prev)
++              put_device(&prev->sdev_gendev);
+ }
+ static void scsi_uninit_cmd(struct scsi_cmnd *cmd)
+-- 
+2.53.0
+
diff --git a/queue-7.0/scsi-scsi_debug-add-missing-newline-in-scsi_debug_de.patch b/queue-7.0/scsi-scsi_debug-add-missing-newline-in-scsi_debug_de.patch
new file mode 100644 (file)
index 0000000..749b1cc
--- /dev/null
@@ -0,0 +1,40 @@
+From 45613a00a0a2105166c48868e17596aa6ae4edbc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 16:53:56 -0400
+Subject: scsi: scsi_debug: Add missing newline in scsi_debug_device_reset()
+
+From: Ewan D. Milne <emilne@redhat.com>
+
+[ Upstream commit e4bb73bf3ac11b4a93634660345b9d764a4a80df ]
+
+A "\n" at the end of the sdev_printk() string appears to have been
+inadvertently removed.  Add it back for correct log message formatting.
+
+Fixes: a743b120227a ("scsi: scsi_debug: Stop printing extra function name in debug logs")
+Assisted-by: Claude:claude-opus-4-6
+Signed-off-by: Ewan D. Milne <emilne@redhat.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: John Garry <john.g.garry@oracle.com>
+Link: https://patch.msgid.link/20260519205356.1040855-1-emilne@redhat.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index 1515495fd9ea7e..040c5e1e713a2e 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -6953,7 +6953,7 @@ static int scsi_debug_device_reset(struct scsi_cmnd *SCpnt)
+       ++num_dev_resets;
+       if (SDEBUG_OPT_ALL_NOISE & sdebug_opts)
+-              sdev_printk(KERN_INFO, sdp, "doing device reset");
++              sdev_printk(KERN_INFO, sdp, "doing device reset\n");
+       scsi_debug_stop_all_queued(sdp);
+       if (devip) {
+-- 
+2.53.0
+
diff --git a/queue-7.0/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch b/queue-7.0/sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
new file mode 100644 (file)
index 0000000..b8dbebc
--- /dev/null
@@ -0,0 +1,50 @@
+From 7946fa974b54dec0de9c545a2d82fbcde4b5abe7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 11:24:11 +0800
+Subject: sctp: fix race between sctp_wait_for_connect and peeloff
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhenghang Xiao <kipreyyy@gmail.com>
+
+[ Upstream commit f14fe6395a8b3d961a61e138ad7b36ba3626dd4e ]
+
+sctp_wait_for_connect() drops and re-acquires the socket lock while
+waiting for the association to reach ESTABLISHED state. During this
+window, another thread can peeloff the association to a new socket via
+getsockopt(SCTP_SOCKOPT_PEELOFF), changing asoc->base.sk. After
+re-acquiring the old socket lock, sctp_wait_for_connect() returns
+success without noticing the migration â€” the caller then accesses
+the association under the wrong lock in sctp_datamsg_from_user().
+
+Add the same sk != asoc->base.sk check that sctp_wait_for_sndbuf()
+already has, returning an error if the association was migrated while
+we slept.
+
+Fixes: 668c9beb9020 ("sctp: implement assign_number for sctp_stream_interleave")
+Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20260527032411.60959-1-kipreyyy@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/socket.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index aeffa10ff2d34a..59e04788e1c760 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -9403,6 +9403,8 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p)
+               release_sock(sk);
+               current_timeo = schedule_timeout(current_timeo);
+               lock_sock(sk);
++              if (sk != asoc->base.sk)
++                      goto do_error;
+               *timeo_p = current_timeo;
+       }
+-- 
+2.53.0
+
index 646d508915beab6e3c93ad904f020dd79d0d5238..00227d5d0b964bb5b19319d22579bdb18fdd7e5a 100644 (file)
@@ -3,3 +3,110 @@ acpi-button-enable-wakeup-gpes-for-acpi-buttons-at-p.patch
 xfrm-move-policy_bydst-rcu-sync-from-per-netns-.exit.patch
 net-sched-sch_sfb-replace-direct-dequeue-call-with-p.patch
 bcache-fix-uninitialized-closure-object.patch
+nfc-llcp-fix-use-after-free-in-llcp_sock_release.patch
+nfc-llcp-fix-use-after-free-race-in-nfc_llcp_recv_cc.patch
+xfrm-check-for-underflow-in-xfrm_state_mtu.patch
+nfc-nxp-nci-i2c-use-rising-edge-irq-on-acpi-systems.patch
+tools-bootconfig-fix-buf-leaks-in-apply_xbc.patch
+hid-remove-duplicate-hid_warn_ratelimited-definition.patch
+kunit-fix-use-after-free-in-debugfs-when-using-kunit.patch
+accel-rocket-fix-uaf-via-dangling-gem-handle-in-crea.patch
+kernel-fork-validate-exit_signal-in-kernel_clone.patch
+esp-fix-page-frag-reference-leak-on-skb_to_sgvec-fai.patch
+netfilter-synproxy-refresh-tcphdr-after-skb_ensure_w.patch
+netfilter-xt_cpu-prefer-raw_smp_processor_id.patch
+netfilter-ebtables-fix-oob-read-in-compat_mtw_from_u.patch
+netfilter-nf_tables-fix-dst-corruption-in-same-regis.patch
+tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
+tap-free-page-on-error-paths-in-tap_get_user_xdp.patch
+tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch
+vsock-keep-poll-shutdown-state-consistent.patch
+net-netlink-fix-sending-unassigned-nsid-after-assign.patch
+net-netlink-don-t-set-nsid-on-local-notifications.patch
+net-smc-do-not-re-initialize-smc-hashtables.patch
+net-iucv-fix-locking-in-.getsockopt.patch
+scsi-core-run-queues-for-all-non-sdev_del-devices-fr.patch
+scsi-scsi_debug-add-missing-newline-in-scsi_debug_de.patch
+ipv4-free-net-ipv4.sysctl_local_reserved_ports-after.patch
+alsa-hda-cs35l56-fix-system-name-string-leaks.patch
+alsa-pcm-oss-fix-setup-list-uaf-on-proc-write-error.patch
+asoc-intel-bytcht_es8316-fix-mclk-leak-on-init-error.patch
+net-mlx5-hws-reject-unsupported-remove-header-action.patch
+net-hsr-fix-potential-oob-access-in-supervision-fram.patch
+accel-ivpu-prevent-uninitialized-data-bug-in-debugfs.patch
+gpio-mxc-fix-irq_high-handling.patch
+drm-i915-aux-use-polling-when-irqs-are-unavailable.patch
+net-avoid-checksumming-unreadable-skb-tail-on-trim.patch
+ethtool-rss-avoid-modifying-the-rss-context-response.patch
+ethtool-rss-add-missing-errno-on-rss-context-delete.patch
+ethtool-rss-fix-falsely-ignoring-indir-table-updates.patch
+ethtool-rss-fix-indir_table-and-hkey-leak-on-get_rxf.patch
+ethtool-rss-fix-hkey-leak-when-indir_size-is-0.patch
+ethtool-rss-avoid-device-context-leak-on-reply-build.patch
+ethtool-module-call-ethnl_ops_complete-on-module-fla.patch
+ethtool-module-avoid-leaking-a-netdev-ref-on-module-.patch
+ethtool-module-avoid-racy-updates-to-dev-ethtool-bit.patch
+ethtool-module-check-fw_flash_in_progress-under-rtnl.patch
+ethtool-module-fix-cleanup-if-socket-used-for-flashi.patch
+ethtool-cmis-require-exact-cdb-reply-length.patch
+ethtool-cmis-fix-u16-to-u8-truncation-of-msleep_pre_.patch
+ethtool-cmis-validate-start_cmd_payload_size-from-mo.patch
+ethtool-cmis-validate-fw-size-against-start_cmd_payl.patch
+cxl-test-update-mock-dev-array-before-calling-platfo.patch
+blk-mq-reinsert-cached-request-to-the-list.patch
+tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
+vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
+tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
+ksmbd-fix-fsctl-permission-bypass-by-adding-a-permis.patch
+asoc-codecs-simple-mux-fix-enum-control-bounds-check.patch
+drm-xe-restore-idledly-regiter-on-engine-reset.patch
+bluetooth-6lowpan-check-skb_clone-return-value-in-se.patch
+bonding-refuse-to-enslave-can-devices.patch
+bridge-fix-sleep-in-atomic-context-in-netlink-path.patch
+bridge-fix-sleep-in-atomic-context-in-sysfs-path.patch
+ethtool-coalesce-cap-profile-updates-at-net_dim_para.patch
+ethtool-tsconfig-fix-reply-error-handling.patch
+ethtool-linkstate-fix-unbalanced-ethnl_ops_complete-.patch
+ethtool-pse-pd-fix-missing-ethnl_ops_complete.patch
+ethtool-tsconfig-fix-missing-ethnl_ops_complete.patch
+ethtool-tsinfo-fix-uninitialized-stats-on-the-by-phc.patch
+ethtool-tsinfo-don-t-pass-err_ptr-to-genlmsg_cancel-.patch
+ethtool-strset-fix-header-attribute-index-in-ethnl_r.patch
+ethtool-eeprom-add-missing-ethnl_ops_begin-_complete.patch
+ethtool-eeprom-add-more-safeties-to-eeprom-netlink-f.patch
+ipv6-rpl-fix-hdrlen-overflow-in-ipv6_rpl_srh_decompr.patch
+net-sched-revert-net-sched-restrict-conditions-for-a.patch
+net-sched-fix-packet-loop-on-netem-when-duplicate-is.patch
+net-introduce-skb-tc-depth-field-to-track-packet-loo.patch
+net-sched-fix-ethx-ingress-ethy-egress-ethx-ingress-.patch
+net-sched-act_mirred-fix-blockcast-recursion-bypass-.patch
+net-sched-act_mirred-fix-return-code-in-early-mirred.patch
+net-hibmcge-disable-relaxed-ordering-to-fix-rx-packe.patch
+net-hibmcge-move-dma_rmb-after-dma_sync_single_for_c.patch
+net-handshake-use-spin_lock_bh-for-hn_lock.patch
+nvme-tcp-store-negative-errno-in-queue-tls_err.patch
+net-handshake-pass-negative-errno-through-handshake_.patch
+net-handshake-hand-off-the-pinned-file-reference-to-.patch
+net-handshake-take-a-long-lived-file-reference-at-su.patch
+net-handshake-drain-pending-requests-at-net-namespac.patch
+dpll-zl3073x-detect-dpll-channel-count-from-chip-id-.patch
+dpll-zl3073x-add-die-temperature-reporting-for-suppo.patch
+dpll-export-__dpll_device_change_ntf-for-use-under-d.patch
+dpll-zl3073x-use-__dpll_device_change_ntf-and-remove.patch
+bluetooth-l2cap-clear-chan-ident-on-ecred-reconfigur.patch
+bluetooth-l2cap-fix-possible-crash-on-l2cap_ecred_co.patch
+bluetooth-hci_sync-set-hci_cmd_drain_workqueue-durin.patch
+bluetooth-hci_sync-reset-device-counters-in-hci_dev_.patch
+gpio-adnp-fix-flow-control-regression-caused-by-scop.patch
+gpio-virtuser-fix-uninitialized-data-bug-in-gpio_vir.patch
+gpio-rockchip-convert-bank-clk-to-devm_clk_get_enabl.patch
+gpio-rockchip-teardown-bugs-and-resource-leaks.patch
+net-mana-add-null-guards-in-teardown-path-to-prevent.patch
+net-mana-skip-redundant-detach-on-already-detached-p.patch
+sctp-fix-race-between-sctp_wait_for_connect-and-peel.patch
+net-pcs-pcs-mtk-lynxi-fix-bpi-r3-serdes-configuratio.patch
+vsock-virtio-bind-uarg-before-filling-zerocopy-skb.patch
+ipv6-fix-possible-infinite-loop-in-rt6_fill_node.patch
+ipv6-fix-possible-infinite-loop-in-fib6_select_path.patch
+net-skbuff-fix-pskb_carve-leaking-zcopy-pages.patch
+revert-ipv6-preserve-insertion-order-for-same-scope-.patch
diff --git a/queue-7.0/tap-free-page-on-error-paths-in-tap_get_user_xdp.patch b/queue-7.0/tap-free-page-on-error-paths-in-tap_get_user_xdp.patch
new file mode 100644 (file)
index 0000000..702514d
--- /dev/null
@@ -0,0 +1,55 @@
+From 192848b7e150e475aa938b298842ebb047bb1441 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 09:32:31 -0700
+Subject: tap: free page on error paths in tap_get_user_xdp()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit 3bcf7aec6a9d16438f2cec29f5d7c8d5b8edf9b2 ]
+
+tap_get_user_xdp() rejects a frame shorter than ETH_HLEN with -EINVAL,
+and returns -ENOMEM when build_skb() fails. Both paths jump to the err
+label without freeing the page that vhost_net_build_xdp() allocated for
+the frame. tap_sendmsg() discards the per-buffer return value and always
+returns 0, so vhost_tx_batch() takes the success path and never frees
+the page; each rejected frame in a batch leaks one page-frag chunk.
+
+Free the page on both error paths, before the skb is built. This is the
+tap counterpart of the same leak in tun_xdp_one().
+
+Fixes: 0efac27791ee ("tap: accept an array of XDP buffs through sendmsg()")
+Fixes: ed7f2afdd0e0 ("tap: add missing verification for short frame")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260521163230.1478627-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tap.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/tap.c b/drivers/net/tap.c
+index a590e07ce0a98c..fae115915c8eff 100644
+--- a/drivers/net/tap.c
++++ b/drivers/net/tap.c
+@@ -1052,6 +1052,7 @@ static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp)
+       int err, depth;
+       if (unlikely(xdp->data_end - xdp->data < ETH_HLEN)) {
++              put_page(virt_to_head_page(xdp->data));
+               err = -EINVAL;
+               goto err;
+       }
+@@ -1061,6 +1062,7 @@ static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp)
+       skb = build_skb(xdp->data_hard_start, buflen);
+       if (!skb) {
++              put_page(virt_to_head_page(xdp->data));
+               err = -ENOMEM;
+               goto err;
+       }
+-- 
+2.53.0
+
diff --git a/queue-7.0/tools-bootconfig-fix-buf-leaks-in-apply_xbc.patch b/queue-7.0/tools-bootconfig-fix-buf-leaks-in-apply_xbc.patch
new file mode 100644 (file)
index 0000000..18122f1
--- /dev/null
@@ -0,0 +1,40 @@
+From ad672bdf9ef924e2b57c79efd27a32e823af81a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 11:01:26 +0800
+Subject: tools/bootconfig: Fix buf leaks in apply_xbc
+
+From: Hongtao Lee <lihongtao@kylinos.cn>
+
+[ Upstream commit f42d01aadcedd7bbf4f9a466cabe25c1781dedad ]
+
+If data calloc failed, free the buf before return.
+
+Link: https://lore.kernel.org/all/20260520030126.147782-1-lihongtao@kylinos.cn/
+
+Fixes: 950313ebf79c ("tools: bootconfig: Add bootconfig command")
+Signed-off-by: Hongtao Lee <lihongtao@kylinos.cn>
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bootconfig/main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
+index 643f707b8f1da1..ddabde20585f21 100644
+--- a/tools/bootconfig/main.c
++++ b/tools/bootconfig/main.c
+@@ -390,8 +390,10 @@ static int apply_xbc(const char *path, const char *xbc_path)
+       /* Backup the bootconfig data */
+       data = calloc(size + BOOTCONFIG_ALIGN + BOOTCONFIG_FOOTER_SIZE, 1);
+-      if (!data)
++      if (!data) {
++              free(buf);
+               return -ENOMEM;
++      }
+       memcpy(data, buf, size);
+       /* Check the data format */
+-- 
+2.53.0
+
diff --git a/queue-7.0/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch b/queue-7.0/tun-free-page-on-build_skb-failure-in-tun_xdp_one.patch
new file mode 100644 (file)
index 0000000..eb6da27
--- /dev/null
@@ -0,0 +1,47 @@
+From 460801af0941c4e69c20b9c35fc6cf3780737583 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 May 2026 09:33:13 -0700
+Subject: tun: free page on build_skb failure in tun_xdp_one()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit aa8963fdce667a42fb7f0bdd2909fadcab02f9a8 ]
+
+When build_skb() fails in tun_xdp_one(), the function sets ret to
+-ENOMEM and jumps to the out label, which returns without freeing the
+page that vhost_net_build_xdp() allocated for the frame. As with the
+short-frame rejection path, tun_sendmsg() discards the per-buffer error
+and still returns total_len, so vhost_tx_batch() takes the success path
+and never frees the page. Each build_skb() failure in a batch leaks one
+page-frag chunk.
+
+Free the page before taking the error path, matching the put_page() the
+other error exits of tun_xdp_one() already perform.
+
+Fixes: 043d222f93ab ("tuntap: accept an array of XDP buffs through sendmsg()")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260521163312.1479805-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 8154d18a2a235a..ca0ae5df73af78 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2437,6 +2437,7 @@ static int tun_xdp_one(struct tun_struct *tun,
+ build:
+       skb = build_skb(xdp->data_hard_start, buflen);
+       if (!skb) {
++              put_page(virt_to_head_page(xdp->data));
+               ret = -ENOMEM;
+               goto out;
+       }
+-- 
+2.53.0
+
diff --git a/queue-7.0/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch b/queue-7.0/tun-free-page-on-short-frame-rejection-in-tun_xdp_on.patch
new file mode 100644 (file)
index 0000000..2213f01
--- /dev/null
@@ -0,0 +1,54 @@
+From f8ab9d7ffb13bb41e1dfb509ba278090aa062bd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 09:00:21 -0700
+Subject: tun: free page on short-frame rejection in tun_xdp_one()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+[ Upstream commit f4feb1e20058e407cb00f45aff47f5b7e19a6bbf ]
+
+tun_xdp_one() returns -EINVAL on a frame shorter than ETH_HLEN without
+freeing the page that vhost_net_build_xdp() allocated for it.
+tun_sendmsg() discards that -EINVAL and still returns total_len, so
+vhost_tx_batch() takes the success path and never frees the page; each
+short frame in a batch leaks one page-frag chunk.
+
+A local process that can open /dev/net/tun and /dev/vhost-net can hit
+this path: it attaches a tun/tap device as the vhost-net backend and
+feeds TX descriptors whose length minus the virtio-net header is below
+ETH_HLEN. Each kick leaks the page-frag chunks for that batch, and a
+tight submission loop exhausts host memory and triggers an OOM panic.
+Free the page before returning -EINVAL, matching the XDP-program error
+path in the same function.
+
+Fixes: 049584807f1d ("tun: add missing verification for short frame")
+Reported-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260520160020.375349-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index c492fda6fc15a7..8154d18a2a235a 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2392,8 +2392,10 @@ static int tun_xdp_one(struct tun_struct *tun,
+       bool skb_xdp = false;
+       struct page *page;
+-      if (unlikely(datasize < ETH_HLEN))
++      if (unlikely(datasize < ETH_HLEN)) {
++              put_page(virt_to_head_page(xdp->data));
+               return -EINVAL;
++      }
+       xdp_prog = rcu_dereference(tun->xdp_prog);
+       if (xdp_prog) {
+-- 
+2.53.0
+
diff --git a/queue-7.0/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch b/queue-7.0/tunnels-do-not-assume-transport-header-in-iptunnel_p.patch
new file mode 100644 (file)
index 0000000..f9c5d6e
--- /dev/null
@@ -0,0 +1,67 @@
+From 4e29eefbf913240fd13aba9d2b510f5b036e0950 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 11:55:12 +0000
+Subject: tunnels: do not assume transport header in
+ iptunnel_pmtud_check_icmp()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 509323077ef79a26ba0c60bb556e45c12c398b2d ]
+
+In some cases, iptunnel_pmtud_check_icmp() can be called while
+skb transport header is not set.
+
+This triggers an out-of-bound access, because
+(typeof(skb->transport_header))~0U is 65535.
+
+Access the icmp header based on IPv4 network header,
+after making sure icmp->type is present in skb linear part.
+
+Note that iptunnel_pmtud_check_icmpv6()) is fine.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Reported-by: Damiano Melotti <melotti@google.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260522115512.1519110-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index a52ba6f671fedf..fc993c78cbcc5e 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -280,7 +280,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct icmphdr *icmph = icmp_hdr(skb);
+       const struct iphdr *iph = ip_hdr(skb);
+       if (mtu < 576 || iph->frag_off != htons(IP_DF))
+@@ -291,9 +290,17 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+           ipv4_is_lbcast(iph->saddr)  || ipv4_is_multicast(iph->saddr))
+               return 0;
+-      if (iph->protocol == IPPROTO_ICMP && icmp_is_err(icmph->type))
+-              return 0;
++      if (iph->protocol == IPPROTO_ICMP) {
++              const struct icmphdr *icmph;
++              if (!pskb_network_may_pull(skb, iph->ihl * 4 +
++                                              offsetofend(struct icmphdr, type)))
++                      return 0;
++              iph = ip_hdr(skb);
++              icmph = (void *)iph + iph->ihl * 4;
++              if (icmp_is_err(icmph->type))
++                      return 0;
++      }
+       return iptunnel_pmtud_build_icmp(skb, mtu);
+ }
+-- 
+2.53.0
+
diff --git a/queue-7.0/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch b/queue-7.0/tunnels-load-network-headers-after-skb_cow-in-iptunn.patch
new file mode 100644 (file)
index 0000000..0f5fc2f
--- /dev/null
@@ -0,0 +1,87 @@
+From e02a263f36925bf91e85998209cad8cc1e2f6841 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:13:35 +0000
+Subject: tunnels: load network headers after skb_cow() in
+ iptunnel_pmtud_build_icmp[v6]()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b4bc94353050b1fa7b702bd4c6600710dd926cff ]
+
+Sashiko found that iptunnel_pmtud_build_icmp() and
+iptunnel_pmtud_build_icmpv6() were caching ip_hdr() and ipv6_hdr()
+before an skb_cow() call which can reallocate skb->head.
+
+Fix this possible UAF by initializing the local variables
+after the skb_cow() call.
+
+Remove skb_reset_network_header() calls which were not needed.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525201335.2361845-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index f430d6f0463e7a..a52ba6f671fedf 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -212,7 +212,7 @@ EXPORT_SYMBOL_GPL(iptunnel_handle_offloads);
+  */
+ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+ {
+-      const struct iphdr *iph = ip_hdr(skb);
++      const struct iphdr *iph;
+       struct icmphdr *icmph;
+       struct iphdr *niph;
+       struct ethhdr eh;
+@@ -226,7 +226,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, 576 - sizeof(*niph) - sizeof(*icmph));
+       if (err)
+@@ -236,7 +235,7 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
+       err = skb_cow(skb, sizeof(*niph) + sizeof(*icmph) + ETH_HLEN);
+       if (err)
+               return err;
+-
++      iph = ip_hdr(skb);
+       icmph = skb_push(skb, sizeof(*icmph));
+       *icmph = (struct icmphdr) {
+               .type                   = ICMP_DEST_UNREACH,
+@@ -308,7 +307,7 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
+  */
+ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+ {
+-      const struct ipv6hdr *ip6h = ipv6_hdr(skb);
++      const struct ipv6hdr *ip6h;
+       struct icmp6hdr *icmp6h;
+       struct ipv6hdr *nip6h;
+       struct ethhdr eh;
+@@ -323,7 +322,6 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
+       pskb_pull(skb, ETH_HLEN);
+-      skb_reset_network_header(skb);
+       err = pskb_trim(skb, IPV6_MIN_MTU - sizeof(*nip6h) - sizeof(*icmp6h));
+       if (err)
+@@ -334,6 +332,7 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
+       if (err)
+               return err;
++      ip6h = ipv6_hdr(skb);
+       icmp6h = skb_push(skb, sizeof(*icmp6h));
+       *icmp6h = (struct icmp6hdr) {
+               .icmp6_type             = ICMPV6_PKT_TOOBIG,
+-- 
+2.53.0
+
diff --git a/queue-7.0/vsock-keep-poll-shutdown-state-consistent.patch b/queue-7.0/vsock-keep-poll-shutdown-state-consistent.patch
new file mode 100644 (file)
index 0000000..07755bd
--- /dev/null
@@ -0,0 +1,247 @@
+From 908ca79c324a091b6705fdbb45748d215bcda089 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 00:56:36 +0800
+Subject: vsock: keep poll shutdown state consistent
+
+From: Ziyu Zhang <ziyuzhang201@gmail.com>
+
+[ Upstream commit aae9d8a5528b8ee9ff8dc5d3558b8a9f852a724a ]
+
+vsock_poll() reads vsk->peer_shutdown before taking the socket lock
+to set EPOLLHUP and EPOLLRDHUP, then reads it again after taking
+the lock to report EOF readability. A shutdown packet can update
+peer_shutdown while poll is waiting for the lock, so one poll invocation
+can report EOF readability without the corresponding HUP/RDHUP bits.
+
+For connectible sockets, take one peer_shutdown snapshot after
+lock_sock() and use it for all peer-shutdown-derived poll bits. For
+datagram sockets, which do not take lock_sock() in poll(), take one
+lockless READ_ONCE() snapshot and pair it with WRITE_ONCE() on the
+writer side.
+
+This keeps the peer-shutdown-derived bits internally consistent for each
+poll pass.
+
+Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
+Signed-off-by: Ziyu Zhang <ziyuzhang201@gmail.com>
+Link: https://patch.msgid.link/20260519165636.62542-1-ziyuzhang201@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/vmw_vsock/af_vsock.c                | 49 ++++++++++++++++---------
+ net/vmw_vsock/hyperv_transport.c        |  9 +++--
+ net/vmw_vsock/virtio_transport_common.c | 14 ++++---
+ net/vmw_vsock/vmci_transport.c          |  8 ++--
+ 4 files changed, 52 insertions(+), 28 deletions(-)
+
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index 08f4dfb9782c28..0a93873eb4672b 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -628,7 +628,7 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
+                */
+               sock_reset_flag(sk, SOCK_DONE);
+               sk->sk_state = TCP_CLOSE;
+-              vsk->peer_shutdown = 0;
++              WRITE_ONCE(vsk->peer_shutdown, 0);
+       }
+       if (sk->sk_type == SOCK_SEQPACKET) {
+@@ -919,7 +919,7 @@ static struct sock *__vsock_create(struct net *net,
+       vsk->rejected = false;
+       vsk->sent_request = false;
+       vsk->ignore_connecting_rst = false;
+-      vsk->peer_shutdown = 0;
++      WRITE_ONCE(vsk->peer_shutdown, 0);
+       INIT_DELAYED_WORK(&vsk->connect_work, vsock_connect_timeout);
+       INIT_DELAYED_WORK(&vsk->pending_work, vsock_pending_work);
+@@ -1227,6 +1227,25 @@ static int vsock_shutdown(struct socket *sock, int mode)
+       return err;
+ }
++static __poll_t vsock_poll_shutdown(struct sock *sk, u32 peer_shutdown)
++{
++      __poll_t mask = 0;
++
++      /* INET sockets treat local write shutdown and peer write shutdown as a
++       * case of EPOLLHUP set.
++       */
++      if (sk->sk_shutdown == SHUTDOWN_MASK ||
++          ((sk->sk_shutdown & SEND_SHUTDOWN) &&
++           (peer_shutdown & SEND_SHUTDOWN)))
++              mask |= EPOLLHUP;
++
++      if (sk->sk_shutdown & RCV_SHUTDOWN ||
++          peer_shutdown & SEND_SHUTDOWN)
++              mask |= EPOLLRDHUP;
++
++      return mask;
++}
++
+ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+                              poll_table *wait)
+ {
+@@ -1244,24 +1263,17 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+               /* Signify that there has been an error on this socket. */
+               mask |= EPOLLERR;
+-      /* INET sockets treat local write shutdown and peer write shutdown as a
+-       * case of EPOLLHUP set.
+-       */
+-      if ((sk->sk_shutdown == SHUTDOWN_MASK) ||
+-          ((sk->sk_shutdown & SEND_SHUTDOWN) &&
+-           (vsk->peer_shutdown & SEND_SHUTDOWN))) {
+-              mask |= EPOLLHUP;
+-      }
+-
+-      if (sk->sk_shutdown & RCV_SHUTDOWN ||
+-          vsk->peer_shutdown & SEND_SHUTDOWN) {
+-              mask |= EPOLLRDHUP;
+-      }
+-
+       if (sk_is_readable(sk))
+               mask |= EPOLLIN | EPOLLRDNORM;
+       if (sock->type == SOCK_DGRAM) {
++              u32 peer_shutdown = READ_ONCE(vsk->peer_shutdown);
++
++              /* DGRAM sockets do not take lock_sock() in poll(), so use one
++               * lockless snapshot for all shutdown-derived mask bits.
++               */
++              mask |= vsock_poll_shutdown(sk, peer_shutdown);
++
+               /* For datagram sockets we can read if there is something in
+                * the queue and write as long as the socket isn't shutdown for
+                * sending.
+@@ -1276,6 +1288,7 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+       } else if (sock_type_connectible(sk->sk_type)) {
+               const struct vsock_transport *transport;
++              u32 peer_shutdown;
+               lock_sock(sk);
+@@ -1308,8 +1321,10 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
+                * terminated should also be considered read, and we check the
+                * shutdown flag for that.
+                */
++              peer_shutdown = READ_ONCE(vsk->peer_shutdown);
++              mask |= vsock_poll_shutdown(sk, peer_shutdown);
+               if (sk->sk_shutdown & RCV_SHUTDOWN ||
+-                  vsk->peer_shutdown & SEND_SHUTDOWN) {
++                  peer_shutdown & SEND_SHUTDOWN) {
+                       mask |= EPOLLIN | EPOLLRDNORM;
+               }
+diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
+index d5b0fd0a889723..842510f7dda2e3 100644
+--- a/net/vmw_vsock/hyperv_transport.c
++++ b/net/vmw_vsock/hyperv_transport.c
+@@ -264,7 +264,7 @@ static void hvs_do_close_lock_held(struct vsock_sock *vsk,
+       struct sock *sk = sk_vsock(vsk);
+       sock_set_flag(sk, SOCK_DONE);
+-      vsk->peer_shutdown = SHUTDOWN_MASK;
++      WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+       if (vsock_stream_has_data(vsk) <= 0)
+               sk->sk_state = TCP_CLOSING;
+       sk->sk_state_change(sk);
+@@ -593,7 +593,9 @@ static int hvs_update_recv_data(struct hvsock *hvs)
+               return -EIO;
+       if (payload_len == 0)
+-              hvs->vsk->peer_shutdown |= SEND_SHUTDOWN;
++              WRITE_ONCE(hvs->vsk->peer_shutdown,
++                         READ_ONCE(hvs->vsk->peer_shutdown) |
++                         SEND_SHUTDOWN);
+       hvs->recv_data_len = payload_len;
+       hvs->recv_data_off = 0;
+@@ -736,7 +738,8 @@ static s64 hvs_stream_has_data(struct vsock_sock *vsk)
+                       return ret;
+               return hvs->recv_data_len;
+       case 0:
+-              vsk->peer_shutdown |= SEND_SHUTDOWN;
++              WRITE_ONCE(vsk->peer_shutdown,
++                         READ_ONCE(vsk->peer_shutdown) | SEND_SHUTDOWN);
+               ret = 0;
+               break;
+       default: /* -1 */
+diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
+index e8fb2e20db0f38..1c0f1e5c75dec8 100644
+--- a/net/vmw_vsock/virtio_transport_common.c
++++ b/net/vmw_vsock/virtio_transport_common.c
+@@ -1221,7 +1221,7 @@ static void virtio_transport_do_close(struct vsock_sock *vsk,
+       struct sock *sk = sk_vsock(vsk);
+       sock_set_flag(sk, SOCK_DONE);
+-      vsk->peer_shutdown = SHUTDOWN_MASK;
++      WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+       if (vsock_stream_has_data(vsk) <= 0)
+               sk->sk_state = TCP_CLOSING;
+       sk->sk_state_change(sk);
+@@ -1424,12 +1424,15 @@ virtio_transport_recv_connected(struct sock *sk,
+       case VIRTIO_VSOCK_OP_CREDIT_UPDATE:
+               sk->sk_write_space(sk);
+               break;
+-      case VIRTIO_VSOCK_OP_SHUTDOWN:
++      case VIRTIO_VSOCK_OP_SHUTDOWN: {
++              u32 peer_shutdown = READ_ONCE(vsk->peer_shutdown);
++
+               if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SHUTDOWN_RCV)
+-                      vsk->peer_shutdown |= RCV_SHUTDOWN;
++                      peer_shutdown |= RCV_SHUTDOWN;
+               if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SHUTDOWN_SEND)
+-                      vsk->peer_shutdown |= SEND_SHUTDOWN;
+-              if (vsk->peer_shutdown == SHUTDOWN_MASK) {
++                      peer_shutdown |= SEND_SHUTDOWN;
++              WRITE_ONCE(vsk->peer_shutdown, peer_shutdown);
++              if (peer_shutdown == SHUTDOWN_MASK) {
+                       if (vsock_stream_has_data(vsk) <= 0 && !sock_flag(sk, SOCK_DONE)) {
+                               (void)virtio_transport_reset(vsk, NULL);
+                               virtio_transport_do_close(vsk, true);
+@@ -1444,6 +1447,7 @@ virtio_transport_recv_connected(struct sock *sk,
+               if (le32_to_cpu(virtio_vsock_hdr(skb)->flags))
+                       sk->sk_state_change(sk);
+               break;
++      }
+       case VIRTIO_VSOCK_OP_RST:
+               virtio_transport_do_close(vsk, true);
+               break;
+diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
+index d2579380f51e5d..5c1ecd5bfdbc21 100644
+--- a/net/vmw_vsock/vmci_transport.c
++++ b/net/vmw_vsock/vmci_transport.c
+@@ -819,7 +819,7 @@ static void vmci_transport_handle_detach(struct sock *sk)
+               /* On a detach the peer will not be sending or receiving
+                * anymore.
+                */
+-              vsk->peer_shutdown = SHUTDOWN_MASK;
++              WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+               /* We should not be sending anymore since the peer won't be
+                * there to receive, but we can still receive if there is data
+@@ -1542,7 +1542,9 @@ static int vmci_transport_recv_connected(struct sock *sk,
+               if (pkt->u.mode) {
+                       vsk = vsock_sk(sk);
+-                      vsk->peer_shutdown |= pkt->u.mode;
++                      WRITE_ONCE(vsk->peer_shutdown,
++                                 READ_ONCE(vsk->peer_shutdown) |
++                                 pkt->u.mode);
+                       sk->sk_state_change(sk);
+               }
+               break;
+@@ -1559,7 +1561,7 @@ static int vmci_transport_recv_connected(struct sock *sk,
+                * a clean shutdown.
+                */
+               sock_set_flag(sk, SOCK_DONE);
+-              vsk->peer_shutdown = SHUTDOWN_MASK;
++              WRITE_ONCE(vsk->peer_shutdown, SHUTDOWN_MASK);
+               if (vsock_stream_has_data(vsk) <= 0)
+                       sk->sk_state = TCP_CLOSING;
+-- 
+2.53.0
+
diff --git a/queue-7.0/vsock-virtio-bind-uarg-before-filling-zerocopy-skb.patch b/queue-7.0/vsock-virtio-bind-uarg-before-filling-zerocopy-skb.patch
new file mode 100644 (file)
index 0000000..32d100d
--- /dev/null
@@ -0,0 +1,89 @@
+From 76f701991ac26a578240a173e7b4ed3688f71c79 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 10:33:01 +0800
+Subject: vsock/virtio: bind uarg before filling zerocopy skb
+
+From: Jingguo Tan <tanjingguo@huawei.com>
+
+[ Upstream commit 1e584c304cfb94a759417130b1fc6d30b30c4cce ]
+
+virtio_transport_send_pkt_info() allocates or reuses the zerocopy uarg
+before entering the send loop, but virtio_transport_alloc_skb() still
+fills the skb before it inherits that uarg. When fixed-buffer vectored
+zerocopy hits MAX_SKB_FRAGS, io_sg_from_iter() may partially attach
+managed frags and return -EMSGSIZE. The rollback path call kfree_skb()
+to free an skb that carries SKBFL_MANAGED_FRAG_REFS but no uarg, so
+skb_release_data() falls through to ordinary frag unref.
+
+Pass the uarg into virtio_transport_alloc_skb() and bind it immediately
+before virtio_transport_fill_skb(). This keeps control or no-payload skbs
+untouched while ensuring success and rollback share one lifetime rule.
+
+Fixes: 581512a6dc93 ("vsock/virtio: MSG_ZEROCOPY flag support")
+Signed-off-by: Lin Ma <malin89@huawei.com>
+Signed-off-by: Rongzhen Cui <cuirongzhen@huawei.com>
+Signed-off-by: Jingguo Tan <tanjingguo@huawei.com>
+Acked-by: Arseniy Krasnov <avkrasnov@salutedevices.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
+Link: https://patch.msgid.link/20260527023301.1075581-1-malin89@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/vmw_vsock/virtio_transport_common.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
+index 1c0f1e5c75dec8..abe7bfcedc5a6d 100644
+--- a/net/vmw_vsock/virtio_transport_common.c
++++ b/net/vmw_vsock/virtio_transport_common.c
+@@ -207,6 +207,7 @@ static u16 virtio_transport_get_type(struct sock *sk)
+ static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *info,
+                                                 size_t payload_len,
+                                                 bool zcopy,
++                                                struct ubuf_info *uarg,
+                                                 u32 src_cid,
+                                                 u32 src_port,
+                                                 u32 dst_cid,
+@@ -247,6 +248,12 @@ static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *
+       if (info->msg && payload_len > 0) {
+               int err;
++              /* Bind the zerocopy lifetime before filling frags so error
++               * rollback frees managed fixed-buffer pages through
++               * the uarg-aware path.
++               */
++              skb_zcopy_set(skb, uarg, NULL);
++
+               err = virtio_transport_fill_skb(skb, info, payload_len, zcopy);
+               if (err)
+                       goto out;
+@@ -366,6 +373,7 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
+               skb_len = min(max_skb_len, rest_len);
+               skb = virtio_transport_alloc_skb(info, skb_len, can_zcopy,
++                                               uarg,
+                                                src_cid, src_port,
+                                                dst_cid, dst_port);
+               if (!skb) {
+@@ -373,8 +381,6 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
+                       break;
+               }
+-              skb_zcopy_set(skb, uarg, NULL);
+-
+               virtio_transport_inc_tx_pkt(vvs, skb);
+               ret = t_ops->send_pkt(skb, info->net);
+@@ -1176,7 +1182,7 @@ static int virtio_transport_reset_no_sock(const struct virtio_transport *t,
+       if (!t)
+               return -ENOTCONN;
+-      reply = virtio_transport_alloc_skb(&info, 0, false,
++      reply = virtio_transport_alloc_skb(&info, 0, false, NULL,
+                                          le64_to_cpu(hdr->dst_cid),
+                                          le32_to_cpu(hdr->dst_port),
+                                          le64_to_cpu(hdr->src_cid),
+-- 
+2.53.0
+
diff --git a/queue-7.0/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch b/queue-7.0/vxlan-do-not-reuse-cached-ip_hdr-value-after-skb_tun.patch
new file mode 100644 (file)
index 0000000..7c2cb29
--- /dev/null
@@ -0,0 +1,54 @@
+From b1f63588e7e767e9b17385d19ab49575780a7475 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2026 20:36:42 +0000
+Subject: vxlan: do not reuse cached ip_hdr() value after
+ skb_tunnel_check_pmtu()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 7d9ef0cb271555d8cf39fefe6c981e1493b25ecf ]
+
+skb_tunnel_check_pmtu() can change skb->head.
+
+Reusing old_iph afer skb_tunnel_check_pmtu() can cause an UAF.
+
+Use instead ip_hdr(skb) as done in drivers/net/bareudp.c
+and drivers/net/geneve.c.
+
+Found by Sashiko.
+
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20260525203642.2389723-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vxlan/vxlan_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
+index a94ac82a613649..0cc3b34add5eb4 100644
+--- a/drivers/net/vxlan/vxlan_core.c
++++ b/drivers/net/vxlan/vxlan_core.c
+@@ -2534,7 +2534,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr),
+                                     vni, md, flags, udp_sum);
+@@ -2608,7 +2608,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+                       goto out_unlock;
+               }
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(tos, ip_hdr(skb), skb);
+               ttl = ttl ? : ip6_dst_hoplimit(ndst);
+               skb_scrub_packet(skb, xnet);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
+-- 
+2.53.0
+
diff --git a/queue-7.0/xfrm-check-for-underflow-in-xfrm_state_mtu.patch b/queue-7.0/xfrm-check-for-underflow-in-xfrm_state_mtu.patch
new file mode 100644 (file)
index 0000000..96bf46a
--- /dev/null
@@ -0,0 +1,85 @@
+From 0275e38f18e7e32158919e688382b990eebb4c2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 10:49:14 -0600
+Subject: xfrm: Check for underflow in xfrm_state_mtu
+
+From: David Ahern <dahern@nvidia.com>
+
+[ Upstream commit 742b04d0550b0ec89dcbc99537ec88653bd1ad90 ]
+
+Leo Lin reported OOB write issue in esp component:
+
+  xfrm_state_mtu() returns u32 but performs its arithmetic in unsigned
+  modulo-2^32 space using an attacker-influenced "header_len + authsize +
+  net_adj" subtracted from a small "mtu" argument. A nobody user can
+  install an IPv4 ESP tunnel SA with a large authentication key
+  (XFRMA_ALG_AUTH_TRUNC, e.g. hmac(sha512), 64-byte key, 64-byte trunc),
+  configure a small interface MTU (68 bytes), and set XFRMA_TFCPAD to a
+  large value. When a single UDP datagram is then sent through the
+  tunnel, xfrm_state_mtu() underflows to a near-2^32 value, and
+  esp_output() consumes it as a signed int via:
+
+        padto      = min(x->tfcpad, xfrm_state_mtu(x, mtu_cached))
+        esp.tfclen = padto - skb->len   (assigned to int)
+
+  esp.tfclen ends up negative (e.g. -207). It is sign-extended to size_t
+  when passed to memset() inside esp_output_fill_trailer(), producing a
+  ~16 EB write of zeroes at skb_tail_pointer(skb). KASAN logs it as
+  "Write of size 18446744073709551537 at addr ffff888...".
+
+Check for underflow and return 1. This causes the sendmsg attempt to
+fail with ENETUNREACH.
+
+Fixes: c5c252389374 ("[XFRM]: Optimize MTU calculation")
+Reported-by: Leo Lin <leo@depthfirst.com>
+Assisted-by: Codex:26.506.31004
+Signed-off-by: David Ahern <dahern@nvidia.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 686014d394298c..f597e4996bb28a 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -3114,10 +3114,14 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+       const struct xfrm_type *type = READ_ONCE(x->type);
+       struct crypto_aead *aead;
+       u32 blksize, net_adj = 0;
++      u32 overhead, payload_mtu;
+       if (x->km.state != XFRM_STATE_VALID ||
+-          !type || type->proto != IPPROTO_ESP)
++          !type || type->proto != IPPROTO_ESP) {
++              if (mtu <= x->props.header_len)
++                      return 1;
+               return mtu - x->props.header_len;
++      }
+       aead = x->data;
+       blksize = ALIGN(crypto_aead_blocksize(aead), 4);
+@@ -3140,8 +3144,17 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+               break;
+       }
+-      return ((mtu - x->props.header_len - crypto_aead_authsize(aead) -
+-               net_adj) & ~(blksize - 1)) + net_adj - 2;
++      overhead = x->props.header_len + crypto_aead_authsize(aead) + net_adj;
++      if (mtu <= overhead)
++              return 1;
++
++      payload_mtu = mtu - overhead;
++      payload_mtu &= ~(blksize - 1);
++      if (payload_mtu <= 2)
++              return 1;
++
++      return payload_mtu + net_adj - 2;
++
+ }
+ EXPORT_SYMBOL_GPL(xfrm_state_mtu);
+-- 
+2.53.0
+