]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
7.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Jul 2026 13:57:09 +0000 (15:57 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Jul 2026 13:57:09 +0000 (15:57 +0200)
added patches:
amt-fix-use-after-free-in-amt-delayed-works.patch
asoc-fsl-imx-card-skip-sysclk-reset-for-active-dais-in-shutdown.patch
asoc-fsl_sai-fix-spurious-bclk-on-resume-by-clearing-byp.patch
binfmt_elf_fdpic-only-honour-the-first-pt_interp.patch
ceph-add-owner-capability-checks-for-ceph_ioc_set_layout.patch
ceph-fix-pre-auth-out-of-bounds-read-on-snaptrace-in-ceph_handle_caps.patch
ceph-fix-refcount-leak-in-ceph_readdir.patch
ceph-fix-writeback_count-leak-in-write_folio_nounlock.patch
fs-preserve-acl_dont_cache-state-in-forget_cached_acl.patch
fs-super-fix-emergency-thaw-double-unlock-of-s_umount.patch
fscrypt-add-missing-superblock-check-in-find_or_insert_direct_key.patch
fscrypt-avoid-dynamic-allocation-in-fscrypt_get_devices.patch
ftrace-add-global-mutex-to-serialize-trace_parser-access.patch
geneve-require-cap_net_admin-in-the-device-netns-for-changelink.patch
ice-fix-ptp-call-trace-during-ptp-release.patch
io_uring-rw-fix-missing-erestartsys-conversion-in-read-paths.patch
iomap-fix-out-of-bounds-bitmap_set-with-zero-length-range.patch
iommu-vt-d-disallow-sva-if-page-walk-is-not-coherent.patch
ksmbd-defer-destroy_previous_session-until-after-ntlm-authentication.patch
ksmbd-validate-minimum-pdu-size-for-transform-requests.patch
libceph-bound-get_version-reply-decode-to-front-len.patch
libceph-bound-pg_-temp-upmap-upmap_items-length-to-ceph_pg_max_size.patch
libceph-fix-multiplication-overflow-in-decode_new_up_state_weight.patch
libceph-fix-two-unsafe-bare-decodes-in-decode_lockers.patch
libceph-guard-missing-crush-type-name-lookup.patch
libceph-refresh-auth-authorizer_buf-_len-after-authorizer-update.patch
libceph-reject-monmaps-advertising-zero-monitors.patch
libceph-reject-zero-bucket-types-in-crush_decode.patch
libceph-remove-debugfs-files-before-client-teardown.patch
m68k-avoid-wunused-but-set-parameter-in-clear_user_page.patch
mm-damon-core-disallow-overlapping-input-ranges-for-damon_set_regions.patch
mm-damon-core-validate-ranges-in-damon_set_regions.patch
mm-huge_memory-set-pg_has_hwpoisoned-only-after-new-folio-head-is-established.patch
mm-kmemleak-fix-checksum-computation-for-per-cpu-objects.patch
mm-memory-failure-trace-change-memory_failure_event-to-ras-subsystem.patch
mm-page_vma_mapped-fix-device-private-pmd-handling.patch
mm-slab-fix-a-memory-leak-due-to-bootstrapping-sheaves-twice.patch
mm-slab-prevent-unbounded-recursion-in-free-path-with-new-kmalloc-type.patch
mm-slub-fix-lost-local-objects-when-bulk-remote-free-batch-fills.patch
net-af_iucv-fix-null-deref-in-afiucv_hs_callback_syn.patch
net-gro-fix-double-aggregation-of-flush-marked-skbs.patch
net-hip04-fix-rx-buffer-leak-on-build_skb-failure.patch
net-iucv-fix-use-after-free-of-a-severed-iucv_path.patch
net-mlx5e-use-sender-devcom-for-mpv-master-up.patch
net-pcs-xpcs-fix-sgmii-state-reading.patch
net-qrtr-ns-raise-node-count-limit-to-512.patch
net-sched-serialize-qdisc_rtab_list-against-concurrent-get-put.patch
net-slip-serialize-receive-against-buffer-reallocation.patch
net-stmmac-intel-skip-serdes-reconfig-when-rate-is-unchanged.patch
net-x25-fix-use-after-free-in-x25_kill_by_neigh.patch
phonet-pep-fix-use-after-free-in-pep_get_sb.patch
proc-fix-broken-error-paths-for-namespace-links.patch
ptp-ptp_s390-add-missing-facility-check.patch
rbd-reset-positive-result-codes-to-zero-in-object-map-update-path.patch
sctp-avoid-auth_enable-sysctl-uaf-during-netns-teardown.patch
sctp-close-udp-tunnel-sockets-during-netns-teardown.patch
sctp-don-t-free-the-asconf-s-own-transport-in-del-ip-processing.patch
selftests-ftrace-reset-triggers-at-top-level-before-instance-loop.patch
smb-client-handle-status_stopped_on_symlink-responses-without-a-symlink-target.patch
super-fix-emergency-thaw-deadlock-on-frozen-block-devices.patch
userfaultfd-prevent-registration-of-special-vmas.patch
vxlan-require-cap_net_admin-in-the-device-netns-for-changelink.patch

63 files changed:
queue-7.1/amt-fix-use-after-free-in-amt-delayed-works.patch [new file with mode: 0644]
queue-7.1/asoc-fsl-imx-card-skip-sysclk-reset-for-active-dais-in-shutdown.patch [new file with mode: 0644]
queue-7.1/asoc-fsl_sai-fix-spurious-bclk-on-resume-by-clearing-byp.patch [new file with mode: 0644]
queue-7.1/binfmt_elf_fdpic-only-honour-the-first-pt_interp.patch [new file with mode: 0644]
queue-7.1/ceph-add-owner-capability-checks-for-ceph_ioc_set_layout.patch [new file with mode: 0644]
queue-7.1/ceph-fix-pre-auth-out-of-bounds-read-on-snaptrace-in-ceph_handle_caps.patch [new file with mode: 0644]
queue-7.1/ceph-fix-refcount-leak-in-ceph_readdir.patch [new file with mode: 0644]
queue-7.1/ceph-fix-writeback_count-leak-in-write_folio_nounlock.patch [new file with mode: 0644]
queue-7.1/fs-preserve-acl_dont_cache-state-in-forget_cached_acl.patch [new file with mode: 0644]
queue-7.1/fs-super-fix-emergency-thaw-double-unlock-of-s_umount.patch [new file with mode: 0644]
queue-7.1/fscrypt-add-missing-superblock-check-in-find_or_insert_direct_key.patch [new file with mode: 0644]
queue-7.1/fscrypt-avoid-dynamic-allocation-in-fscrypt_get_devices.patch [new file with mode: 0644]
queue-7.1/ftrace-add-global-mutex-to-serialize-trace_parser-access.patch [new file with mode: 0644]
queue-7.1/geneve-require-cap_net_admin-in-the-device-netns-for-changelink.patch [new file with mode: 0644]
queue-7.1/ice-fix-ptp-call-trace-during-ptp-release.patch [new file with mode: 0644]
queue-7.1/io_uring-rw-fix-missing-erestartsys-conversion-in-read-paths.patch [new file with mode: 0644]
queue-7.1/iomap-fix-out-of-bounds-bitmap_set-with-zero-length-range.patch [new file with mode: 0644]
queue-7.1/iommu-vt-d-disallow-sva-if-page-walk-is-not-coherent.patch [new file with mode: 0644]
queue-7.1/ksmbd-defer-destroy_previous_session-until-after-ntlm-authentication.patch [new file with mode: 0644]
queue-7.1/ksmbd-validate-minimum-pdu-size-for-transform-requests.patch [new file with mode: 0644]
queue-7.1/libceph-bound-get_version-reply-decode-to-front-len.patch [new file with mode: 0644]
queue-7.1/libceph-bound-pg_-temp-upmap-upmap_items-length-to-ceph_pg_max_size.patch [new file with mode: 0644]
queue-7.1/libceph-fix-multiplication-overflow-in-decode_new_up_state_weight.patch [new file with mode: 0644]
queue-7.1/libceph-fix-two-unsafe-bare-decodes-in-decode_lockers.patch [new file with mode: 0644]
queue-7.1/libceph-guard-missing-crush-type-name-lookup.patch [new file with mode: 0644]
queue-7.1/libceph-refresh-auth-authorizer_buf-_len-after-authorizer-update.patch [new file with mode: 0644]
queue-7.1/libceph-reject-monmaps-advertising-zero-monitors.patch [new file with mode: 0644]
queue-7.1/libceph-reject-zero-bucket-types-in-crush_decode.patch [new file with mode: 0644]
queue-7.1/libceph-remove-debugfs-files-before-client-teardown.patch [new file with mode: 0644]
queue-7.1/m68k-avoid-wunused-but-set-parameter-in-clear_user_page.patch [new file with mode: 0644]
queue-7.1/mm-damon-core-disallow-overlapping-input-ranges-for-damon_set_regions.patch [new file with mode: 0644]
queue-7.1/mm-damon-core-validate-ranges-in-damon_set_regions.patch [new file with mode: 0644]
queue-7.1/mm-huge_memory-set-pg_has_hwpoisoned-only-after-new-folio-head-is-established.patch [new file with mode: 0644]
queue-7.1/mm-kmemleak-fix-checksum-computation-for-per-cpu-objects.patch [new file with mode: 0644]
queue-7.1/mm-memory-failure-trace-change-memory_failure_event-to-ras-subsystem.patch [new file with mode: 0644]
queue-7.1/mm-page_vma_mapped-fix-device-private-pmd-handling.patch [new file with mode: 0644]
queue-7.1/mm-slab-fix-a-memory-leak-due-to-bootstrapping-sheaves-twice.patch [new file with mode: 0644]
queue-7.1/mm-slab-prevent-unbounded-recursion-in-free-path-with-new-kmalloc-type.patch [new file with mode: 0644]
queue-7.1/mm-slub-fix-lost-local-objects-when-bulk-remote-free-batch-fills.patch [new file with mode: 0644]
queue-7.1/net-af_iucv-fix-null-deref-in-afiucv_hs_callback_syn.patch [new file with mode: 0644]
queue-7.1/net-gro-fix-double-aggregation-of-flush-marked-skbs.patch [new file with mode: 0644]
queue-7.1/net-hip04-fix-rx-buffer-leak-on-build_skb-failure.patch [new file with mode: 0644]
queue-7.1/net-iucv-fix-use-after-free-of-a-severed-iucv_path.patch [new file with mode: 0644]
queue-7.1/net-mlx5e-use-sender-devcom-for-mpv-master-up.patch [new file with mode: 0644]
queue-7.1/net-pcs-xpcs-fix-sgmii-state-reading.patch [new file with mode: 0644]
queue-7.1/net-qrtr-ns-raise-node-count-limit-to-512.patch [new file with mode: 0644]
queue-7.1/net-sched-serialize-qdisc_rtab_list-against-concurrent-get-put.patch [new file with mode: 0644]
queue-7.1/net-slip-serialize-receive-against-buffer-reallocation.patch [new file with mode: 0644]
queue-7.1/net-stmmac-intel-skip-serdes-reconfig-when-rate-is-unchanged.patch [new file with mode: 0644]
queue-7.1/net-x25-fix-use-after-free-in-x25_kill_by_neigh.patch [new file with mode: 0644]
queue-7.1/phonet-pep-fix-use-after-free-in-pep_get_sb.patch [new file with mode: 0644]
queue-7.1/proc-fix-broken-error-paths-for-namespace-links.patch [new file with mode: 0644]
queue-7.1/ptp-ptp_s390-add-missing-facility-check.patch [new file with mode: 0644]
queue-7.1/rbd-reset-positive-result-codes-to-zero-in-object-map-update-path.patch [new file with mode: 0644]
queue-7.1/sctp-avoid-auth_enable-sysctl-uaf-during-netns-teardown.patch [new file with mode: 0644]
queue-7.1/sctp-close-udp-tunnel-sockets-during-netns-teardown.patch [new file with mode: 0644]
queue-7.1/sctp-don-t-free-the-asconf-s-own-transport-in-del-ip-processing.patch [new file with mode: 0644]
queue-7.1/selftests-ftrace-reset-triggers-at-top-level-before-instance-loop.patch [new file with mode: 0644]
queue-7.1/series
queue-7.1/smb-client-handle-status_stopped_on_symlink-responses-without-a-symlink-target.patch [new file with mode: 0644]
queue-7.1/super-fix-emergency-thaw-deadlock-on-frozen-block-devices.patch [new file with mode: 0644]
queue-7.1/userfaultfd-prevent-registration-of-special-vmas.patch [new file with mode: 0644]
queue-7.1/vxlan-require-cap_net_admin-in-the-device-netns-for-changelink.patch [new file with mode: 0644]

diff --git a/queue-7.1/amt-fix-use-after-free-in-amt-delayed-works.patch b/queue-7.1/amt-fix-use-after-free-in-amt-delayed-works.patch
new file mode 100644 (file)
index 0000000..777954c
--- /dev/null
@@ -0,0 +1,89 @@
+From ea20c44935d6142daecfa9b39d635033a7553e1b Mon Sep 17 00:00:00 2001
+From: Shihuang Liu <shlomojune6@gmail.com>
+Date: Wed, 22 Jul 2026 19:39:19 +0800
+Subject: amt: fix use-after-free in AMT delayed works
+
+From: Shihuang Liu <shlomojune6@gmail.com>
+
+commit ea20c44935d6142daecfa9b39d635033a7553e1b upstream.
+
+When an AMT device is removed, pending delayed works can still access
+the freed amt_dev structure, which may result in kernel crashes or
+memory corruption.
+
+amt_dev_stop() cancels req_wq and discovery_wq with
+cancel_delayed_work_sync(), but these works can be scheduled again
+from event_wq after the cancellation. This allows delayed works to
+access the freed amt_dev structure after the netdev has been released.
+
+The following is a simple race scenario:
+
+CPU0                         CPU1
+
+amt_dev_stop()
+cancel_delayed_work_sync()
+                             amt_event_work()
+                             mod_delayed_work(req_wq)
+free netdev
+                             req_wq accesses freed amt_dev
+
+Use disable_delayed_work_sync() in amt_dev_stop() to prevent req_wq and
+discovery_wq from being queued again and wait for running work items
+to complete.
+
+The delayed works are disabled after initialization in
+amt_newlink() and enabled only when the device is successfully opened.
+This keeps the delayed work lifecycle synchronized with the lifetime
+of the AMT device.
+
+Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shihuang Liu <shlomojune6@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Taehee Yoo <ap420073@gmail.com>
+Link: https://patch.msgid.link/20260722113919.7723-1-shlomojune6@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/amt.c |   14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/amt.c
++++ b/drivers/net/amt.c
+@@ -3034,9 +3034,15 @@ static int amt_dev_open(struct net_devic
+       amt->event_idx = 0;
+       amt->nr_events = 0;
++      enable_delayed_work(&amt->discovery_wq);
++      enable_delayed_work(&amt->req_wq);
++
+       err = amt_socket_create(amt);
+-      if (err)
++      if (err) {
++              disable_delayed_work(&amt->req_wq);
++              disable_delayed_work(&amt->discovery_wq);
+               return err;
++      }
+       amt->req_cnt = 0;
+       amt->remote_ip = 0;
+@@ -3062,8 +3068,8 @@ static int amt_dev_stop(struct net_devic
+       struct sk_buff *skb;
+       int i;
+-      cancel_delayed_work_sync(&amt->req_wq);
+-      cancel_delayed_work_sync(&amt->discovery_wq);
++      disable_delayed_work_sync(&amt->req_wq);
++      disable_delayed_work_sync(&amt->discovery_wq);
+       cancel_delayed_work_sync(&amt->secret_wq);
+       /* shutdown */
+@@ -3317,6 +3323,8 @@ static int amt_newlink(struct net_device
+       INIT_DELAYED_WORK(&amt->req_wq, amt_req_work);
+       INIT_DELAYED_WORK(&amt->secret_wq, amt_secret_work);
+       INIT_WORK(&amt->event_wq, amt_event_work);
++      disable_delayed_work(&amt->req_wq);
++      disable_delayed_work(&amt->discovery_wq);
+       INIT_LIST_HEAD(&amt->tunnel_list);
+       return 0;
+ err:
diff --git a/queue-7.1/asoc-fsl-imx-card-skip-sysclk-reset-for-active-dais-in-shutdown.patch b/queue-7.1/asoc-fsl-imx-card-skip-sysclk-reset-for-active-dais-in-shutdown.patch
new file mode 100644 (file)
index 0000000..b99ddf8
--- /dev/null
@@ -0,0 +1,50 @@
+From 9f86aea992568c2b4db78c80ff9508af9e050ff7 Mon Sep 17 00:00:00 2001
+From: Chancel Liu <chancel.liu@nxp.com>
+Date: Fri, 10 Jul 2026 12:13:33 +0900
+Subject: ASoC: fsl: imx-card: Skip sysclk reset for active DAIs in shutdown
+
+From: Chancel Liu <chancel.liu@nxp.com>
+
+commit 9f86aea992568c2b4db78c80ff9508af9e050ff7 upstream.
+
+In a full-duplex setup, when one direction (playback or capture) is
+closed while the other is still running, imx_aif_shutdown() was
+unconditionally calling snd_soc_dai_set_sysclk() with rate=0 for all
+cpu/codec DAIs, which would disable the clock still needed by the
+active stream.
+
+Add snd_soc_dai_active() checks before clearing sysclk so that only
+truly inactive DAIs have their clocks reset.
+
+Fixes: 2260bc6ea8bd ("ASoC: imx-card: Add WM8524 support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Chancel Liu <chancel.liu@nxp.com>
+Link: https://patch.msgid.link/20260710031333.3491445-1-chancel.liu@oss.nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/fsl/imx-card.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/sound/soc/fsl/imx-card.c
++++ b/sound/soc/fsl/imx-card.c
+@@ -496,11 +496,15 @@ static void imx_aif_shutdown(struct snd_
+       struct snd_soc_dai *codec_dai;
+       int i;
+-      for_each_rtd_cpu_dais(rtd, i, cpu_dai)
+-              snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT);
++      for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
++              if (!snd_soc_dai_active(cpu_dai))
++                      snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT);
++      }
+-      for_each_rtd_codec_dais(rtd, i, codec_dai)
+-              snd_soc_dai_set_sysclk(codec_dai, 0, 0, SND_SOC_CLOCK_IN);
++      for_each_rtd_codec_dais(rtd, i, codec_dai) {
++              if (!snd_soc_dai_active(codec_dai))
++                      snd_soc_dai_set_sysclk(codec_dai, 0, 0, SND_SOC_CLOCK_IN);
++      }
+ }
+ static const struct snd_soc_ops imx_aif_ops = {
diff --git a/queue-7.1/asoc-fsl_sai-fix-spurious-bclk-on-resume-by-clearing-byp.patch b/queue-7.1/asoc-fsl_sai-fix-spurious-bclk-on-resume-by-clearing-byp.patch
new file mode 100644 (file)
index 0000000..c42623d
--- /dev/null
@@ -0,0 +1,80 @@
+From d091132889c1378dd0944a72f86eae3e4da1e4fa Mon Sep 17 00:00:00 2001
+From: Chancel Liu <chancel.liu@nxp.com>
+Date: Fri, 10 Jul 2026 16:08:35 +0900
+Subject: ASoC: fsl_sai: Fix spurious BCLK on resume by clearing BYP
+
+From: Chancel Liu <chancel.liu@nxp.com>
+
+commit d091132889c1378dd0944a72f86eae3e4da1e4fa upstream.
+
+When the BCLK divider ratio is 1:1, fsl_sai_set_bclk() enables bypass
+mode by setting BYP, but never clears the bit. The BYP=1 value remains
+in the regcache, and is restored by regcache_sync() on the next runtime
+resume.
+
+Since BYP=1 combined with BCD=1 immediately outputs the ungated MCLK
+as BCLK without waiting for BCE/TE/RE to be enabled, the clock is
+driven prematurely before the stream is fully configured, causing
+noise on some codecs.
+
+Fix this by clearing BYP and BCI in fsl_sai_hw_free() taking into
+account sync mode and the opposite stream's state, so that the regcache
+holds BYP=0 before runtime suspend and regcache_sync() on resume will
+not restore bypass mode prematurely.
+
+Fixes: a50b7926d015 ("ASoC: fsl_sai: implement 1:1 bclk:mclk ratio support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Chancel Liu <chancel.liu@nxp.com>
+Reviewed-by: Shengjiu Wang <shengjiu.wang@gmail.com>
+Link: https://patch.msgid.link/20260710070835.3749817-1-chancel.liu@oss.nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/fsl/fsl_sai.c |   29 +++++++++++++++++++++++++----
+ 1 file changed, 25 insertions(+), 4 deletions(-)
+
+--- a/sound/soc/fsl/fsl_sai.c
++++ b/sound/soc/fsl/fsl_sai.c
+@@ -804,6 +804,8 @@ static int fsl_sai_hw_free(struct snd_pc
+       struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
+       bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+       unsigned int ofs = sai->soc_data->reg_offset;
++      int adir = tx ? RX : TX;
++      int dir  = tx ? TX : RX;
+       /* Clear xMR to avoid channel swap with mclk_with_tere enabled case */
+       regmap_write(sai->regmap, FSL_SAI_xMR(tx), 0);
+@@ -811,10 +813,29 @@ static int fsl_sai_hw_free(struct snd_pc
+       regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
+                          FSL_SAI_CR3_TRCE_MASK, 0);
+-      if (!sai->is_consumer_mode[tx] &&
+-          sai->mclk_streams & BIT(substream->stream)) {
+-              clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]);
+-              sai->mclk_streams &= ~BIT(substream->stream);
++      if (!sai->is_consumer_mode[tx]) {
++              bool adir_active = !!(sai->mclk_streams & BIT(!substream->stream));
++              /*
++               * If opposite stream provides clocks for synchronous mode and
++               * it is inactive, Clear BYP and BCI
++               */
++              if (fsl_sai_dir_is_synced(sai, adir) && !adir_active)
++                      regmap_update_bits(sai->regmap, FSL_SAI_xCR2(!tx, ofs),
++                                         FSL_SAI_CR2_BCI | FSL_SAI_CR2_BYP, 0);
++              /*
++               * Clear BYP and BCI of current stream if either of:
++               * 1. current stream doesn't provide clocks for synchronous mode
++               * 2. current stream provides clocks for synchronous mode but no
++               *    more stream is active.
++               */
++              if (!fsl_sai_dir_is_synced(sai, dir) || !adir_active)
++                      regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
++                                         FSL_SAI_CR2_BCI | FSL_SAI_CR2_BYP, 0);
++
++              if (sai->mclk_streams & BIT(substream->stream)) {
++                      clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]);
++                      sai->mclk_streams &= ~BIT(substream->stream);
++              }
+       }
+       return 0;
diff --git a/queue-7.1/binfmt_elf_fdpic-only-honour-the-first-pt_interp.patch b/queue-7.1/binfmt_elf_fdpic-only-honour-the-first-pt_interp.patch
new file mode 100644 (file)
index 0000000..24b5359
--- /dev/null
@@ -0,0 +1,47 @@
+From 3349ef6a366a61d631f6a263d12cea240957719d Mon Sep 17 00:00:00 2001
+From: Christian Brauner <brauner@kernel.org>
+Date: Tue, 21 Jul 2026 13:20:45 +0200
+Subject: binfmt_elf_fdpic: only honour the first PT_INTERP
+
+From: Christian Brauner <brauner@kernel.org>
+
+commit 3349ef6a366a61d631f6a263d12cea240957719d upstream.
+
+The program header scan handles PT_INTERP from a switch nested in the
+scan loop, so its break leaves the switch and not the loop. A binary
+carrying more than one PT_INTERP runs the case again and overwrites both
+interpreter_name and interpreter. The previous name allocation leaks and
+so does the previous interpreter reference, along with the write denial
+open_exec() took on it. The denial is never released, so the file stays
+unwritable for as long as the system runs.
+
+An unprivileged caller reaches this with a crafted binary and repeats it
+at will. binfmt_elf stops at the first PT_INTERP. Do the same here.
+
+The flaw dates back to the driver's introduction in the pre-git history
+tree introduced in v2.6.11 by 91808d6ebe39 ("[PATCH] FRV: Add FDPIC ELF
+binary format driver").
+
+Link: https://patch.msgid.link/20260721-gezittert-medium-kreide-b41fc1f0277e@brauner
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Reviewed-by: Jori Koolstra <jkoolstra@xs4all.nl>
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/binfmt_elf_fdpic.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/binfmt_elf_fdpic.c
++++ b/fs/binfmt_elf_fdpic.c
+@@ -231,6 +231,10 @@ static int load_elf_fdpic_binary(struct
+       for (i = 0; i < exec_params.hdr.e_phnum; i++, phdr++) {
+               switch (phdr->p_type) {
+               case PT_INTERP:
++                      /* elf ABI allows only one interpreter */
++                      if (interpreter_name)
++                              continue;
++
+                       retval = -ENOMEM;
+                       if (phdr->p_filesz > PATH_MAX)
+                               goto error;
diff --git a/queue-7.1/ceph-add-owner-capability-checks-for-ceph_ioc_set_layout.patch b/queue-7.1/ceph-add-owner-capability-checks-for-ceph_ioc_set_layout.patch
new file mode 100644 (file)
index 0000000..d549501
--- /dev/null
@@ -0,0 +1,52 @@
+From cee38bbf5556a8e0a232ccae41649580827d7806 Mon Sep 17 00:00:00 2001
+From: Max Kellermann <max.kellermann@ionos.com>
+Date: Tue, 21 Jul 2026 08:20:46 +0200
+Subject: ceph: add owner/capability checks for CEPH_IOC_SET_LAYOUT*
+
+From: Max Kellermann <max.kellermann@ionos.com>
+
+commit cee38bbf5556a8e0a232ccae41649580827d7806 upstream.
+
+These permission checks were already missing in the initial
+impementation of these ioctls.  This Ceph allows any user who owns a
+file descriptor to manipulate the layout of any file, even if they
+don't have write permissions.
+
+It might be a good idea to guard other ioctls with permission checks
+as well or even disallow regular users (even if they own the file) to
+manipulate layout settings completely, as this may be abused to DoS
+the Ceph servers, but right now, I find it most urgent to have setter
+checks at all.
+
+Cc: stable@vger.kernel.org
+Fixes: 8f4e91dee2a2 ("ceph: ioctls")
+Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
+Reviewed-by: Xiubo Li <xiubo.li@clyso.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ceph/ioctl.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/fs/ceph/ioctl.c
++++ b/fs/ceph/ioctl.c
+@@ -72,6 +72,9 @@ static long ceph_ioctl_set_layout(struct
+       struct ceph_ioctl_layout nl;
+       int err;
++      if (!inode_owner_or_capable(&nop_mnt_idmap, inode))
++              return -EACCES;
++
+       if (copy_from_user(&l, arg, sizeof(l)))
+               return -EFAULT;
+@@ -142,6 +145,9 @@ static long ceph_ioctl_set_layout_policy
+       int err;
+       struct ceph_mds_client *mdsc = ceph_sb_to_fs_client(inode->i_sb)->mdsc;
++      if (!inode_owner_or_capable(&nop_mnt_idmap, inode))
++              return -EACCES;
++
+       /* copy and validate */
+       if (copy_from_user(&l, arg, sizeof(l)))
+               return -EFAULT;
diff --git a/queue-7.1/ceph-fix-pre-auth-out-of-bounds-read-on-snaptrace-in-ceph_handle_caps.patch b/queue-7.1/ceph-fix-pre-auth-out-of-bounds-read-on-snaptrace-in-ceph_handle_caps.patch
new file mode 100644 (file)
index 0000000..fde531d
--- /dev/null
@@ -0,0 +1,72 @@
+From 4dbc71bcaf9a30abf3920a4e2cc4ed33bba78c02 Mon Sep 17 00:00:00 2001
+From: Bryam Vargas <hexlabsecurity@proton.me>
+Date: Fri, 29 May 2026 00:37:24 +0000
+Subject: ceph: fix pre-auth out-of-bounds read on snaptrace in ceph_handle_caps()
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+commit 4dbc71bcaf9a30abf3920a4e2cc4ed33bba78c02 upstream.
+
+ceph_handle_caps() reads snap_trace_len from the wire-format
+ceph_mds_caps header and uses it unconditionally to build a fake
+end pointer (snaptrace + snaptrace_len) that is later handed to
+ceph_update_snap_trace() in the CEPH_CAP_OP_IMPORT case:
+
+    snaptrace     = h + 1;
+    snaptrace_len = le32_to_cpu(h->snap_trace_len);
+    p             = snaptrace + snaptrace_len;
+    ...
+    case CEPH_CAP_OP_IMPORT:
+        if (snaptrace_len) {
+            ...
+            if (ceph_update_snap_trace(mdsc, snaptrace,
+                                       snaptrace + snaptrace_len,
+                                       false, &realm)) { ... }
+
+ceph_update_snap_trace() then decodes a struct ceph_mds_snap_realm
+from snaptrace using ceph_decode_need(&p, e, sizeof(*ri), bad)
+with the attacker-supplied fake end e == snaptrace + snaptrace_len.
+With snaptrace_len == 0xFFFFFFFF the bound check is trivially
+satisfied, ri = p reads sizeof(struct ceph_mds_snap_realm) past
+the legitimate msg->front buffer, and ri->num_snaps /
+ri->num_prior_parent_snaps then drive further out-of-bounds
+reads of the encoded snap arrays.
+
+The eleven msg_version >= 2 .. msg_version >= 12 decoder blocks
+above the op switch each catch this OOB through their
+ceph_decode_*_safe() / ceph_decode_need() helpers, but they sit
+behind a hdr.version-gated if, so a malicious or compromised
+MDS that sets msg->hdr.version = 1 reaches the IMPORT path with
+no version-gated decoder having validated snap_trace_len. The
+shape has been present since ceph_handle_caps() was introduced.
+
+Validate snap_trace_len against the message front buffer before
+consuming it, using the canonical ceph_decode_need() / ceph_has_room()
+helper.  The helper bounds the length with subtraction (n <= end - p,
+guarded by end >= p) rather than pointer addition, so it is wrap-safe
+for the attacker-controlled u32 length on 32-bit builds where
+p + snap_trace_len could overflow the address space.  This matches the
+rest of the ceph decode path (e.g. the pool_ns_len check a few lines
+below), and the existing goto bad cleanup already covers this exit
+path.
+
+Cc: stable@vger.kernel.org
+Fixes: a8599bd821d0 ("ceph: capability management")
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ceph/caps.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -4365,6 +4365,7 @@ void ceph_handle_caps(struct ceph_mds_se
+       snaptrace = h + 1;
+       snaptrace_len = le32_to_cpu(h->snap_trace_len);
++      ceph_decode_need(&snaptrace, end, snaptrace_len, bad);
+       p = snaptrace + snaptrace_len;
+       if (msg_version >= 2) {
diff --git a/queue-7.1/ceph-fix-refcount-leak-in-ceph_readdir.patch b/queue-7.1/ceph-fix-refcount-leak-in-ceph_readdir.patch
new file mode 100644 (file)
index 0000000..c2ba7c1
--- /dev/null
@@ -0,0 +1,51 @@
+From c3e64079d8b9663e3998d0caac9aba915b6b93ae Mon Sep 17 00:00:00 2001
+From: WenTao Liang <vulab@iscas.ac.cn>
+Date: Thu, 11 Jun 2026 22:40:07 +0800
+Subject: ceph: fix refcount leak in ceph_readdir()
+
+From: WenTao Liang <vulab@iscas.ac.cn>
+
+commit c3e64079d8b9663e3998d0caac9aba915b6b93ae upstream.
+
+The ceph_readdir() function allocates a ceph_mds_request via
+ceph_mdsc_create_request() and stores it in dfi->last_readdir. In
+the directory entry processing loop, if the entry's offset is less
+than ctx->pos or if the inode pointer is unexpectedly NULL, the
+function returns -EIO without releasing the reference held by
+dfi->last_readdir, causing a refcount leak.
+
+Fix this by adding ceph_mdsc_put_request(dfi->last_readdir) before
+returning on these error paths. Also set dfi->last_readdir to NULL
+for safety, matching the cleanup done at the normal exit.
+
+Cc: stable@vger.kernel.org
+Fixes: af9ffa6df7e3 ("ceph: add support to readdir for encrypted names")
+Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
+Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Reviewed-by: Alex Markuze <amarkuze@redhat.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ceph/dir.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/fs/ceph/dir.c
++++ b/fs/ceph/dir.c
+@@ -546,11 +546,16 @@ more:
+                       pr_warn_client(cl,
+                               "%p %llx.%llx rde->offset 0x%llx ctx->pos 0x%llx\n",
+                               inode, ceph_vinop(inode), rde->offset, ctx->pos);
++                      ceph_mdsc_put_request(dfi->last_readdir);
++                      dfi->last_readdir = NULL;
+                       return -EIO;
+               }
+-              if (WARN_ON_ONCE(!rde->inode.in))
++              if (WARN_ON_ONCE(!rde->inode.in)) {
++                      ceph_mdsc_put_request(dfi->last_readdir);
++                      dfi->last_readdir = NULL;
+                       return -EIO;
++              }
+               ctx->pos = rde->offset;
+               doutc(cl, "%p %llx.%llx (%d/%d) -> %llx '%.*s' %p\n", inode,
diff --git a/queue-7.1/ceph-fix-writeback_count-leak-in-write_folio_nounlock.patch b/queue-7.1/ceph-fix-writeback_count-leak-in-write_folio_nounlock.patch
new file mode 100644 (file)
index 0000000..47a696a
--- /dev/null
@@ -0,0 +1,64 @@
+From cbf59617cd715219e84c50d106a3d0e1e8ba054e Mon Sep 17 00:00:00 2001
+From: Wentao Liang <vulab@iscas.ac.cn>
+Date: Thu, 4 Jun 2026 02:19:51 +0000
+Subject: ceph: fix writeback_count leak in write_folio_nounlock()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+commit cbf59617cd715219e84c50d106a3d0e1e8ba054e upstream.
+
+write_folio_nounlock() increments fsc->writeback_count to track
+in-flight writeback operations. On several error paths where the
+function returns early (folio lookup failure, snapshot context
+allocation failure, and writepages submission failure), the function
+returns without calling atomic_long_dec_return() to decrement the
+counter.
+
+Each leaked increment keeps the counter above zero, which can prevent
+the filesystem from cleanly unmounting or suspending writes.
+
+Add atomic_long_dec_return() calls on all error paths that currently
+return without decrementing the counter.
+
+Cc: stable@vger.kernel.org
+Fixes: d55207717ded ("ceph: add encryption support to writepage and writepages")
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ceph/addr.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/fs/ceph/addr.c
++++ b/fs/ceph/addr.c
+@@ -790,6 +790,9 @@ static int write_folio_nounlock(struct f
+                                   ceph_wbc.truncate_size, true);
+       if (IS_ERR(req)) {
+               folio_redirty_for_writepage(wbc, folio);
++              if (atomic_long_dec_return(&fsc->writeback_count) <
++                              CONGESTION_OFF_THRESH(fsc->mount_options->congestion_kb))
++                      fsc->write_congested = false;
+               return PTR_ERR(req);
+       }
+@@ -809,6 +812,9 @@ static int write_folio_nounlock(struct f
+                       folio_redirty_for_writepage(wbc, folio);
+                       folio_end_writeback(folio);
+                       ceph_osdc_put_request(req);
++                      if (atomic_long_dec_return(&fsc->writeback_count) <
++                                      CONGESTION_OFF_THRESH(fsc->mount_options->congestion_kb))
++                              fsc->write_congested = false;
+                       return PTR_ERR(bounce_page);
+               }
+       }
+@@ -847,6 +853,9 @@ static int write_folio_nounlock(struct f
+                             ceph_vinop(inode), folio);
+                       folio_redirty_for_writepage(wbc, folio);
+                       folio_end_writeback(folio);
++                      if (atomic_long_dec_return(&fsc->writeback_count) <
++                                      CONGESTION_OFF_THRESH(fsc->mount_options->congestion_kb))
++                              fsc->write_congested = false;
+                       return err;
+               }
+               if (err == -EBLOCKLISTED)
diff --git a/queue-7.1/fs-preserve-acl_dont_cache-state-in-forget_cached_acl.patch b/queue-7.1/fs-preserve-acl_dont_cache-state-in-forget_cached_acl.patch
new file mode 100644 (file)
index 0000000..3d38e6a
--- /dev/null
@@ -0,0 +1,57 @@
+From 4b9a5458d02e214ef2b384124ca626e3e381d778 Mon Sep 17 00:00:00 2001
+From: Amir Goldstein <amir73il@gmail.com>
+Date: Tue, 14 Jul 2026 00:09:31 +0200
+Subject: fs: preserve ACL_DONT_CACHE state in forget_cached_acl()
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+commit 4b9a5458d02e214ef2b384124ca626e3e381d778 upstream.
+
+The ACL_DONT_CACHE state is meant to be a constant state for the inode
+for filesystems that want to opt out of posix acl caching.
+
+Commit facd61053cff1 ("fuse: fixes after adapting to new posix acl api")
+used this facility to opt out of posix acl caching for fuse inodes with
+fuse server that does not negotiate FUSE_POSIX_ACL (fc->posix_acl).
+
+The commit also takes care to gate the forget_all_cached_acls() call in
+fuse_set_acl() on fc->posix_acl because there is no need for it, but
+there are other placed in fuse code which call forget_all_cached_acls()
+unconditional to fc->posix_acl and those cause the loss of the
+ACL_DONT_CACHE state.
+
+This is not only a functional bug. Properly timed, a get_acl() from this
+fuse filesystem can return a stale cached value, as was observed in tests,
+because set_acl() does not invalidate the unintentional acl cache.
+
+We could fix this in fuse, but it actually makes no sense for the vfs
+helper forget_cached_acl() to invalidate the ACL_DONT_CACHE state, so
+let it not do that to fix fuse and future users of ACL_DONT_CACHE.
+
+Fixes: facd61053cff1 ("fuse: fixes after adapting to new posix acl api")
+Cc: stable@vger.kernel.org
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Link: https://patch.msgid.link/20260713220932.413004-2-amir73il@gmail.com
+Reviewed-by: Luis Henriques <luis@igalia.com>
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/posix_acl.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/fs/posix_acl.c
++++ b/fs/posix_acl.c
+@@ -93,6 +93,13 @@ static void __forget_cached_acl(struct p
+ {
+       struct posix_acl *old;
++      /*
++       * ACL_DONT_CACHE is expected to be a "const" value and xchg it with
++       * ACL_NOT_CACHED would enable acl caching for the inode -
++       * clearly not what the caller has intended.
++       */
++      if (READ_ONCE(*p) == ACL_DONT_CACHE)
++              return;
+       old = xchg(p, ACL_NOT_CACHED);
+       if (!is_uncached_acl(old))
+               posix_acl_release(old);
diff --git a/queue-7.1/fs-super-fix-emergency-thaw-double-unlock-of-s_umount.patch b/queue-7.1/fs-super-fix-emergency-thaw-double-unlock-of-s_umount.patch
new file mode 100644 (file)
index 0000000..a1c83a8
--- /dev/null
@@ -0,0 +1,95 @@
+From 503d67fbaec6fdeaba391cb497675071db9d16ea Mon Sep 17 00:00:00 2001
+From: Chen Changcheng <chenchangcheng@kylinos.cn>
+Date: Tue, 21 Jul 2026 14:41:40 +0800
+Subject: fs/super: fix emergency thaw double-unlock of s_umount
+
+From: Chen Changcheng <chenchangcheng@kylinos.cn>
+
+commit 503d67fbaec6fdeaba391cb497675071db9d16ea upstream.
+
+do_thaw_all() iterates over all superblocks via __iterate_supers()
+with SUPER_ITER_EXCL, which acquires s_umount exclusively before
+calling the callback and releases it afterwards. However, the
+callback do_thaw_all_callback() calls thaw_super_locked() which
+unconditionally releases s_umount on every code path. This results
+in a second unlock attempt in __iterate_supers() that corrupts the
+rwsem state, triggering a DEBUG_RWSEMS warning:
+
+[  182.601148] sysrq: Emergency Thaw of all frozen filesystems
+[  182.601865] ------------[ cut here ]------------
+[  182.602375] DEBUG_RWSEMS_WARN_ON((rwsem_owner(sem) != current) && !rwsem_test_oflags(sem, RWSEM_NONSPINNABLE)): count = 0x0, magic = 0xffff99b1011e5870, owner = 0x0, curr 0xffff99b101b06c80, list not empty
+[  182.603817] WARNING: kernel/locking/rwsem.c:1412 at up_write+0xa3/0x170, CPU#2: kworker/2:1/53
+[  182.604578] Modules linked in:
+[  182.604864] CPU: 2 UID: 0 PID: 53 Comm: kworker/2:1 Not tainted 7.2.0-rc4-00001-gbd3bd93ea98a-dirty #4 PREEMPT(lazy)
+[  182.605711] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1kylin1 04/01/2014
+[  182.606417] Workqueue: events do_thaw_all
+[  182.606750] RIP: 0010:up_write+0xaf/0x170
+[  182.607076] Code: 19 3a 92 48 0f 44 c2 48 8b 55 08 48 8b 55 00 4c 8b 45 08 48 8b 55 00 48 8d 3d ad 91 e0 01 48 8b 4d 20 50 48 c7 c6 f0 8c 26 92 <67> 48 0f b9 3a e8 d7 93 4e 00 58 eb 81 48 83 7f 18 00 48 c7 c2 8d
+[  182.608563] RSP: 0018:ffffb670001d7e08 EFLAGS: 00010246
+[  182.609007] RAX: ffffffff92349e8d RBX: 0000000000000000 RCX: ffff99b1011e5870
+[  182.609595] RDX: 0000000000000000 RSI: ffffffff92268cf0 RDI: ffffffff92914d10
+[  182.610283] RBP: ffff99b1011e5870 R08: 0000000000000000 R09: ffff99b101b06c80
+[  182.610847] R10: ffff99b10139a808 R11: fefefefefefefeff R12: 0000000000000000
+[  182.611414] R13: ffffffff90cf74d0 R14: 0000000000000000 R15: ffff99b1011e5800
+[  182.612009] FS:  0000000000000000(0000) GS:ffff99b1eaaee000(0000) knlGS:0000000000000000
+[  182.612670] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  182.613146] CR2: 00000000005c631c CR3: 00000000013ee000 CR4: 00000000000006f0
+[  182.613722] Call Trace:
+[  182.613946]  <TASK>
+[  182.614130]  __iterate_supers+0x128/0x150
+[  182.614463]  do_thaw_all+0x1b/0x30
+[  182.614759]  process_scheduled_works+0xbb/0x3f0
+[  182.615150]  ? __pfx_worker_thread+0x10/0x10
+[  182.615499]  worker_thread+0x129/0x270
+[  182.615816]  ? __pfx_worker_thread+0x10/0x10
+[  182.616201]  kthread+0xe2/0x120
+[  182.616469]  ? __pfx_kthread+0x10/0x10
+[  182.616792]  ret_from_fork+0x15b/0x240
+[  182.617115]  ? __pfx_kthread+0x10/0x10
+[  182.617426]  ret_from_fork_asm+0x1a/0x30
+[  182.617761]  </TASK>
+[  182.617968] ---[ end trace 0000000000000000 ]---
+[  182.618412] Emergency Thaw complete
+
+Fix this by switching to SUPER_ITER_UNLOCKED and acquiring s_umount
+in the callback via super_lock_excl() before calling
+thaw_super_locked(). This matches the locking pattern expected by
+thaw_super_locked() and eliminates the double unlock.
+
+While at it, remove the dead 'return;' at the end of
+do_thaw_all_callback().
+
+Fixes: 2992476528ae ("super: use a common iterator (Part 1)")
+Cc: stable@vger.kernel.org
+Signed-off-by: Chen Changcheng <chenchangcheng@kylinos.cn>
+Link: https://patch.msgid.link/20260721064140.152305-1-chenchangcheng@kylinos.cn
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/super.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/fs/super.c
++++ b/fs/super.c
+@@ -1145,16 +1145,19 @@ void emergency_remount(void)
+ static void do_thaw_all_callback(struct super_block *sb, void *unused)
+ {
++      if (!super_lock_excl(sb))
++              return;
++
+       if (IS_ENABLED(CONFIG_BLOCK))
+               while (sb->s_bdev && !bdev_thaw(sb->s_bdev))
+                       pr_warn("Emergency Thaw on %pg\n", sb->s_bdev);
++
+       thaw_super_locked(sb, FREEZE_HOLDER_USERSPACE, NULL);
+-      return;
+ }
+ static void do_thaw_all(struct work_struct *work)
+ {
+-      __iterate_supers(do_thaw_all_callback, NULL, SUPER_ITER_EXCL);
++      __iterate_supers(do_thaw_all_callback, NULL, SUPER_ITER_UNLOCKED);
+       kfree(work);
+       printk(KERN_WARNING "Emergency Thaw complete\n");
+ }
diff --git a/queue-7.1/fscrypt-add-missing-superblock-check-in-find_or_insert_direct_key.patch b/queue-7.1/fscrypt-add-missing-superblock-check-in-find_or_insert_direct_key.patch
new file mode 100644 (file)
index 0000000..e83afbc
--- /dev/null
@@ -0,0 +1,66 @@
+From b5fa40226e71c17847b9ff2816c6ca4133d0d994 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@kernel.org>
+Date: Sat, 18 Jul 2026 20:31:20 -0700
+Subject: fscrypt: Add missing superblock check in find_or_insert_direct_key()
+
+From: Eric Biggers <ebiggers@kernel.org>
+
+commit b5fa40226e71c17847b9ff2816c6ca4133d0d994 upstream.
+
+The legacy 'fscrypt_direct_keys' table caches master keys that are used
+by v1 encryption policies that have FSCRYPT_POLICY_FLAG_DIRECT_KEY.
+It's just a global table for all filesystems (since the keys can be
+provided by the legacy process-subscribed keyrings mechanism, which
+makes it difficult to reuse super_block::s_master_keys).
+
+The entries in it ('struct fscrypt_direct_key') do contain a super_block
+pointer, though, for passing to fscrypt_destroy_inline_crypt_key() when
+the last inode that references the key is evicted.
+
+However, when finding the fscrypt_direct_key for an inode, we weren't
+actually comparing the super_block pointer.  As a result, inodes with
+different super_blocks could point to the same fscrypt_direct_key.  That
+could extend the lifetime of a fscrypt_direct_key beyond the
+super_block it points to, causing a use-after-free later.
+
+Fix this by creating distinct fscrypt_direct_key structs for distinct
+super_block structs.
+
+Note that this problem doesn't exist in the v2 policy equivalent
+("per-mode keys"), since the data structures there are per super_block.
+
+Fixes: 22e9947a4b2b ("fscrypt: stop holding extra request_queue references")
+Cc: stable@vger.kernel.org
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Closes: https://sashiko.dev/#/patchset/20260717044303.425265-1-ebiggers%40kernel.org
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://patch.msgid.link/20260719033120.122120-1-ebiggers@kernel.org
+Signed-off-by: Eric Biggers <ebiggers@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/crypto/keysetup_v1.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/fs/crypto/keysetup_v1.c
++++ b/fs/crypto/keysetup_v1.c
+@@ -147,13 +147,19 @@ find_or_insert_direct_key(struct fscrypt
+               if (memcmp(ci->ci_policy.v1.master_key_descriptor,
+                          dk->dk_descriptor, FSCRYPT_KEY_DESCRIPTOR_SIZE) != 0)
+                       continue;
++              /* The sb is used at eviction time, so it must be the same. */
++              if (ci->ci_inode->i_sb != dk->dk_sb)
++                      continue;
+               if (ci->ci_mode != dk->dk_mode)
+                       continue;
+               if (!fscrypt_is_key_prepared(&dk->dk_key, ci))
+                       continue;
+               if (crypto_memneq(raw_key, dk->dk_raw, ci->ci_mode->keysize))
+                       continue;
+-              /* using existing tfm with same (descriptor, mode, raw_key) */
++              /*
++               * Use an existing prepared key with the same (descriptor, sb,
++               * mode, inlinecrypt, raw_key) combination.
++               */
+               refcount_inc(&dk->dk_refcount);
+               spin_unlock(&fscrypt_direct_keys_lock);
+               free_direct_key(to_insert);
diff --git a/queue-7.1/fscrypt-avoid-dynamic-allocation-in-fscrypt_get_devices.patch b/queue-7.1/fscrypt-avoid-dynamic-allocation-in-fscrypt_get_devices.patch
new file mode 100644 (file)
index 0000000..9a8ff1b
--- /dev/null
@@ -0,0 +1,253 @@
+From 6fe4e4b8259e1330945b5f3c9476e08473b8e0e8 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@kernel.org>
+Date: Sat, 18 Jul 2026 22:56:02 -0700
+Subject: fscrypt: Avoid dynamic allocation in fscrypt_get_devices()
+
+From: Eric Biggers <ebiggers@kernel.org>
+
+commit 6fe4e4b8259e1330945b5f3c9476e08473b8e0e8 upstream.
+
+When a blk_crypto_key starts being used or is evicted, fs/crypto/ calls
+fscrypt_get_devices() to get the filesystem's list of block devices,
+then iterates over them and calls blk_crypto_config_supported(),
+blk_crypto_start_using_key(), or blk_crypto_evict_key() on each one.
+
+Currently, the block device pointers are placed in a dynamically
+allocated array.  This dynamic allocation is problematic because:
+
+- It can fail, especially at the fscrypt_destroy_inline_crypt_key() call
+  site when it's invoked for inode eviction under direct reclaim.
+
+- fscrypt_destroy_inline_crypt_key() doesn't handle the failure.  It
+  just zeroizes and frees the blk_crypto_key without calling
+  blk_crypto_evict_key().  That causes a use-after-free.
+
+For now, let's fix this in the straightforward and easily-backportable
+way by switching to an on-stack array.  Currently the fscrypt
+multi-device functionality is used only by f2fs, which has a hardcoded
+limit of 8 block devices.  An on-stack array works fine for that.
+
+(Of course, this solution won't scale up to large number of block
+devices.  For that we'd need a different solution, like moving the block
+device iteration into the filesystem.  Or in the case of btrfs, which
+will only support blk-crypto-fallback, we should make it just call
+blk-crypto-fallback directly, so the block devices won't be needed.)
+
+Fixes: 22e9947a4b2b ("fscrypt: stop holding extra request_queue references")
+Cc: stable@vger.kernel.org
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Closes: https://sashiko.dev/#/patchset/20260713023708.9245-1-ebiggers%40kernel.org
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://patch.msgid.link/20260719055602.78828-1-ebiggers@kernel.org
+Signed-off-by: Eric Biggers <ebiggers@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/crypto/inline_crypt.c |   57 ++++++++++++++++-------------------------------
+ fs/f2fs/super.c          |   25 +++++++++++---------
+ include/linux/fscrypt.h  |   20 +++++++++-------
+ 3 files changed, 45 insertions(+), 57 deletions(-)
+
+--- a/fs/crypto/inline_crypt.c
++++ b/fs/crypto/inline_crypt.c
+@@ -22,22 +22,14 @@
+ #include "fscrypt_private.h"
+-static struct block_device **fscrypt_get_devices(struct super_block *sb,
+-                                               unsigned int *num_devs)
++static unsigned int
++fscrypt_get_devices(struct super_block *sb,
++                  struct block_device *devs[FSCRYPT_MAX_DEVICES])
+ {
+-      struct block_device **devs;
+-
+-      if (sb->s_cop->get_devices) {
+-              devs = sb->s_cop->get_devices(sb, num_devs);
+-              if (devs)
+-                      return devs;
+-      }
+-      devs = kmalloc_obj(*devs);
+-      if (!devs)
+-              return ERR_PTR(-ENOMEM);
++      if (sb->s_cop->get_devices)
++              return sb->s_cop->get_devices(sb, devs);
+       devs[0] = sb->s_bdev;
+-      *num_devs = 1;
+-      return devs;
++      return 1;
+ }
+ static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_inode_info *ci)
+@@ -96,7 +88,7 @@ int fscrypt_select_encryption_impl(struc
+       const struct inode *inode = ci->ci_inode;
+       struct super_block *sb = inode->i_sb;
+       struct blk_crypto_config crypto_cfg;
+-      struct block_device **devs;
++      struct block_device *devs[FSCRYPT_MAX_DEVICES];
+       unsigned int num_devs;
+       unsigned int i;
+@@ -135,20 +127,15 @@ int fscrypt_select_encryption_impl(struc
+       crypto_cfg.key_type = is_hw_wrapped_key ?
+               BLK_CRYPTO_KEY_TYPE_HW_WRAPPED : BLK_CRYPTO_KEY_TYPE_RAW;
+-      devs = fscrypt_get_devices(sb, &num_devs);
+-      if (IS_ERR(devs))
+-              return PTR_ERR(devs);
+-
++      num_devs = fscrypt_get_devices(sb, devs);
+       for (i = 0; i < num_devs; i++) {
+               if (!blk_crypto_config_supported(devs[i], &crypto_cfg))
+-                      goto out_free_devs;
++                      return 0;
+       }
+       fscrypt_log_blk_crypto_impl(ci->ci_mode, devs, num_devs, &crypto_cfg);
+       ci->ci_inlinecrypt = true;
+-out_free_devs:
+-      kfree(devs);
+       return 0;
+ }
+@@ -164,7 +151,7 @@ int fscrypt_prepare_inline_crypt_key(str
+       enum blk_crypto_key_type key_type = is_hw_wrapped ?
+               BLK_CRYPTO_KEY_TYPE_HW_WRAPPED : BLK_CRYPTO_KEY_TYPE_RAW;
+       struct blk_crypto_key *blk_key;
+-      struct block_device **devs;
++      struct block_device *devs[FSCRYPT_MAX_DEVICES];
+       unsigned int num_devs;
+       unsigned int i;
+       int err;
+@@ -182,17 +169,12 @@ int fscrypt_prepare_inline_crypt_key(str
+       }
+       /* Start using blk-crypto on all the filesystem's block devices. */
+-      devs = fscrypt_get_devices(sb, &num_devs);
+-      if (IS_ERR(devs)) {
+-              err = PTR_ERR(devs);
+-              goto fail;
+-      }
++      num_devs = fscrypt_get_devices(sb, devs);
+       for (i = 0; i < num_devs; i++) {
+               err = blk_crypto_start_using_key(devs[i], blk_key);
+               if (err)
+                       break;
+       }
+-      kfree(devs);
+       if (err) {
+               fscrypt_err(inode, "error %d starting to use blk-crypto", err);
+               goto fail;
+@@ -210,20 +192,21 @@ void fscrypt_destroy_inline_crypt_key(st
+                                     struct fscrypt_prepared_key *prep_key)
+ {
+       struct blk_crypto_key *blk_key = prep_key->blk_key;
+-      struct block_device **devs;
++      struct block_device *devs[FSCRYPT_MAX_DEVICES];
+       unsigned int num_devs;
+       unsigned int i;
+       if (!blk_key)
+               return;
+-      /* Evict the key from all the filesystem's block devices. */
+-      devs = fscrypt_get_devices(sb, &num_devs);
+-      if (!IS_ERR(devs)) {
+-              for (i = 0; i < num_devs; i++)
+-                      blk_crypto_evict_key(devs[i], blk_key);
+-              kfree(devs);
+-      }
++      /*
++       * Evict the key from all the filesystem's block devices.
++       * This *must* be done before the key is freed.
++       */
++      num_devs = fscrypt_get_devices(sb, devs);
++      for (i = 0; i < num_devs; i++)
++              blk_crypto_evict_key(devs[i], blk_key);
++
+       kfree_sensitive(blk_key);
+ }
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -3731,24 +3731,27 @@ static bool f2fs_has_stable_inodes(struc
+       return true;
+ }
+-static struct block_device **f2fs_get_devices(struct super_block *sb,
+-                                            unsigned int *num_devs)
++static unsigned int
++f2fs_get_devices(struct super_block *sb,
++               struct block_device *devs[FSCRYPT_MAX_DEVICES])
+ {
+       struct f2fs_sb_info *sbi = F2FS_SB(sb);
+-      struct block_device **devs;
++      int ndevs;
+       int i;
+-      if (!f2fs_is_multi_device(sbi))
+-              return NULL;
++      static_assert(MAX_DEVICES <= FSCRYPT_MAX_DEVICES);
+-      devs = kmalloc_objs(*devs, sbi->s_ndevs);
+-      if (!devs)
+-              return ERR_PTR(-ENOMEM);
++      if (!f2fs_is_multi_device(sbi)) {
++              devs[0] = sb->s_bdev;
++              return 1;
++      }
++      ndevs = sbi->s_ndevs;
++      if (WARN_ON_ONCE(ndevs > FSCRYPT_MAX_DEVICES))
++              ndevs = FSCRYPT_MAX_DEVICES;
+-      for (i = 0; i < sbi->s_ndevs; i++)
++      for (i = 0; i < ndevs; i++)
+               devs[i] = FDEV(i).bdev;
+-      *num_devs = sbi->s_ndevs;
+-      return devs;
++      return ndevs;
+ }
+ static const struct fscrypt_operations f2fs_cryptops = {
+--- a/include/linux/fscrypt.h
++++ b/include/linux/fscrypt.h
+@@ -57,6 +57,9 @@ struct fscrypt_name {
+ /* Maximum value for the third parameter of fscrypt_operations.set_context(). */
+ #define FSCRYPT_SET_CONTEXT_MAX_SIZE  40
++/* Maximum supported number of block devices per filesystem */
++#define FSCRYPT_MAX_DEVICES   8
++
+ #ifdef CONFIG_FS_ENCRYPTION
+ /* Crypto operations for filesystems */
+@@ -181,21 +184,20 @@ struct fscrypt_operations {
+       bool (*has_stable_inodes)(struct super_block *sb);
+       /*
+-       * Return an array of pointers to the block devices to which the
+-       * filesystem may write encrypted file contents, NULL if the filesystem
+-       * only has a single such block device, or an ERR_PTR() on error.
+-       *
+-       * On successful non-NULL return, *num_devs is set to the number of
+-       * devices in the returned array.  The caller must free the returned
+-       * array using kfree().
++       * Retrieve the list of block devices to which the filesystem may write
++       * encrypted file contents.
++       *
++       * This writes the block_device pointers to @devs and returns the count
++       * (between 1 and FSCRYPT_MAX_DEVICES inclusively).
+        *
+        * If the filesystem can use multiple block devices (other than block
+        * devices that aren't used for encrypted file contents, such as
+        * external journal devices), and wants to support inline encryption,
+        * then it must implement this function.  Otherwise it's not needed.
+        */
+-      struct block_device **(*get_devices)(struct super_block *sb,
+-                                           unsigned int *num_devs);
++      unsigned int (*get_devices)(
++              struct super_block *sb,
++              struct block_device *devs[FSCRYPT_MAX_DEVICES]);
+ };
+ int fscrypt_d_revalidate(struct inode *dir, const struct qstr *name,
diff --git a/queue-7.1/ftrace-add-global-mutex-to-serialize-trace_parser-access.patch b/queue-7.1/ftrace-add-global-mutex-to-serialize-trace_parser-access.patch
new file mode 100644 (file)
index 0000000..58c2c52
--- /dev/null
@@ -0,0 +1,98 @@
+From 7720b63bcef3f54c7fe288774b720a227d54a306 Mon Sep 17 00:00:00 2001
+From: Tengda Wu <wutengda@huaweicloud.com>
+Date: Sat, 25 Jul 2026 02:47:21 +0000
+Subject: ftrace: Add global mutex to serialize trace_parser access
+
+From: Tengda Wu <wutengda@huaweicloud.com>
+
+commit 7720b63bcef3f54c7fe288774b720a227d54a306 upstream.
+
+In ftrace, the trace_parser structure is allocated and initialized when
+a trace file is opened, and is subsequently used across write and release
+handlers to parse user input.
+
+The affected handler paths and their specific functions are:
+  - Open paths: ftrace_regex_open(), ftrace_graph_open()
+  - Write paths: ftrace_regex_write(), ftrace_graph_write()
+  - Release paths: ftrace_regex_release(), ftrace_graph_release()
+
+If userspace opens a trace file descriptor and shares it across multiple
+threads, concurrent write calls will race on the parser's internal state,
+specifically the 'idx', 'cont', and 'buffer' fields, leading to corrupted
+input or undefined behavior.
+
+Fix this by adding a global mutex, parser_lock, to serialize all access
+to trace_parser across write and release paths, preventing concurrent
+corruption of parser state.
+
+Fixes: e704eff3ff51 ("ftrace: Have set_graph_function handle multiple functions in one write")
+Fixes: 689fd8b65d66 ("tracing: trace parser support for function and graph")
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260725024721.1983675-1-wutengda@huaweicloud.com
+Signed-off-by: Tengda Wu <wutengda@huaweicloud.com>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/ftrace.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -1098,6 +1098,12 @@ struct ftrace_ops global_ops = {
+ };
+ /*
++ * parser_lock - Protects trace_parser state against concurrent operations.
++ * Held across trace_get_user() and subsequent buffer parsing to prevent races.
++ */
++static DEFINE_MUTEX(parser_lock);
++
++/*
+  * Used by the stack unwinder to know about dynamic ftrace trampolines.
+  */
+ struct ftrace_ops *ftrace_ops_trampoline(unsigned long addr)
+@@ -5824,6 +5830,8 @@ ftrace_regex_write(struct file *file, co
+       /* iter->hash is a local copy, so we don't need regex_lock */
+       parser = &iter->parser;
++
++      guard(mutex)(&parser_lock);
+       read = trace_get_user(parser, ubuf, cnt, ppos);
+       if (read >= 0 && trace_parser_loaded(parser) &&
+@@ -6961,12 +6969,14 @@ int ftrace_regex_release(struct inode *i
+               iter = file->private_data;
+       parser = &iter->parser;
++      mutex_lock(&parser_lock);
+       if (trace_parser_loaded(parser)) {
+               int enable = !(iter->flags & FTRACE_ITER_NOTRACE);
+               ftrace_process_regex(iter, parser->buffer,
+                                    parser->idx, enable);
+       }
++      mutex_unlock(&parser_lock);
+       trace_parser_put(parser);
+@@ -7298,10 +7308,12 @@ ftrace_graph_release(struct inode *inode
+               parser = &fgd->parser;
++              mutex_lock(&parser_lock);
+               if (trace_parser_loaded((parser))) {
+                       ret = ftrace_graph_set_hash(fgd->new_hash,
+                                                   parser->buffer);
+               }
++              mutex_unlock(&parser_lock);
+               trace_parser_put(parser);
+@@ -7414,6 +7426,7 @@ ftrace_graph_write(struct file *file, co
+       parser = &fgd->parser;
++      guard(mutex)(&parser_lock);
+       read = trace_get_user(parser, ubuf, cnt, ppos);
+       if (read >= 0 && trace_parser_loaded(parser) &&
diff --git a/queue-7.1/geneve-require-cap_net_admin-in-the-device-netns-for-changelink.patch b/queue-7.1/geneve-require-cap_net_admin-in-the-device-netns-for-changelink.patch
new file mode 100644 (file)
index 0000000..d0367ad
--- /dev/null
@@ -0,0 +1,52 @@
+From 8efb8f8bbb353b8f2fdf4f37534c6d96c9f69e01 Mon Sep 17 00:00:00 2001
+From: Doruk Tan Ozturk <doruk@0sec.ai>
+Date: Thu, 16 Jul 2026 22:35:00 +0200
+Subject: geneve: require CAP_NET_ADMIN in the device netns for changelink
+
+From: Doruk Tan Ozturk <doruk@0sec.ai>
+
+commit 8efb8f8bbb353b8f2fdf4f37534c6d96c9f69e01 upstream.
+
+A tunnel changelink() operates on at most two netns, dev_net(dev) and
+the sticky underlay netns geneve->net. They differ once the device is
+created in or moved to a netns other than the one the request runs in.
+The rtnl changelink path checks CAP_NET_ADMIN only against dev_net(dev),
+so a caller privileged there but not in geneve->net can rewrite a geneve
+device whose underlay lives in geneve->net.
+
+geneve_changelink() applies the new configuration against geneve->net:
+geneve_link_config() and the geneve_quiesce()/geneve_unquiesce() pair
+reopen the underlay sockets in that netns (geneve_sock_add() uses
+geneve->net), so the same reasoning as the tunnel changelink series
+applies here.
+
+Gate geneve_changelink() with rtnl_dev_link_net_capable(), at the top of
+the op before any attribute is parsed, matching ipgre_changelink() and
+the rest of the "require CAP_NET_ADMIN in the device netns for
+changelink" series.
+
+Found by 0sec automated security-research tooling (https://0sec.ai).
+
+Fixes: 5b861f6baa3a ("geneve: add rtnl changelink support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260716203500.70573-3-doruk@0sec.ai
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/geneve.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -2251,6 +2251,9 @@ static int geneve_changelink(struct net_
+       struct geneve_config cfg;
+       int err;
++      if (!rtnl_dev_link_net_capable(dev, geneve->net))
++              return -EPERM;
++
+       /* If the geneve device is configured for metadata (or externally
+        * controlled, for example, OVS), then nothing can be changed.
+        */
diff --git a/queue-7.1/ice-fix-ptp-call-trace-during-ptp-release.patch b/queue-7.1/ice-fix-ptp-call-trace-during-ptp-release.patch
new file mode 100644 (file)
index 0000000..52bb870
--- /dev/null
@@ -0,0 +1,54 @@
+From f6a7e00b81e35ef1325234925f2fe1e53b466f92 Mon Sep 17 00:00:00 2001
+From: Paul Greenwalt <paul.greenwalt@intel.com>
+Date: Fri, 17 Jul 2026 11:53:31 -0700
+Subject: ice: fix PTP Call Trace during PTP release
+
+From: Paul Greenwalt <paul.greenwalt@intel.com>
+
+commit f6a7e00b81e35ef1325234925f2fe1e53b466f92 upstream.
+
+If a PF reset occurs when the PTP state is ICE_PTP_UNINIT, then
+ice_ptp_rebuild() will update the state to ICE_PTP_ERROR. This will
+result in the following PTP release call trace during driver unload:
+
+    kernel BUG at lib/list_debug.c:52!
+    ice_ptp_release+0x332/0x3c0 [ice]
+    ice_deinit_features.part.0+0x10e/0x120 [ice]
+    ice_remove+0x100/0x220 [ice]
+
+This was observed when passing PF1 through to a VM. ice_ptp_init()
+fails because ctrl_pf is NULL and sets the state to ICE_PTP_UNINIT.
+
+Fix by detecting the ICE_PTP_UNINIT state in ice_ptp_rebuild() and
+returning without error, preventing the invalid state transition to
+ICE_PTP_ERROR. The only valid path to ICE_PTP_ERROR is from
+ICE_PTP_RESETTING after a failed rebuild.
+
+Fixes: 8293e4cb2ff5 ("ice: introduce PTP state machine")
+Cc: stable@vger.kernel.org
+Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com>
+Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Link: https://patch.msgid.link/20260717185340.3595286-10-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ice/ice_ptp.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
+@@ -3035,6 +3035,11 @@ void ice_ptp_rebuild(struct ice_pf *pf,
+       struct ice_ptp *ptp = &pf->ptp;
+       int err;
++      if (ptp->state == ICE_PTP_UNINIT) {
++              dev_dbg(ice_pf_to_dev(pf), "PTP was not initialized, skipping rebuild\n");
++              return;
++      }
++
+       if (ptp->state == ICE_PTP_READY) {
+               ice_ptp_prepare_for_reset(pf, reset_type);
+       } else if (ptp->state != ICE_PTP_RESETTING) {
diff --git a/queue-7.1/io_uring-rw-fix-missing-erestartsys-conversion-in-read-paths.patch b/queue-7.1/io_uring-rw-fix-missing-erestartsys-conversion-in-read-paths.patch
new file mode 100644 (file)
index 0000000..8323df6
--- /dev/null
@@ -0,0 +1,100 @@
+From ab05caca123c6d0b41850b7c05b246e4dca4a770 Mon Sep 17 00:00:00 2001
+From: Yitang Yang <yi1tang.yang@gmail.com>
+Date: Wed, 22 Jul 2026 20:45:51 +0800
+Subject: io_uring/rw: fix missing ERESTARTSYS conversion in read paths
+
+From: Yitang Yang <yi1tang.yang@gmail.com>
+
+commit ab05caca123c6d0b41850b7c05b246e4dca4a770 upstream.
+
+Both read and write may receive internal restart error codes from
+the filesystem layer and should be converted to -EINTR. However,
+when multishot read support was added, the error code normalization
+was lost for both io_read() and io_read_mshot().
+
+Extract the conversion into io_fixup_restart_res() and apply it
+in all three locations: io_rw_done(), io_read(), and io_read_mshot().
+
+Fixes: a08d195b586a ("io_uring/rw: split io_read() into a helper")
+Cc: stable@vger.kernel.org
+Signed-off-by: Yitang Yang <yi1tang.yang@gmail.com>
+Link: https://patch.msgid.link/20260722124551.130563-1-yi1tang.yang@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ io_uring/rw.c |   42 +++++++++++++++++++++++++-----------------
+ 1 file changed, 25 insertions(+), 17 deletions(-)
+
+--- a/io_uring/rw.c
++++ b/io_uring/rw.c
+@@ -615,6 +615,24 @@ static void io_complete_rw_iopoll(struct
+       smp_store_release(&req->iopoll_completed, 1);
+ }
++static inline ssize_t io_fixup_restart_res(ssize_t ret)
++{
++      switch (ret) {
++      case -ERESTARTSYS:
++      case -ERESTARTNOINTR:
++      case -ERESTARTNOHAND:
++      case -ERESTART_RESTARTBLOCK:
++              /*
++               * We can't just restart the syscall, since previously
++               * submitted sqes may already be in progress. Just fail
++               * this IO with EINTR.
++               */
++              return -EINTR;
++      default:
++              return ret;
++      }
++}
++
+ static inline void io_rw_done(struct io_kiocb *req, ssize_t ret)
+ {
+       struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
+@@ -624,21 +642,8 @@ static inline void io_rw_done(struct io_
+               return;
+       /* transform internal restart error codes */
+-      if (unlikely(ret < 0)) {
+-              switch (ret) {
+-              case -ERESTARTSYS:
+-              case -ERESTARTNOINTR:
+-              case -ERESTARTNOHAND:
+-              case -ERESTART_RESTARTBLOCK:
+-                      /*
+-                       * We can't just restart the syscall, since previously
+-                       * submitted sqes may already be in progress. Just fail
+-                       * this IO with EINTR.
+-                       */
+-                      ret = -EINTR;
+-                      break;
+-              }
+-      }
++      if (unlikely(ret < 0))
++              ret = io_fixup_restart_res(ret);
+       if (req->flags & REQ_F_IOPOLL)
+               io_complete_rw_iopoll(&rw->kiocb, ret);
+@@ -1034,7 +1039,8 @@ int io_read(struct io_kiocb *req, unsign
+       if (req->flags & REQ_F_BUFFERS_COMMIT)
+               io_kbuf_recycle(req, sel.buf_list, issue_flags);
+-      return ret;
++
++      return io_fixup_restart_res(ret);
+ }
+ int io_read_mshot(struct io_kiocb *req, unsigned int issue_flags)
+@@ -1068,8 +1074,10 @@ int io_read_mshot(struct io_kiocb *req,
+               return IOU_RETRY;
+       } else if (ret <= 0) {
+               io_kbuf_recycle(req, sel.buf_list, issue_flags);
+-              if (ret < 0)
++              if (ret < 0) {
++                      ret = io_fixup_restart_res(ret);
+                       req_set_fail(req);
++              }
+       } else if (!(req->flags & REQ_F_APOLL_MULTISHOT)) {
+               cflags = io_put_kbuf(req, ret, sel.buf_list);
+       } else {
diff --git a/queue-7.1/iomap-fix-out-of-bounds-bitmap_set-with-zero-length-range.patch b/queue-7.1/iomap-fix-out-of-bounds-bitmap_set-with-zero-length-range.patch
new file mode 100644 (file)
index 0000000..02047bf
--- /dev/null
@@ -0,0 +1,81 @@
+From 9c7d8f7c8994c790fca501dc45ce66e7356cbe05 Mon Sep 17 00:00:00 2001
+From: Zhang Yi <yi.zhang@huawei.com>
+Date: Tue, 14 Jul 2026 16:23:24 +0800
+Subject: iomap: fix out-of-bounds bitmap_set() with zero-length range
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+commit 9c7d8f7c8994c790fca501dc45ce66e7356cbe05 upstream.
+
+ifs_set_range_dirty() and ifs_set_range_uptodate() compute last_blk
+as (off + len - 1) >> i_blkbits.  When off is 0 and len is 0, the
+unsigned subtraction underflows to SIZE_MAX, producing a huge
+last_blk and nr_blks value that causes bitmap_set() to write far
+beyond the ifs->state allocation.
+
+Regarding ifs_set_range_uptodate(), it is temporarily safe because len
+cannot be passed in as 0. However, for ifs_set_range_dirty() this is
+reachable from __iomap_write_end(): when copy_folio_from_iter_atomic()
+returns 0 (e.g. user buffer fault) and the folio is already uptodate,
+the guard at the top of __iomap_write_end() does not trigger because
+!folio_test_uptodate() is false, and iomap_set_range_dirty() is called
+with copied == 0.
+
+Add a !len guard to both functions before the computation, so that a
+zero-length range is a no-op.
+
+Fixes: 4ce02c679722 ("iomap: Add per-block dirty state tracking to improve performance")
+Cc: stable@vger.kernel.org # v6.6
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Link: https://patch.msgid.link/20260714082325.325163-5-yi.zhang@huaweicloud.com
+Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
+Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/iomap/buffered-io.c |   22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+--- a/fs/iomap/buffered-io.c
++++ b/fs/iomap/buffered-io.c
+@@ -67,11 +67,13 @@ static bool ifs_set_range_uptodate(struc
+               struct iomap_folio_state *ifs, size_t off, size_t len)
+ {
+       struct inode *inode = folio->mapping->host;
+-      unsigned int first_blk = off >> inode->i_blkbits;
+-      unsigned int last_blk = (off + len - 1) >> inode->i_blkbits;
+-      unsigned int nr_blks = last_blk - first_blk + 1;
++      unsigned int first_blk, last_blk;
+-      bitmap_set(ifs->state, first_blk, nr_blks);
++      if (len) {
++              first_blk = off >> inode->i_blkbits;
++              last_blk = (off + len - 1) >> inode->i_blkbits;
++              bitmap_set(ifs->state, first_blk, last_blk - first_blk + 1);
++      }
+       return ifs_is_fully_uptodate(folio, ifs);
+ }
+@@ -203,13 +205,17 @@ static void ifs_set_range_dirty(struct f
+ {
+       struct inode *inode = folio->mapping->host;
+       unsigned int blks_per_folio = i_blocks_per_folio(inode, folio);
+-      unsigned int first_blk = (off >> inode->i_blkbits);
+-      unsigned int last_blk = (off + len - 1) >> inode->i_blkbits;
+-      unsigned int nr_blks = last_blk - first_blk + 1;
++      unsigned int first_blk, last_blk;
+       unsigned long flags;
++      if (!len)
++              return;
++
++      first_blk = off >> inode->i_blkbits;
++      last_blk = (off + len - 1) >> inode->i_blkbits;
+       spin_lock_irqsave(&ifs->state_lock, flags);
+-      bitmap_set(ifs->state, first_blk + blks_per_folio, nr_blks);
++      bitmap_set(ifs->state, first_blk + blks_per_folio,
++                 last_blk - first_blk + 1);
+       spin_unlock_irqrestore(&ifs->state_lock, flags);
+ }
diff --git a/queue-7.1/iommu-vt-d-disallow-sva-if-page-walk-is-not-coherent.patch b/queue-7.1/iommu-vt-d-disallow-sva-if-page-walk-is-not-coherent.patch
new file mode 100644 (file)
index 0000000..32f5253
--- /dev/null
@@ -0,0 +1,43 @@
+From 780dfed688622ea01be3c9c2c55eec2207f05e04 Mon Sep 17 00:00:00 2001
+From: Lu Baolu <baolu.lu@linux.intel.com>
+Date: Thu, 16 Jul 2026 13:35:53 +0800
+Subject: iommu/vt-d: Disallow SVA if page walk is not coherent
+
+From: Lu Baolu <baolu.lu@linux.intel.com>
+
+commit 780dfed688622ea01be3c9c2c55eec2207f05e04 upstream.
+
+Hardware implementations report Scalable-Mode Page-walk Coherency Support
+via the SMPWCS field in the extended capability register. If the hardware
+does not support page-walk coherency, a clflush is required every time
+the page table entries (which are walked by the IOMMU hardware) are
+updated.
+
+In the SVA case, page tables are managed by the CPU mm core, not by the
+IOMMU driver. Because the IOMMU driver has no way of knowing whether the
+CPU page table management code has ensured coherency via clflush, the
+driver must deny SVA if the hardware does not support coherent paging.
+
+Fixes: ff3dc6521f78 ("iommu/vt-d: Fix CPU and IOMMU SVM feature matching checks")
+Cc: stable@vger.kernel.org
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Reviewed-by: Samiullah Khawaja <skhawaja@google.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/intel/svm.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iommu/intel/svm.c
++++ b/drivers/iommu/intel/svm.c
+@@ -27,7 +27,7 @@
+ void intel_svm_check(struct intel_iommu *iommu)
+ {
+-      if (!pasid_supported(iommu))
++      if (!pasid_supported(iommu) || !ecap_smpwc(iommu->ecap))
+               return;
+       if (cpu_feature_enabled(X86_FEATURE_GBPAGES) &&
diff --git a/queue-7.1/ksmbd-defer-destroy_previous_session-until-after-ntlm-authentication.patch b/queue-7.1/ksmbd-defer-destroy_previous_session-until-after-ntlm-authentication.patch
new file mode 100644 (file)
index 0000000..6b2d0e3
--- /dev/null
@@ -0,0 +1,60 @@
+From c74801ee524f477c174a1899782b6c3b6918d407 Mon Sep 17 00:00:00 2001
+From: James Montgomery <james_montgomery@disroot.org>
+Date: Fri, 3 Jul 2026 15:26:41 -0400
+Subject: ksmbd: defer destroy_previous_session() until after NTLM authentication
+
+From: James Montgomery <james_montgomery@disroot.org>
+
+commit c74801ee524f477c174a1899782b6c3b6918d407 upstream.
+
+In ntlm_authenticate(), destroy_previous_session() is called using a
+user pointer resolved from the client-supplied NTLM blob username field
+before the NTLMv2 response is validated. An authenticated attacker can
+set the NTLM blob username to match a victim account and set
+PreviousSessionId to the victim's session ID; destroy_previous_session()
+destroys the victim's session while ksmbd_decode_ntlmssp_auth_blob()
+subsequently rejects the request with -EPERM.
+
+Move destroy_previous_session() and the prev_id assignment to after
+ksmbd_decode_ntlmssp_auth_blob() returns success and use sess->user
+rather than the pre-authentication lookup result. This matches the
+ordering already used by krb5_authenticate(), where
+destroy_previous_session() is called only after
+ksmbd_krb5_authenticate() returns success.
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/linux-cifs/20260702155449.3639773-1-james_montgomery@disroot.org/
+Signed-off-by: James Montgomery <james_montgomery@disroot.org>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/server/smb2pdu.c |    9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+--- a/fs/smb/server/smb2pdu.c
++++ b/fs/smb/server/smb2pdu.c
+@@ -1535,11 +1535,6 @@ static int ntlm_authenticate(struct ksmb
+               return -EPERM;
+       }
+-      /* Check for previous session */
+-      prev_id = le64_to_cpu(req->PreviousSessionId);
+-      if (prev_id && prev_id != sess->id)
+-              destroy_previous_session(conn, user, prev_id);
+-
+       if (sess->state == SMB2_SESSION_VALID) {
+               /*
+                * Reuse session if anonymous try to connect
+@@ -1579,6 +1574,10 @@ static int ntlm_authenticate(struct ksmb
+               }
+       }
++      prev_id = le64_to_cpu(req->PreviousSessionId);
++      if (prev_id && prev_id != sess->id)
++              destroy_previous_session(conn, sess->user, prev_id);
++
+       /*
+        * If session state is SMB2_SESSION_VALID, We can assume
+        * that it is reauthentication. And the user/password
diff --git a/queue-7.1/ksmbd-validate-minimum-pdu-size-for-transform-requests.patch b/queue-7.1/ksmbd-validate-minimum-pdu-size-for-transform-requests.patch
new file mode 100644 (file)
index 0000000..d41d4b8
--- /dev/null
@@ -0,0 +1,74 @@
+From cfc0b8e5080aec87700774e8568765eaa4b7b92b Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <linkinjeon@kernel.org>
+Date: Sat, 4 Jul 2026 11:30:27 +0900
+Subject: ksmbd: validate minimum PDU size for transform requests
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+commit cfc0b8e5080aec87700774e8568765eaa4b7b92b upstream.
+
+The receive path applies the minimum SMB2 PDU size check only when
+ProtocolId is SMB2_PROTO_NUMBER. A packet carrying
+SMB2_TRANSFORM_PROTO_NUM bypasses the check even when the negotiated
+dialect does not provide transform handling.
+
+On an SMB 2.1 connection, a short transform packet therefore reaches
+init_smb2_rsp_hdr(), which interprets the request as a full SMB2 header
+and reads beyond the request allocation. The copied fields can then be
+returned to the unauthenticated client.
+
+Compression transforms are converted to ordinary SMB2 messages before
+protocol validation. After that conversion, validate ordinary SMB2
+requests against SMB2_MIN_SUPPORTED_PDU_SIZE and require encryption
+transform requests to contain both a transform header and an SMB2
+header. This rejects truncated requests before work allocation.
+
+Fixes: 368ba06881c3 ("ksmbd: check the validation of pdu_size in ksmbd_conn_handler_loop")
+Cc: stable@vger.kernel.org
+Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-31063
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/server/connection.c |   16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+--- a/fs/smb/server/connection.c
++++ b/fs/smb/server/connection.c
+@@ -440,6 +440,8 @@ bool ksmbd_conn_alive(struct ksmbd_conn
+ /* "+2" for BCC field (ByteCount, 2 bytes) */
+ #define SMB1_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb_hdr) + 2)
+ #define SMB2_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb2_pdu))
++#define SMB2_TRANSFORM_MIN_SUPPORTED_PDU_SIZE \
++      (sizeof(struct smb2_transform_hdr) + sizeof(struct smb2_hdr))
+ /**
+  * ksmbd_conn_handler_loop() - session thread to listen on new smb requests
+@@ -454,6 +456,7 @@ int ksmbd_conn_handler_loop(void *p)
+       struct ksmbd_conn *conn = (struct ksmbd_conn *)p;
+       struct ksmbd_transport *t = conn->transport;
+       unsigned int pdu_size, max_allowed_pdu_size, max_req;
++      __le32 proto;
+       char hdr_buf[4] = {0,};
+       int size;
+@@ -534,11 +537,14 @@ recheck:
+               if (!ksmbd_smb_request(conn))
+                       break;
+-              if (((struct smb2_hdr *)smb_get_msg(conn->request_buf))->ProtocolId ==
+-                  SMB2_PROTO_NUMBER) {
+-                      if (pdu_size < SMB2_MIN_SUPPORTED_PDU_SIZE)
+-                              break;
+-              }
++              proto = *(__le32 *)smb_get_msg(conn->request_buf);
++              if (proto == SMB2_PROTO_NUMBER &&
++                  pdu_size < SMB2_MIN_SUPPORTED_PDU_SIZE)
++                      break;
++
++              if (proto == SMB2_TRANSFORM_PROTO_NUM &&
++                  pdu_size < SMB2_TRANSFORM_MIN_SUPPORTED_PDU_SIZE)
++                      break;
+               if (!default_conn_ops.process_fn) {
+                       pr_err("No connection request callback\n");
diff --git a/queue-7.1/libceph-bound-get_version-reply-decode-to-front-len.patch b/queue-7.1/libceph-bound-get_version-reply-decode-to-front-len.patch
new file mode 100644 (file)
index 0000000..9be426f
--- /dev/null
@@ -0,0 +1,47 @@
+From d3c32939fa0e3ee9b883b9a0fd1972c5c444e3d0 Mon Sep 17 00:00:00 2001
+From: Douya Le <ldy3087146292@gmail.com>
+Date: Sun, 7 Jun 2026 17:35:49 +0800
+Subject: libceph: bound get_version reply decode to front len
+
+From: Douya Le <ldy3087146292@gmail.com>
+
+commit d3c32939fa0e3ee9b883b9a0fd1972c5c444e3d0 upstream.
+
+handle_get_version_reply() uses msg->front_alloc_len as the decode
+boundary for MON_GET_VERSION_REPLY.  That is the size of the reused
+reply buffer, not the number of bytes actually received.
+
+A truncated reply can therefore pass ceph_decode_need() and decode the
+second u64 from stale tail bytes left in the buffer by an earlier
+message, causing an uninitialized memory read.
+
+Use msg->front.iov_len as the receive-side decode boundary, matching
+other libceph reply handlers and limiting decoding to the bytes that
+were actually read from the wire.
+
+Cc: stable@vger.kernel.org
+Fixes: 513a8243d67f ("libceph: mon_get_version request infrastructure")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Assisted-by: Codex:GPT-5.4
+Signed-off-by: Douya Le <ldy3087146292@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/mon_client.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ceph/mon_client.c
++++ b/net/ceph/mon_client.c
+@@ -821,7 +821,7 @@ static void handle_get_version_reply(str
+       struct ceph_mon_generic_request *req;
+       u64 tid = le64_to_cpu(msg->hdr.tid);
+       void *p = msg->front.iov_base;
+-      void *end = p + msg->front_alloc_len;
++      void *const end = p + msg->front.iov_len;
+       u64 handle;
+       dout("%s msg %p tid %llu\n", __func__, msg, tid);
diff --git a/queue-7.1/libceph-bound-pg_-temp-upmap-upmap_items-length-to-ceph_pg_max_size.patch b/queue-7.1/libceph-bound-pg_-temp-upmap-upmap_items-length-to-ceph_pg_max_size.patch
new file mode 100644 (file)
index 0000000..9c1502b
--- /dev/null
@@ -0,0 +1,68 @@
+From 9f00f9cf2be293efe899db67dc5272e3a9c62717 Mon Sep 17 00:00:00 2001
+From: Xiang Mei <xmei5@asu.edu>
+Date: Mon, 8 Jun 2026 21:40:09 -0700
+Subject: libceph: bound pg_{temp,upmap,upmap_items} length to CEPH_PG_MAX_SIZE
+
+From: Xiang Mei <xmei5@asu.edu>
+
+commit 9f00f9cf2be293efe899db67dc5272e3a9c62717 upstream.
+
+__decode_pg_temp() decodes an user-controlled length but only rejects
+values large enough to overflow the allocation; it does not bound it to
+CEPH_PG_MAX_SIZE. The helper backs both pg_temp and pg_upmap decoding, and
+apply_upmap()/get_temp_osds() later copy the decoded list into the fixed-size
+on-stack array struct ceph_osds.osds[CEPH_PG_MAX_SIZE]. A monitor that sends
+an OSDMap with a pg_temp/pg_upmap entry longer than 32 thus causes a stack
+out-of-bounds write.
+
+An OSD set for a single PG can never exceed CEPH_PG_MAX_SIZE, so reject longer
+entries at decode time. The bound is well below the old overflow threshold, so
+it also covers the allocation-size overflow the previous check guarded against.
+
+  BUG: KASAN: stack-out-of-bounds in ceph_pg_to_up_acting_osds
+  Write of size 4 ... by task exploit
+   kasan_report (mm/kasan/report.c:595)
+   ceph_pg_to_up_acting_osds (net/ceph/osdmap.c:2617 net/ceph/osdmap.c:2833)
+   calc_target (net/ceph/osd_client.c:1638)
+   __submit_request (net/ceph/osd_client.c:2394)
+   ceph_osdc_start_request (net/ceph/osd_client.c:2490)
+   ceph_osdc_call (net/ceph/osd_client.c:5164)
+   rbd_dev_image_probe (drivers/block/rbd.c:6899)
+   do_rbd_add (drivers/block/rbd.c:7138)
+   ...
+  kernel BUG at net/ceph/osdmap.c:2670!
+
+[ idryomov: do the same in __decode_pg_upmap_items() ]
+
+Cc: stable@vger.kernel.org
+Fixes: a303bb0e5834 ("libceph: introduce and switch to decode_pg_mapping()")
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Reviewed-by: Alex Markuze <amarkuze@redhat.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/osdmap.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/ceph/osdmap.c
++++ b/net/ceph/osdmap.c
+@@ -1436,7 +1436,7 @@ static struct ceph_pg_mapping *__decode_
+       ceph_decode_32_safe(p, end, len, e_inval);
+       if (len == 0 && incremental)
+               return NULL;    /* new_pg_temp: [] to remove */
+-      if ((size_t)len > (SIZE_MAX - sizeof(*pg)) / sizeof(u32))
++      if (len > CEPH_PG_MAX_SIZE)
+               return ERR_PTR(-EINVAL);
+       ceph_decode_need(p, end, len * sizeof(u32), e_inval);
+@@ -1617,7 +1617,7 @@ static struct ceph_pg_mapping *__decode_
+       u32 len, i;
+       ceph_decode_32_safe(p, end, len, e_inval);
+-      if ((size_t)len > (SIZE_MAX - sizeof(*pg)) / (2 * sizeof(u32)))
++      if (len > CEPH_PG_MAX_SIZE)
+               return ERR_PTR(-EINVAL);
+       ceph_decode_need(p, end, 2 * len * sizeof(u32), e_inval);
diff --git a/queue-7.1/libceph-fix-multiplication-overflow-in-decode_new_up_state_weight.patch b/queue-7.1/libceph-fix-multiplication-overflow-in-decode_new_up_state_weight.patch
new file mode 100644 (file)
index 0000000..6df62aa
--- /dev/null
@@ -0,0 +1,55 @@
+From 98917a499ec7064c14fc56d180a4fd636fc2784c Mon Sep 17 00:00:00 2001
+From: Raphael Zimmer <raphael.zimmer@tu-ilmenau.de>
+Date: Wed, 27 May 2026 16:06:17 +0200
+Subject: libceph: Fix multiplication overflow in decode_new_up_state_weight()
+
+From: Raphael Zimmer <raphael.zimmer@tu-ilmenau.de>
+
+commit 98917a499ec7064c14fc56d180a4fd636fc2784c upstream.
+
+If a message of type CEPH_MSG_OSD_MAP contains a (maliciously) corrupted
+osdmap, out-of-bounds memory accesses may occur in
+decode_new_up_state_weight(). This happens because the bounds check for
+the new_state part is based on calculating its length depending on a len
+value read from the incoming message. This calculation may overflow
+leading to an incorrect bounds check. Subsequently, out-of-bounds reads
+may occur when decoding this part.
+
+This patch switches the multiplication to use check_mul_overflow() to
+abort processing the osdmap if an overflow occurred. Therefore,
+osdmaps/messages containing large values for len that result in a
+multiplication overflow are treated as invalid.
+
+[ idryomov: rename new_state_len -> new_state_item_size, formatting ]
+
+Cc: stable@vger.kernel.org
+Fixes: 930c53286977 ("libceph: apply new_state before new_up_client on incrementals")
+Signed-off-by: Raphael Zimmer <raphael.zimmer@tu-ilmenau.de>
+Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/osdmap.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/net/ceph/osdmap.c
++++ b/net/ceph/osdmap.c
+@@ -1842,6 +1842,8 @@ static int decode_new_up_state_weight(vo
+       void *new_up_client;
+       void *new_state;
+       void *new_weight_end;
++      const u32 new_state_item_size =
++          sizeof(u32) + (struct_v >= 5 ? sizeof(u32) : sizeof(u8));
+       u32 len;
+       int ret;
+       int i;
+@@ -1862,7 +1864,8 @@ static int decode_new_up_state_weight(vo
+       new_state = *p;
+       ceph_decode_32_safe(p, end, len, e_inval);
+-      len *= sizeof(u32) + (struct_v >= 5 ? sizeof(u32) : sizeof(u8));
++      if (check_mul_overflow(len, new_state_item_size, &len))
++              goto e_inval;
+       ceph_decode_need(p, end, len, e_inval);
+       *p += len;
diff --git a/queue-7.1/libceph-fix-two-unsafe-bare-decodes-in-decode_lockers.patch b/queue-7.1/libceph-fix-two-unsafe-bare-decodes-in-decode_lockers.patch
new file mode 100644 (file)
index 0000000..6af4b8b
--- /dev/null
@@ -0,0 +1,104 @@
+From a109a556115271ca7896dcda7b4b7e45e156c227 Mon Sep 17 00:00:00 2001
+From: Pavitra Jha <jhapavitra98@gmail.com>
+Date: Tue, 2 Jun 2026 00:17:35 -0400
+Subject: libceph: fix two unsafe bare decodes in decode_lockers()
+
+From: Pavitra Jha <jhapavitra98@gmail.com>
+
+commit a109a556115271ca7896dcda7b4b7e45e156c227 upstream.
+
+decode_lockers() in cls_lock_client.c contains two bare decode operations
+that allow a malicious or compromised OSD to trigger slab-out-of-bounds
+reads:
+
+1. ceph_decode_32(p) at the num_lockers field has no preceding bounds
+   check. ceph_start_decoding() accepts struct_len=0 as valid -- the
+   internal ceph_decode_need(p, end, 0, bad) always passes -- so when an
+   OSD sends struct_len=0, ceph_start_decoding() returns success with
+   p == end. The immediately following bare ceph_decode_32(p) then reads
+   4 bytes past the validated buffer boundary. The garbage value is
+   passed directly to kzalloc_objs() as the locker count.
+
+   The sibling function decode_watchers() in osd_client.c already uses
+   ceph_decode_32_safe() after its own ceph_start_decoding() call.
+   decode_lockers() was the only site using the bare variant.
+
+2. ceph_decode_8(p) after the decode_locker() loop has no preceding
+   bounds check. If an OSD crafts num_lockers such that the loop
+   advances p exactly to end, the subsequent bare ceph_decode_8(p) reads
+   one byte past the validated buffer boundary. The result is passed
+   directly into *type, which is used as a lock type discriminator by
+   callers, giving an OSD-controlled one-byte OOB read with direct
+   influence over the lock type field.
+
+Fix both by replacing bare operations with their safe variants:
+  ceph_decode_32(p) -> ceph_decode_32_safe(p, end, *num_lockers,
+                                           err_inval)
+  ceph_decode_8(p)  -> ceph_decode_8_safe(p, end, *type,
+                                          err_free_lockers)
+
+The goto targets differ intentionally:
+  err_inval: is a new label returning -EINVAL directly. It is used for
+  the pre-allocation failure path where *lockers is not yet allocated
+  and must not be passed to ceph_free_lockers().
+
+  err_free_lockers: is the existing label. It is used for the
+  post-allocation failure path where *lockers is allocated and must
+  be freed.
+
+ret is set to -EINVAL before ceph_decode_8_safe() so that
+err_free_lockers returns the correct error code on bounds violation.
+Without this, err_free_lockers would return a stale ret value (0 from
+the successful decode_locker() loop), silently swallowing the error.
+
+-EINVAL is correct for both failure paths. The data received from the
+OSD is structurally malformed. -ENOMEM would misrepresent the failure
+class to callers and to stable@ backporters triaging error paths.
+
+Attacker model: a malicious or compromised OSD in a multi-tenant Ceph
+deployment can trigger this against any kernel client that issues the
+lock.get_info class method (e.g. during RBD exclusive lock acquisition).
+
+[ idryomov: trim changelog, formatting ]
+
+Cc: stable@vger.kernel.org
+Fixes: d4ed4a530562 ("libceph: support for lock.lock_info")
+Signed-off-by: Pavitra Jha <jhapavitra98@gmail.com>
+Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/cls_lock_client.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/net/ceph/cls_lock_client.c
++++ b/net/ceph/cls_lock_client.c
+@@ -299,7 +299,7 @@ static int decode_lockers(void **p, void
+       if (ret)
+               return ret;
+-      *num_lockers = ceph_decode_32(p);
++      ceph_decode_32_safe(p, end, *num_lockers, err_inval);
+       *lockers = kzalloc_objs(**lockers, *num_lockers, GFP_NOIO);
+       if (!*lockers)
+               return -ENOMEM;
+@@ -310,7 +310,8 @@ static int decode_lockers(void **p, void
+                       goto err_free_lockers;
+       }
+-      *type = ceph_decode_8(p);
++      ret = -EINVAL;
++      ceph_decode_8_safe(p, end, *type, err_free_lockers);
+       s = ceph_extract_encoded_string(p, end, NULL, GFP_NOIO);
+       if (IS_ERR(s)) {
+               ret = PTR_ERR(s);
+@@ -320,6 +321,9 @@ static int decode_lockers(void **p, void
+       *tag = s;
+       return 0;
++err_inval:
++      return -EINVAL;
++
+ err_free_lockers:
+       ceph_free_lockers(*lockers, *num_lockers);
+       return ret;
diff --git a/queue-7.1/libceph-guard-missing-crush-type-name-lookup.patch b/queue-7.1/libceph-guard-missing-crush-type-name-lookup.patch
new file mode 100644 (file)
index 0000000..eb39aa2
--- /dev/null
@@ -0,0 +1,50 @@
+From bbeae12fda3384a90fbebc8a19ba9d33f85b5361 Mon Sep 17 00:00:00 2001
+From: Zhao Zhang <zzhan461@ucr.edu>
+Date: Fri, 19 Jun 2026 15:40:03 +0800
+Subject: libceph: guard missing CRUSH type name lookup
+
+From: Zhao Zhang <zzhan461@ucr.edu>
+
+commit bbeae12fda3384a90fbebc8a19ba9d33f85b5361 upstream.
+
+Localized read selection can walk a parent bucket whose name exists in
+the CRUSH map while its type has no matching entry in type_names.
+get_immediate_parent() then dereferences a NULL type_cn and passes an
+invalid pointer into strcmp(), causing a null-ptr-deref.
+
+Skip such malformed parent buckets unless both the bucket name and type
+name metadata are present. This keeps malformed hierarchy data from
+crashing locality lookup and safely falls back to "not local".
+
+[ idryomov: add WARN_ON_ONCE ]
+
+Cc: stable@vger.kernel.org
+Fixes: 117d96a04f00 ("libceph: support for balanced and localized reads")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Assisted-by: Codex:GPT-5.4
+Signed-off-by: Zhao Zhang <zzhan461@ucr.edu>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/osdmap.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/net/ceph/osdmap.c
++++ b/net/ceph/osdmap.c
+@@ -3058,8 +3058,11 @@ static int get_immediate_parent(struct c
+                       if (b->items[j] != id)
+                               continue;
+-                      *parent_type_id = b->type;
+                       type_cn = lookup_crush_name(&c->type_names, b->type);
++                      if (WARN_ON_ONCE(!type_cn))
++                              continue;
++
++                      *parent_type_id = b->type;
+                       parent_loc->cl_type_name = type_cn->cn_name;
+                       parent_loc->cl_name = cn->cn_name;
+                       return b->id;
diff --git a/queue-7.1/libceph-refresh-auth-authorizer_buf-_len-after-authorizer-update.patch b/queue-7.1/libceph-refresh-auth-authorizer_buf-_len-after-authorizer-update.patch
new file mode 100644 (file)
index 0000000..bda96e2
--- /dev/null
@@ -0,0 +1,61 @@
+From 937d61f86d377a3aa578adae7a3dfcecdddf9d89 Mon Sep 17 00:00:00 2001
+From: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
+Date: Mon, 29 Jun 2026 13:14:22 -0400
+Subject: libceph: refresh auth->authorizer_buf{,_len} after authorizer update
+
+From: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
+
+commit 937d61f86d377a3aa578adae7a3dfcecdddf9d89 upstream.
+
+ceph_x_create_authorizer() caches au->buf->vec.iov_base and
+au->buf->vec.iov_len in struct ceph_auth_handshake.  These
+cached values are then used by the messenger connect code when
+sending the authorizer.
+
+ceph_x_update_authorizer() can rebuild the authorizer when a newer
+service ticket is available.  If the rebuilt authorizer no longer
+fits in the existing buffer, ceph_x_build_authorizer() drops its
+reference to au->buf and allocates a new one.  If this is the final
+reference, ceph_buffer_put() frees the old ceph_buffer and its
+vec.iov_base, but auth->authorizer_buf still points at that freed
+memory.
+
+A subsequent msgr1 reconnect can therefore queue the stale pointer
+and trigger a KASAN slab-use-after-free in _copy_from_iter() while
+tcp_sendmsg() copies the authorizer.
+
+Refresh auth->authorizer_buf and auth->authorizer_buf_len after a
+successful authorizer rebuild so the messenger sends the current
+buffer.
+
+Cc: stable@vger.kernel.org
+Fixes: 0bed9b5c523d ("libceph: add update_authorizer auth method")
+Closes: https://lore.kernel.org/all/E378850E-106C-427B-A241-970EB2D054D7@gmail.com/
+Signed-off-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
+Reviewed-by: Alex Markuze <amarkuze@redhat.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/auth_x.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -849,9 +849,16 @@ static int ceph_x_update_authorizer(
+       au = (struct ceph_x_authorizer *)auth->authorizer;
+       if (au->secret_id < th->secret_id) {
++              int ret;
++
+               dout("ceph_x_update_authorizer service %u secret %llu < %llu\n",
+                    au->service, au->secret_id, th->secret_id);
+-              return ceph_x_build_authorizer(ac, th, au);
++              ret = ceph_x_build_authorizer(ac, th, au);
++              if (ret)
++                      return ret;
++
++              auth->authorizer_buf = au->buf->vec.iov_base;
++              auth->authorizer_buf_len = au->buf->vec.iov_len;
+       }
+       return 0;
+ }
diff --git a/queue-7.1/libceph-reject-monmaps-advertising-zero-monitors.patch b/queue-7.1/libceph-reject-monmaps-advertising-zero-monitors.patch
new file mode 100644 (file)
index 0000000..670cbe8
--- /dev/null
@@ -0,0 +1,47 @@
+From 40480eee361ed9676b3f844d532ac28b47251634 Mon Sep 17 00:00:00 2001
+From: Raphael Zimmer <raphael.zimmer@tu-ilmenau.de>
+Date: Fri, 29 May 2026 09:42:57 +0200
+Subject: libceph: Reject monmaps advertising zero monitors
+
+From: Raphael Zimmer <raphael.zimmer@tu-ilmenau.de>
+
+commit 40480eee361ed9676b3f844d532ac28b47251634 upstream.
+
+A message of type CEPH_MSG_MON_MAP contains a monmap that is sent from a
+monitor to the client. This monmap contains information about the
+existing monitors in the cluster. Currently, a monmap indicating that
+there are zero monitors in the cluster is treated as valid. However, it
+is impossible to have zero monitors in the cluster and still receive a
+valid monmap from a monitor. Therefore, such a monmap must be corrupted
+and should be treated as invalid. Furthermore, a monmap with a monitor
+count of zero can subsequently crash the client when attempting to open
+a session with a monitor in __open_session(). This happens because the
+"BUG_ON(monc->monmap->num_mon < 1)" assertion in pick_new_mon() is
+triggered.
+
+This patch extends a check in ceph_monmap_decode() to also reject
+arriving mon_maps with num_mon == 0 rather than only with
+num_mon > CEPH_MAX_MON.
+
+[ idryomov: drop "log output for unusual values of num_mon" part ]
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Raphael Zimmer <raphael.zimmer@tu-ilmenau.de>
+Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/mon_client.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ceph/mon_client.c
++++ b/net/ceph/mon_client.c
+@@ -114,7 +114,7 @@ static struct ceph_monmap *ceph_monmap_d
+       dout("%s fsid %pU epoch %u num_mon %u\n", __func__, &fsid, epoch,
+            num_mon);
+-      if (num_mon > CEPH_MAX_MON)
++      if (num_mon == 0 || num_mon > CEPH_MAX_MON)
+               goto e_inval;
+       monmap = kmalloc_flex(*monmap, mon_inst, num_mon, GFP_NOIO);
diff --git a/queue-7.1/libceph-reject-zero-bucket-types-in-crush_decode.patch b/queue-7.1/libceph-reject-zero-bucket-types-in-crush_decode.patch
new file mode 100644 (file)
index 0000000..fc7cdab
--- /dev/null
@@ -0,0 +1,46 @@
+From 05f90284223381005d6bcddab3fda4a97f9c3401 Mon Sep 17 00:00:00 2001
+From: Douya Le <ldy3087146292@gmail.com>
+Date: Fri, 29 May 2026 16:11:44 +0800
+Subject: libceph: reject zero bucket types in crush_decode
+
+From: Douya Le <ldy3087146292@gmail.com>
+
+commit 05f90284223381005d6bcddab3fda4a97f9c3401 upstream.
+
+CRUSH bucket type 0 is reserved for devices.  The mapper relies on
+that invariant and uses type 0 to identify leaf devices.
+
+If crush_decode() accepts a bucket with type 0, a malformed CRUSH map
+can make the mapper treat a negative bucket ID as a device and pass it
+to is_out(), which then indexes the OSD weight array with a negative
+value.
+
+Reject zero bucket types while decoding the CRUSH map so the invalid
+state never reaches the mapper.
+
+Cc: stable@vger.kernel.org
+Fixes: f24e9980eb86 ("ceph: OSD client")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Assisted-by: Codex:GPT-5.4
+Signed-off-by: Douya Le <ldy3087146292@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/osdmap.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/ceph/osdmap.c
++++ b/net/ceph/osdmap.c
+@@ -518,6 +518,8 @@ static struct crush_map *crush_decode(vo
+               ceph_decode_need(p, end, 4*sizeof(u32), bad);
+               b->id = ceph_decode_32(p);
+               b->type = ceph_decode_16(p);
++              if (b->type == 0)
++                      goto bad;
+               b->alg = ceph_decode_8(p);
+               if (b->alg != alg) {
+                       b->alg = 0;
diff --git a/queue-7.1/libceph-remove-debugfs-files-before-client-teardown.patch b/queue-7.1/libceph-remove-debugfs-files-before-client-teardown.patch
new file mode 100644 (file)
index 0000000..d4ddc1f
--- /dev/null
@@ -0,0 +1,51 @@
+From e4c804726c4afce3ba648b982d564f6af2cfa328 Mon Sep 17 00:00:00 2001
+From: Douya Le <ldy3087146292@gmail.com>
+Date: Mon, 15 Jun 2026 14:31:06 +0800
+Subject: libceph: remove debugfs files before client teardown
+
+From: Douya Le <ldy3087146292@gmail.com>
+
+commit e4c804726c4afce3ba648b982d564f6af2cfa328 upstream.
+
+ceph_destroy_client() tears down the monitor client before removing
+the per-client debugfs files. A concurrent read of the monmap debugfs
+file can enter monmap_show() after ceph_monc_stop() has freed
+monc->monmap, triggering a use-after-free.
+
+Remove the debugfs files before stopping the OSD and monitor clients.
+debugfs_remove() drains active handlers and prevents new accesses, so
+the debugfs callbacks can no longer race the rest of client teardown.
+
+Cc: stable@vger.kernel.org
+Fixes: 76aa844d5b2f ("ceph: debugfs")
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Assisted-by: Codex:GPT-5.4
+Signed-off-by: Douya Le <ldy3087146292@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/ceph_common.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/ceph/ceph_common.c
++++ b/net/ceph/ceph_common.c
+@@ -762,13 +762,13 @@ void ceph_destroy_client(struct ceph_cli
+       atomic_set(&client->msgr.stopping, 1);
++      ceph_debugfs_client_cleanup(client);
++
+       /* unmount */
+       ceph_osdc_stop(&client->osdc);
+       ceph_monc_stop(&client->monc);
+       ceph_messenger_fini(&client->msgr);
+-      ceph_debugfs_client_cleanup(client);
+-
+       ceph_destroy_options(client->options);
+       kfree(client);
diff --git a/queue-7.1/m68k-avoid-wunused-but-set-parameter-in-clear_user_page.patch b/queue-7.1/m68k-avoid-wunused-but-set-parameter-in-clear_user_page.patch
new file mode 100644 (file)
index 0000000..78b3101
--- /dev/null
@@ -0,0 +1,61 @@
+From 955b67c3ddf9912a670ed80eae7769745b4f405e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Mon, 25 May 2026 10:33:52 +0200
+Subject: m68k: avoid -Wunused-but-set-parameter in clear_user_page()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Weißschuh <linux@weissschuh.net>
+
+commit 955b67c3ddf9912a670ed80eae7769745b4f405e upstream.
+
+The loop in clear_user_pages() iterates over all pages and calls
+clear_user_page() for each of them.  During the loop "vaddr" is modified.
+However on m68k clear_user() is a macro which does not use "vaddr".  The
+compiler sees a variable which is modified but never used and emits a
+warning for that:
+
+include/linux/highmem.h: In function 'clear_user_pages':
+include/linux/highmem.h:234:63: warning: parameter 'vaddr' set but not used [-Wunused-but-set-parameter=]
+    static inline void clear_user_pages(void *addr, unsigned long vaddr,
+
+Other architectures use an inline function for clear_user_page() which
+avoids the warning.  This is not possible on m68k, as dlush_dcache_page()
+is another macro which is not yet defined where clear_user_page() is
+defined.  Including cacheflush_mm.h will trigger recursive and lots of
+other issues.
+
+So hide the warning with a cast to (void) instead.
+
+While we are here, do the same for copy_user_page().
+
+Link: https://lore.kernel.org/20260525-m68k-clear_user_page-v2-1-0c8981c6eca1@weissschuh.net
+Fixes: 62a9f5a85b98 ("mm: introduce clear_pages() and clear_user_pages()")
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Cc: Andreas Schwab <schwab@linux-m68k.org>
+Cc: Ankur Arora <ankur.a.arora@oracle.com>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/m68k/include/asm/page_mm.h |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/m68k/include/asm/page_mm.h
++++ b/arch/m68k/include/asm/page_mm.h
+@@ -55,10 +55,12 @@ static inline void clear_page(void *page
+ #define clear_user_page(addr, vaddr, page)    \
+       do {    clear_page(addr);               \
+               flush_dcache_page(page);        \
++              (void)(vaddr);                  \
+       } while (0)
+ #define copy_user_page(to, from, vaddr, page) \
+       do {    copy_page(to, from);            \
+               flush_dcache_page(page);        \
++              (void)(vaddr);                  \
+       } while (0)
+ extern unsigned long m68k_memoffset;
diff --git a/queue-7.1/mm-damon-core-disallow-overlapping-input-ranges-for-damon_set_regions.patch b/queue-7.1/mm-damon-core-disallow-overlapping-input-ranges-for-damon_set_regions.patch
new file mode 100644 (file)
index 0000000..37cb7a1
--- /dev/null
@@ -0,0 +1,70 @@
+From 954157679ec34661c2e87e7eb796104a797c32db Mon Sep 17 00:00:00 2001
+From: SJ Park <sj@kernel.org>
+Date: Fri, 3 Jul 2026 09:56:08 -0700
+Subject: mm/damon/core: disallow overlapping input ranges for damon_set_regions()
+
+From: SJ Park <sj@kernel.org>
+
+commit 954157679ec34661c2e87e7eb796104a797c32db upstream.
+
+damon_set_regions() assumes the input ranges are sorted by the address and
+don't overlap each other.  Hence the assumption was initially to be
+explicitly validated.  But commit 97d482f4592f ("mm/damon/sysfs: reuse
+damon_set_regions() for regions setting") has mistakenly removed the
+validation.
+
+This can make DAMON behave in unexpected ways.  At the best, the
+monitoring results snapshot will just look weird since there will be
+overlapping regions.  DAMOS will also work weirdly, applying the same
+action multiple times for overlapping regions, and make DAMOS quota weird.
+More seriously, depending on the setup and regions updates sequence,
+negative size regions can be made.  It will trigger WARN_ONCE() if the
+kernel is built with CONFIG_DAMON_DEBUG_SANITY=y.  Depending on the
+monitoring results, the negative size region can further trigger division
+by zero in damon_merge_two_regions().
+
+Note that some of the consequences including the WARN_ONCE() and the
+divide by zero depend on commits that were introduced after the root cause
+commit 97d482f4592f ("mm/damon/sysfs: reuse damon_set_regions() for
+regions setting").
+
+Fix the problems by checking the assumption and returning an error if
+the input ranges don't meet the assumption.
+
+The issue was discovered [1] by Sashiko.
+
+Link: https://lore.kernel.org/20260703165610.92894-1-sj@kernel.org
+Link: https://lore.kernel.org/20260630041806.151124-1-sj@kernel.org [1]
+Fixes: 97d482f4592f ("mm/damon/sysfs: reuse damon_set_regions() for regions setting")
+Signed-off-by: SJ Park <sj@kernel.org>
+Cc: <stable@vger.kernel.org> # 5.19.x
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/damon/core.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/mm/damon/core.c
++++ b/mm/damon/core.c
+@@ -240,12 +240,19 @@ int damon_set_regions(struct damon_targe
+ {
+       struct damon_region *r, *next;
+       unsigned int i;
++      unsigned long last_end;
+       int err;
+       for (i = 0; i < nr_ranges; i++) {
+-              if (ALIGN_DOWN(ranges[i].start, min_region_sz) >=
+-                              ALIGN(ranges[i].end, min_region_sz))
++              unsigned long start, end;
++
++              start = ALIGN_DOWN(ranges[i].start, min_region_sz);
++              end = ALIGN(ranges[i].end, min_region_sz);
++              if (start >= end)
++                      return -EINVAL;
++              if (i > 0 && last_end > start)
+                       return -EINVAL;
++              last_end = end;
+       }
+       /* Remove regions which are not in the new ranges */
diff --git a/queue-7.1/mm-damon-core-validate-ranges-in-damon_set_regions.patch b/queue-7.1/mm-damon-core-validate-ranges-in-damon_set_regions.patch
new file mode 100644 (file)
index 0000000..4efbd3e
--- /dev/null
@@ -0,0 +1,60 @@
+From 1292c0ecb1caefb8ca064a3639d5673991e8810c Mon Sep 17 00:00:00 2001
+From: SJ Park <sj@kernel.org>
+Date: Mon, 29 Jun 2026 20:52:19 -0700
+Subject: mm/damon/core: validate ranges in damon_set_regions()
+
+From: SJ Park <sj@kernel.org>
+
+commit 1292c0ecb1caefb8ca064a3639d5673991e8810c upstream.
+
+DAMON core logic assumes zero length regions don't exist.  However, a few
+DAMON API callers including DAMON_SYSFS, DAMON_RECLAIM and DAMON_LRU_SORT
+allow users to set empty monitoring target regions.  This could result in
+WARN_ONCE() on CONFIG_DAMON_DEBUG_SANITY enabled kernel, and
+divide-by-zero from damon_merge_two_regions().
+
+For example, the WANR_ONCE() can be triggered like below.
+
+    # grep DAMON_DEBUG_SANITY /boot/config-$(uname -r)
+    # CONFIG_DAMON_DEBUG_SANITY=y
+    # damo start
+    # cd /sys/kernel/mm/damon/admin/kdamonds/0
+    # echo 0 > contexts/0/targets/0/regions/0/start
+    # echo 0 > contexts/0/targets/0/regions/0/end
+    # echo commit > state
+    # dmesg
+    [....]
+    [   73.705780] ------------[ cut here ]------------
+    [   73.707552] start 0 >= end 0
+    [   73.708452] WARNING: mm/damon/core.c:359 at damon_new_region+0x6e/0x80, CPU#1: kdamond.0/758
+    [...]
+
+All DAMON API callers eventually use damon_set_regions() to setup the
+regions.  Add the validation logic in the function.
+
+Link: https://lore.kernel.org/20260630035221.146458-1-sj@kernel.org
+Fixes: 43b0536cb471 ("mm/damon: introduce DAMON-based Reclamation (DAMON_RECLAIM)")
+Signed-off-by: SJ Park <sj@kernel.org>
+Cc: Yang yingliang <yangyingliang@huawei.com>
+Cc: <stable@vger.kernel.org> # 5.16.x
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/damon/core.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/mm/damon/core.c
++++ b/mm/damon/core.c
+@@ -242,6 +242,12 @@ int damon_set_regions(struct damon_targe
+       unsigned int i;
+       int err;
++      for (i = 0; i < nr_ranges; i++) {
++              if (ALIGN_DOWN(ranges[i].start, min_region_sz) >=
++                              ALIGN(ranges[i].end, min_region_sz))
++                      return -EINVAL;
++      }
++
+       /* Remove regions which are not in the new ranges */
+       damon_for_each_region_safe(r, next, t) {
+               for (i = 0; i < nr_ranges; i++) {
diff --git a/queue-7.1/mm-huge_memory-set-pg_has_hwpoisoned-only-after-new-folio-head-is-established.patch b/queue-7.1/mm-huge_memory-set-pg_has_hwpoisoned-only-after-new-folio-head-is-established.patch
new file mode 100644 (file)
index 0000000..0a9134f
--- /dev/null
@@ -0,0 +1,105 @@
+From e1cd30eceb6908fc13bebce41283b885d71ee8d6 Mon Sep 17 00:00:00 2001
+From: Rik van Riel <riel@surriel.com>
+Date: Wed, 1 Jul 2026 13:42:34 -0400
+Subject: mm/huge_memory: set PG_has_hwpoisoned only after new folio head is established
+
+From: Rik van Riel <riel@surriel.com>
+
+commit e1cd30eceb6908fc13bebce41283b885d71ee8d6 upstream.
+
+__split_folio_to_order() copies the hwpoison state onto each new sub-folio
+while splitting a folio to a non-zero order.  It does so via
+
+       if (handle_hwpoison && page_range_has_hwpoisoned(new_head, new_nr_pages))
+               folio_set_has_hwpoisoned(new_folio);
+
+*before* clear_compound_head(new_head)/prep_compound_page(new_head, ...)
+turns @new_head from a tail page into a proper folio head.
+
+PG_has_hwpoisoned is a FOLIO_SECOND_PAGE flag, so
+folio_set_has_hwpoisoned() resolves to folio_flags(folio, 1).  With the
+new compound_info-based page-flags layout, folio_flags() asserts the page
+is not a tail:
+
+       VM_BUG_ON_PGFLAGS(page->compound_info & 1, page);
+       VM_BUG_ON_PGFLAGS(n > 0 && !test_bit(PG_head, &page->flags.f), page);
+
+At the current call site @new_head still has the tail marker
+(compound_info bit 0 set, PG_head clear), so on CONFIG_DEBUG_VM kernels
+this hits:
+
+  kernel BUG at include/linux/page-flags.h:354
+  folio_flags+0x82
+  folio_set_has_hwpoisoned
+  __split_folio_to_order
+  __split_unmapped_folio
+  __folio_split
+  truncate_inode_partial_folio  (shmem hole-punch / MADV_REMOVE)
+
+Reproduced by syzkaller: hwpoison-inject a few subpages of a large shmem
+folio, then MADV_REMOVE (fallocate punch hole) on the same range, which
+splits the partial folio to a non-zero order.
+
+memory_failure() tries to split the poisoned folio to order 0 first, but
+that split is best-effort; when it fails the folio is left large with
+PG_has_hwpoisoned set, the case fa5a06170036 added this hwpoison copying
+for.
+
+Move the folio_set_has_hwpoisoned() call to after
+clear_compound_head()/prep_compound_page(), where @new_folio is a real
+order-new_order head folio (handle_hwpoison implies new_order != 0, so a
+second page always exists).  The flag still lands on the same struct page
+(page[1] of the new folio); only the ordering relative to compound-head
+setup changes, satisfying the FOLIO_SECOND_PAGE precondition.
+
+Link: https://lore.kernel.org/20260701174235.3173401-1-riel@surriel.com
+Fixes: fa5a06170036 ("mm/huge_memory: preserve PG_has_hwpoisoned if a folio is split to >0 order")
+Signed-off-by: Rik van Riel <riel@surriel.com>
+Assisted-by: Claude:claude-opus-4-8
+Reviewed-by: Zi Yan <ziy@nvidia.com>
+Acked-by: David Hildenbrand (Arm) <david@kernel.org>
+Tested-by: Lance Yang <lance.yang@linux.dev>
+Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
+Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
+Cc: Barry Song <baohua@kernel.org>
+Cc: Dev Jain <dev.jain@arm.com>
+Cc: Lance Yang <lance.yang@linux.dev>
+Cc: Liam R. Howlett <liam@infradead.org>
+Cc: Nico Pache <npache@redhat.com>
+Cc: Ryan Roberts <ryan.roberts@arm.com>
+Cc: Yang Shi <yang@os.amperecomputing.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/huge_memory.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -3649,10 +3649,6 @@ static void __split_folio_to_order(struc
+                                (1L << PG_dropbehind) |
+                                LRU_GEN_MASK | LRU_REFS_MASK));
+-              if (handle_hwpoison &&
+-                  page_range_has_hwpoisoned(new_head, new_nr_pages))
+-                      folio_set_has_hwpoisoned(new_folio);
+-
+               new_folio->mapping = folio->mapping;
+               new_folio->index = folio->index + i;
+@@ -3674,6 +3670,14 @@ static void __split_folio_to_order(struc
+                       folio_set_large_rmappable(new_folio);
+               }
++              /*
++               * PG_has_hwpoisoned is on the 2nd page, so set it after
++               * the compound head is prepped.
++               */
++              if (handle_hwpoison &&
++                  page_range_has_hwpoisoned(new_head, new_nr_pages))
++                      folio_set_has_hwpoisoned(new_folio);
++
+               if (folio_test_young(folio))
+                       folio_set_young(new_folio);
+               if (folio_test_idle(folio))
diff --git a/queue-7.1/mm-kmemleak-fix-checksum-computation-for-per-cpu-objects.patch b/queue-7.1/mm-kmemleak-fix-checksum-computation-for-per-cpu-objects.patch
new file mode 100644 (file)
index 0000000..9fe470e
--- /dev/null
@@ -0,0 +1,74 @@
+From 79c37ae3733e93d9d8ea12ecb44f717e61439024 Mon Sep 17 00:00:00 2001
+From: Breno Leitao <leitao@debian.org>
+Date: Fri, 3 Jul 2026 09:17:24 -0700
+Subject: mm/kmemleak: fix checksum computation for per-cpu objects
+
+From: Breno Leitao <leitao@debian.org>
+
+commit 79c37ae3733e93d9d8ea12ecb44f717e61439024 upstream.
+
+The per-cpu object checksum folds each CPU's CRC together with XOR and
+seeds every CRC with 0.  Both choices make update_checksum() miss content
+changes:
+
+  - XOR is self-cancelling, so equal contents on two CPUs cancel out and
+    simultaneous identical changes leave the checksum unchanged.
+  - crc32(0, ...) over all-zero content is 0, so a freshly allocated,
+    zeroed per-cpu area checksums to 0, matching the initial value, and
+    the object is never seen to change.
+
+See discussions at [0].
+
+When update_checksum() wrongly reports an actively modified object as
+unchanged, kmemleak stops greying it for an extra scan and can report a
+live per-cpu object as a leak.
+
+Fold the per-cpu CRC as a single rolling checksum across all CPUs and
+initialise the object checksum to ~0 so the first computed value always
+registers as a change, even for content that hashes to 0.
+reset_checksum() is seeded the same way.
+
+Link: https://lore.kernel.org/all/akfYImSNDh3OjIfR@gmail.com [0]
+Link: https://lore.kernel.org/20260703-kmemleak_checksum-v1-1-5e0ab7d6966f@debian.org
+Fixes: 6c99d4eb7c5e ("kmemleak: enable tracking for percpu pointers")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Co-developed-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/kmemleak.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/mm/kmemleak.c
++++ b/mm/kmemleak.c
+@@ -676,7 +676,7 @@ static struct kmemleak_object *__alloc_o
+       atomic_set(&object->use_count, 1);
+       object->excess_ref = 0;
+       object->count = 0;                      /* white color initially */
+-      object->checksum = 0;
++      object->checksum = ~0;
+       object->del_state = 0;
+       /* task information */
+@@ -970,7 +970,7 @@ static void reset_checksum(unsigned long
+       }
+       raw_spin_lock_irqsave(&object->lock, flags);
+-      object->checksum = 0;
++      object->checksum = ~0;
+       raw_spin_unlock_irqrestore(&object->lock, flags);
+       put_object(object);
+ }
+@@ -1399,7 +1399,8 @@ static bool update_checksum(struct kmeml
+               for_each_possible_cpu(cpu) {
+                       void *ptr = per_cpu_ptr((void __percpu *)object->pointer, cpu);
+-                      object->checksum ^= crc32(0, kasan_reset_tag((void *)ptr), object->size);
++                      object->checksum = crc32(object->checksum,
++                                               kasan_reset_tag((void *)ptr), object->size);
+               }
+       } else {
+               object->checksum = crc32(0, kasan_reset_tag((void *)object->pointer), object->size);
diff --git a/queue-7.1/mm-memory-failure-trace-change-memory_failure_event-to-ras-subsystem.patch b/queue-7.1/mm-memory-failure-trace-change-memory_failure_event-to-ras-subsystem.patch
new file mode 100644 (file)
index 0000000..ccec2e4
--- /dev/null
@@ -0,0 +1,53 @@
+From e57d6e9e20b551e4910d7a6331a81775c3ad6693 Mon Sep 17 00:00:00 2001
+From: Xie Yuanbin <xieyuanbin1@huawei.com>
+Date: Fri, 5 Jun 2026 16:12:13 +0800
+Subject: mm/memory-failure: trace: change memory_failure_event to ras subsystem
+
+From: Xie Yuanbin <xieyuanbin1@huawei.com>
+
+commit e57d6e9e20b551e4910d7a6331a81775c3ad6693 upstream.
+
+Commit 97f0b1345219 ("tracing: add trace event for memory-failure")
+introduced memory_failure_event in ras subsystem.  commit 31807483d395
+("mm/memory-failure: remove the selection of RAS") changed
+memory_failure_event to memory_failure subsystem.  This breaks the
+backward compatibility, some user programs rely on it.
+
+Change memory_failure_event to ras subsystem to keep backward
+compatibility.
+
+Link: https://lore.kernel.org/20260605081213.154660-1-xieyuanbin1@huawei.com
+Fixes: 31807483d395 ("mm/memory-failure: remove the selection of RAS")
+Signed-off-by: Xie Yuanbin <xieyuanbin1@huawei.com>
+Reported-by: Yi Lai <yi1.lai@intel.com>
+Reported-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Closes: https://lore.kernel.org/linux-mm/CY8PR11MB7134346A3E4BB28ECA28D6E989132@CY8PR11MB7134.namprd11.prod.outlook.com
+Acked-by: David Hildenbrand (Arm) <david@kernel.org>
+Reviewed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Reviewed-by: Lance Yang <lance.yang@linux.dev>
+Reviewed-by: Miaohe Lin <linmiaohe@huawei.com>
+Tested-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Reviewed-by: Lance Yang <lance.yang@linux.dev>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/trace/events/memory-failure.h |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/include/trace/events/memory-failure.h
++++ b/include/trace/events/memory-failure.h
+@@ -1,6 +1,10 @@
+ /* SPDX-License-Identifier: GPL-2.0 */
+ #undef TRACE_SYSTEM
+-#define TRACE_SYSTEM memory_failure
++/*
++ * For historical versions, memory_failure_event is in ras subsystem,
++ * some user programs depend on it.
++ */
++#define TRACE_SYSTEM ras
+ #define TRACE_INCLUDE_FILE memory-failure
+ #if !defined(_TRACE_MEMORY_FAILURE_H) || defined(TRACE_HEADER_MULTI_READ)
diff --git a/queue-7.1/mm-page_vma_mapped-fix-device-private-pmd-handling.patch b/queue-7.1/mm-page_vma_mapped-fix-device-private-pmd-handling.patch
new file mode 100644 (file)
index 0000000..c988f4f
--- /dev/null
@@ -0,0 +1,118 @@
+From f84ca9b1888d8fce7dfefe0e750fa971f8797486 Mon Sep 17 00:00:00 2001
+From: Wei Yang <richard.weiyang@gmail.com>
+Date: Tue, 30 Jun 2026 02:15:40 +0000
+Subject: mm/page_vma_mapped: fix device-private PMD handling
+
+From: Wei Yang <richard.weiyang@gmail.com>
+
+commit f84ca9b1888d8fce7dfefe0e750fa971f8797486 upstream.
+
+Commit 65edfda6f3f2 ("mm/rmap: extend rmap and migration support
+device-private entries") introduced the concept of device-private PMD
+entries, but did not correctly update the rmap walk code to account for
+them.
+
+As a result, when page_vma_mapped_walk() encounters device-private PMD
+entries, it takes no action other than to acquire the PMD lock and exit.
+
+However this is highly problematic for two reasons - firstly, device
+private entries possess a PFN so check_pmd() needs to be called to ensure
+an overlapping PFN range.
+
+Secondly, and more importantly, if PVMW_MIGRATION is set the caller
+assumes the returned entry is a migration entry, resulting in memory
+corruption when the caller tries to interpret the device private entry as
+such.
+
+In addition, commit 146287290023 ("mm/huge_memory: implement
+device-private THP splitting") allowed device private PMDs to be split
+like THP mappings, but again did not update this code path.
+
+As a result, we might race a PMD split prior to acquiring the PMD lock.
+
+This patch addresses all of these issues by invoking check_pmd(), ensuring
+PMVW_MIGRATION is not set and checks whether a split raced us we do for
+PMD THP and migration entries.
+
+Instead of checking for a subset of the cases after taking the pmd_lock(),
+put device-private along with pmd_trans_huge() and
+pmd_is_migration_entry().  Also remove thp_migration_supported() as it is
+already guarded by pmd_is_migration_entry().
+
+[akpm@linux-foundation.org: fix Raspberry Pi 1 build, per David]
+Link: https://lore.kernel.org/20260630021540.17297-1-richard.weiyang@gmail.com
+Fixes: 65edfda6f3f2 ("mm/rmap: extend rmap and migration support device-private entries")
+Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
+Suggested-by: David Hildenbrand <david@kernel.org>
+Reviewed-by: Lance Yang <lance.yang@linux.dev>
+Acked-by: Balbir Singh <balbirs@nvidia.com>
+Tested-by: Klara Modin <klarasmodin@gmail.com>
+Cc: SeongJae Park <sj@kernel.org>
+Cc: Zi Yan <ziy@nvidia.com>
+Cc: Lorenzo Stoakes <ljs@kernel.org>
+Cc: <stable@vger.kernel.org>q
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/page_vma_mapped.c |   31 +++++++++++++++++--------------
+ 1 file changed, 17 insertions(+), 14 deletions(-)
+
+--- a/mm/page_vma_mapped.c
++++ b/mm/page_vma_mapped.c
+@@ -242,21 +242,31 @@ restart:
+                */
+               pmde = pmdp_get_lockless(pvmw->pmd);
+-              if (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde)) {
++              if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
++                  (pmd_trans_huge(pmde) || pmd_is_migration_entry(pmde) ||
++                  pmd_is_device_private_entry(pmde))) {
+                       pvmw->ptl = pmd_lock(mm, pvmw->pmd);
+                       pmde = *pvmw->pmd;
+-                      if (!pmd_present(pmde)) {
++                      if (pmd_is_migration_entry(pmde)) {
+                               softleaf_t entry;
+-                              if (!thp_migration_supported() ||
+-                                  !(pvmw->flags & PVMW_MIGRATION))
++                              if (!(pvmw->flags & PVMW_MIGRATION))
+                                       return not_found(pvmw);
+                               entry = softleaf_from_pmd(pmde);
++                              if (!check_pmd(softleaf_to_pfn(entry), pvmw))
++                                      return not_found(pvmw);
++                              return true;
++                      } else if (pmd_is_device_private_entry(pmde)) {
++                              softleaf_t entry;
+-                              if (!softleaf_is_migration(entry) ||
+-                                  !check_pmd(softleaf_to_pfn(entry), pvmw))
++                              if (pvmw->flags & PVMW_MIGRATION)
++                                      return not_found(pvmw);
++                              entry = softleaf_from_pmd(pmde);
++                              if (!check_pmd(softleaf_to_pfn(entry), pvmw))
+                                       return not_found(pvmw);
+                               return true;
++                      } else if (!pmd_present(pmde)) {
++                              return not_found(pvmw);
+                       }
+                       if (likely(pmd_trans_huge(pmde))) {
+                               if (pvmw->flags & PVMW_MIGRATION)
+@@ -265,17 +275,10 @@ restart:
+                                       return not_found(pvmw);
+                               return true;
+                       }
+-                      /* THP pmd was split under us: handle on pte level */
++                      /* THP/device-private pmd was split under us: handle on pte level */
+                       spin_unlock(pvmw->ptl);
+                       pvmw->ptl = NULL;
+               } else if (!pmd_present(pmde)) {
+-                      const softleaf_t entry = softleaf_from_pmd(pmde);
+-
+-                      if (softleaf_is_device_private(entry)) {
+-                              pvmw->ptl = pmd_lock(mm, pvmw->pmd);
+-                              return true;
+-                      }
+-
+                       if ((pvmw->flags & PVMW_SYNC) &&
+                           thp_vma_suitable_order(vma, pvmw->address,
+                                                  PMD_ORDER) &&
diff --git a/queue-7.1/mm-slab-fix-a-memory-leak-due-to-bootstrapping-sheaves-twice.patch b/queue-7.1/mm-slab-fix-a-memory-leak-due-to-bootstrapping-sheaves-twice.patch
new file mode 100644 (file)
index 0000000..e32589c
--- /dev/null
@@ -0,0 +1,58 @@
+From 1dba91a0493b7ffe9cbbcf7a8df1b361ddcac515 Mon Sep 17 00:00:00 2001
+From: "Harry Yoo (Oracle)" <harry@kernel.org>
+Date: Mon, 13 Jul 2026 23:28:49 +0900
+Subject: mm/slab: fix a memory leak due to bootstrapping sheaves twice
+
+From: Harry Yoo (Oracle) <harry@kernel.org>
+
+commit 1dba91a0493b7ffe9cbbcf7a8df1b361ddcac515 upstream.
+
+When kmalloc caches are aliased, multiple cache pointers reference
+the same kmem_cache. As a result, iterating over kmalloc indices and
+bootstrapping sheaves can bootstrap the same cache more than once and
+leak memory.
+
+Currently, this could happen when the architecture specifies
+minimum alignment for slab caches that is larger than
+ARCH_KMALLOC_MINALIGN.
+
+Bootstrap sheaves only when the cache does not have them already.
+Add a warning when bootstrap_cache_sheaves() is called for a cache
+that already has sheaves enabled.
+
+Fixes: 913ffd3a1bf5 ("slab: handle kmalloc sheaves bootstrap")
+Cc: stable@vger.kernel.org
+Signed-off-by: Harry Yoo (Oracle) <harry@kernel.org>
+Reviewed-by: Suren Baghdasaryan <surenb@google.com>
+Link: https://patch.msgid.link/20260713-kmalloc-no-objext-v3-1-47c7bd138de7@kernel.org
+Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/slub.c |    9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -8423,6 +8423,8 @@ static void __init bootstrap_cache_sheav
+       bool failed = false;
+       int node, cpu;
++      VM_WARN_ON_ONCE(cache_has_sheaves(s));
++
+       capacity = calculate_sheaf_capacity(s, &empty_args);
+       /* capacity can be 0 due to debugging or SLUB_TINY */
+@@ -8473,8 +8475,11 @@ static void __init bootstrap_kmalloc_she
+       for (type = KMALLOC_NORMAL; type <= KMALLOC_RANDOM_END; type++) {
+               for (int idx = 0; idx < KMALLOC_SHIFT_HIGH + 1; idx++) {
+-                      if (kmalloc_caches[type][idx])
+-                              bootstrap_cache_sheaves(kmalloc_caches[type][idx]);
++                      struct kmem_cache *s = kmalloc_caches[type][idx];
++
++                      /* Do not bootstrap twice when caches are aliased */
++                      if (s && !cache_has_sheaves(s))
++                              bootstrap_cache_sheaves(s);
+               }
+       }
+ }
diff --git a/queue-7.1/mm-slab-prevent-unbounded-recursion-in-free-path-with-new-kmalloc-type.patch b/queue-7.1/mm-slab-prevent-unbounded-recursion-in-free-path-with-new-kmalloc-type.patch
new file mode 100644 (file)
index 0000000..fa64e20
--- /dev/null
@@ -0,0 +1,425 @@
+From d9e6a7623938968e3752b67e37eaff097e559a54 Mon Sep 17 00:00:00 2001
+From: "Harry Yoo (Oracle)" <harry@kernel.org>
+Date: Mon, 13 Jul 2026 23:28:52 +0900
+Subject: mm/slab: prevent unbounded recursion in free path with new kmalloc type
+
+From: Harry Yoo (Oracle) <harry@kernel.org>
+
+commit d9e6a7623938968e3752b67e37eaff097e559a54 upstream.
+
+Commit 280ea9c3154b ("mm/slab: avoid allocating slabobj_ext array from
+its own slab") avoided recursive allocation of obj_exts from kmalloc
+caches of the same size, by bumping the obj_exts array's allocation
+size whenever the array size equals the size of the object being
+allocated.
+
+However, as reported by Danielle Costantino and Shakeel Butt,
+even slabs from kmalloc caches of different sizes can form a cycle
+by allocating obj_exts arrays from each other [1]:
+
+  What happened: a KMALLOC_NORMAL slab's obj_exts array (used by
+  allocation profiling / memcg accounting) is itself kmalloc()'d from a
+  KMALLOC_NORMAL cache, so the "slab holds another slab's obj_exts array"
+  relation can form cycles. With sizeof(struct slabobj_ext) == 16 and
+  the host's geometry:
+
+  - kmalloc-512 has 64 objects/slab -> array is 64*16 == 1024 bytes,
+    served from kmalloc-1k;
+  - kmalloc-1k  has 32 objects/slab -> array is 32*16 ==  512 bytes,
+    served from kmalloc-512.
+
+  A kmalloc-512 slab and a kmalloc-1k slab therefore hold each other's
+  obj_exts array.  Discarding one frees the other's array, which empties
+  and discards that slab, which frees the first's array, and so on:
+  __free_slab() -> free_slab_obj_exts() -> kfree() -> discard_slab() ->
+  __free_slab() recurses along the cycle until the stack is exhausted.
+
+With memory allocation profiling, this allows unbounded recursion
+in the free path and led to a stack overflow on a production host in
+the Meta fleet [1]:
+
+  BUG: TASK stack guard page was hit
+  Oops: stack guard page
+  RIP: 0010:kfree+0x8/0x5d0
+  Call Trace:
+   __free_slab+0x66/0xc0
+   kfree+0x3f0/0x5d0
+   ... ( ~125x __free_slab <-> kfree ) ...
+   <kernel driver freeing a resource>
+   do_syscall_64
+
+It is proposed [1] to resolve this issue by always serving the obj_exts
+array allocation from kmalloc caches (or large kmalloc) of sizes larger
+than the object size. However, as pointed out by Vlastimil Babka [2],
+this can waste an excessive amount of memory as slabs from large
+kmalloc sizes (e.g. kmalloc-8k) generally need obj_exts arrays much
+smaller than the object size.
+
+Therefore, rather than bumping the size, let us take a different
+approach; disallow formation of cycles between kmalloc types when
+allocating obj_exts arrays. Currently, all obj_exts arrays are served
+from normal kmalloc caches. Cycles cannot be created if obj_exts arrays
+of normal kmalloc caches are served from a special kmalloc type that can
+never have obj_exts arrays.
+
+To achieve this, create a new kmalloc type called KMALLOC_NO_OBJ_EXT.
+KMALLOC_NO_OBJ_EXT caches are created with SLAB_NO_OBJ_EXT flag when
+either 1) memory allocation profiling is not permanently disabled,
+or 2) kmalloc types with a priority higher than KMALLOC_CGROUP are
+aliased with KMALLOC_NORMAL.
+
+Sheaf bootstrapping for KMALLOC_NO_OBJ_EXT caches now must be deferred
+because allocation of a barn can trigger obj_exts array allocation of
+normal kmalloc caches when the KMALLOC_NO_OBJ_EXT cache for that size
+is not ready yet. For simplicity, perform bootstrapping of sheaves for
+all kmalloc caches later.
+
+Introduce a new slab alloc flag, SLAB_ALLOC_NO_OBJ_EXT, to prevent
+allocation of obj_exts arrays, and let kmalloc_slab() override the type
+to KMALLOC_NO_OBJ_EXT when specified. Note that kmalloc_type() remains
+unchanged because kmalloc_flags() bypasses the kmalloc fastpath.
+
+Do not pass SLAB_ALLOC_NO_RECURSE to kmalloc_flags() in
+alloc_slab_obj_exts() and instead use SLAB_ALLOC_NO_OBJ_EXT only when
+the objects are allocated from normal kmalloc caches. While this
+prevents unbounded recursive allocation of obj_exts, it allows
+KMALLOC_NO_OBJ_EXT caches to have sheaves.
+
+Since sheaf allocations specify SLAB_ALLOC_NO_RECURSE that prevents
+allocation of both sheaves and obj_exts arrays, the recursion depth
+is bounded.
+
+obj_exts arrays for non-kmalloc-normal caches can now have a valid tag.
+Do not call mark_obj_codetag_empty() when freeing an obj_exts array to
+avoid false warnings. KMALLOC_NO_OBJ_EXT don't need this as they never
+allocate those arrays.
+
+Reported-by: Danielle Costantino <dcostantino@meta.com>
+Reported-by: Shakeel Butt <shakeel.butt@linux.dev>
+Closes: https://lore.kernel.org/linux-mm/20260625230029.703750-1-shakeel.butt@linux.dev [1]
+Fixes: 4b8736964640 ("mm/slab: add allocation accounting into slab allocation and free paths")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/linux-mm/c5c4208d-a6f0-413e-bad9-49be12f12d55@kernel.org [2]
+Signed-off-by: Harry Yoo (Oracle) <harry@kernel.org>
+Reviewed-by: Suren Baghdasaryan <surenb@google.com>
+Link: https://patch.msgid.link/20260713-kmalloc-no-objext-v3-4-47c7bd138de7@kernel.org
+Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/slab.h |  6 +++
+ mm/slab.h            | 32 ++++++++++++++--
+ mm/slab_common.c     | 19 +++++++++-
+ mm/slub.c            | 90 ++++++++++++++++----------------------------
+ 4 files changed, 85 insertions(+), 62 deletions(-)
+
+diff --git a/include/linux/slab.h b/include/linux/slab.h
+index 08d7b6c9c4d6..3a14df50766a 100644
+--- a/include/linux/slab.h
++++ b/include/linux/slab.h
+@@ -708,6 +708,9 @@ enum kmalloc_cache_type {
+ #endif
+ #ifndef CONFIG_MEMCG
+       KMALLOC_CGROUP = KMALLOC_NORMAL,
++#endif
++#ifndef CONFIG_SLAB_OBJ_EXT
++      KMALLOC_NO_OBJ_EXT = KMALLOC_NORMAL,
+ #endif
+       KMALLOC_PARTITION_START = KMALLOC_NORMAL,
+       KMALLOC_PARTITION_END = KMALLOC_PARTITION_START + KMALLOC_PARTITION_CACHES_NR,
+@@ -721,6 +724,9 @@ enum kmalloc_cache_type {
+ #endif
+ #ifdef CONFIG_MEMCG
+       KMALLOC_CGROUP,
++#endif
++#ifdef CONFIG_SLAB_OBJ_EXT
++      KMALLOC_NO_OBJ_EXT,
+ #endif
+       NR_KMALLOC_TYPES
+ };
+diff --git a/mm/slab.h b/mm/slab.h
+index 281a65233795..f5e336b6b6b0 100644
+--- a/mm/slab.h
++++ b/mm/slab.h
+@@ -22,6 +22,7 @@
+ #define SLAB_ALLOC_NOLOCK     0x01 /* a kmalloc_nolock() allocation */
+ #define SLAB_ALLOC_NEW_SLAB   0x02 /* a flag for alloc_slab_obj_exts() */
+ #define SLAB_ALLOC_NO_RECURSE 0x04 /* prevent kmalloc() recursion */
++#define SLAB_ALLOC_NO_OBJ_EXT 0x08 /* prevent obj_exts array allocation */
+ static inline bool alloc_flags_allow_spinning(const unsigned int alloc_flags)
+ {
+@@ -386,12 +387,17 @@ static inline unsigned int size_index_elem(unsigned int bytes)
+  * KMALLOC_MAX_CACHE_SIZE and the caller must check that.
+  */
+ static inline struct kmem_cache *
+-kmalloc_slab(size_t size, kmem_buckets *b, gfp_t flags, kmalloc_token_t token)
++kmalloc_slab(size_t size, kmem_buckets *b, gfp_t flags, kmalloc_token_t token,
++           unsigned int alloc_flags)
+ {
+       unsigned int index;
++      enum kmalloc_cache_type type = kmalloc_type(flags, token);
++
++      if (alloc_flags & SLAB_ALLOC_NO_OBJ_EXT)
++              type = KMALLOC_NO_OBJ_EXT;
+       if (!b)
+-              b = &kmalloc_caches[kmalloc_type(flags, token)];
++              b = &kmalloc_caches[type];
+       if (size <= 192)
+               index = kmalloc_size_index[size_index_elem(size)];
+       else
+@@ -426,7 +432,8 @@ static inline bool is_kmalloc_normal(struct kmem_cache *s)
+ {
+       if (!is_kmalloc_cache(s))
+               return false;
+-      return !(s->flags & (SLAB_CACHE_DMA|SLAB_ACCOUNT|SLAB_RECLAIM_ACCOUNT));
++
++      return !(s->flags & (SLAB_CACHE_DMA|SLAB_ACCOUNT|SLAB_RECLAIM_ACCOUNT|SLAB_NO_OBJ_EXT));
+ }
+ bool __kfree_rcu_sheaf(struct kmem_cache *s, void *obj);
+@@ -529,6 +536,25 @@ static inline void metadata_access_disable(void)
+       kasan_enable_current();
+ }
++/*
++ * Return true if KMALLOC_NORMAL caches may need obj_exts arrays.
++ *
++ * Memory allocation profiling requires obj_exts for all caches.
++ * Memcg usually doesn't need them for normal kmalloc caches, but kmalloc types
++ * with a priority higher than KMALLOC_CGROUP can be aliased with KMALLOC_NORMAL.
++ */
++static inline bool need_kmalloc_no_objext(void)
++{
++      if (!mem_alloc_profiling_permanently_disabled())
++              return true;
++
++      if (!mem_cgroup_kmem_disabled() &&
++                      (KMALLOC_NORMAL == KMALLOC_RECLAIM))
++              return true;
++
++      return false;
++}
++
+ #ifdef CONFIG_SLAB_OBJ_EXT
+ /*
+diff --git a/mm/slab_common.c b/mm/slab_common.c
+index b6426d7ceec9..03ecac12cd86 100644
+--- a/mm/slab_common.c
++++ b/mm/slab_common.c
+@@ -783,11 +783,15 @@ u8 kmalloc_size_index[24] __ro_after_init = {
+ size_t kmalloc_size_roundup(size_t size)
+ {
+       if (size && size <= KMALLOC_MAX_CACHE_SIZE) {
++              struct kmem_cache *s;
++
+               /*
+                * The flags don't matter since size_index is common to all.
+                * Neither does the caller for just getting ->object_size.
+                */
+-              return kmalloc_slab(size, NULL, GFP_KERNEL, __kmalloc_token(0))->object_size;
++              s = kmalloc_slab(size, NULL, GFP_KERNEL, __kmalloc_token(0),
++                               SLAB_ALLOC_DEFAULT);
++              return s->object_size;
+       }
+       /* Above the smaller buckets, size is a multiple of page size. */
+@@ -843,6 +847,12 @@ EXPORT_SYMBOL(kmalloc_size_roundup);
+ #define KMALLOC_PARTITION_NAME(N, sz)
+ #endif
++#ifdef CONFIG_SLAB_OBJ_EXT
++#define KMALLOC_NO_OBJ_EXT_NAME(sz) .name[KMALLOC_NO_OBJ_EXT] = "kmalloc-no-objext-" #sz,
++#else
++#define KMALLOC_NO_OBJ_EXT_NAME(sz)
++#endif
++
+ #define INIT_KMALLOC_INFO(__size, __short_size)                       \
+ {                                                             \
+       .name[KMALLOC_NORMAL]  = "kmalloc-" #__short_size,      \
+@@ -850,6 +860,7 @@ EXPORT_SYMBOL(kmalloc_size_roundup);
+       KMALLOC_CGROUP_NAME(__short_size)                       \
+       KMALLOC_DMA_NAME(__short_size)                          \
+       KMALLOC_PARTITION_NAME(KMALLOC_PARTITION_CACHES_NR, __short_size)       \
++      KMALLOC_NO_OBJ_EXT_NAME(__short_size)                   \
+       .size = __size,                                         \
+ }
+@@ -957,6 +968,12 @@ new_kmalloc_cache(int idx, enum kmalloc_cache_type type)
+                       return;
+               }
+               flags |= SLAB_ACCOUNT;
++      } else if (IS_ENABLED(CONFIG_SLAB_OBJ_EXT) && type == KMALLOC_NO_OBJ_EXT) {
++              if (!need_kmalloc_no_objext()) {
++                      kmalloc_caches[type][idx] = kmalloc_caches[KMALLOC_NORMAL][idx];
++                      return;
++              }
++              flags |= SLAB_NO_OBJ_EXT | SLAB_NO_MERGE;
+       } else if (IS_ENABLED(CONFIG_ZONE_DMA) && (type == KMALLOC_DMA)) {
+               flags |= SLAB_CACHE_DMA;
+       }
+diff --git a/mm/slub.c b/mm/slub.c
+index abe748b7dddb..0337e60db5ac 100644
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -2123,42 +2123,6 @@ static inline void init_slab_obj_exts(struct slab *slab)
+       slab->obj_exts = 0;
+ }
+-/*
+- * Calculate the allocation size for slabobj_ext array.
+- *
+- * When memory allocation profiling is enabled, the obj_exts array
+- * could be allocated from the same slab cache it's being allocated for.
+- * This would prevent the slab from ever being freed because it would
+- * always contain at least one allocated object (its own obj_exts array).
+- *
+- * To avoid this, increase the allocation size when we detect the array
+- * may come from the same cache, forcing it to use a different cache.
+- */
+-static inline size_t obj_exts_alloc_size(struct kmem_cache *s,
+-                                       struct slab *slab, gfp_t gfp)
+-{
+-      size_t sz = sizeof(struct slabobj_ext) * slab->objects;
+-      struct kmem_cache *obj_exts_cache;
+-
+-      if (sz > KMALLOC_MAX_CACHE_SIZE)
+-              return sz;
+-
+-      if (!is_kmalloc_normal(s))
+-              return sz;
+-
+-      obj_exts_cache = kmalloc_slab(sz, NULL, gfp, __kmalloc_token(0));
+-      /*
+-       * We can't simply compare s with obj_exts_cache, because partitioned kmalloc
+-       * caches have multiple caches per size, selected by caller address or type.
+-       * Since caller address or type may differ between kmalloc_slab() and actual
+-       * allocation, bump size when sizes are equal.
+-       */
+-      if (s->object_size == obj_exts_cache->object_size)
+-              return obj_exts_cache->object_size + 1;
+-
+-      return sz;
+-}
+-
+ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
+                       gfp_t gfp, unsigned int alloc_flags)
+ {
+@@ -2168,14 +2132,18 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
+       unsigned long new_exts;
+       unsigned long old_exts;
+       struct slabobj_ext *vec;
+-      size_t sz;
++      size_t sz = sizeof(struct slabobj_ext) * slab->objects;
+       gfp &= ~OBJCGS_CLEAR_MASK;
+-      /* Prevent recursive extension vector allocation */
+-      alloc_flags |= SLAB_ALLOC_NO_RECURSE;
+-      alloc_flags &= ~SLAB_ALLOC_NEW_SLAB;
++      /*
++       * In most cases, obj_exts arrays are allocated from normal kmalloc.
++       * However, normal kmalloc caches must allocate them from
++       * KMALLOC_NO_OBJ_EXT caches to prevent recursion.
++       */
++      if (is_kmalloc_normal(s))
++              alloc_flags |= SLAB_ALLOC_NO_OBJ_EXT;
+-      sz = obj_exts_alloc_size(s, slab, gfp);
++      alloc_flags &= ~SLAB_ALLOC_NEW_SLAB;
+       /* This will use kmalloc_nolock() if alloc_flags say so */
+       vec = kmalloc_flags(sz, gfp | __GFP_ZERO, alloc_flags, slab_nid(slab));
+@@ -2193,8 +2161,21 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
+               return -ENOMEM;
+       }
+-      VM_WARN_ON_ONCE(virt_to_slab(vec) != NULL &&
+-                      virt_to_slab(vec)->slab_cache == s);
++      if (IS_ENABLED(CONFIG_DEBUG_VM)) {
++              struct kmem_cache *exts_cache;
++              struct slab *exts_slab;
++
++              exts_slab = virt_to_slab(vec);
++              if (exts_slab) {
++                      /*
++                       * The vector must be allocated from either normal or
++                       * KMALLOC_NO_OBJ_EXT kmalloc caches to avoid cycles.
++                       */
++                      exts_cache = exts_slab->slab_cache;
++                      WARN_ON_ONCE(!is_kmalloc_normal(exts_cache) &&
++                                      !(exts_cache->flags & SLAB_NO_OBJ_EXT));
++              }
++      }
+       new_exts = (unsigned long)vec;
+ #ifdef CONFIG_MEMCG
+@@ -2217,7 +2198,6 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
+                * assign slabobj_exts in parallel. In this case the existing
+                * objcg vector should be reused.
+                */
+-              mark_obj_codetag_empty(vec);
+               if (unlikely(!allow_spin))
+                       kfree_nolock(vec);
+               else
+@@ -2253,14 +2233,6 @@ static inline void free_slab_obj_exts(struct slab *slab, bool allow_spin)
+               return;
+       }
+-      /*
+-       * obj_exts was created with SLAB_ALLOC_NO_RECURSE flag, therefore its
+-       * corresponding extension will be NULL. alloc_tag_sub() will throw a
+-       * warning if slab has extensions but the extension of an object is
+-       * NULL, therefore replace NULL with CODETAG_EMPTY to indicate that
+-       * the extension for obj_exts is expected to be NULL.
+-       */
+-      mark_obj_codetag_empty(obj_exts);
+       if (allow_spin)
+               kfree(obj_exts);
+       else
+@@ -5356,7 +5328,7 @@ void *__do_kmalloc_node(kmem_buckets *b, gfp_t flags, int node,
+       if (unlikely(!size))
+               return ZERO_SIZE_PTR;
+-      s = kmalloc_slab(size, b, flags, token);
++      s = kmalloc_slab(size, b, flags, token, ac->alloc_flags);
+       ret = slab_alloc_node(s, flags, node, ac);
+       ret = kasan_kmalloc(s, ret, size, flags);
+@@ -5419,7 +5391,9 @@ static void *__kmalloc_nolock_noprof(DECL_TOKEN_PARAMS(size, token), gfp_t gfp_f
+ retry:
+       if (unlikely(size > KMALLOC_MAX_CACHE_SIZE))
+               return NULL;
+-      s = kmalloc_slab(size, NULL, gfp_flags, PASS_TOKEN_PARAM(token));
++
++      s = kmalloc_slab(size, NULL, gfp_flags, PASS_TOKEN_PARAM(token),
++                       ac->alloc_flags);
+       if (!(s->flags & __CMPXCHG_DOUBLE) && !kmem_cache_debug(s))
+               /*
+@@ -7979,10 +7953,10 @@ static int calculate_sizes(struct kmem_cache_args *args, struct kmem_cache *s)
+               s->allocflags |= __GFP_RECLAIMABLE;
+       /*
+-       * For KMALLOC_NORMAL caches we enable sheaves later by
+-       * bootstrap_kmalloc_sheaves() to avoid recursion
++       * For kmalloc caches we enable sheaves later by
++       * bootstrap_kmalloc_sheaves() to avoid recursion.
+        */
+-      if (!is_kmalloc_normal(s))
++      if (!is_kmalloc_cache(s))
+               s->sheaf_capacity = calculate_sheaf_capacity(s, args);
+       /*
+@@ -8548,7 +8522,7 @@ static void __init bootstrap_kmalloc_sheaves(void)
+ {
+       enum kmalloc_cache_type type;
+-      for (type = KMALLOC_NORMAL; type <= KMALLOC_PARTITION_END; type++) {
++      for (type = KMALLOC_NORMAL; type < NR_KMALLOC_TYPES; type++) {
+               for (int idx = 0; idx < KMALLOC_SHIFT_HIGH + 1; idx++) {
+                       struct kmem_cache *s = kmalloc_caches[type][idx];
+-- 
+2.55.0
+
diff --git a/queue-7.1/mm-slub-fix-lost-local-objects-when-bulk-remote-free-batch-fills.patch b/queue-7.1/mm-slub-fix-lost-local-objects-when-bulk-remote-free-batch-fills.patch
new file mode 100644 (file)
index 0000000..78c6335
--- /dev/null
@@ -0,0 +1,95 @@
+From af9ea231c0b4530edc389a3126a69e0699b7699d Mon Sep 17 00:00:00 2001
+From: Shengming Hu <hu.shengming@zte.com.cn>
+Date: Mon, 6 Jul 2026 21:39:09 +0800
+Subject: mm/slub: fix lost local objects when bulk remote free batch fills
+
+From: Shengming Hu <hu.shengming@zte.com.cn>
+
+commit af9ea231c0b4530edc389a3126a69e0699b7699d upstream.
+
+In free_to_pcs_bulk(), when remote_objects[] fills to PCS_BATCH_MAX,
+the code jumps to flush_remote to free the batch. If all remote entries
+have already been compacted out of p[] via tail swaps while local objects
+remain, the flush_remote path returns early since `i < size` no longer
+holds. The leftover local objects are then neither cached in the sheaf
+nor returned to the slab freelist, causing a memory leak.
+
+For illustration:
+ size = 64, local objects at p[0..31], remote objects at p[32..63]
+ After scanning all remotes: i = 32, size = 32
+ p[0..31] local objects are dropped.
+
+Harry pointed out that, although the logic contains a real leak, it does
+not appear to be triggerable with the current in-tree users. To hit this
+path, at least PCS_BATCH_MAX objects, currently hardcoded to 32, need to
+be collected in remote_objects[]. Looking at current kmem_cache_free_bulk()
+users:
+
+* maple_node has sheaf_capacity = 32
+* skbuff_head_cache has sheaf_capacity = 28
+* panthor and msm drivers have sheaf_capacity = 4
+
+The sheaf capacity is, at least for now, derived purely from the object
+size, with the user-requested capacity used as a minimum. Therefore, among
+the current users, only maple_node has a sheaf_capacity large enough to
+reach PCS_BATCH_MAX.
+
+However, for the bug to trigger in maple_node, all objects in the sheaf
+would have to be from remote nodes. In that case, there would be no local
+objects left to leak. So this issue was found by code review rather than
+from a runtime report, and it does not seem to be triggerable by current
+users.
+
+Still, the bug could become reachable with future users, a different sheaf
+capacity, or a change to PCS_BATCH_MAX. Fix the logic by freeing a full
+remote batch in place during the scan and then continuing to process the
+compacted array. This keeps all local objects on the normal fast path,
+while the tail path only handles any leftover partial remote batch. The
+redundant next_remote_batch jump label is removed as well.
+
+Fixes: 989b09b73978 ("slab: skip percpu sheaves for remote object freeing")
+Signed-off-by: Shengming Hu <hu.shengming@zte.com.cn>
+Link: https://patch.msgid.link/202607062139095043SOsLi6TIf403tcjPf8fm@zte.com.cn
+Cc: stable@vger.kernel.org
+Reviewed-by: Harry Yoo (Oracle) <harry@kernel.org>
+Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/slub.c |   12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -6066,7 +6066,6 @@ static void free_to_pcs_bulk(struct kmem
+       void *remote_objects[PCS_BATCH_MAX];
+       unsigned int remote_nr = 0;
+-next_remote_batch:
+       while (i < size) {
+               struct slab *slab = virt_to_slab(p[i]);
+@@ -6081,8 +6080,11 @@ next_remote_batch:
+               if (unlikely(!can_free_to_pcs(slab))) {
+                       remote_objects[remote_nr] = p[i];
+                       p[i] = p[--size];
+-                      if (++remote_nr >= PCS_BATCH_MAX)
+-                              goto flush_remote;
++                      if (++remote_nr >= PCS_BATCH_MAX) {
++                              __kmem_cache_free_bulk(s, remote_nr, &remote_objects[0]);
++                              stat_add(s, FREE_SLOWPATH, remote_nr);
++                              remote_nr = 0;
++                      }
+                       continue;
+               }
+@@ -6166,10 +6168,6 @@ flush_remote:
+       if (remote_nr) {
+               __kmem_cache_free_bulk(s, remote_nr, &remote_objects[0]);
+               stat_add(s, FREE_SLOWPATH, remote_nr);
+-              if (i < size) {
+-                      remote_nr = 0;
+-                      goto next_remote_batch;
+-              }
+       }
+ }
diff --git a/queue-7.1/net-af_iucv-fix-null-deref-in-afiucv_hs_callback_syn.patch b/queue-7.1/net-af_iucv-fix-null-deref-in-afiucv_hs_callback_syn.patch
new file mode 100644 (file)
index 0000000..fa431f2
--- /dev/null
@@ -0,0 +1,46 @@
+From 47a5116e56a6b6fe1e909f244e39cd0fc26ceee4 Mon Sep 17 00:00:00 2001
+From: Hidayath Khan <hidayath@linux.ibm.com>
+Date: Thu, 9 Jul 2026 21:17:32 +0200
+Subject: net/af_iucv: fix NULL deref in afiucv_hs_callback_syn()
+
+From: Hidayath Khan <hidayath@linux.ibm.com>
+
+commit 47a5116e56a6b6fe1e909f244e39cd0fc26ceee4 upstream.
+
+afiucv_hs_callback_syn() allocates the child socket with GFP_ATOMIC.
+If the allocation fails, nsk is NULL.
+
+The connection-refused path is entered when the listen state check
+fails, the accept backlog is full, or nsk is NULL. The code
+unconditionally calls iucv_sock_kill(nsk) in that path.
+
+iucv_sock_kill() does not accept a NULL socket pointer and immediately
+dereferences sk via sock_flag(sk, SOCK_ZAPPED). When nsk is NULL,
+calling iucv_sock_kill(nsk) results in a NULL pointer dereference.
+
+Only call iucv_sock_kill() when a child socket was successfully
+allocated.
+
+Fixes: 3881ac441f64 ("af_iucv: add HiperSockets transport")
+Cc: stable@vger.kernel.org
+Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
+Signed-off-by: Hidayath Khan <hidayath@linux.ibm.com>
+Link: https://patch.msgid.link/20260709191732.124092-1-hidayath@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/iucv/af_iucv.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -1874,7 +1874,8 @@ static int afiucv_hs_callback_syn(struct
+               afiucv_swap_src_dest(skb);
+               trans_hdr->flags = AF_IUCV_FLAG_SYN | AF_IUCV_FLAG_FIN;
+               err = dev_queue_xmit(skb);
+-              iucv_sock_kill(nsk);
++              if (nsk)
++                      iucv_sock_kill(nsk);
+               bh_unlock_sock(sk);
+               goto out;
+       }
diff --git a/queue-7.1/net-gro-fix-double-aggregation-of-flush-marked-skbs.patch b/queue-7.1/net-gro-fix-double-aggregation-of-flush-marked-skbs.patch
new file mode 100644 (file)
index 0000000..4072337
--- /dev/null
@@ -0,0 +1,83 @@
+From e751256486d0ded20f5a9f9863467f1dce65142f Mon Sep 17 00:00:00 2001
+From: Shiming Cheng <shiming.cheng@mediatek.com>
+Date: Thu, 9 Jul 2026 09:46:39 +0800
+Subject: net: gro: fix double aggregation of flush-marked skbs
+
+From: Shiming Cheng <shiming.cheng@mediatek.com>
+
+commit e751256486d0ded20f5a9f9863467f1dce65142f upstream.
+
+Commit 0ab03f353d36 ("net-gro: Fix GRO flush when receiving a GSO
+packet.") added a flush check to skb_gro_receive(), but
+skb_gro_receive_list() lacks the same validation.
+
+As a result, packets marked with NAPI_GRO_CB(skb)->flush may still be
+re-aggregated.
+
+This allows already-GRO'd packets with existing frag_list to be
+re-aggregated into a new GRO session, corrupting the frag_list chain
+structure. When skb_segment() attempts to unpack these malformed packets,
+it encounters invalid state and triggers a kernel panic.
+
+Scenario (Tethering/Device forwarding):
+  1. Driver: Generated aggregated packet P1 via LRO with frag_list
+  2. Dev A: Receives aggregated fraglist packet and flush flag set
+  3. Dev A: Re-enters GRO, skb_gro_receive_list() is called
+  4. Missing flush check allows re-aggregation despite flush flag
+  5. Frag_list chain becomes corrupted (loops or dangling refs)
+  6. Dev B: TX path calls skb_segment(), crashes on corrupted frag_list
+
+Root cause in skb_segment():
+  The check at line ~4891:
+    if (hsize <= 0 && i >= nfrags && skb_headlen(list_skb) &&
+        (skb_headlen(list_skb) == len || sg)) {
+
+  When frag_list is corrupted by double aggregation, when list_skb is
+  a NULL pointer from skb->next, skb_headlen(list_skb) dereference
+  NULL/corrupted pointers occurs.
+
+Call Trace:
+ skb_headlen(NULL skb)
+ skb_segment
+ tcp_gso_segment
+ tcp4_gso_segment
+ inet_gso_segment
+ skb_mac_gso_segment
+ __skb_gso_segment
+ skb_gso_segment
+ validate_xmit_skb
+ validate_xmit_skb_list
+ sch_direct_xmit
+ qdisc_restart
+ __qdisc_run
+ qdisc_run
+ net_tx_action
+
+Fix: Add NAPI_GRO_CB(skb)->flush validation to the early-return check in
+skb_gro_receive_list(), matching the defensive programming pattern of
+skb_gro_receive().
+
+Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shiming Cheng <shiming.cheng@mediatek.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260709014704.3625-1-shiming.cheng@mediatek.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/gro.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/core/gro.c
++++ b/net/core/gro.c
+@@ -229,7 +229,9 @@ done:
+ int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
+ {
+-      if (unlikely(p->len + skb->len >= 65536))
++      /* make sure to check flush flag and to not merge */
++      if (unlikely(p->len + skb->len >= 65536 ||
++                   NAPI_GRO_CB(skb)->flush))
+               return -E2BIG;
+       if (!pskb_may_pull(skb, skb_gro_offset(skb))) {
diff --git a/queue-7.1/net-hip04-fix-rx-buffer-leak-on-build_skb-failure.patch b/queue-7.1/net-hip04-fix-rx-buffer-leak-on-build_skb-failure.patch
new file mode 100644 (file)
index 0000000..60ef3a0
--- /dev/null
@@ -0,0 +1,64 @@
+From 14fa65d10f5696b063a7d8d26e8291ea84a2c6ed Mon Sep 17 00:00:00 2001
+From: Fan Wu <fanwu01@zju.edu.cn>
+Date: Sun, 12 Jul 2026 14:27:29 +0000
+Subject: net: hip04: fix RX buffer leak on build_skb failure
+
+From: Fan Wu <fanwu01@zju.edu.cn>
+
+commit 14fa65d10f5696b063a7d8d26e8291ea84a2c6ed upstream.
+
+When build_skb() fails in hip04_rx_poll(), the driver jumps to the
+refill path without releasing the current RX buffer and its DMA mapping.
+Installing a replacement buffer then overwrites the slot references and
+leaks both resources.
+
+Keep the current slot intact and return budget so NAPI retries the same
+buffer.  Also free a newly allocated RX fragment when dma_map_single()
+fails.
+
+This issue was found by an in-house static analysis tool.
+
+Fixes: 701a0fd52318 ("hip04_eth: fix missing error handle for build_skb failed")
+Cc: stable@vger.kernel.org
+Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260712142729.2057636-1-fanwu01@zju.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/hisilicon/hip04_eth.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/hisilicon/hip04_eth.c
++++ b/drivers/net/ethernet/hisilicon/hip04_eth.c
+@@ -594,7 +594,11 @@ static int hip04_rx_poll(struct napi_str
+               skb = build_skb(buf, priv->rx_buf_size);
+               if (unlikely(!skb)) {
+                       net_dbg_ratelimited("build_skb failed\n");
+-                      goto refill;
++                      /* Retain the slot; return budget so NAPI retries this
++                       * buffer. Refill would overwrite rx_buf[]/rx_phys[]
++                       * and leak them.
++                       */
++                      return budget;
+               }
+               dma_unmap_single(priv->dev, priv->rx_phys[priv->rx_head],
+@@ -622,14 +626,15 @@ static int hip04_rx_poll(struct napi_str
+                       rx++;
+               }
+-refill:
+               buf = netdev_alloc_frag(priv->rx_buf_size);
+               if (!buf)
+                       goto done;
+               phys = dma_map_single(priv->dev, buf,
+                                     RX_BUF_SIZE, DMA_FROM_DEVICE);
+-              if (dma_mapping_error(priv->dev, phys))
++              if (dma_mapping_error(priv->dev, phys)) {
++                      skb_free_frag(buf);
+                       goto done;
++              }
+               priv->rx_buf[priv->rx_head] = buf;
+               priv->rx_phys[priv->rx_head] = phys;
+               hip04_set_recv_desc(priv, phys);
diff --git a/queue-7.1/net-iucv-fix-use-after-free-of-a-severed-iucv_path.patch b/queue-7.1/net-iucv-fix-use-after-free-of-a-severed-iucv_path.patch
new file mode 100644 (file)
index 0000000..a672db8
--- /dev/null
@@ -0,0 +1,61 @@
+From be7cc4656eb1f54029610e82d1f0fdd3f9b5ec0a Mon Sep 17 00:00:00 2001
+From: Bryam Vargas <hexlabsecurity@proton.me>
+Date: Tue, 7 Jul 2026 02:00:54 -0500
+Subject: net/iucv: fix use-after-free of a severed iucv_path
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+commit be7cc4656eb1f54029610e82d1f0fdd3f9b5ec0a upstream.
+
+af_iucv queues not-yet-received message notifications on iucv->message_q,
+each holding a raw pointer to the connection's iucv_path.  When the peer
+severs the connection, iucv_sever_path() frees that path with
+iucv_path_free() but leaves the notifications queued.  A later recvmsg()
+drains message_q via iucv_process_message_q() and hands the stale path to
+message_receive() -- a use-after-free of the freed iucv_path.
+
+Drop the queued notifications when the path is severed; once the path is
+gone they can no longer be received.  This also frees the notifications
+leaked when a socket is closed with messages still queued.
+
+Fixes: f0703c80e515 ("[AF_IUCV]: postpone receival of iucv-packets")
+Closes: https://sashiko.dev/#/patchset/20260705-b4-disp-fc79c0dc-v1-1-d2cdcb57afa9@proton.me?part=1
+Cc: stable@vger.kernel.org
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Link: https://patch.msgid.link/20260707-b4-disp-783fedbb-v1-1-463b9dbda2ea@proton.me
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/iucv/af_iucv.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -336,6 +336,7 @@ static void iucv_sever_path(struct sock
+       unsigned char user_data[16];
+       struct iucv_sock *iucv = iucv_sk(sk);
+       struct iucv_path *path = iucv->path;
++      struct sock_msg_q *p, *n;
+       /* Whoever resets the path pointer, must sever and free it. */
+       if (xchg(&iucv->path, NULL)) {
+@@ -347,6 +348,19 @@ static void iucv_sever_path(struct sock
+               } else
+                       pr_iucv->path_sever(path, NULL);
+               iucv_path_free(path);
++
++              /*
++               * Message notifications queued on message_q still reference
++               * the now freed path; drop them, otherwise a later recvmsg()
++               * would pass the freed iucv_path to message_receive() via
++               * iucv_process_message_q().
++               */
++              spin_lock_bh(&iucv->message_q.lock);
++              list_for_each_entry_safe(p, n, &iucv->message_q.list, list) {
++                      list_del(&p->list);
++                      kfree(p);
++              }
++              spin_unlock_bh(&iucv->message_q.lock);
+       }
+ }
diff --git a/queue-7.1/net-mlx5e-use-sender-devcom-for-mpv-master-up.patch b/queue-7.1/net-mlx5e-use-sender-devcom-for-mpv-master-up.patch
new file mode 100644 (file)
index 0000000..b075644
--- /dev/null
@@ -0,0 +1,78 @@
+From e32649b4bad90a6216d8e93cd7dd050af8ac9740 Mon Sep 17 00:00:00 2001
+From: Manjunath Patil <manjunath.b.patil@oracle.com>
+Date: Tue, 7 Jul 2026 16:39:11 -0700
+Subject: net/mlx5e: Use sender devcom for MPV master-up
+
+From: Manjunath Patil <manjunath.b.patil@oracle.com>
+
+commit e32649b4bad90a6216d8e93cd7dd050af8ac9740 upstream.
+
+After PCIe DPC recovery, mlx5 reloads the affected functions and
+replays multiport affiliation events. In the reported failure, the
+first relevant device error was:
+
+  pcieport 0000:10:01.1: DPC: containment event
+  pcieport 0000:10:01.1: PCIe Bus Error: severity=Uncorrected (Fatal)
+  pcieport 0000:10:01.1:    [ 5] SDES                   (First)
+
+mlx5 recovered the PCI functions and resumed 0000:11:00.1. During
+that resume, RDMA multiport binding replayed
+MLX5_DRIVER_EVENT_AFFILIATION_DONE and mlx5e sent
+MPV_DEVCOM_MASTER_UP. The host then panicked with:
+
+  BUG: kernel NULL pointer dereference, address: 0000000000000010
+  RIP: mlx5_devcom_comp_set_ready+0x5/0x40 [mlx5_core]
+  RDI: 0000000000000000
+
+Call trace included:
+
+  mlx5_devcom_comp_set_ready
+  mlx5e_devcom_event_mpv
+  mlx5_devcom_send_event
+  mlx5_ib_bind_slave_port
+  mlx5r_mp_probe
+  mlx5_pci_resume
+
+MPV devcom registration publishes mlx5e private data to the component
+peer list before mlx5e_devcom_init_mpv() stores the returned component
+device in priv->devcom. A concurrent master-up event can therefore
+reach a peer whose private data is visible but whose priv->devcom
+backpointer is still NULL.
+
+MPV_DEVCOM_MASTER_UP already carries the sender/master mlx5e private
+data as event_data. The ready bit is stored on the shared devcom
+component, not on an individual peer. Use the sender devcom when
+marking the MPV component ready.
+
+This preserves the readiness transition while avoiding a NULL
+dereference of the peer devcom pointer during affiliation replay after
+PCI error recovery.
+
+Fixes: bf11485f8419 ("net/mlx5: Register mlx5e priv to devcom in MPV mode")
+Assisted-by: Codex:gpt-5
+Signed-off-by: Manjunath Patil <manjunath.b.patil@oracle.com>
+Cc: stable@vger.kernel.org # 6.7+
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20260707233911.3651139-1-manjunath.b.patil@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -211,11 +211,11 @@ static void mlx5e_disable_async_events(s
+ static int mlx5e_devcom_event_mpv(int event, void *my_data, void *event_data)
+ {
+-      struct mlx5e_priv *slave_priv = my_data;
++      struct mlx5e_priv *master_priv = event_data;
+       switch (event) {
+       case MPV_DEVCOM_MASTER_UP:
+-              mlx5_devcom_comp_set_ready(slave_priv->devcom, true);
++              mlx5_devcom_comp_set_ready(master_priv->devcom, true);
+               break;
+       case MPV_DEVCOM_MASTER_DOWN:
+               /* no need for comp set ready false since we unregister after
diff --git a/queue-7.1/net-pcs-xpcs-fix-sgmii-state-reading.patch b/queue-7.1/net-pcs-xpcs-fix-sgmii-state-reading.patch
new file mode 100644 (file)
index 0000000..46916f0
--- /dev/null
@@ -0,0 +1,114 @@
+From def9a4745e105145133e442dd8a1c126caf0f553 Mon Sep 17 00:00:00 2001
+From: Coia Prant <coiaprant@gmail.com>
+Date: Fri, 17 Jul 2026 15:43:25 +0800
+Subject: net: pcs: xpcs: fix SGMII state reading
+
+From: Coia Prant <coiaprant@gmail.com>
+
+commit def9a4745e105145133e442dd8a1c126caf0f553 upstream.
+
+Commit 2a22b7ae2fa3 ("net: pcs: xpcs: adapt Wangxun NICs for SGMII mode")
+added a path in xpcs_get_state_c37_sgmii() that reads speed/duplex from
+BMCR after AN completes. However, BMCR does not reflect the negotiated
+result on the hardware where this has been tested:
+
+- On RK3568 (MAC side SGMII), BMCR returns a fixed hardware reset value
+- Wangxun engineer Jiawen Wu confirmed that on their side, "BMCR looks
+  like it only wants to be return as 0" [0]
+
+The correct information is available in CL37_ANSGM_STS, which contains
+the actual link status and negotiated speed/duplex.
+
+This bug was previously masked by phylink core, which overrides the PCS
+link state with the PHY state when a PHY is present:
+
+        /* If we have a phy, the "up" state is the union of both the
+         * PHY and the MAC
+         */
+        if (phy)
+                link_state.link &= pl->phy_state.link;
+
+Thus, when the link is down, the PHY's link_down state is applied on top
+of whatever the PCS reports, hiding the broken PCS state reading path.
+
+Modify xpcs_get_state_c37_sgmii() to:
+1. Read link state from CL37_ANSGM_STS
+2. If link is up, report speed/duplex from CL37_ANSGM_STS
+3. Remove the broken BMCR reading path entirely
+
+Also properly set state->an_complete to reflect the AN completion status,
+and clear CL37_ANCMPLT_INTR when link is down to avoid stale state.
+
+[0] https://lore.kernel.org/all/000c01dd1593$2ac0b0f0$804212d0$@trustnetic.com/
+
+Fixes: 2a22b7ae2fa3 ("net: pcs: xpcs: adapt Wangxun NICs for SGMII mode")
+Cc: stable@vger.kernel.org
+Tested-by: Jiawen Wu <jiawenwu@trustnetic.com>
+Signed-off-by: Coia Prant <coiaprant@gmail.com>
+Tested-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260717074324.3250043-2-coiaprant@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/pcs/pcs-xpcs.c |   32 +++++++-------------------------
+ 1 file changed, 7 insertions(+), 25 deletions(-)
+
+--- a/drivers/net/pcs/pcs-xpcs.c
++++ b/drivers/net/pcs/pcs-xpcs.c
+@@ -1058,6 +1058,7 @@ static int xpcs_get_state_c37_sgmii(stru
+       /* Reset link_state */
+       state->link = false;
++      state->an_complete = false;
+       state->speed = SPEED_UNKNOWN;
+       state->duplex = DUPLEX_UNKNOWN;
+       state->pause = 0;
+@@ -1069,6 +1070,8 @@ static int xpcs_get_state_c37_sgmii(stru
+       if (ret < 0)
+               return ret;
++      state->an_complete = ret & DW_VR_MII_AN_STS_C37_ANCMPLT_INTR;
++
+       if (ret & DW_VR_MII_C37_ANSGM_SP_LNKSTS) {
+               int speed_value;
+@@ -1086,34 +1089,13 @@ static int xpcs_get_state_c37_sgmii(stru
+                       state->duplex = DUPLEX_FULL;
+               else
+                       state->duplex = DUPLEX_HALF;
+-      } else if (ret == DW_VR_MII_AN_STS_C37_ANCMPLT_INTR) {
+-              int speed, duplex;
+-
+-              state->link = true;
+-
+-              speed = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_BMCR);
+-              if (speed < 0)
+-                      return speed;
+-              speed &= BMCR_SPEED100 | BMCR_SPEED1000;
+-              if (speed == BMCR_SPEED1000)
+-                      state->speed = SPEED_1000;
+-              else if (speed == BMCR_SPEED100)
+-                      state->speed = SPEED_100;
+-              else if (speed == 0)
+-                      state->speed = SPEED_10;
+-
+-              duplex = xpcs_read(xpcs, MDIO_MMD_VEND2, MII_ADVERTISE);
+-              if (duplex < 0)
+-                      return duplex;
+-
+-              if (duplex & ADVERTISE_1000XFULL)
+-                      state->duplex = DUPLEX_FULL;
+-              else if (duplex & ADVERTISE_1000XHALF)
+-                      state->duplex = DUPLEX_HALF;
++              return 0;
++      }
++      /* Clear AN complete status or interrupt */
++      if (state->an_complete)
+               xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_INTR_STS, 0);
+-      }
+       return 0;
+ }
diff --git a/queue-7.1/net-qrtr-ns-raise-node-count-limit-to-512.patch b/queue-7.1/net-qrtr-ns-raise-node-count-limit-to-512.patch
new file mode 100644 (file)
index 0000000..2b0f3bc
--- /dev/null
@@ -0,0 +1,38 @@
+From ff194cffd586cbd4cc49eccb002c65f2a902a277 Mon Sep 17 00:00:00 2001
+From: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+Date: Mon, 13 Jul 2026 16:59:01 +0200
+Subject: net: qrtr: ns: Raise node count limit to 512
+
+From: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+
+commit ff194cffd586cbd4cc49eccb002c65f2a902a277 upstream.
+
+The current node limit of 64 breaks the functionality for a number of AI200
+deployments that have up to 384 nodes. Raise the limit to 512.
+
+Fixes: 27d5e84e810b ("net: qrtr: ns: Limit the total number of nodes")
+Cc: stable@vger.kernel.org
+Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260713145901.212396-1-youssef.abdulrahman@oss.qualcomm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/qrtr/ns.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/qrtr/ns.c
++++ b/net/qrtr/ns.c
+@@ -76,11 +76,11 @@ struct qrtr_node {
+  * requirements. If the requirement changes in the future, these values can be
+  * increased.
+  */
+-#define QRTR_NS_MAX_NODES   64
++#define QRTR_NS_MAX_NODES   512
+ #define QRTR_NS_MAX_SERVERS 256
+ #define QRTR_NS_MAX_LOOKUPS 64
+-static u8 node_count;
++static u16 node_count;
+ static struct qrtr_node *node_get(unsigned int node_id)
+ {
diff --git a/queue-7.1/net-sched-serialize-qdisc_rtab_list-against-concurrent-get-put.patch b/queue-7.1/net-sched-serialize-qdisc_rtab_list-against-concurrent-get-put.patch
new file mode 100644 (file)
index 0000000..731397d
--- /dev/null
@@ -0,0 +1,133 @@
+From f43ee0c0730d6191629b5ee1ceae27b1ebfdc047 Mon Sep 17 00:00:00 2001
+From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
+Date: Wed, 15 Jul 2026 08:41:14 -0300
+Subject: net/sched: serialize qdisc_rtab_list against concurrent get/put
+
+From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
+
+commit f43ee0c0730d6191629b5ee1ceae27b1ebfdc047 upstream.
+
+qdisc_get_rtab() and qdisc_put_rtab() mutate the process-global singly
+linked list qdisc_rtab_list and a plain non-atomic 'int refcnt' with no
+lock. This was only safe because every caller historically held the RTNL
+mutex, which serialized all rate-table lookups, inserts and frees.
+
+That invariant no longer holds. cls_flower sets
+TCF_PROTO_OPS_DOIT_UNLOCKED, so tc_new_tfilter() keeps rtnl_held == false
+for it and sets TCA_ACT_FLAGS_NO_RTNL. That flag propagates through
+tcf_exts_validate_ex() -> tcf_action_init() -> tcf_action_init_1() ->
+tcf_police_init(), which calls qdisc_get_rtab()/qdisc_put_rtab() with the
+RTNL mutex NOT held. Two RTM_NEWTFILTER requests on different CPUs, each
+adding a flower filter with a police action carrying the same rate, then
+race on qdisc_rtab_list and on the non-atomic refcnt, leading to a
+use-after-free / double-free of the kmalloc-2k struct qdisc_rate_table.
+qdisc_rtab_list is a single global (not per-netns), so the corrupted
+object is shared system-wide.
+
+  BUG: KASAN: slab-use-after-free in qdisc_put_rtab+0x12f/0x160
+   qdisc_put_rtab+0x12f/0x160
+   tcf_police_init+0xda9/0x1590
+   tcf_action_init_1+0x460/0x6b0
+   tcf_action_init+0x439/0xa40
+   tcf_exts_validate_ex+0x42d/0x550
+   fl_change+0xddd/0x7da0
+   tc_new_tfilter+0xaa7/0x2420
+   rtnetlink_rcv_msg+0x95e/0xe90
+  which belongs to the cache kmalloc-2k of size 2048
+
+Protect qdisc_rtab_list and the refcount with a dedicated spinlock. The
+(sleeping, GFP_KERNEL) allocation in qdisc_get_rtab() is performed before
+taking the lock; if a concurrent inserter added an identical table in the
+meantime the freshly allocated one is freed under the lock, so no
+duplicate is leaked. qdisc_put_rtab() now decrements the refcount and
+unlinks under the same lock.
+
+Fixes: 470502de5bdb ("net: sched: unlock rules update API")
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
+Cc: stable@vger.kernel.org
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20260715114114.446841-1-qwe.aldo@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_api.c |   24 +++++++++++++++++++-----
+ 1 file changed, 19 insertions(+), 5 deletions(-)
+
+--- a/net/sched/sch_api.c
++++ b/net/sched/sch_api.c
+@@ -415,12 +415,13 @@ static __u8 __detect_linklayer(struct tc
+ }
+ static struct qdisc_rate_table *qdisc_rtab_list;
++static DEFINE_SPINLOCK(qdisc_rtab_lock);
+ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
+                                       struct nlattr *tab,
+                                       struct netlink_ext_ack *extack)
+ {
+-      struct qdisc_rate_table *rtab;
++      struct qdisc_rate_table *rtab, *new_rtab;
+       if (tab == NULL || r->rate == 0 ||
+           r->cell_log == 0 || r->cell_log >= 32 ||
+@@ -429,15 +430,20 @@ struct qdisc_rate_table *qdisc_get_rtab(
+               return NULL;
+       }
++      new_rtab = kmalloc_obj(*new_rtab);
++
++      spin_lock(&qdisc_rtab_lock);
+       for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) {
+               if (!memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) &&
+                   !memcmp(&rtab->data, nla_data(tab), TC_RTAB_SIZE)) {
+                       rtab->refcnt++;
++                      spin_unlock(&qdisc_rtab_lock);
++                      kfree(new_rtab);
+                       return rtab;
+               }
+       }
+-      rtab = kmalloc_obj(*rtab);
++      rtab = new_rtab;
+       if (rtab) {
+               rtab->rate = *r;
+               rtab->refcnt = 1;
+@@ -449,6 +455,7 @@ struct qdisc_rate_table *qdisc_get_rtab(
+       } else {
+               NL_SET_ERR_MSG(extack, "Failed to allocate new qdisc rate table");
+       }
++      spin_unlock(&qdisc_rtab_lock);
+       return rtab;
+ }
+ EXPORT_SYMBOL(qdisc_get_rtab);
+@@ -457,18 +464,25 @@ void qdisc_put_rtab(struct qdisc_rate_ta
+ {
+       struct qdisc_rate_table *rtab, **rtabp;
+-      if (!tab || --tab->refcnt)
++      if (!tab)
++              return;
++
++      spin_lock(&qdisc_rtab_lock);
++      if (--tab->refcnt) {
++              spin_unlock(&qdisc_rtab_lock);
+               return;
++      }
+       for (rtabp = &qdisc_rtab_list;
+            (rtab = *rtabp) != NULL;
+            rtabp = &rtab->next) {
+               if (rtab == tab) {
+                       *rtabp = rtab->next;
+-                      kfree(rtab);
+-                      return;
++                      break;
+               }
+       }
++      spin_unlock(&qdisc_rtab_lock);
++      kfree(tab);
+ }
+ EXPORT_SYMBOL(qdisc_put_rtab);
diff --git a/queue-7.1/net-slip-serialize-receive-against-buffer-reallocation.patch b/queue-7.1/net-slip-serialize-receive-against-buffer-reallocation.patch
new file mode 100644 (file)
index 0000000..6504078
--- /dev/null
@@ -0,0 +1,51 @@
+From ee7f9bb9320add61f7b367d7e6cd55e3a3a4d65d Mon Sep 17 00:00:00 2001
+From: Sungmin Kang <726ksm@gmail.com>
+Date: Sat, 18 Jul 2026 16:36:30 +0900
+Subject: net: slip: serialize receive against buffer reallocation
+
+From: Sungmin Kang <726ksm@gmail.com>
+
+commit ee7f9bb9320add61f7b367d7e6cd55e3a3a4d65d upstream.
+
+sl_realloc_bufs() replaces rbuff and updates buffsize while holding
+sl->lock. slip_receive_buf() reads those fields and writes through rbuff
+without holding the lock.
+
+An MTU change can therefore race with receive processing. An MTU shrink
+can expose the new smaller rbuff with the old larger bound, causing an
+out-of-bounds write. A receive callback which already loaded the old
+rbuff can instead continue writing after that buffer has been freed.
+
+Serialize receive processing with sl_realloc_bufs() by holding sl->lock
+while consuming each receive batch.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sungmin Kang <726ksm@gmail.com>
+Link: https://patch.msgid.link/20260718073631.1674-1-726ksm@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/slip/slip.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/slip/slip.c
++++ b/drivers/net/slip/slip.c
+@@ -693,6 +693,8 @@ static void slip_receive_buf(struct tty_
+       if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
+               return;
++      spin_lock_bh(&sl->lock);
++
+       /* Read the characters out of the buffer */
+       while (count--) {
+               if (fp && *fp++) {
+@@ -708,6 +710,8 @@ static void slip_receive_buf(struct tty_
+ #endif
+                       slip_unesc(sl, *cp++);
+       }
++
++      spin_unlock_bh(&sl->lock);
+ }
+ /************************************
diff --git a/queue-7.1/net-stmmac-intel-skip-serdes-reconfig-when-rate-is-unchanged.patch b/queue-7.1/net-stmmac-intel-skip-serdes-reconfig-when-rate-is-unchanged.patch
new file mode 100644 (file)
index 0000000..ca9bdad
--- /dev/null
@@ -0,0 +1,98 @@
+From 0ab78ead2481adb52f9eb5b403865c529f6f2348 Mon Sep 17 00:00:00 2001
+From: Markus Breitenberger <bre@keba.com>
+Date: Mon, 13 Jul 2026 19:16:19 +0200
+Subject: net: stmmac: intel: skip SerDes reconfig when rate is unchanged
+
+From: Markus Breitenberger <bre@keba.com>
+
+commit 0ab78ead2481adb52f9eb5b403865c529f6f2348 upstream.
+
+intel_mac_finish() is registered as the phylink mac_finish()
+callback for the Elkhart Lake SGMII ports. phylink calls it at
+the end of every major link reconfiguration, including the
+initial one during probe.
+
+The callback selects the PMC ModPHY LCPLL programming for the
+requested MAC-side interface and then power-cycles the SerDes.
+On Elkhart Lake that ModPHY is also used by the on-die AHCI
+SATA PHY. Reapplying the programming during the initial
+boot-time link-up disturbs the shared analog block while it is
+still driving SATA, so the SATA link fails to train:
+
+  ata1: SATA link down (SStatus 1 SControl 300)
+
+The disk carrying the root filesystem is never detected and the
+system hangs at rootwait. Ethernet itself comes up normally,
+which makes the failure look unrelated to the network driver.
+
+Before mac_finish() runs, the legacy SerDes power-up path has
+already programmed SERDES_GCR0 for the current interface. The
+1G and 2.5G ModPHY tables selected by mac_finish() correspond
+to the SerDes lane rate, so read that rate back from SERDES_GCR0
+and skip the PMC reprogramming and SerDes power-cycle when it
+already matches the selected interface.
+
+This keeps the disruptive reprogramming out of the boot path
+when the SerDes is configured correctly, while preserving the
+previous behavior when a real SGMII/1000BASE-X to 2500BASE-X
+rate change is needed. If the register read fails, reconfigure
+as before.
+
+Fixes: a42f6b3f1cc1 ("net: stmmac: configure SerDes according to the interface mode")
+Cc: stable@vger.kernel.org
+Signed-off-by: Markus Breitenberger <bre@keba.com>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260713171619.192452-1-bre@breiti.cc
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c |   31 ++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+@@ -524,6 +524,32 @@ static int intel_set_reg_access(const st
+       return ret;
+ }
++/*
++ * Return true if the SerDes lane rate must change to serve @interface.
++ * If the current rate cannot be determined, reconfigure as before.
++ */
++static bool intel_serdes_needs_reconfig(struct stmmac_priv *priv,
++                                      struct intel_priv_data *intel_priv,
++                                      phy_interface_t interface)
++{
++      u32 cur_rate, want_rate;
++      int data;
++
++      if (!intel_priv->mdio_adhoc_addr)
++              return true;
++
++      data = mdiobus_read(priv->mii, intel_priv->mdio_adhoc_addr,
++                          SERDES_GCR0);
++      if (data < 0)
++              return true;
++
++      cur_rate = (data & SERDES_RATE_MASK) >> SERDES_RATE_PCIE_SHIFT;
++      want_rate = interface == PHY_INTERFACE_MODE_2500BASEX ?
++                      SERDES_RATE_PCIE_GEN2 : SERDES_RATE_PCIE_GEN1;
++
++      return cur_rate != want_rate;
++}
++
+ static int intel_mac_finish(struct net_device *ndev,
+                           void *intel_data,
+                           unsigned int mode,
+@@ -535,6 +561,11 @@ static int intel_mac_finish(struct net_d
+       int max_regs = 0;
+       int ret = 0;
++      if (!intel_serdes_needs_reconfig(priv, intel_priv, interface)) {
++              priv->plat->phy_interface = interface;
++              return 0;
++      }
++
+       ret = intel_tsn_lane_is_available(ndev, intel_priv);
+       if (ret < 0) {
+               netdev_info(priv->dev, "No TSN lane available to set the registers.\n");
diff --git a/queue-7.1/net-x25-fix-use-after-free-in-x25_kill_by_neigh.patch b/queue-7.1/net-x25-fix-use-after-free-in-x25_kill_by_neigh.patch
new file mode 100644 (file)
index 0000000..d349400
--- /dev/null
@@ -0,0 +1,66 @@
+From 5499e0602d2faafd42c580d25f615903c3fbe11b Mon Sep 17 00:00:00 2001
+From: David Lee <david.lee@trailofbits.com>
+Date: Mon, 13 Jul 2026 10:47:50 +0000
+Subject: net/x25: fix use-after-free in x25_kill_by_neigh()
+
+From: David Lee <david.lee@trailofbits.com>
+
+commit 5499e0602d2faafd42c580d25f615903c3fbe11b upstream.
+
+x25_kill_by_neigh() walks the global X.25 socket list looking for sockets
+attached to a terminating neighbour. x25_list_lock protects list membership
+while the lookup is in progress, but it does not pin a socket's lifetime
+after the lock is dropped.
+
+The function currently drops x25_list_lock before calling lock_sock(s). A
+concurrent close can run x25_release(), remove the same socket from
+x25_list, and drop the last socket reference in that window. The neighbour
+teardown path can then lock or inspect a freed struct sock/struct x25_sock.
+
+Take sock_hold(s) while x25_list_lock still proves that the list entry is
+live, then drop the temporary reference after the socket has been locked,
+rechecked, and released. Recheck x25_sk(s)->neighbour after lock_sock(),
+because another path may have disconnected the socket before this path
+acquired the socket lock. Restart the list walk after each disconnect
+because the list lock was dropped and the previous iterator state may no
+longer be valid.
+
+A QEMU/KASAN run against origin/master reproduced a slab-use-after-free in
+x25_kill_by_neigh().
+
+Fixes: 7781607938c8 ("net/x25: Fix null-ptr-deref caused by x25_disconnect")
+Cc: stable@vger.kernel.org
+Signed-off-by: David Lee <david.lee@trailofbits.com>
+Assisted-by: Codex:gpt-5.5
+Acked-by: Martin Schiller <ms@dev.tdt.de>
+Link: https://patch.msgid.link/20260713104752.241175-1-david.lee@trailofbits.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/x25/af_x25.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/net/x25/af_x25.c
++++ b/net/x25/af_x25.c
+@@ -1772,15 +1772,19 @@ void x25_kill_by_neigh(struct x25_neigh
+ {
+       struct sock *s;
++again:
+       write_lock_bh(&x25_list_lock);
+       sk_for_each(s, &x25_list) {
+               if (x25_sk(s)->neighbour == nb) {
++                      sock_hold(s);
+                       write_unlock_bh(&x25_list_lock);
+                       lock_sock(s);
+-                      x25_disconnect(s, ENETUNREACH, 0, 0);
++                      if (x25_sk(s)->neighbour == nb)
++                              x25_disconnect(s, ENETUNREACH, 0, 0);
+                       release_sock(s);
+-                      write_lock_bh(&x25_list_lock);
++                      sock_put(s);
++                      goto again;
+               }
+       }
+       write_unlock_bh(&x25_list_lock);
diff --git a/queue-7.1/phonet-pep-fix-use-after-free-in-pep_get_sb.patch b/queue-7.1/phonet-pep-fix-use-after-free-in-pep_get_sb.patch
new file mode 100644 (file)
index 0000000..273d200
--- /dev/null
@@ -0,0 +1,48 @@
+From 0f71f852a96af9685858ce59fda34ecbf85c283d Mon Sep 17 00:00:00 2001
+From: Breno Leitao <leitao@debian.org>
+Date: Tue, 21 Jul 2026 01:58:45 -0700
+Subject: phonet: pep: fix use-after-free in pep_get_sb()
+
+From: Breno Leitao <leitao@debian.org>
+
+commit 0f71f852a96af9685858ce59fda34ecbf85c283d upstream.
+
+pep_get_sb() doesn't consider that pskb_may_pull() might have relocated
+the skb data, and continue to access the older pointer, causing UAF.
+
+Reproduced under KASAN:
+
+  BUG: KASAN: slab-use-after-free in pep_get_sb+0x234/0x3b0
+  Read of size 1 at addr ff11000105510f50 by task repro/157
+   pep_get_sb+0x234/0x3b0
+   pipe_handler_do_rcv+0x5f7/0xa10
+   pep_do_rcv+0x203/0x410
+   __sk_receive_skb+0x471/0x4a0
+   phonet_rcv+0x5b3/0x6c0
+   __netif_receive_skb+0xcc/0x1d0
+
+Refetch the header with skb_header_pointer() after pskb_may_pull(), so
+the possibly stale pointer is no longer dereferenced. There are better
+ways to solve this, but, this is the less instrusive one.
+
+Fixes: 9641458d3ec4 ("Phonet: Pipe End Point for Phonet Pipes protocol")
+Cc: stable@vger.kernel.org
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Link: https://patch.msgid.link/20260721-phonet_get_sb_uaf-v1-1-95fd7881cc4e@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/phonet/pep.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/phonet/pep.c
++++ b/net/phonet/pep.c
+@@ -55,6 +55,8 @@ static unsigned char *pep_get_sb(struct
+       ph = skb_header_pointer(skb, 0, 2, &h);
+       if (ph == NULL || ph->sb_len < 2 || !pskb_may_pull(skb, ph->sb_len))
+               return NULL;
++      /* pskb_may_pull() may have reallocated the head; refetch ph. */
++      ph = skb_header_pointer(skb, 0, 2, &h);
+       ph->sb_len -= 2;
+       *ptype = ph->sb_type;
+       *plen = ph->sb_len;
diff --git a/queue-7.1/proc-fix-broken-error-paths-for-namespace-links.patch b/queue-7.1/proc-fix-broken-error-paths-for-namespace-links.patch
new file mode 100644 (file)
index 0000000..ee75b5c
--- /dev/null
@@ -0,0 +1,52 @@
+From 425224c2d700391729be7fe6929a88ef4e2d7a4e Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+Date: Mon, 6 Jul 2026 20:22:42 +0200
+Subject: proc: Fix broken error paths for namespace links
+
+From: Jann Horn <jannh@google.com>
+
+commit 425224c2d700391729be7fe6929a88ef4e2d7a4e upstream.
+
+Don't return the return value of down_read_killable() (0) when a ptrace
+access check fails, return -EACCES as intended.
+
+Reported-by: Magnus Lindholm <linmag7@gmail.com>
+Closes: https://lore.kernel.org/r/20260706170735.2941493-1-linmag7@gmail.com
+Fixes: 6650527444da ("proc: protect ptrace_may_access() with exec_update_lock (part 1)")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jann Horn <jannh@google.com>
+Link: https://patch.msgid.link/20260706-procfs-ns-eacces-fix-v1-1-a69ab14c02e6@google.com
+Tested-by: Magnus Lindholm <linmag7@gmail.com>
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/proc/namespaces.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/proc/namespaces.c
++++ b/fs/proc/namespaces.c
+@@ -46,7 +46,7 @@ static const char *proc_ns_get_link(stru
+       const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops;
+       struct task_struct *task;
+       struct path ns_path;
+-      int error = -EACCES;
++      int error;
+       if (!dentry)
+               return ERR_PTR(-ECHILD);
+@@ -59,6 +59,7 @@ static const char *proc_ns_get_link(stru
+       if (error)
+               goto out_put_task;
++      error = -EACCES;
+       if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
+               goto out;
+@@ -90,6 +91,7 @@ static int proc_ns_readlink(struct dentr
+       if (res)
+               goto out_put_task;
++      res = -EACCES;
+       if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
+               res = ns_get_name(name, sizeof(name), task, ns_ops);
+               if (res >= 0)
diff --git a/queue-7.1/ptp-ptp_s390-add-missing-facility-check.patch b/queue-7.1/ptp-ptp_s390-add-missing-facility-check.patch
new file mode 100644 (file)
index 0000000..d94bccc
--- /dev/null
@@ -0,0 +1,45 @@
+From e78f1ac37afcb16cb6fef8a2c92591eab6558956 Mon Sep 17 00:00:00 2001
+From: Sven Schnelle <svens@linux.ibm.com>
+Date: Tue, 14 Jul 2026 15:03:42 +0200
+Subject: ptp: ptp_s390: Add missing facility check
+
+From: Sven Schnelle <svens@linux.ibm.com>
+
+commit e78f1ac37afcb16cb6fef8a2c92591eab6558956 upstream.
+
+Only register the physical clock when facility 28 is installed
+and PTFF QAF returns that PTFF QPT is available.
+
+Fixes: 2d7de7a3010d ("s390/time: Add PtP driver")
+Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
+Cc: stable@kernel.org
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Link: https://patch.msgid.link/20260714130342.1971700-3-svens@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ptp/ptp_s390.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/ptp/ptp_s390.c
++++ b/drivers/ptp/ptp_s390.c
+@@ -107,6 +107,9 @@ static __init int ptp_s390_init(void)
+       if (IS_ERR(ptp_stcke_clock))
+               return PTR_ERR(ptp_stcke_clock);
++      if (!test_facility(28) || !ptff_query(PTFF_QPT))
++              return 0;
++
+       ptp_qpt_clock = ptp_clock_register(&ptp_s390_qpt_info, NULL);
+       if (IS_ERR(ptp_qpt_clock)) {
+               ptp_clock_unregister(ptp_stcke_clock);
+@@ -117,7 +120,8 @@ static __init int ptp_s390_init(void)
+ static __exit void ptp_s390_exit(void)
+ {
+-      ptp_clock_unregister(ptp_qpt_clock);
++      if (ptp_qpt_clock)
++              ptp_clock_unregister(ptp_qpt_clock);
+       ptp_clock_unregister(ptp_stcke_clock);
+ }
diff --git a/queue-7.1/rbd-reset-positive-result-codes-to-zero-in-object-map-update-path.patch b/queue-7.1/rbd-reset-positive-result-codes-to-zero-in-object-map-update-path.patch
new file mode 100644 (file)
index 0000000..8974f09
--- /dev/null
@@ -0,0 +1,58 @@
+From a6c4250b81bd30beae94e1b7a4b26fa1193ad2e4 Mon Sep 17 00:00:00 2001
+From: Raphael Zimmer <raphael.zimmer@tu-ilmenau.de>
+Date: Thu, 9 Jul 2026 13:26:20 +0200
+Subject: rbd: Reset positive result codes to zero in object map update path
+
+From: Raphael Zimmer <raphael.zimmer@tu-ilmenau.de>
+
+commit a6c4250b81bd30beae94e1b7a4b26fa1193ad2e4 upstream.
+
+In a reply message to an RBD request, a positive result code indicates
+a data payload, which is not allowed for writes. While
+rbd_osd_req_callback() already resets a positive result code for writes
+to zero, rbd_object_map_callback() does not. This allows a corrupted
+reply to an object map update to trigger the rbd_assert(*result < 0) in
+__rbd_obj_handle_request(). This happens, because
+rbd_object_map_callback() calls rbd_obj_handle_request() ->
+__rbd_obj_handle_request() and passes this positive result code. From
+__rbd_obj_handle_request(), rbd_obj_advance_write() is called, which
+leaves the positive result code unchanged and returns true. Therefore,
+the if(done && *result) branch is executed in __rbd_obj_handle_request()
+and the assertion triggers.
+
+This patch fixes the issue by adjusting the logic in the
+rbd_object_map_callback() path. A positive result code for an object map
+update is now reset to zero (similar to rbd_osd_req_callback()), and the
+message is subsequently handled the same way as if the result code was
+zero from the beginning. Additionally, a WARN_ON_ONCE() is added for
+this case.
+
+Cc: stable@vger.kernel.org
+Fixes: 22e8bd51bb04 ("rbd: support for object-map and fast-diff")
+Signed-off-by: Raphael Zimmer <raphael.zimmer@tu-ilmenau.de>
+Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/rbd.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -1957,10 +1957,15 @@ static int rbd_object_map_update_finish(
+       bool has_current_state;
+       void *p;
+-      if (osd_req->r_result)
++      if (osd_req->r_result < 0)
+               return osd_req->r_result;
+       /*
++       * Writes aren't allowed to return a data payload.
++       */
++      WARN_ON_ONCE(osd_req->r_result > 0);
++
++      /*
+        * Nothing to do for a snapshot object map.
+        */
+       if (osd_req->r_num_ops == 1)
diff --git a/queue-7.1/sctp-avoid-auth_enable-sysctl-uaf-during-netns-teardown.patch b/queue-7.1/sctp-avoid-auth_enable-sysctl-uaf-during-netns-teardown.patch
new file mode 100644 (file)
index 0000000..5e37d0c
--- /dev/null
@@ -0,0 +1,130 @@
+From f8d5e7846025f4ab15a461235f8ebae9094a361a Mon Sep 17 00:00:00 2001
+From: Zhiling Zou <roxy520tt@gmail.com>
+Date: Wed, 15 Jul 2026 09:50:10 +0800
+Subject: sctp: avoid auth_enable sysctl UAF during netns teardown
+
+From: Zhiling Zou <roxy520tt@gmail.com>
+
+commit f8d5e7846025f4ab15a461235f8ebae9094a361a upstream.
+
+proc_sctp_do_auth() updates the SCTP control socket after changing
+net.sctp.auth_enable. The handler gets the per-net SCTP state from
+ctl->data, so an already opened sysctl file can still target a network
+namespace while that namespace is being torn down.
+
+SCTP previously registered its per-net sysctls from sctp_defaults_init(),
+while the control socket is created later from sctp_ctrlsock_init(). This
+exposed a window during initialization where auth_enable was writable
+before net->sctp.ctl_sock existed, and a teardown window where auth_enable
+stayed writable after inet_ctl_sock_destroy() had released the control
+socket.
+
+Move the per-net SCTP sysctl registration into sctp_ctrlsock_init() after
+sctp_ctl_sock_init() succeeds, and unregister the sysctl table before
+destroying the control socket in sctp_ctrlsock_exit(). If sysctl
+registration fails after the control socket was created, destroy the
+control socket in the same init path.
+
+Make sctp_sysctl_net_unregister() tolerate a missing header and clear the
+saved pointer so init-error and exit paths can safely share the unregister
+helper.
+
+Fixes: 15649fd5415e ("sctp: sysctl: auth_enable: avoid using current->nsproxy")
+Cc: stable@vger.kernel.org
+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>
+Co-developed-by: Qi Tang <tpluszz77@gmail.com>
+Signed-off-by: Qi Tang <tpluszz77@gmail.com>
+Signed-off-by: Zhiling Zou <roxy520tt@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/390cd5e91ed60eea27b0b64d0468301a9e73b808.1784033357.git.roxy520tt@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/protocol.c |   20 ++++++++++++--------
+ net/sctp/sysctl.c   |    9 +++++++--
+ 2 files changed, 19 insertions(+), 10 deletions(-)
+
+--- a/net/sctp/protocol.c
++++ b/net/sctp/protocol.c
+@@ -1377,10 +1377,6 @@ static int __net_init sctp_defaults_init
+       net->sctp.l3mdev_accept = 1;
+ #endif
+-      status = sctp_sysctl_net_register(net);
+-      if (status)
+-              goto err_sysctl_register;
+-
+       /* Allocate and initialise sctp mibs.  */
+       status = init_sctp_mibs(net);
+       if (status)
+@@ -1414,8 +1410,6 @@ err_init_proc:
+       cleanup_sctp_mibs(net);
+ #endif
+ err_init_mibs:
+-      sctp_sysctl_net_unregister(net);
+-err_sysctl_register:
+       return status;
+ }
+@@ -1430,7 +1424,6 @@ static void __net_exit sctp_defaults_exi
+       net->sctp.proc_net_sctp = NULL;
+ #endif
+       cleanup_sctp_mibs(net);
+-      sctp_sysctl_net_unregister(net);
+ }
+ static struct pernet_operations sctp_defaults_ops = {
+@@ -1444,16 +1437,27 @@ static int __net_init sctp_ctrlsock_init
+       /* Initialize the control inode/socket for handling OOTB packets.  */
+       status = sctp_ctl_sock_init(net);
+-      if (status)
++      if (status) {
+               pr_err("Failed to initialize the SCTP control sock\n");
++              return status;
++      }
++
++      status = sctp_sysctl_net_register(net);
++      if (status) {
++              inet_ctl_sock_destroy(net->sctp.ctl_sock);
++              net->sctp.ctl_sock = NULL;
++      }
+       return status;
+ }
+ static void __net_exit sctp_ctrlsock_exit(struct net *net)
+ {
++      sctp_sysctl_net_unregister(net);
++
+       /* Free the control endpoint.  */
+       inet_ctl_sock_destroy(net->sctp.ctl_sock);
++      net->sctp.ctl_sock = NULL;
+ }
+ static struct pernet_operations sctp_ctrlsock_ops = {
+--- a/net/sctp/sysctl.c
++++ b/net/sctp/sysctl.c
+@@ -615,11 +615,16 @@ int sctp_sysctl_net_register(struct net
+ void sctp_sysctl_net_unregister(struct net *net)
+ {
++      struct ctl_table_header *header = net->sctp.sysctl_header;
+       const struct ctl_table *table;
+-      table = net->sctp.sysctl_header->ctl_table_arg;
+-      unregister_net_sysctl_table(net->sctp.sysctl_header);
++      if (!header)
++              return;
++
++      table = header->ctl_table_arg;
++      unregister_net_sysctl_table(header);
+       kfree(table);
++      net->sctp.sysctl_header = NULL;
+ }
+ static struct ctl_table_header *sctp_sysctl_header;
diff --git a/queue-7.1/sctp-close-udp-tunnel-sockets-during-netns-teardown.patch b/queue-7.1/sctp-close-udp-tunnel-sockets-during-netns-teardown.patch
new file mode 100644 (file)
index 0000000..a5929e1
--- /dev/null
@@ -0,0 +1,43 @@
+From ffb2bd7ade36ec4da32c46a6eddbf4515316d08c Mon Sep 17 00:00:00 2001
+From: Zhiling Zou <roxy520tt@gmail.com>
+Date: Wed, 15 Jul 2026 09:50:11 +0800
+Subject: sctp: close UDP tunnel sockets during netns teardown
+
+From: Zhiling Zou <roxy520tt@gmail.com>
+
+commit ffb2bd7ade36ec4da32c46a6eddbf4515316d08c upstream.
+
+proc_sctp_do_udp_port() starts per-net SCTP UDP tunneling sockets when
+net.sctp.udp_port is set, and stops/restarts them when the sysctl value
+changes. The netns exit path does not stop these sockets, so a namespace
+can be torn down while its SCTP UDP tunnel sockets are still installed.
+
+Close the UDP tunnel sockets from sctp_ctrlsock_exit() after unregistering
+the per-net sysctl table. This prevents new sysctl writes from racing in
+while the sockets are being released, and closes the sockets before the
+control socket is destroyed.
+
+Fixes: 046c052b475e ("sctp: enable udp tunneling socks")
+Cc: stable@vger.kernel.org
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Closes: https://sashiko.dev/#/patchset/b9f1f02b0780ad6a719e2413f5f0bb8eb7702d94.1782585631.git.roxy520tt%40gmail.com
+Signed-off-by: Zhiling Zou <roxy520tt@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/6dab75f22855cb219e2e30a5497cab03b970ab91.1784033357.git.roxy520tt@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/protocol.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/sctp/protocol.c
++++ b/net/sctp/protocol.c
+@@ -1454,6 +1454,7 @@ static int __net_init sctp_ctrlsock_init
+ static void __net_exit sctp_ctrlsock_exit(struct net *net)
+ {
+       sctp_sysctl_net_unregister(net);
++      sctp_udp_sock_stop(net);
+       /* Free the control endpoint.  */
+       inet_ctl_sock_destroy(net->sctp.ctl_sock);
diff --git a/queue-7.1/sctp-don-t-free-the-asconf-s-own-transport-in-del-ip-processing.patch b/queue-7.1/sctp-don-t-free-the-asconf-s-own-transport-in-del-ip-processing.patch
new file mode 100644 (file)
index 0000000..ac284ce
--- /dev/null
@@ -0,0 +1,62 @@
+From 9b2854f86f0b56e9027d68e7a3fc909d1a9b566f Mon Sep 17 00:00:00 2001
+From: Jun Yang <junvyyang@tencent.com>
+Date: Tue, 21 Jul 2026 21:14:05 +0800
+Subject: sctp: don't free the ASCONF's own transport in DEL-IP processing
+
+From: Jun Yang <junvyyang@tencent.com>
+
+commit 9b2854f86f0b56e9027d68e7a3fc909d1a9b566f upstream.
+
+sctp_process_asconf() caches the transport the ASCONF chunk is processed
+against in asconf->transport (== chunk->transport, set once in sctp_rcv()).
+For an ASCONF located through its Address Parameter by
+__sctp_rcv_asconf_lookup(), that cached transport corresponds to the
+Address Parameter, which need not be the packet's source address.
+
+sctp_process_asconf_param() rejects a DEL-IP for the packet source address
+(ADDIP D8, SCTP_ERROR_DEL_SRC_IP), but nothing protects asconf->transport.
+A single ASCONF can therefore carry, in order:
+
+    [Address Parameter L] [DEL-IP L] [DEL-IP 0.0.0.0]
+
+where L differs from the source. The DEL-IP for L passes the D8 check and
+calls sctp_assoc_rm_peer() on the transport that asconf->transport still
+points at, freeing it (RCU-deferred). The following wildcard DEL-IP then
+reuses the now-dangling asconf->transport in sctp_assoc_set_primary() and
+sctp_assoc_del_nonprimary_peers(): set_primary() dereferences the freed
+transport (->ipaddr, ->state) and plants the dangling pointer into
+asoc->peer.primary_path / active_path, and del_nonprimary_peers(), keeping
+only the pointer that is no longer on the list, removes every real
+transport, leaving the association with a transport_count of 0 and
+primary_path/active_path pointing at freed memory.
+
+Reject a DEL-IP that targets the transport the ASCONF is being processed
+against, mirroring the existing source-address guard, so the wildcard
+branch can never reuse a freed transport.
+
+Fixes: 42e30bf3463c ("[SCTP]: Handle the wildcard ADD-IP Address parameter")
+Cc: stable@kernel.org
+Signed-off-by: Jun Yang <junvyyang@tencent.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/tencent_73762ED1DF08CC9D5F5F61954B01350CFE0A@qq.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/sm_make_chunk.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/net/sctp/sm_make_chunk.c
++++ b/net/sctp/sm_make_chunk.c
+@@ -3153,6 +3153,12 @@ static __be16 sctp_process_asconf_param(
+               if (!peer)
+                       return SCTP_ERROR_DNS_FAILED;
++              /* Don't free asconf->transport; a later wildcard DEL-IP
++               * parameter reuses it.
++               */
++              if (peer == asconf->transport)
++                      return SCTP_ERROR_REQ_REFUSED;
++
+               sctp_assoc_rm_peer(asoc, peer);
+               break;
+       case SCTP_PARAM_SET_PRIMARY:
diff --git a/queue-7.1/selftests-ftrace-reset-triggers-at-top-level-before-instance-loop.patch b/queue-7.1/selftests-ftrace-reset-triggers-at-top-level-before-instance-loop.patch
new file mode 100644 (file)
index 0000000..71a97f7
--- /dev/null
@@ -0,0 +1,45 @@
+From 1a087033a6bad73b4140020b40e819b0933aafc3 Mon Sep 17 00:00:00 2001
+From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
+Date: Fri, 17 Jul 2026 11:51:59 +0900
+Subject: selftests/ftrace: Reset triggers at top level before instance loop
+
+From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+
+commit 1a087033a6bad73b4140020b40e819b0933aafc3 upstream.
+
+When running instance tests, 'ftracetest' creates a new ftrace instance
+and runs the tests inside it. Before starting each test, it executes
+'initialize_system()' to reset the ftrace state to initial-state.
+
+However, since 'initialize_system()' is executed in the context of the
+instance directory, it only cleans up triggers and filters of that
+instance.
+Any triggers or dynamic events left behind in the top-level instance by
+previous failed top-level tests, are left completely untouched. These
+top-level leftovers can cause subsequent instance-based tests to fail
+or even crash the kernel.
+
+Fix this by executing 'initialize_system()' in the top-level tracing
+directory once before entering the instance loop.
+
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/178425671889.84440.9477850701738666404.stgit@devnote2
+Fixes: b5b77be812de ("selftests: ftrace: Allow some tests to be run in a tracing instance")
+Assisted-by: Antigravity:gemini-3.5-flash
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/ftrace/ftracetest |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/tools/testing/selftests/ftrace/ftracetest
++++ b/tools/testing/selftests/ftrace/ftracetest
+@@ -503,6 +503,7 @@ for t in $TEST_CASES; do
+ done
+ # Test on instance loop
++(cd $TRACING_DIR; initialize_system)
+ INSTANCE=" (instance) "
+ for t in $TEST_CASES; do
+   test_on_instance $t || continue
index f417da5e6a7e4d0a165d4c9c938736fd3b02c8e5..04d98dd14c6864ca2eeb3d0fc7de8a496aafecdf 100644 (file)
@@ -614,3 +614,65 @@ mptcp-pm-userspace-fix-use-after-free-in-get_local_id.patch
 selftests-mptcp-userspace_pm-fix-undefined-variable-port.patch
 afs-fix-afs_edit_dir_remove-to-get-not-find-block-0.patch
 btrfs-do-not-try-compression-for-data-reloc-inodes.patch
+userfaultfd-prevent-registration-of-special-vmas.patch
+mm-damon-core-validate-ranges-in-damon_set_regions.patch
+m68k-avoid-wunused-but-set-parameter-in-clear_user_page.patch
+mm-damon-core-disallow-overlapping-input-ranges-for-damon_set_regions.patch
+mm-kmemleak-fix-checksum-computation-for-per-cpu-objects.patch
+mm-memory-failure-trace-change-memory_failure_event-to-ras-subsystem.patch
+mm-page_vma_mapped-fix-device-private-pmd-handling.patch
+mm-huge_memory-set-pg_has_hwpoisoned-only-after-new-folio-head-is-established.patch
+sctp-don-t-free-the-asconf-s-own-transport-in-del-ip-processing.patch
+sctp-avoid-auth_enable-sysctl-uaf-during-netns-teardown.patch
+sctp-close-udp-tunnel-sockets-during-netns-teardown.patch
+ceph-add-owner-capability-checks-for-ceph_ioc_set_layout.patch
+ceph-fix-pre-auth-out-of-bounds-read-on-snaptrace-in-ceph_handle_caps.patch
+ceph-fix-refcount-leak-in-ceph_readdir.patch
+ceph-fix-writeback_count-leak-in-write_folio_nounlock.patch
+libceph-bound-get_version-reply-decode-to-front-len.patch
+libceph-bound-pg_-temp-upmap-upmap_items-length-to-ceph_pg_max_size.patch
+libceph-fix-multiplication-overflow-in-decode_new_up_state_weight.patch
+libceph-fix-two-unsafe-bare-decodes-in-decode_lockers.patch
+libceph-guard-missing-crush-type-name-lookup.patch
+libceph-refresh-auth-authorizer_buf-_len-after-authorizer-update.patch
+libceph-reject-monmaps-advertising-zero-monitors.patch
+libceph-reject-zero-bucket-types-in-crush_decode.patch
+libceph-remove-debugfs-files-before-client-teardown.patch
+amt-fix-use-after-free-in-amt-delayed-works.patch
+asoc-fsl-imx-card-skip-sysclk-reset-for-active-dais-in-shutdown.patch
+asoc-fsl_sai-fix-spurious-bclk-on-resume-by-clearing-byp.patch
+binfmt_elf_fdpic-only-honour-the-first-pt_interp.patch
+fs-super-fix-emergency-thaw-double-unlock-of-s_umount.patch
+fs-preserve-acl_dont_cache-state-in-forget_cached_acl.patch
+fscrypt-add-missing-superblock-check-in-find_or_insert_direct_key.patch
+fscrypt-avoid-dynamic-allocation-in-fscrypt_get_devices.patch
+ftrace-add-global-mutex-to-serialize-trace_parser-access.patch
+io_uring-rw-fix-missing-erestartsys-conversion-in-read-paths.patch
+iomap-fix-out-of-bounds-bitmap_set-with-zero-length-range.patch
+iommu-vt-d-disallow-sva-if-page-walk-is-not-coherent.patch
+mm-slub-fix-lost-local-objects-when-bulk-remote-free-batch-fills.patch
+mm-slab-fix-a-memory-leak-due-to-bootstrapping-sheaves-twice.patch
+net-stmmac-intel-skip-serdes-reconfig-when-rate-is-unchanged.patch
+phonet-pep-fix-use-after-free-in-pep_get_sb.patch
+vxlan-require-cap_net_admin-in-the-device-netns-for-changelink.patch
+net-slip-serialize-receive-against-buffer-reallocation.patch
+geneve-require-cap_net_admin-in-the-device-netns-for-changelink.patch
+net-af_iucv-fix-null-deref-in-afiucv_hs_callback_syn.patch
+net-iucv-fix-use-after-free-of-a-severed-iucv_path.patch
+net-mlx5e-use-sender-devcom-for-mpv-master-up.patch
+net-sched-serialize-qdisc_rtab_list-against-concurrent-get-put.patch
+net-x25-fix-use-after-free-in-x25_kill_by_neigh.patch
+net-gro-fix-double-aggregation-of-flush-marked-skbs.patch
+net-hip04-fix-rx-buffer-leak-on-build_skb-failure.patch
+net-pcs-xpcs-fix-sgmii-state-reading.patch
+net-qrtr-ns-raise-node-count-limit-to-512.patch
+proc-fix-broken-error-paths-for-namespace-links.patch
+ptp-ptp_s390-add-missing-facility-check.patch
+ice-fix-ptp-call-trace-during-ptp-release.patch
+selftests-ftrace-reset-triggers-at-top-level-before-instance-loop.patch
+super-fix-emergency-thaw-deadlock-on-frozen-block-devices.patch
+rbd-reset-positive-result-codes-to-zero-in-object-map-update-path.patch
+smb-client-handle-status_stopped_on_symlink-responses-without-a-symlink-target.patch
+ksmbd-defer-destroy_previous_session-until-after-ntlm-authentication.patch
+ksmbd-validate-minimum-pdu-size-for-transform-requests.patch
+mm-slab-prevent-unbounded-recursion-in-free-path-with-new-kmalloc-type.patch
diff --git a/queue-7.1/smb-client-handle-status_stopped_on_symlink-responses-without-a-symlink-target.patch b/queue-7.1/smb-client-handle-status_stopped_on_symlink-responses-without-a-symlink-target.patch
new file mode 100644 (file)
index 0000000..418faa9
--- /dev/null
@@ -0,0 +1,163 @@
+From 2eb74eef4b7eda8df593d22fb48e94ef959ec8a5 Mon Sep 17 00:00:00 2001
+From: Carl Johnson <carl@jpartners.org>
+Date: Tue, 21 Jul 2026 13:27:55 -0400
+Subject: smb: client: handle STATUS_STOPPED_ON_SYMLINK responses without a symlink target
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Carl Johnson <carl@jpartners.org>
+
+commit 2eb74eef4b7eda8df593d22fb48e94ef959ec8a5 upstream.
+
+The macOS built-in SMB server returns STATUS_STOPPED_ON_SYMLINK for a
+CREATE on a path whose final component is a symlink, but it does not
+include a Symbolic Link Error Response in the error data: both
+ErrorContextCount and ByteCount are zero, so the symlink target is not
+present in the response at all.  Per [MS-SMB2] section 2.2.2 such a
+response should carry a valid Symbolic Link Error Response, so this is a
+server bug, but the target can still be retrieved with
+FSCTL_GET_REPARSE_POINT.
+
+Frame from a capture against macOS 26.5.2 (build 25F84):
+
+    SMB2 hdr : Status=0x8000002d STATUS_STOPPED_ON_SYMLINK, Cmd=Create
+    Error Rsp: StructureSize=0x0009
+               Error Context Count: 0
+               Byte Count: 0
+               Error Data: 00
+
+symlink_data() cannot find a struct smb2_symlink_err_rsp in such a
+response and returns -EINVAL, which parse_create_response() propagates,
+so smb2_query_path_info() bails out at
+
+       if (rc || !data->reparse_point)
+               goto out;
+
+before it can retry with SMB2_OP_GET_REPARSE.  stat(), readlink() and ls
+of any server-side symlink then fail with -EINVAL:
+
+  $ ls -la Config
+  l????????? ? ? ? ? ? Config.json
+  $ stat Config/Config.json
+  stat: cannot statx 'Config/Config.json': Invalid argument
+
+A 5.10 client resolves these symlinks correctly against the same server
+and share, so this is a regression for Apple SMB servers.
+
+Handle it in several places:
+
+ - symlink_data() detects the empty response (ErrorContextCount and
+   ByteCount both zero) and returns a distinct -ENODATA, so that "server
+   did not send the target" can be told apart from a genuinely malformed
+   response and only this case is worked around.
+
+ - parse_create_response() treats -ENODATA like
+   STATUS_IO_REPARSE_TAG_NOT_HANDLED, which does not carry the target
+   either: leave the reparse tag unset and clear rc, so the existing
+   SMB2_OP_GET_REPARSE path retrieves the target.
+
+ - smb2_query_path_info() only fixes up the symlink target type when the
+   target is already known.  SMB2_OP_GET_REPARSE sets data->reparse.tag
+   but does not parse the target out of the reparse buffer; that happens
+   later, in reparse_info_to_fattr().  Without this check
+   smb2_fix_symlink_target_type() is called with a NULL target and
+   returns -EIO.  This could not happen with servers that send the target
+   inline and therefore skip SMB2_OP_GET_REPARSE.
+
+ - smb2_open_file() maps -ENODATA to -EIO, matching
+   STATUS_IO_REPARSE_TAG_NOT_HANDLED, so its callers retrieve the target
+   with SMB2_OP_GET_REPARSE as well.
+
+Tested on Debian 13, kernel 6.18.38 (armv7), against macOS 26.5.2:
+symlinks now resolve, including relative, parent-traversing and directory
+symlinks, and reads through symlinks succeed.
+
+Cc: stable@vger.kernel.org
+Co-developed-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Carl Johnson <carl@jpartners.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/smb2file.c  |   21 +++++++++++++++++++++
+ fs/smb/client/smb2inode.c |   23 ++++++++++++++++++++---
+ 2 files changed, 41 insertions(+), 3 deletions(-)
+
+--- a/fs/smb/client/smb2file.c
++++ b/fs/smb/client/smb2file.c
+@@ -30,6 +30,19 @@ static struct smb2_symlink_err_rsp *syml
+       u8 *end = (u8 *)err + iov->iov_len;
+       u32 len;
++      /*
++       * Per [MS-SMB2] section 2.2.2, a STATUS_STOPPED_ON_SYMLINK response has to
++       * carry a Symbolic Link Error Response, so ByteCount cannot be zero.  Some
++       * servers (e.g. the macOS built-in SMB server) violate this and return an
++       * empty error response, with both ErrorContextCount and ByteCount set to
++       * zero, i.e. without the symlink target.  Detect this and return -ENODATA
++       * so that callers can tell "server did not send the target" apart from a
++       * malformed response, and retrieve the target with FSCTL_GET_REPARSE_POINT
++       * instead.
++       */
++      if (!err->ErrorContextCount && !le32_to_cpu(err->ByteCount))
++              return ERR_PTR(-ENODATA);
++
+       if (err->ErrorContextCount) {
+               struct smb2_error_context_rsp *p;
+@@ -201,6 +214,14 @@ int smb2_open_file(const unsigned int xi
+                       rc = smb2_parse_symlink_response(oparms->cifs_sb, &err_iov,
+                                                        oparms->path,
+                                                        &data->symlink_target);
++                      /*
++                       * If smb2_parse_symlink_response returned -ENODATA then the
++                       * symlink_target was not sent. Treat this as if the SMB2_open()
++                       * failed with STATUS_IO_REPARSE_TAG_NOT_HANDLED status, which is
++                       * indicated by the -EIO errno.
++                       */
++                      if (rc == -ENODATA)
++                              rc = -EIO;
+                       if (!rc) {
+                               memset(smb2_data, 0, sizeof(*smb2_data));
+                               oparms->create_options |= OPEN_REPARSE_POINT;
+--- a/fs/smb/client/smb2inode.c
++++ b/fs/smb/client/smb2inode.c
+@@ -792,9 +792,19 @@ static int parse_create_response(struct
+               rc = smb2_parse_symlink_response(cifs_sb, iov,
+                                                full_path,
+                                                &data->symlink_target);
+-              if (rc)
++              if (rc != 0 && rc != -ENODATA)
+                       return rc;
+-              tag = IO_REPARSE_TAG_SYMLINK;
++              /*
++               * -ENODATA means that the response was parsed but did not contain
++               * the symlink target at all (see symlink_data()).  Treat it like
++               * STATUS_IO_REPARSE_TAG_NOT_HANDLED, which does not contain it
++               * either: leave the tag unset and clear rc, so that the caller
++               * retrieves the target with SMB2_OP_GET_REPARSE.
++               */
++              if (rc == -ENODATA)
++                      rc = 0;
++              else
++                      tag = IO_REPARSE_TAG_SYMLINK;
+               reparse_point = true;
+               break;
+       case STATUS_SUCCESS:
+@@ -987,7 +997,14 @@ int smb2_query_path_info(const unsigned
+                               rc = -EOPNOTSUPP;
+               }
+-              if (data->reparse.tag == IO_REPARSE_TAG_SYMLINK && !rc) {
++              /*
++               * If the symlink was already parsed in create response then it is needed to fix
++               * its type now (after the second call with OPEN_REPARSE_POINT which filled the
++               * data->fi.Attributes). If the symlink was not parsed in create response then
++               * the data->symlink_target was not filled yet and then the type will be fixed
++               * later after data->symlink_target is filled.
++               */
++              if (data->reparse.tag == IO_REPARSE_TAG_SYMLINK && !rc && data->symlink_target) {
+                       bool directory = le32_to_cpu(data->fi.Attributes) & ATTR_DIRECTORY;
+                       rc = smb2_fix_symlink_target_type(&data->symlink_target, directory, cifs_sb);
+               }
diff --git a/queue-7.1/super-fix-emergency-thaw-deadlock-on-frozen-block-devices.patch b/queue-7.1/super-fix-emergency-thaw-deadlock-on-frozen-block-devices.patch
new file mode 100644 (file)
index 0000000..5fbe67b
--- /dev/null
@@ -0,0 +1,144 @@
+From 749d7aa0377aae32af8c0a4ad43371e7bf830ab5 Mon Sep 17 00:00:00 2001
+From: Christian Brauner <brauner@kernel.org>
+Date: Thu, 23 Jul 2026 11:37:05 +0200
+Subject: super: fix emergency thaw deadlock on frozen block devices
+
+From: Christian Brauner <brauner@kernel.org>
+
+commit 749d7aa0377aae32af8c0a4ad43371e7bf830ab5 upstream.
+
+do_thaw_all_callback() calls bdev_thaw() while holding sb->s_umount
+exclusively. If the block device was frozen via bdev_freeze() dropping
+the last block layer freeze reference calls fs_bdev_thaw() which
+reacquires s_umount:
+
+  do_thaw_all_callback(sb)
+    super_lock_excl(sb)                     # holds sb->s_umount
+    bdev_thaw(sb->s_bdev)
+      mutex_lock(&bdev->bd_fsfreeze_mutex)
+      # bd_fsfreeze_count drops 1 -> 0
+      bd_holder_ops->thaw == fs_bdev_thaw
+        get_bdev_super(bdev)
+          bdev_super_lock(bdev, true)
+            super_lock(sb, true)
+              down_write(&sb->s_umount)     # same task: deadlock
+
+The emergency thaw worker deadlocks against itself holding both
+s_umount and bd_fsfreeze_mutex. That fscks any subsequent unmount,
+freeze, or thaw of that filesystem and block device.
+
+  [   81.878470] sysrq: Show Blocked State
+  [   81.880140] task:kworker/0:1     state:D stack:0     pid:11    tgid:11    ppid:2      task_flags:0x4208060 flags:0x00080000
+  [   81.884876] Workqueue: events do_thaw_all
+  [   81.886656] Call Trace:
+  [   81.887759]  <TASK>
+  [   81.888763]  __schedule+0x579/0x1420
+  [   81.890372]  schedule+0x3a/0x100
+  [   81.891794]  schedule_preempt_disabled+0x15/0x30
+  [   81.893848]  rwsem_down_write_slowpath+0x1ea/0x900
+  [   81.895191]  ? __pfx_do_thaw_all_callback+0x10/0x10
+  [   81.896528]  down_write+0xbd/0xc0
+  [   81.897505]  super_lock+0x91/0x180
+  [   81.898457]  ? __mutex_lock+0xa99/0x1140
+  [   81.900748]  ? __mutex_unlock_slowpath+0x1f/0x400
+  [   81.902069]  bdev_super_lock+0x5b/0x150
+  [   81.903132]  get_bdev_super+0x10/0x60
+  [   81.904042]  fs_bdev_thaw+0x23/0xf0
+  [   81.904755]  bdev_thaw+0x82/0x100
+  [   81.905484]  do_thaw_all_callback+0x2c/0x50
+  [   81.906298]  __iterate_supers+0x5d/0x130
+  [   81.907067]  do_thaw_all+0x20/0x40
+  [   81.907739]  process_one_work+0x206/0x5e0
+  [   81.908545]  worker_thread+0x1e2/0x3c0
+  [   81.909339]  ? __pfx_worker_thread+0x10/0x10
+  [   81.910171]  kthread+0xf4/0x130
+  [   81.910799]  ? __pfx_kthread+0x10/0x10
+  [   81.911528]  ret_from_fork+0x2e2/0x3b0
+  [   81.912259]  ? __pfx_kthread+0x10/0x10
+  [   81.913010]  ret_from_fork_asm+0x1a/0x30
+  [   81.913806]  </TASK>
+
+bdev_super_lock() even documents the violated requirement with
+lockdep_assert_not_held(&sb->s_umount).
+
+Acquiring bd_fsfreeze_mutex under s_umount also inverts the
+bd_fsfreeze_mutex vs. s_umount ordering established by
+bdev_{freeze,thaw}() and can thus ABBA against a concurrent block-layer
+freeze even when the recursive path isn't hit.
+
+Fix this by not holding s_umount around the bdev_thaw() loop at all. Pin
+the superblock with an active reference instead as
+filesystems_freeze_callback() does. The active reference keeps the
+superblock from being shut down and so ->s_bdev stays valid without
+holding s_umount. The block-layer-held freeze is dropped by
+fs_bdev_thaw() with FREEZE_MAY_NEST | FREEZE_HOLDER_USERSPACE exactly as
+a regular unfreeze would and thaw_super_locked() handles
+filesystem-level freezes as before.
+
+The emergency thaw path has deadlocked like this in one form or
+another for a long long time but the current exclusively-held
+shape dates back to commit [1] where thaw_bdev() already ended in
+thaw_super() with s_umount held by do_thaw_all_callback().
+
+Fixes: 08fdc8a0138a ("buffer.c: call thaw_super during emergency thaw") [1]
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260723-work-super-emergency_thaw-v1-1-7c315c600245@kernel.org
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/super.c |   29 ++++++++++++++++-------------
+ 1 file changed, 16 insertions(+), 13 deletions(-)
+
+--- a/fs/super.c
++++ b/fs/super.c
+@@ -1143,16 +1143,30 @@ void emergency_remount(void)
+       }
+ }
++static inline bool get_active_super(struct super_block *sb)
++{
++      bool active = false;
++
++      if (super_lock_excl(sb)) {
++              active = atomic_inc_not_zero(&sb->s_active);
++              super_unlock_excl(sb);
++      }
++      return active;
++}
++
+ static void do_thaw_all_callback(struct super_block *sb, void *unused)
+ {
+-      if (!super_lock_excl(sb))
++      if (!get_active_super(sb))
+               return;
++      /* fs_bdev_thaw() acquires s_umount so it must not be held here */
+       if (IS_ENABLED(CONFIG_BLOCK))
+               while (sb->s_bdev && !bdev_thaw(sb->s_bdev))
+                       pr_warn("Emergency Thaw on %pg\n", sb->s_bdev);
+-      thaw_super_locked(sb, FREEZE_HOLDER_USERSPACE, NULL);
++      if (super_lock_excl(sb))
++              thaw_super_locked(sb, FREEZE_HOLDER_USERSPACE, NULL);
++      deactivate_super(sb);
+ }
+ static void do_thaw_all(struct work_struct *work)
+@@ -1178,17 +1192,6 @@ void emergency_thaw_all(void)
+       }
+ }
+-static inline bool get_active_super(struct super_block *sb)
+-{
+-      bool active = false;
+-
+-      if (super_lock_excl(sb)) {
+-              active = atomic_inc_not_zero(&sb->s_active);
+-              super_unlock_excl(sb);
+-      }
+-      return active;
+-}
+-
+ static const char *filesystems_freeze_ptr = "filesystems_freeze";
+ static void filesystems_freeze_callback(struct super_block *sb, void *freeze_all_ptr)
diff --git a/queue-7.1/userfaultfd-prevent-registration-of-special-vmas.patch b/queue-7.1/userfaultfd-prevent-registration-of-special-vmas.patch
new file mode 100644 (file)
index 0000000..3ec59ef
--- /dev/null
@@ -0,0 +1,58 @@
+From 3c58f641e813c3c71039f8fd4d4e2a3aab713288 Mon Sep 17 00:00:00 2001
+From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
+Date: Thu, 18 Jun 2026 12:50:17 +0300
+Subject: userfaultfd: prevent registration of special VMAs
+
+From: Mike Rapoport (Microsoft) <rppt@kernel.org>
+
+commit 3c58f641e813c3c71039f8fd4d4e2a3aab713288 upstream.
+
+Vova Tokarev says:
+
+  userfaultfd allows registration on shadow stack VMAs.  With userfaultfd
+  access, you can register on the shadow stack, discard a page ... and
+  inject a page with chosen return addresses via UFFDIO_COPY.
+
+Update vma_can_userfault() to reject VM_SHADOW_STACK.
+
+While on it, also reject VM_SPECIAL so that if a driver would implement
+vm_uffd_ops, it wouldn't be possible to register special VMAs with
+userfaultfd.
+
+Since VM_SPECIAL includes VM_DONTEXPAND which is set but hugetlb, exclude
+hugetlb VMAs from the check for VM_SPECIAL.
+
+Link: https://lore.kernel.org/20260618095017.2553004-1-rppt@kernel.org
+Fixes: 54007f818206 ("mm: Introduce VM_SHADOW_STACK for shadow stack memory")
+Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
+Reported-by: vova tokarev <vladimirelitokarev@gmail.com>
+Acked-by: David Hildenbrand (Arm) <david@kernel.org>
+Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: Jan Kara <jack@suse.cz>
+Cc: Linus Torvalds <torvalds@linuxfoundation.org>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/userfaultfd.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/mm/userfaultfd.c
++++ b/mm/userfaultfd.c
+@@ -2095,7 +2095,10 @@ bool vma_can_userfault(struct vm_area_st
+ {
+       const struct vm_uffd_ops *ops = vma_uffd_ops(vma);
+-      if (vma->vm_flags & VM_DROPPABLE)
++      if (vma->vm_flags & (VM_DROPPABLE | VM_SHADOW_STACK))
++              return false;
++
++      if (!is_vm_hugetlb_page(vma) && (vma->vm_flags & VM_SPECIAL))
+               return false;
+       vm_flags &= __VM_UFFD_FLAGS;
diff --git a/queue-7.1/vxlan-require-cap_net_admin-in-the-device-netns-for-changelink.patch b/queue-7.1/vxlan-require-cap_net_admin-in-the-device-netns-for-changelink.patch
new file mode 100644 (file)
index 0000000..8bd837b
--- /dev/null
@@ -0,0 +1,51 @@
+From 3a61bd9637f3d929aa846e4eb3d98b48c26fcb0e Mon Sep 17 00:00:00 2001
+From: Doruk Tan Ozturk <doruk@0sec.ai>
+Date: Thu, 16 Jul 2026 22:34:59 +0200
+Subject: vxlan: require CAP_NET_ADMIN in the device netns for changelink
+
+From: Doruk Tan Ozturk <doruk@0sec.ai>
+
+commit 3a61bd9637f3d929aa846e4eb3d98b48c26fcb0e upstream.
+
+A tunnel changelink() operates on at most two netns, dev_net(dev) and
+the sticky underlay netns vxlan->net. They differ once the device is
+created in or moved to a netns other than the one the request runs in.
+The rtnl changelink path checks CAP_NET_ADMIN only against dev_net(dev),
+so a caller privileged there but not in vxlan->net can rewrite a vxlan
+device whose underlay lives in vxlan->net.
+
+vxlan_changelink() validates and applies the new configuration against
+vxlan->net (vxlan_config_validate(vxlan->net, ...)) and can reopen the
+underlay socket in that netns, so the same reasoning as the tunnel
+changelink series applies here.
+
+Gate vxlan_changelink() with rtnl_dev_link_net_capable(), at the top of
+the op before any attribute is parsed, matching ipgre_changelink() and
+the rest of the "require CAP_NET_ADMIN in the device netns for
+changelink" series.
+
+Found by 0sec automated security-research tooling (https://0sec.ai).
+
+Fixes: 8bcdc4f3a20b ("vxlan: add changelink support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260716203500.70573-2-doruk@0sec.ai
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/vxlan/vxlan_core.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/vxlan/vxlan_core.c
++++ b/drivers/net/vxlan/vxlan_core.c
+@@ -4422,6 +4422,9 @@ static int vxlan_changelink(struct net_d
+       struct vxlan_rdst *dst;
+       int err;
++      if (!rtnl_dev_link_net_capable(dev, vxlan->net))
++              return -EPERM;
++
+       dst = &vxlan->default_dst;
+       err = vxlan_nl2conf(tb, data, dev, &conf, true, extack);
+       if (err)