]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
7.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 2 Jul 2026 13:57:44 +0000 (15:57 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 2 Jul 2026 13:57:44 +0000 (15:57 +0200)
added patches:
9p-avoid-putting-oldfid-in-p9_client_walk-error-path.patch
blk-cgroup-fix-uaf-in-__blkcg_rstat_flush.patch
fbdev-fbcon-fix-out-of-bounds-read-in-err_out-of-fbcon_do_set_font.patch
fbdev-fix-fb_new_modelist-to-prevent-null-ptr-deref-in-fb_videomode_to_var.patch
fbdev-modedb-fix-a-possible-uaf-in-fb_find_mode.patch
fbdev-modedb-fix-misaligned-fields-in-the-1920x1080-60-mode.patch
fbdev-omap2-fix-use-after-free-in-omapfb_mmap.patch
fpga-region-fix-use-after-free-in-child_regions_with_firmware.patch
gfs2-fix-use-after-free-in-gfs2_qd_dealloc.patch
hdlc_ppp-sync-per-proto-timers-before-freeing-hdlc-state.patch
i2c-core-fix-adapter-registration-race.patch
irqchip-imgpdc-fix-resource-leak-add-missing-chained-handler-cleanup-on-remove.patch
ksmbd-fix-out-of-bounds-read-in-smb_check_perm_dacl.patch
kvm-svm-fix-page-overflow-in-sev_dbg_crypt-for-encrypt-path.patch
kvm-x86-hyper-v-bound-the-bank-index-when-querying-sparse-banks.patch
loongarch-report-dying-cpu-to-rcu-in-stop_this_cpu.patch
mips-smp-report-dying-cpu-to-rcu-in-stop_this_cpu.patch
nfs-prevent-resource-leak-in-nfs_alloc_server.patch
nfsd-avoid-leaking-pre-allocated-openowner-on-unconfirmed-retry-race.patch
nfsd-check-get_user-return-when-reading-princhashlen.patch
nfsd-fix-dead-acl-conflict-guard-in-nfsd4_create.patch
nfsd-fix-inverted-cp_ttl-check-in-async-copy-reaper.patch
nfsd-fix-posix_acl-leak-and-ignored-error-in-nfsd4_create_file.patch
nfsd-fix-posix_acl-leak-on-setacl-decode-failure.patch
nfsd-fix-secinfo_no_name-decode-error-cleanup.patch
nfsd-release-layout-stid-on-setlease-failure.patch
nfsd-reset-write-verifier-on-deferred-writeback-errors.patch
nfsv4-clear-exception-state-on-successful-mkdir-retry.patch
nfsv4-flexfiles-reject-zero-filehandle-version-count.patch
nfsv4-pnfs-reject-zero-length-r_addr-in-nfs4_decode_mp_ds_addr.patch
ntfs-serialize-volume-label-accesses.patch
ocfs2-reject-oversized-group-bitmap-descriptors.patch
pnfs-fix-use-after-free-in-pnfs_update_layout.patch
power-reset-linkstation-poweroff-fix-use-after-free-in-the-linkstation_poweroff_init.patch
pwrseq-core-fix-use-after-free-in-pwrseq_debugfs_seq_next.patch
riscv-kfence-call-mark_new_valid_map-for-kfence_unprotect.patch
rpmsg-char-fix-use-after-free-on-probe-error-path.patch
sched-mmcid-fix-oob-clear_bit-when-cid-is-mm_cid_unset-in-fixup-path.patch
tipc-fix-slab-use-after-free-read-in-tipc_aead_decrypt_done.patch

40 files changed:
queue-7.1/9p-avoid-putting-oldfid-in-p9_client_walk-error-path.patch [new file with mode: 0644]
queue-7.1/blk-cgroup-fix-uaf-in-__blkcg_rstat_flush.patch [new file with mode: 0644]
queue-7.1/fbdev-fbcon-fix-out-of-bounds-read-in-err_out-of-fbcon_do_set_font.patch [new file with mode: 0644]
queue-7.1/fbdev-fix-fb_new_modelist-to-prevent-null-ptr-deref-in-fb_videomode_to_var.patch [new file with mode: 0644]
queue-7.1/fbdev-modedb-fix-a-possible-uaf-in-fb_find_mode.patch [new file with mode: 0644]
queue-7.1/fbdev-modedb-fix-misaligned-fields-in-the-1920x1080-60-mode.patch [new file with mode: 0644]
queue-7.1/fbdev-omap2-fix-use-after-free-in-omapfb_mmap.patch [new file with mode: 0644]
queue-7.1/fpga-region-fix-use-after-free-in-child_regions_with_firmware.patch [new file with mode: 0644]
queue-7.1/gfs2-fix-use-after-free-in-gfs2_qd_dealloc.patch [new file with mode: 0644]
queue-7.1/hdlc_ppp-sync-per-proto-timers-before-freeing-hdlc-state.patch [new file with mode: 0644]
queue-7.1/i2c-core-fix-adapter-registration-race.patch [new file with mode: 0644]
queue-7.1/irqchip-imgpdc-fix-resource-leak-add-missing-chained-handler-cleanup-on-remove.patch [new file with mode: 0644]
queue-7.1/ksmbd-fix-out-of-bounds-read-in-smb_check_perm_dacl.patch [new file with mode: 0644]
queue-7.1/kvm-svm-fix-page-overflow-in-sev_dbg_crypt-for-encrypt-path.patch [new file with mode: 0644]
queue-7.1/kvm-x86-hyper-v-bound-the-bank-index-when-querying-sparse-banks.patch [new file with mode: 0644]
queue-7.1/loongarch-report-dying-cpu-to-rcu-in-stop_this_cpu.patch [new file with mode: 0644]
queue-7.1/mips-smp-report-dying-cpu-to-rcu-in-stop_this_cpu.patch [new file with mode: 0644]
queue-7.1/nfs-prevent-resource-leak-in-nfs_alloc_server.patch [new file with mode: 0644]
queue-7.1/nfsd-avoid-leaking-pre-allocated-openowner-on-unconfirmed-retry-race.patch [new file with mode: 0644]
queue-7.1/nfsd-check-get_user-return-when-reading-princhashlen.patch [new file with mode: 0644]
queue-7.1/nfsd-fix-dead-acl-conflict-guard-in-nfsd4_create.patch [new file with mode: 0644]
queue-7.1/nfsd-fix-inverted-cp_ttl-check-in-async-copy-reaper.patch [new file with mode: 0644]
queue-7.1/nfsd-fix-posix_acl-leak-and-ignored-error-in-nfsd4_create_file.patch [new file with mode: 0644]
queue-7.1/nfsd-fix-posix_acl-leak-on-setacl-decode-failure.patch [new file with mode: 0644]
queue-7.1/nfsd-fix-secinfo_no_name-decode-error-cleanup.patch [new file with mode: 0644]
queue-7.1/nfsd-release-layout-stid-on-setlease-failure.patch [new file with mode: 0644]
queue-7.1/nfsd-reset-write-verifier-on-deferred-writeback-errors.patch [new file with mode: 0644]
queue-7.1/nfsv4-clear-exception-state-on-successful-mkdir-retry.patch [new file with mode: 0644]
queue-7.1/nfsv4-flexfiles-reject-zero-filehandle-version-count.patch [new file with mode: 0644]
queue-7.1/nfsv4-pnfs-reject-zero-length-r_addr-in-nfs4_decode_mp_ds_addr.patch [new file with mode: 0644]
queue-7.1/ntfs-serialize-volume-label-accesses.patch [new file with mode: 0644]
queue-7.1/ocfs2-reject-oversized-group-bitmap-descriptors.patch [new file with mode: 0644]
queue-7.1/pnfs-fix-use-after-free-in-pnfs_update_layout.patch [new file with mode: 0644]
queue-7.1/power-reset-linkstation-poweroff-fix-use-after-free-in-the-linkstation_poweroff_init.patch [new file with mode: 0644]
queue-7.1/pwrseq-core-fix-use-after-free-in-pwrseq_debugfs_seq_next.patch [new file with mode: 0644]
queue-7.1/riscv-kfence-call-mark_new_valid_map-for-kfence_unprotect.patch [new file with mode: 0644]
queue-7.1/rpmsg-char-fix-use-after-free-on-probe-error-path.patch [new file with mode: 0644]
queue-7.1/sched-mmcid-fix-oob-clear_bit-when-cid-is-mm_cid_unset-in-fixup-path.patch [new file with mode: 0644]
queue-7.1/series
queue-7.1/tipc-fix-slab-use-after-free-read-in-tipc_aead_decrypt_done.patch [new file with mode: 0644]

diff --git a/queue-7.1/9p-avoid-putting-oldfid-in-p9_client_walk-error-path.patch b/queue-7.1/9p-avoid-putting-oldfid-in-p9_client_walk-error-path.patch
new file mode 100644 (file)
index 0000000..ba00efb
--- /dev/null
@@ -0,0 +1,54 @@
+From 1a3860d46e3eb47dbd60339783cdad7904486b9f Mon Sep 17 00:00:00 2001
+From: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
+Date: Thu, 28 May 2026 13:39:16 +0800
+Subject: 9p: avoid putting oldfid in p9_client_walk() error path
+
+From: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
+
+commit 1a3860d46e3eb47dbd60339783cdad7904486b9f upstream.
+
+When p9_client_walk() is called with clone set to false, fid aliases
+oldfid. If the walk subsequently fails after the request has been sent,
+the error path jumps to clunk_fid, which currently calls p9_fid_put(fid)
+unconditionally.
+
+This drops a reference to oldfid even though ownership of oldfid remains
+with the caller. If this is the last reference, oldfid can be clunked and
+destroyed while the caller still expects it to be valid. A later use or
+put of oldfid can then trigger a use-after-free or refcount underflow.
+
+Fix this by only putting fid in the clunk_fid error path when it does not
+alias oldfid, matching the existing guard in the error path below.
+
+This can be triggered when a multi-component walk is split into multiple
+p9_client_walk() calls and a later non-cloning walk fails. A reproducer
+and refcount warning logs are available on request.
+
+Fixes: b48dbb998d70 ("9p fid refcount: add p9_fid_get/put wrappers")
+Cc: stable@vger.kernel.org
+Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
+Reported-by: Ao Wang <wangao@seu.edu.cn>
+Reported-by: Xuewei Feng <fengxw06@126.com>
+Reported-by: Qi Li <qli01@tsinghua.edu.cn>
+Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
+Assisted-by: GLM 5.1
+Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
+Message-ID: <20260528053918.53550-1-zhaoyz24@mails.tsinghua.edu.cn>
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/9p/client.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -1092,7 +1092,8 @@ struct p9_fid *p9_client_walk(struct p9_
+ clunk_fid:
+       kfree(wqids);
+-      p9_fid_put(fid);
++      if (fid != oldfid)
++              p9_fid_put(fid);
+       fid = NULL;
+ error:
diff --git a/queue-7.1/blk-cgroup-fix-uaf-in-__blkcg_rstat_flush.patch b/queue-7.1/blk-cgroup-fix-uaf-in-__blkcg_rstat_flush.patch
new file mode 100644 (file)
index 0000000..86691f6
--- /dev/null
@@ -0,0 +1,76 @@
+From 0ab5ee5a1badb58cbb2242617cb01a4972b1f2a2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michal=20Koutn=C3=BD?= <mkoutny@suse.com>
+Date: Thu, 5 Feb 2026 23:54:23 +0800
+Subject: blk-cgroup: fix UAF in __blkcg_rstat_flush()
+
+From: Michal Koutný <mkoutny@suse.com>
+
+commit 0ab5ee5a1badb58cbb2242617cb01a4972b1f2a2 upstream.
+
+When multiple blkgs in the same blkcg are released concurrently,
+a use-after-free can occur. The race happens when one blkg's
+__blkcg_rstat_flush() removes another blkg's iostat entries via
+llist_del_all(). The second blkg sees an empty list and proceeds
+to free itself while the first is still iterating over its entries.
+
+Move the flush from __blkg_release() (RCU callback) to blkg_release()
+(before call_rcu). This ensures the RCU grace period waits for any
+concurrent flush's rcu_read_lock() section to complete before freeing.
+
+Cc: stable@vger.kernel.org
+Cc: Jay Shin <jaeshin@redhat.com>
+Cc: Tejun Heo <tj@kernel.org>
+Cc: Waiman Long <longman@redhat.com>
+Fixes: 20cb1c2fb756 ("blk-cgroup: Flush stats before releasing blkcg_gq")
+Reported-by: coregee2000@gmail.com
+Closes: https://lore.kernel.org/linux-block/CAHPqNmwT9oRpem3J3erS_W0uSQND47LGGSBsNxP8E6uSUish1w@mail.gmail.com/
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Tested-by: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev>
+Link: https://patch.msgid.link/20260205155425.342084-1-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ block/blk-cgroup.c |   21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -164,20 +164,10 @@ static void blkg_free(struct blkcg_gq *b
+ static void __blkg_release(struct rcu_head *rcu)
+ {
+       struct blkcg_gq *blkg = container_of(rcu, struct blkcg_gq, rcu_head);
+-      struct blkcg *blkcg = blkg->blkcg;
+-      int cpu;
+ #ifdef CONFIG_BLK_CGROUP_PUNT_BIO
+       WARN_ON(!bio_list_empty(&blkg->async_bios));
+ #endif
+-      /*
+-       * Flush all the non-empty percpu lockless lists before releasing
+-       * us, given these stat belongs to us.
+-       *
+-       * blkg_stat_lock is for serializing blkg stat update
+-       */
+-      for_each_possible_cpu(cpu)
+-              __blkcg_rstat_flush(blkcg, cpu);
+       /* release the blkcg and parent blkg refs this blkg has been holding */
+       css_put(&blkg->blkcg->css);
+@@ -195,6 +185,17 @@ static void __blkg_release(struct rcu_he
+ static void blkg_release(struct percpu_ref *ref)
+ {
+       struct blkcg_gq *blkg = container_of(ref, struct blkcg_gq, refcnt);
++      struct blkcg *blkcg = blkg->blkcg;
++      int cpu;
++
++      /*
++       * Flush all the non-empty percpu lockless lists before releasing
++       * us, given these stat belongs to us.
++       *
++       * blkg_stat_lock is for serializing blkg stat update
++       */
++      for_each_possible_cpu(cpu)
++              __blkcg_rstat_flush(blkcg, cpu);
+       call_rcu(&blkg->rcu_head, __blkg_release);
+ }
diff --git a/queue-7.1/fbdev-fbcon-fix-out-of-bounds-read-in-err_out-of-fbcon_do_set_font.patch b/queue-7.1/fbdev-fbcon-fix-out-of-bounds-read-in-err_out-of-fbcon_do_set_font.patch
new file mode 100644 (file)
index 0000000..28804f3
--- /dev/null
@@ -0,0 +1,65 @@
+From 8fdc8c2057eea08d40ce2c8eed41ff9e451c65c2 Mon Sep 17 00:00:00 2001
+From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Date: Fri, 26 Jun 2026 00:03:06 +0800
+Subject: fbdev: fbcon: fix out-of-bounds read in err_out of fbcon_do_set_font()
+
+From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+
+commit 8fdc8c2057eea08d40ce2c8eed41ff9e451c65c2 upstream.
+
+When fbcon_do_set_font() fails (e.g., due to a memory allocation failure
+inside vc_resize() under heavy memory pressure), it jumps to the `err_out`
+label to roll back the console state. However, the current rollback logic
+forgets to restore the `hi_font` state, leading to a severe state machine
+corruption.
+
+Earlier in the function, `set_vc_hi_font()` might be called to change
+`vc->vc_hi_font_mask` and mutate the screen buffer. If `vc_resize()`
+subsequently fails, the `err_out` path restores `vc_font.charcount`
+but entirely skips rolling back the `vc_hi_font_mask` and the screen
+buffer.
+
+This mismatch leaves the terminal in a desynchronized state. Because
+`vc_hi_font_mask` remains set, the VT subsystem will still accept
+character indices greater than 255 from userspace and write them to the
+screen buffer. Subsequent rendering calls (e.g., `fbcon_putcs()`) will
+then use these inflated indices to access the reverted, 256-character
+font array, leading to a deterministic out-of-bounds read and potential
+kernel memory disclosure.
+
+Fix this by adding the missing rollback logic for the `hi_font` mask
+and screen buffer in the error path.
+
+Fixes: a5a923038d70 ("fbdev: fbcon: Properly revert changes when vc_resize() failed")
+Cc: stable@vger.kernel.org
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/fbdev/core/fbcon.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -2407,6 +2407,7 @@ static int fbcon_do_set_font(struct vc_d
+       int resize, ret, old_width, old_height, old_charcount;
+       font_data_t *old_fontdata = p->fontdata;
+       const u8 *old_data = vc->vc_font.data;
++      unsigned short old_hi_font_mask = vc->vc_hi_font_mask;
+       font_data_get(data);
+@@ -2453,6 +2454,12 @@ err_out:
+       vc->vc_font.height = old_height;
+       vc->vc_font.charcount = old_charcount;
++      /* Restore the hi_font state and screen buffer */
++      if (old_hi_font_mask && !vc->vc_hi_font_mask)
++              set_vc_hi_font(vc, true);
++      else if (!old_hi_font_mask && vc->vc_hi_font_mask)
++              set_vc_hi_font(vc, false);
++
+       font_data_put(data);
+       return ret;
diff --git a/queue-7.1/fbdev-fix-fb_new_modelist-to-prevent-null-ptr-deref-in-fb_videomode_to_var.patch b/queue-7.1/fbdev-fix-fb_new_modelist-to-prevent-null-ptr-deref-in-fb_videomode_to_var.patch
new file mode 100644 (file)
index 0000000..2c6c549
--- /dev/null
@@ -0,0 +1,59 @@
+From 7f08fc10fa3d3366dc3af723970bd03d7d6d10e3 Mon Sep 17 00:00:00 2001
+From: Ian Bridges <icb@fastmail.org>
+Date: Wed, 24 Jun 2026 23:13:12 -0500
+Subject: fbdev: Fix fb_new_modelist to prevent null-ptr-deref in fb_videomode_to_var
+
+From: Ian Bridges <icb@fastmail.org>
+
+commit 7f08fc10fa3d3366dc3af723970bd03d7d6d10e3 upstream.
+
+info->var, a framebuffer's current mode, is expected to have a matching
+entry in info->modelist. var_to_display() relies on this and treats a
+failed fb_match_mode() as "This should not happen". fb_set_var() keeps it
+true by adding the mode to the list on every change, and
+do_register_framebuffer() does the same at registration.
+
+store_modes() replaces the modelist from userspace. fb_new_modelist()
+validates the new modes but does not check that info->var still has a
+match. It relies on fbcon_new_modelist() to re-point consoles, but that
+only handles consoles mapped to the framebuffer. With fbcon unbound there
+are none, so info->var is left describing a mode that is no longer in the
+list.
+
+A later console takeover runs var_to_display(), where fb_match_mode()
+returns NULL and leaves fb_display[i].mode NULL. fbcon_switch() passes it
+to display_to_var(), and fb_videomode_to_var() dereferences the NULL mode.
+
+Keep the current mode in the list in fb_new_modelist(), the same way
+fb_set_var() does.
+
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Ian Bridges <icb@fastmail.org>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/fbdev/core/fbmem.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/video/fbdev/core/fbmem.c
++++ b/drivers/video/fbdev/core/fbmem.c
+@@ -734,6 +734,18 @@ int fb_new_modelist(struct fb_info *info
+       if (list_empty(&info->modelist))
+               return 1;
++      /*
++       * The new modelist may not contain the current mode (info->var), and
++       * fbcon_new_modelist() below only re-points consoles mapped to this
++       * framebuffer. Add the current mode here so info->var keeps a match
++       * even when fbcon is unbound.
++       */
++      if (!fb_match_mode(&info->var, &info->modelist)) {
++              fb_var_to_videomode(&mode, &info->var);
++              if (fb_add_videomode(&mode, &info->modelist))
++                      return 1;
++      }
++
+       fbcon_new_modelist(info);
+       return 0;
diff --git a/queue-7.1/fbdev-modedb-fix-a-possible-uaf-in-fb_find_mode.patch b/queue-7.1/fbdev-modedb-fix-a-possible-uaf-in-fb_find_mode.patch
new file mode 100644 (file)
index 0000000..a350830
--- /dev/null
@@ -0,0 +1,61 @@
+From 85b6256469cebdac395e7447147e06b2e151014f Mon Sep 17 00:00:00 2001
+From: Tuo Li <islituo@gmail.com>
+Date: Wed, 10 Jun 2026 10:50:14 +0800
+Subject: fbdev: modedb: fix a possible UAF in fb_find_mode()
+
+From: Tuo Li <islituo@gmail.com>
+
+commit 85b6256469cebdac395e7447147e06b2e151014f upstream.
+
+If mode_option is NULL, it is assigned from mode_option_buf:
+
+  if (!mode_option) {
+    fb_get_options(NULL, &mode_option_buf);
+    mode_option = mode_option_buf;
+  }
+
+Later, name is assigned from mode_option:
+
+  const char *name = mode_option;
+
+However, mode_option_buf is freed before name is no longer used:
+
+  kfree(mode_option_buf);
+
+while name is still accessed by:
+
+  if ((name_matches(db[i], name, namelen) ||
+
+Since name aliases mode_option_buf, this may result in a
+use-after-free.
+
+Fix this by extending the lifetime of mode_option_buf until the end of the
+function by using scope-based resource management for cleanup.
+
+Signed-off-by: Tuo Li <islituo@gmail.com>
+Cc: stable@vger.kernel.org # v6.5+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/fbdev/core/modedb.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/video/fbdev/core/modedb.c
++++ b/drivers/video/fbdev/core/modedb.c
+@@ -626,7 +626,7 @@ int fb_find_mode(struct fb_var_screeninf
+                const struct fb_videomode *default_mode,
+                unsigned int default_bpp)
+ {
+-      char *mode_option_buf = NULL;
++      char *mode_option_buf __free(kfree) = NULL;
+       int i;
+       /* Set up defaults */
+@@ -724,7 +724,6 @@ int fb_find_mode(struct fb_var_screeninf
+                       res_specified = 1;
+               }
+ done:
+-              kfree(mode_option_buf);
+               if (cvt) {
+                       struct fb_videomode cvt_mode;
+                       int ret;
diff --git a/queue-7.1/fbdev-modedb-fix-misaligned-fields-in-the-1920x1080-60-mode.patch b/queue-7.1/fbdev-modedb-fix-misaligned-fields-in-the-1920x1080-60-mode.patch
new file mode 100644 (file)
index 0000000..3815c0f
--- /dev/null
@@ -0,0 +1,46 @@
+From d894c48a57d78206e4df9c90d4acfaf39394806a Mon Sep 17 00:00:00 2001
+From: Steffen Persvold <spersvold@gmail.com>
+Date: Fri, 12 Jun 2026 18:40:41 +0200
+Subject: fbdev: modedb: Fix misaligned fields in the 1920x1080-60 mode
+
+From: Steffen Persvold <spersvold@gmail.com>
+
+commit d894c48a57d78206e4df9c90d4acfaf39394806a upstream.
+
+The 1920x1080@60 modedb entry has one too many initializers before
+its sync field: a stray "0" occupies the sync slot, which shifts the
+remaining values by one field. The entry therefore decodes as
+sync = 0, vmode = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT (0x3,
+i.e. FB_VMODE_INTERLACED | FB_VMODE_DOUBLE), and flag =
+FB_VMODE_NONINTERLACED, instead of the intended sync = positive H/V,
+vmode = non-interlaced.
+
+fb_find_mode() then returns a 1920x1080 mode flagged as interlaced +
+doublescan with active-low syncs. Drivers that honour var->vmode and
+var->sync when programming display timing enable doublescan and the
+wrong sync polarity, corrupting the output.
+
+Drop the stray initializer so sync and vmode hold their intended
+values (positive H/V sync, non-interlaced), matching the adjacent
+1920x1200 entry.
+
+Fixes: c8902258b2b8 ("fbdev: modedb: Add 1920x1080 at 60 Hz video mode")
+Cc: stable@vger.kernel.org
+Signed-off-by: Steffen Persvold <spersvold@gmail.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/fbdev/core/modedb.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/video/fbdev/core/modedb.c
++++ b/drivers/video/fbdev/core/modedb.c
+@@ -259,7 +259,7 @@ static const struct fb_videomode modedb[
+               FB_VMODE_DOUBLE },
+       /* 1920x1080 @ 60 Hz, 67.3 kHz hsync */
+-      { NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5, 0,
++      { NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5,
+               FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               FB_VMODE_NONINTERLACED },
diff --git a/queue-7.1/fbdev-omap2-fix-use-after-free-in-omapfb_mmap.patch b/queue-7.1/fbdev-omap2-fix-use-after-free-in-omapfb_mmap.patch
new file mode 100644 (file)
index 0000000..daefee3
--- /dev/null
@@ -0,0 +1,74 @@
+From 7958e67375aa111522086286bba13cfc0816ce8d Mon Sep 17 00:00:00 2001
+From: Hongling Zeng <zenghongling@kylinos.cn>
+Date: Tue, 2 Jun 2026 16:54:21 +0800
+Subject: fbdev: omap2: fix use-after-free in omapfb_mmap
+
+From: Hongling Zeng <zenghongling@kylinos.cn>
+
+commit 7958e67375aa111522086286bba13cfc0816ce8d upstream.
+
+omapfb_mmap() has a race condition with OMAPFB_SETUP_PLANE ioctl that
+can lead to use-after-free:
+
+The fb_mmap() entry point holds mm_lock but not lock (fb_info->lock),
+while ioctl handlers like OMAPFB_SETUP_PLANE hold lock but not mm_lock.
+This allows concurrent execution.
+
+In omapfb_mmap():
+1. rg = omapfb_get_mem_region(ofbi->region);      // Get old region ref
+2. start = omapfb_get_region_paddr(ofbi);          // Read from NEW region
+3. len = fix->smem_len;                             // Read from NEW region
+4. vm_iomap_memory(vma, start, len);               // Map NEW region memory
+5. atomic_inc(&rg->map_count);                      // Increment OLD region!
+
+Concurrently, OMAPFB_SETUP_PLANE can:
+- Reassign ofbi->region = new_rg
+- Update fix->smem_len
+- OMAPFB_SETUP_MEM then checks NEW region's map_count (0!) and frees it
+
+This leaves userspace with a mapping to freed physical memory.
+
+The fix is to read all required values (start, len) from the same
+region reference (rg) that will have its map_count incremented,
+preventing the region from being freed while still mapped.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/fbdev/omap2/omapfb/omapfb-main.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
++++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
+@@ -1099,7 +1099,11 @@ static int omapfb_mmap(struct fb_info *f
+       rg = omapfb_get_mem_region(ofbi->region);
+-      start = omapfb_get_region_paddr(ofbi);
++      if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
++              start = rg->vrfb.paddr[0];
++      else
++              start = rg->paddr;
++
+       len = fix->smem_len;
+       DBG("user mmap region start %lx, len %d, off %lx\n", start, len,
+@@ -1109,6 +1113,8 @@ static int omapfb_mmap(struct fb_info *f
+       vma->vm_ops = &mmap_user_ops;
+       vma->vm_private_data = rg;
++      atomic_inc(&rg->map_count);
++
+       r = vm_iomap_memory(vma, start, len);
+       if (r)
+               goto error;
+@@ -1121,6 +1127,7 @@ static int omapfb_mmap(struct fb_info *f
+       return 0;
+ error:
++      atomic_dec(&rg->map_count);
+       omapfb_put_mem_region(rg);
+       return r;
diff --git a/queue-7.1/fpga-region-fix-use-after-free-in-child_regions_with_firmware.patch b/queue-7.1/fpga-region-fix-use-after-free-in-child_regions_with_firmware.patch
new file mode 100644 (file)
index 0000000..e5b52c9
--- /dev/null
@@ -0,0 +1,39 @@
+From 54f3c5643ec523a04b6ec0e7c19eb10f5ebebdd3 Mon Sep 17 00:00:00 2001
+From: Wentao Liang <vulab@iscas.ac.cn>
+Date: Wed, 8 Apr 2026 15:45:34 +0000
+Subject: fpga: region: fix use-after-free in child_regions_with_firmware()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+commit 54f3c5643ec523a04b6ec0e7c19eb10f5ebebdd3 upstream.
+
+Move of_node_put(child_region) after the error print to avoid accessing
+freed memory when pr_err() references child_region.
+
+Fixes: 0fa20cdfcc1f ("fpga: fpga-region: device tree control for FPGA")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+[ Yilun: Fix the Fixes tag ]
+Reviewed-by: Xu Yilun <yilun.xu@intel.com>
+Link: https://lore.kernel.org/r/20260408154534.404327-1-vulab@iscas.ac.cn
+Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/of-fpga-region.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/fpga/of-fpga-region.c
++++ b/drivers/fpga/of-fpga-region.c
+@@ -168,11 +168,10 @@ static int child_regions_with_firmware(s
+                                                    fpga_region_of_match);
+       }
+-      of_node_put(child_region);
+-
+       if (ret)
+               pr_err("firmware-name not allowed in child FPGA region: %pOF",
+                      child_region);
++      of_node_put(child_region);
+       return ret;
+ }
diff --git a/queue-7.1/gfs2-fix-use-after-free-in-gfs2_qd_dealloc.patch b/queue-7.1/gfs2-fix-use-after-free-in-gfs2_qd_dealloc.patch
new file mode 100644 (file)
index 0000000..50b5843
--- /dev/null
@@ -0,0 +1,48 @@
+From f9c9ec2c319f843b70ecdf939d48b52d189bc081 Mon Sep 17 00:00:00 2001
+From: Tristan Madani <tristan@talencesecurity.com>
+Date: Fri, 1 May 2026 11:02:03 +0000
+Subject: gfs2: fix use-after-free in gfs2_qd_dealloc
+
+From: Tristan Madani <tristan@talencesecurity.com>
+
+commit f9c9ec2c319f843b70ecdf939d48b52d189bc081 upstream.
+
+gfs2_qd_dealloc(), called as an RCU callback from gfs2_qd_dispose(),
+accesses the superblock object sdp through qd->qd_sbd after freeing qd.
+It does so to decrement sd_quota_count and wake up sd_kill_wait.
+
+However, by the time the RCU callback runs, gfs2_put_super() may have
+already freed sdp via free_sbd().  This can happen when
+gfs2_quota_cleanup() is called during unmount: it disposes of quota
+objects via call_rcu() and then waits on sd_kill_wait with a 60-second
+timeout.  If the timeout expires, or if gfs2_gl_hash_clear() triggers
+additional qd_put() calls that schedule more RCU callbacks after the
+wait completes, gfs2_put_super() will proceed to free the superblock
+while RCU callbacks referencing it are still pending.
+
+Add an rcu_barrier() before free_sbd() in gfs2_put_super() to ensure
+all pending RCU callbacks (including gfs2_qd_dealloc) have completed
+before the superblock is freed.
+
+Fixes: a475c5dd16e5 ("gfs2: Free quota data objects synchronously")
+Reported-by: syzbot+42a37bf8045847d8f9d2@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=42a37bf8045847d8f9d2
+Tested-by: syzbot+42a37bf8045847d8f9d2@syzkaller.appspotmail.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/gfs2/super.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -643,6 +643,7 @@ restart:
+       gfs2_delete_debugfs_file(sdp);
+       gfs2_sys_fs_del(sdp);
++      rcu_barrier();
+       free_sbd(sdp);
+ }
diff --git a/queue-7.1/hdlc_ppp-sync-per-proto-timers-before-freeing-hdlc-state.patch b/queue-7.1/hdlc_ppp-sync-per-proto-timers-before-freeing-hdlc-state.patch
new file mode 100644 (file)
index 0000000..ed1a06d
--- /dev/null
@@ -0,0 +1,109 @@
+From c78a4e41ab5ead6193ad8a2dd92e8906bae659fa Mon Sep 17 00:00:00 2001
+From: Fan Wu <fanwu01@zju.edu.cn>
+Date: Wed, 17 Jun 2026 02:05:18 +0000
+Subject: hdlc_ppp: sync per-proto timers before freeing hdlc state
+
+From: Fan Wu <fanwu01@zju.edu.cn>
+
+commit c78a4e41ab5ead6193ad8a2dd92e8906bae659fa upstream.
+
+Each PPP control protocol (LCP/IPCP/IPV6CP) embedded in struct ppp
+registers a timer via timer_setup(). That struct ppp is the
+hdlc->state allocation, which detach_hdlc_protocol() frees with kfree()
+in both teardown paths: unregister_hdlc_device() and the re-attach inside
+attach_hdlc_protocol().
+
+The ppp proto never registered a .detach callback, so
+detach_hdlc_protocol() performs no timer synchronization before the
+kfree(). The only cancel, timer_delete(&proto->timer) in ppp_cp_event(),
+is partial (it does not wait for a running callback) and only runs on the
+->CLOSED transition; ppp_stop()/ppp_close() do not sync either. A
+ppp_timer callback already executing (blocked on ppp->lock) survives the
+kfree and then dereferences proto->state / ppp->lock in freed memory,
+leading to a use-after-free.
+
+Fix this by adding a .detach helper that calls timer_shutdown_sync() on
+every per-proto timer. detach_hdlc_protocol() invokes proto->detach(dev)
+before kfree(hdlc->state), so timer_shutdown_sync()
+now runs on both free paths.
+timer_shutdown_sync() is used instead of timer_delete_sync() because the
+keepalive path re-arms the timer through add_timer()/mod_timer() and
+shutdown blocks any re-activation during teardown.
+
+Initialize the per-protocol timers in ppp_ioctl() when the protocol is
+attached, and remove the now-redundant timer_setup() from ppp_start(), so
+that the timers are initialized exactly once at attach time and
+ppp_timer_release() never operates on uninitialized timer_list
+structures. attach_hdlc_protocol() uses kmalloc() (not kzalloc), so
+struct ppp's protos[i].timer is uninitialized garbage until the first
+timer_setup(); without this init-at-attach, attaching the PPP protocol
+without ever bringing the device up would leave timer_shutdown_sync()
+operating on uninitialized memory in .detach. Moving the init out of
+ppp_start() (which only runs on NETDEV_UP) into the attach path makes the
+initialization unconditional and avoids initializing the same timer_list
+twice.
+
+This bug was found by static analysis.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
+Link: https://patch.msgid.link/20260617020518.116319-1-fanwu01@zju.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wan/hdlc_ppp.c |   15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wan/hdlc_ppp.c
++++ b/drivers/net/wan/hdlc_ppp.c
+@@ -619,7 +619,6 @@ static void ppp_start(struct net_device
+               struct proto *proto = &ppp->protos[i];
+               proto->dev = dev;
+-              timer_setup(&proto->timer, ppp_timer, 0);
+               proto->state = CLOSED;
+       }
+       ppp->protos[IDX_LCP].pid = PID_LCP;
+@@ -639,6 +638,15 @@ static void ppp_close(struct net_device
+       ppp_tx_flush();
+ }
++static void ppp_timer_release(struct net_device *dev)
++{
++      struct ppp *ppp = get_ppp(dev);
++      int i;
++
++      for (i = 0; i < IDX_COUNT; i++)
++              timer_shutdown_sync(&ppp->protos[i].timer);
++}
++
+ static struct hdlc_proto proto = {
+       .start          = ppp_start,
+       .stop           = ppp_stop,
+@@ -647,6 +655,7 @@ static struct hdlc_proto proto = {
+       .ioctl          = ppp_ioctl,
+       .netif_rx       = ppp_rx,
+       .module         = THIS_MODULE,
++      .detach         = ppp_timer_release,
+ };
+ static const struct header_ops ppp_header_ops = {
+@@ -657,7 +666,7 @@ static int ppp_ioctl(struct net_device *
+ {
+       hdlc_device *hdlc = dev_to_hdlc(dev);
+       struct ppp *ppp;
+-      int result;
++      int i, result;
+       switch (ifs->type) {
+       case IF_GET_PROTO:
+@@ -685,6 +694,8 @@ static int ppp_ioctl(struct net_device *
+                       return result;
+               ppp = get_ppp(dev);
++              for (i = 0; i < IDX_COUNT; i++)
++                      timer_setup(&ppp->protos[i].timer, ppp_timer, 0);
+               spin_lock_init(&ppp->lock);
+               ppp->req_timeout = 2;
+               ppp->cr_retries = 10;
diff --git a/queue-7.1/i2c-core-fix-adapter-registration-race.patch b/queue-7.1/i2c-core-fix-adapter-registration-race.patch
new file mode 100644 (file)
index 0000000..3800e57
--- /dev/null
@@ -0,0 +1,61 @@
+From ba14d7cf2fe7284610a29854bdff22b2537d3ce6 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 11 May 2026 16:37:12 +0200
+Subject: i2c: core: fix adapter registration race
+
+From: Johan Hovold <johan@kernel.org>
+
+commit ba14d7cf2fe7284610a29854bdff22b2537d3ce6 upstream.
+
+Adapters can be looked up based on their id using i2c_get_adapter()
+which takes a reference to the embedded struct device.
+
+Make sure that the adapter (including its struct device) has been
+initialised before adding it to the IDR to avoid accessing uninitialised
+data which could, for example, lead to NULL-pointer dereferences or
+use-after-free.
+
+Note that the i2c-dev chardev, which is registered from a bus notifier,
+currently uses i2c_get_adapter() so the adapter needs to be added to the
+IDR before registration.
+
+Fixes: 6e13e6418418 ("i2c: Add i2c_add_numbered_adapter()")
+Cc: stable@vger.kernel.org     # 2.6.22
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i2c/i2c-core-base.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/i2c/i2c-core-base.c
++++ b/drivers/i2c/i2c-core-base.c
+@@ -1569,6 +1569,10 @@ static int i2c_register_adapter(struct i
+       pm_suspend_ignore_children(&adap->dev, true);
+       pm_runtime_enable(&adap->dev);
++      mutex_lock(&core_lock);
++      idr_replace(&i2c_adapter_idr, adap, adap->nr);
++      mutex_unlock(&core_lock);
++
+       res = device_add(&adap->dev);
+       if (res) {
+               pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
+@@ -1627,7 +1631,7 @@ static int __i2c_add_numbered_adapter(st
+       int id;
+       mutex_lock(&core_lock);
+-      id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1, GFP_KERNEL);
++      id = idr_alloc(&i2c_adapter_idr, NULL, adap->nr, adap->nr + 1, GFP_KERNEL);
+       mutex_unlock(&core_lock);
+       if (WARN(id < 0, "couldn't get idr"))
+               return id == -ENOSPC ? -EBUSY : id;
+@@ -1661,7 +1665,7 @@ int i2c_add_adapter(struct i2c_adapter *
+       }
+       mutex_lock(&core_lock);
+-      id = idr_alloc(&i2c_adapter_idr, adapter,
++      id = idr_alloc(&i2c_adapter_idr, NULL,
+                      __i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
+       mutex_unlock(&core_lock);
+       if (WARN(id < 0, "couldn't get idr"))
diff --git a/queue-7.1/irqchip-imgpdc-fix-resource-leak-add-missing-chained-handler-cleanup-on-remove.patch b/queue-7.1/irqchip-imgpdc-fix-resource-leak-add-missing-chained-handler-cleanup-on-remove.patch
new file mode 100644 (file)
index 0000000..9516865
--- /dev/null
@@ -0,0 +1,64 @@
+From 37738fdf2ab1e504d1c63ce5bc0aeb6452d8f057 Mon Sep 17 00:00:00 2001
+From: Qingshuang Fu <fuqingshuang@kylinos.cn>
+Date: Thu, 18 Jun 2026 10:13:52 +0800
+Subject: irqchip/imgpdc: Fix resource leak, add missing chained handler cleanup on remove
+
+From: Qingshuang Fu <fuqingshuang@kylinos.cn>
+
+commit 37738fdf2ab1e504d1c63ce5bc0aeb6452d8f057 upstream.
+
+The driver allocates domain generic chips using
+irq_alloc_domain_generic_chips() during probe and sets up chained
+handlers using irq_set_chained_handler_and_data(). However, on driver
+removal, the generic chips are not freed and the chained handlers are
+not removed.
+
+The generic chips remain on the global gc_list and may later be accessed by
+generic interrupt chip suspend, resume, or shutdown callbacks after the
+driver has been removed, potentially resulting in a use-after-free and
+kernel crash.
+
+The chained handlers that were installed in probe for peripheral and
+syswake interrupts are also left dangling, which can lead to spurious
+interrupts accessing freed memory.
+
+Fix these issues by:
+
+  - Setting IRQ_DOMAIN_FLAG_DESTROY_GC flag in domain->flags, so the
+    core code automatically removes generic chips when irq_domain_remove()
+    is called
+
+  - Clearing all chained handlers with NULL in pdc_intc_remove()
+
+Fixes: b6ef9161e43a ("irq-imgpdc: add ImgTec PDC irqchip driver")
+Signed-off-by: Qingshuang Fu <fuqingshuang@kylinos.cn>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260618021352.661773-1-fffsqian@163.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/irqchip/irq-imgpdc.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/irqchip/irq-imgpdc.c
++++ b/drivers/irqchip/irq-imgpdc.c
+@@ -378,6 +378,7 @@ static int pdc_intc_probe(struct platfor
+               dev_err(&pdev->dev, "cannot add IRQ domain\n");
+               return -ENOMEM;
+       }
++      priv->domain->flags |= IRQ_DOMAIN_FLAG_DESTROY_GC;
+       /*
+        * Set up 2 generic irq chips with 2 chip types.
+@@ -465,6 +466,11 @@ static void pdc_intc_remove(struct platf
+ {
+       struct pdc_intc_priv *priv = platform_get_drvdata(pdev);
++      for (unsigned int i = 0; i < priv->nr_perips; ++i)
++              irq_set_chained_handler_and_data(priv->perip_irqs[i], NULL, NULL);
++
++      irq_set_chained_handler_and_data(priv->syswake_irq, NULL, NULL);
++
+       irq_domain_remove(priv->domain);
+ }
diff --git a/queue-7.1/ksmbd-fix-out-of-bounds-read-in-smb_check_perm_dacl.patch b/queue-7.1/ksmbd-fix-out-of-bounds-read-in-smb_check_perm_dacl.patch
new file mode 100644 (file)
index 0000000..eafeee7
--- /dev/null
@@ -0,0 +1,62 @@
+From 1ef06004ed4bd6d3ed8c840d9d1a376b66d4935b Mon Sep 17 00:00:00 2001
+From: Hem Parekh <hemparekh1596@gmail.com>
+Date: Tue, 2 Jun 2026 16:56:46 -0700
+Subject: ksmbd: fix out-of-bounds read in smb_check_perm_dacl()
+
+From: Hem Parekh <hemparekh1596@gmail.com>
+
+commit 1ef06004ed4bd6d3ed8c840d9d1a376b66d4935b upstream.
+
+The permission-check ACE walk in smb_check_perm_dacl() validates the ACE
+header size and caps sid.num_subauth at SID_MAX_SUB_AUTHORITIES, but it
+never checks that ace->size is actually large enough to contain
+num_subauth sub-authorities before compare_sids() dereferences them.
+
+CIFS_SID_BASE_SIZE covers the SID header up to but excluding the
+sub_auth[] array, and offsetof(struct smb_ace, sid) is the ACE header,
+so the existing guards only guarantee the 8-byte SID base, i.e. zero
+sub-authorities. compare_sids() then reads ace->sid.sub_auth[i] for
+i < min(local_sid->num_subauth, ace->sid.num_subauth). The local
+comparison SIDs (sid_everyone, sid_unix_NFS_mode, and the id_to_sid()
+result) always have at least one sub-authority, and an attacker controls
+the ACE revision and authority bytes (which lie within the in-bounds SID
+base), so they can match one of those SIDs and force the sub_auth read.
+
+A crafted ACE with size == 16 and num_subauth >= 1 placed at the tail of
+the security descriptor therefore causes a heap out-of-bounds read of up
+to SID_MAX_SUB_AUTHORITIES * sizeof(__le32) bytes past the pntsd
+allocation. The security descriptor is loaded by ksmbd_vfs_get_sd_xattr()
+into a buffer sized exactly to the on-disk data (kzalloc(sd_size) in
+ndr_decode_v4_ntacl()), so the read lands past the allocation. The
+malformed descriptor can be stored verbatim via SMB2_SET_INFO (the DACL
+is not normalised before being written to the security.NTACL xattr) and
+the read fires on a subsequent SMB2_CREATE access check, making this
+reachable by an authenticated client on a share that uses ACL xattrs.
+
+Add the missing num_subauth-versus-ace_size check, mirroring the
+identical guards already present in the sibling parsers parse_dacl() and
+smb_inherit_dacl().
+
+Fixes: d07b26f39246 ("ksmbd: require minimum ACE size in smb_check_perm_dacl()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Hem Parekh <hemparekh1596@gmail.com>
+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/smbacl.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/smb/server/smbacl.c
++++ b/fs/smb/server/smbacl.c
+@@ -1477,7 +1477,9 @@ int smb_check_perm_dacl(struct ksmbd_con
+                       break;
+               aces_size -= ace_size;
+-              if (ace->sid.num_subauth > SID_MAX_SUB_AUTHORITIES)
++              if (ace->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
++                  ace_size < offsetof(struct smb_ace, sid) + CIFS_SID_BASE_SIZE +
++                            sizeof(__le32) * ace->sid.num_subauth)
+                       break;
+               if (!compare_sids(&sid, &ace->sid) ||
diff --git a/queue-7.1/kvm-svm-fix-page-overflow-in-sev_dbg_crypt-for-encrypt-path.patch b/queue-7.1/kvm-svm-fix-page-overflow-in-sev_dbg_crypt-for-encrypt-path.patch
new file mode 100644 (file)
index 0000000..0715644
--- /dev/null
@@ -0,0 +1,93 @@
+From 78ee2d50185a037b3d2452a97f3dad69c3f7f389 Mon Sep 17 00:00:00 2001
+From: Ashutosh Desai <ashutoshdesai993@gmail.com>
+Date: Fri, 1 May 2026 13:35:32 -0700
+Subject: KVM: SVM: Fix page overflow in sev_dbg_crypt() for ENCRYPT path
+
+From: Ashutosh Desai <ashutoshdesai993@gmail.com>
+
+commit 78ee2d50185a037b3d2452a97f3dad69c3f7f389 upstream.
+
+In sev_dbg_crypt(), the per-iteration transfer length is bounded by
+the source page offset (PAGE_SIZE - s_off) but not by the destination
+page offset (PAGE_SIZE - d_off).  When d_off > s_off, the encrypt
+path (__sev_dbg_encrypt_user) performs a read-modify-write using a
+single-page intermediate buffer (dst_tpage):
+
+  1. __sev_dbg_decrypt() expands the size to round_up(len + (d_off & 15), 16)
+     before issuing the PSP command.  If len + (d_off & 15) > PAGE_SIZE,
+     the PSP writes beyond the end of the 4096-byte dst_tpage allocation.
+
+  2. The subsequent memcpy()/copy_from_user() into
+     page_address(dst_tpage) + (d_off & 15) of 'len' bytes overflows
+     by up to 15 bytes under the same condition.
+
+Trigger example: s_off = 0, d_off = 1, debug.len = PAGE_SIZE -
+the PSP is instructed to write round_up(4097, 16) = 4112 bytes to
+a 4096-byte buffer.
+
+Fix by also bounding len by (PAGE_SIZE - d_off), the same check that
+sev_send_update_data() already performs for its single-page guest
+region.
+
+ ==================================================================
+ BUG: KASAN: slab-use-after-free in sev_dbg_crypt+0x993/0xd10 [kvm_amd]
+ Write of size 4095 at addr ff110062293bb009 by task sev_dbg_test/228214
+
+ CPU: 96 UID: 0 PID: 228214 Comm: sev_dbg_test Tainted: G     U  W           7.0.0-smp--5ce9b0c48211-dbg #156 PREEMPTLAZY
+ Tainted: [U]=USER, [W]=WARN
+ Hardware name: Google Astoria/astoria, BIOS 0.20250817.1-0 08/25/2025
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x54/0x70
+  print_report+0xbc/0x260
+  kasan_report+0xa2/0xd0
+  kasan_check_range+0x25f/0x2c0
+  __asan_memcpy+0x40/0x70
+  sev_dbg_crypt+0x993/0xd10 [kvm_amd]
+  sev_mem_enc_ioctl+0x33c/0x450 [kvm_amd]
+  kvm_vm_ioctl+0x65d/0x6d0 [kvm]
+  __se_sys_ioctl+0xb2/0x100
+  do_syscall_64+0xe8/0x870
+  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+  </TASK>
+
+ The buggy address belongs to the physical page:
+ page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x7fe72b6a0 pfn:0x62293bb
+ memcg:ff11000112827d82
+ flags: 0x1400000000000000(node=1|zone=1)
+ raw: 1400000000000000 0000000000000000 dead000000000122 0000000000000000
+ raw: 00000007fe72b6a0 0000000000000000 00000001ffffffff ff11000112827d82
+ page dumped because: kasan: bad access detected
+
+ Memory state around the buggy address:
+  ff110062293bbf00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  ff110062293bbf80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ >ff110062293bc000: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
+                    ^
+  ff110062293bc080: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
+  ff110062293bc100: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
+ ==================================================================
+ Disabling lock debugging due to kernel taint
+
+Fixes: 24f41fb23a39 ("KVM: SVM: Add support for SEV DEBUG_DECRYPT command")
+Fixes: 7d1594f5d94b ("KVM: SVM: Add support for SEV DEBUG_ENCRYPT command")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ashutosh Desai <ashutoshdesai993@gmail.com>
+[sean: add sample KASAN splat, Fixes, and stable@]
+Link: https://patch.msgid.link/20260501203537.2120074-2-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/svm/sev.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/x86/kvm/svm/sev.c
++++ b/arch/x86/kvm/svm/sev.c
+@@ -1396,6 +1396,7 @@ static int sev_dbg_crypt(struct kvm *kvm
+               s_off = vaddr & ~PAGE_MASK;
+               d_off = dst_vaddr & ~PAGE_MASK;
+               len = min_t(size_t, (PAGE_SIZE - s_off), size);
++              len = min_t(size_t, len, PAGE_SIZE - d_off);
+               if (dec)
+                       ret = __sev_dbg_decrypt_user(kvm,
diff --git a/queue-7.1/kvm-x86-hyper-v-bound-the-bank-index-when-querying-sparse-banks.patch b/queue-7.1/kvm-x86-hyper-v-bound-the-bank-index-when-querying-sparse-banks.patch
new file mode 100644 (file)
index 0000000..07dbcd8
--- /dev/null
@@ -0,0 +1,91 @@
+From 4721f8160f17554b003e8928bb61e6c9b2fe92a3 Mon Sep 17 00:00:00 2001
+From: Hyunwoo Kim <imv4bel@gmail.com>
+Date: Sat, 6 Jun 2026 23:44:52 +0900
+Subject: KVM: x86: hyper-v: Bound the bank index when querying sparse banks
+
+From: Hyunwoo Kim <imv4bel@gmail.com>
+
+commit 4721f8160f17554b003e8928bb61e6c9b2fe92a3 upstream.
+
+When checking if a VP ID is included in a sparse bank set, explicitly check
+that the ID can actually be contained in a sparse bank (the TLFS allows for
+a maximum of 64 banks of 64 vCPUs each).  When handling a paravirtual TLB
+flush for L2, the VP ID is copied verbatim from the enlightened VMCS,
+without any bounds check, i.e. isn't guaranteed to be under the limit of
+4096.
+
+Failure to check the bounds of the VP ID leads to an out-of-bounds read
+when testing the sparse bank, and super strictly speaking could lead to KVM
+performing an unnecessary TLB flush for an L2 vCPU.
+
+  ==================================================================
+  BUG: KASAN: use-after-free in hv_is_vp_in_sparse_set+0x85/0x100 [kvm]
+  Read of size 8 at addr ffff88811ba5f598 by task hyperv_evmcs/2802
+
+  CPU: 12 UID: 1000 PID: 2802 Comm: hyperv_evmcs Not tainted 7.1.0-rc2 #7 PREEMPT
+  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
+  Call Trace:
+   <TASK>
+   dump_stack_lvl+0x51/0x60
+   print_report+0xcb/0x5d0
+   kasan_report+0xb4/0xe0
+   kasan_check_range+0x35/0x1b0
+   hv_is_vp_in_sparse_set+0x85/0x100 [kvm]
+   kvm_hv_flush_tlb+0xe9e/0x16c0 [kvm]
+   kvm_hv_hypercall+0xe6b/0x1e60 [kvm]
+   vmx_handle_exit+0x485/0x1b60 [kvm_intel]
+   kvm_arch_vcpu_ioctl_run+0x22e3/0x5070 [kvm]
+   kvm_vcpu_ioctl+0x5d0/0x10c0 [kvm]
+   __x64_sys_ioctl+0x129/0x1a0
+   do_syscall_64+0xb9/0xcf0
+   entry_SYSCALL_64_after_hwframe+0x4b/0x53
+  RIP: 0033:0x7f0e62d1a9bf
+   </TASK>
+
+  The buggy address belongs to the physical page:
+  page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffffffffffffffff pfn:0x11ba5f
+  flags: 0x4000000000000000(zone=1)
+  raw: 4000000000000000 0000000000000000 00000000ffffffff 0000000000000000
+  raw: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000000
+  page dumped because: kasan: bad access detected
+
+  Memory state around the buggy address:
+   ffff88811ba5f480: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+   ffff88811ba5f500: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+  >ffff88811ba5f580: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+                              ^
+   ffff88811ba5f600: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+   ffff88811ba5f680: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+  ==================================================================
+  Disabling lock debugging due to kernel taint
+
+Opportunistically add a compile time assertion to ensure the maximum number
+of sparse banks exactly matches the number of possible bits in the passed
+in mask.
+
+Cc: stable@vger.kernel.org
+Fixes: c58a318f6090 ("KVM: x86: hyper-v: L2 TLB flush")
+Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
+Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Link: https://patch.msgid.link/aiQyZIJtO-2Aj_xN@v4bel
+[sean: add KASAN splat, drop comment, add assert, massage changelog]
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/hyperv.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/x86/kvm/hyperv.c
++++ b/arch/x86/kvm/hyperv.c
+@@ -1839,6 +1839,11 @@ static bool hv_is_vp_in_sparse_set(u32 v
+       int valid_bit_nr = vp_id / HV_VCPUS_PER_SPARSE_BANK;
+       unsigned long sbank;
++      BUILD_BUG_ON(BITS_PER_TYPE(valid_bank_mask) != HV_MAX_SPARSE_VCPU_BANKS);
++
++      if (valid_bit_nr >= HV_MAX_SPARSE_VCPU_BANKS)
++              return false;
++
+       if (!test_bit(valid_bit_nr, (unsigned long *)&valid_bank_mask))
+               return false;
diff --git a/queue-7.1/loongarch-report-dying-cpu-to-rcu-in-stop_this_cpu.patch b/queue-7.1/loongarch-report-dying-cpu-to-rcu-in-stop_this_cpu.patch
new file mode 100644 (file)
index 0000000..aea6abd
--- /dev/null
@@ -0,0 +1,60 @@
+From f2539c56c74691e7a88af6372ba2b48c06ed2fe4 Mon Sep 17 00:00:00 2001
+From: Huacai Chen <chenhuacai@loongson.cn>
+Date: Thu, 25 Jun 2026 13:03:49 +0800
+Subject: LoongArch: Report dying CPU to RCU in stop_this_cpu()
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+commit f2539c56c74691e7a88af6372ba2b48c06ed2fe4 upstream.
+
+This is a port of MIPS commit 9f3f3bdc6d9dac1 ("MIPS: smp: report dying
+CPU to RCU in stop_this_cpu()"). smp_send_stop() parks all secondary
+CPUs in stop_this_cpu(). And the function marks the CPU offline for the
+scheduler via set_cpu_online(false) but never informs RCU, so RCU keeps
+expecting a quiescent state from CPUs that are now spinning forever with
+interrupts disabled.
+
+As long as nothing waits for an RCU grace period after smp_send_stop()
+this is harmless, which is why it went unnoticed. However, since commit
+91840be8f710370 ("irq_work: Fix use-after-free in irq_work_single() on
+PREEMPT_RT"), irq_work_sync() calls synchronize_rcu() on architectures
+without an irq_work self-IPI, i.e. where arch_irq_work_has_interrupt()
+returns false. Any irq_work_sync() issued in the reboot/shutdown/halt
+path after smp_send_stop() then blocks on a grace period that can never
+complete, hanging the reboot:
+
+  WARNING: CPU: 0 PID: 15 at kernel/irq_work.c:144 irq_work_queue_on
+  ...
+  rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
+  rcu: Offline CPU 1 blocking current GP.
+  rcu: Offline CPU 2 blocking current GP.
+  rcu: Offline CPU 3 blocking current GP.
+
+This issue needs some hacks to reproduce, and it was not noticed on
+LoongArch because arch_irq_work_has_interrupt() usually returns true.
+
+Call rcutree_report_cpu_dead() once interrupts are disabled, mirroring
+the generic CPU-hotplug offline path, so RCU stops waiting on the parked
+CPUs and grace periods can still complete. LoongArch shuts down all CPUs
+here without going through the CPU-hotplug mechanism, so this report is
+not otherwise issued.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 91840be8f710 ("irq_work: Fix use-after-free in irq_work_single() on PREEMPT_RT")
+Reviewed-by: Guo Ren <guoren@kernel.org>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/loongarch/kernel/smp.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/loongarch/kernel/smp.c
++++ b/arch/loongarch/kernel/smp.c
+@@ -705,6 +705,7 @@ static void stop_this_cpu(void *dummy)
+       set_cpu_online(smp_processor_id(), false);
+       calculate_cpu_foreign_map();
+       local_irq_disable();
++      rcutree_report_cpu_dead();
+       while (true);
+ }
diff --git a/queue-7.1/mips-smp-report-dying-cpu-to-rcu-in-stop_this_cpu.patch b/queue-7.1/mips-smp-report-dying-cpu-to-rcu-in-stop_this_cpu.patch
new file mode 100644 (file)
index 0000000..a589032
--- /dev/null
@@ -0,0 +1,71 @@
+From 9f3f3bdc6d9dac1a5a8262ee7ad0f2ff1527a7e7 Mon Sep 17 00:00:00 2001
+From: Jonas Jelonek <jelonek.jonas@gmail.com>
+Date: Mon, 8 Jun 2026 09:37:29 +0000
+Subject: MIPS: smp: report dying CPU to RCU in stop_this_cpu()
+
+From: Jonas Jelonek <jelonek.jonas@gmail.com>
+
+commit 9f3f3bdc6d9dac1a5a8262ee7ad0f2ff1527a7e7 upstream.
+
+smp_send_stop() parks all secondary CPUs in stop_this_cpu(). The function
+marks the CPU offline for the scheduler via set_cpu_online(false) but
+never informs RCU, so RCU keeps expecting a quiescent state from CPUs
+that are now spinning forever with interrupts disabled.
+
+As long as nothing waits for an RCU grace period after smp_send_stop()
+this is harmless, which is why it went unnoticed. Since commit
+91840be8f710 ("irq_work: Fix use-after-free in irq_work_single() on PREEMPT_RT")
+however, irq_work_sync() calls synchronize_rcu() on architectures without
+an irq_work self-IPI, i.e. where arch_irq_work_has_interrupt() returns
+false. That is the asm-generic default used by MIPS. Any irq_work_sync()
+issued in the reboot/shutdown path after smp_send_stop() then blocks on
+a grace period that can never complete, hanging the reboot:
+
+  WARNING: CPU: 0 PID: 15 at kernel/irq_work.c:144 irq_work_queue_on
+  ...
+  rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
+  rcu: Offline CPU 1 blocking current GP.
+  rcu: Offline CPU 2 blocking current GP.
+  rcu: Offline CPU 3 blocking current GP.
+
+This issue was noticed on several Realtek MIPS switch SoCs (MIPS
+interAptiv) and came up during kernel bump downstream in OpenWrt from
+6.18.33 to 6.18.34, after the backport of the patch to the 6.18 stable
+branch. The patch also has been backported all the way back to 6.1.
+
+Call rcutree_report_cpu_dead() once interrupts are disabled, mirroring the
+generic CPU-hotplug offline path, so RCU stops waiting on the parked CPUs
+and grace periods can still complete. MIPS shuts down all CPUs here
+without going through the CPU-hotplug mechanism, so this report is not
+otherwise issued. Reporting a dying CPU to RCU outside the regular hotplug
+offline path is not unprecedented: arm64 does the same in cpu_die_early().
+There it is an exception for a CPU that was coming online and is aborting
+bringup, rather than the default shutdown action as on MIPS.
+
+Fixes: 91840be8f710 ("irq_work: Fix use-after-free in irq_work_single() on PREEMPT_RT")
+CC: stable@vger.kernel.org
+Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/mips/kernel/smp.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/mips/kernel/smp.c
++++ b/arch/mips/kernel/smp.c
+@@ -20,6 +20,7 @@
+ #include <linux/sched/mm.h>
+ #include <linux/cpumask.h>
+ #include <linux/cpu.h>
++#include <linux/rcupdate.h>
+ #include <linux/err.h>
+ #include <linux/ftrace.h>
+ #include <linux/irqdomain.h>
+@@ -422,6 +423,7 @@ static void stop_this_cpu(void *dummy)
+       set_cpu_online(smp_processor_id(), false);
+       calculate_cpu_foreign_map();
+       local_irq_disable();
++      rcutree_report_cpu_dead();
+       while (1);
+ }
diff --git a/queue-7.1/nfs-prevent-resource-leak-in-nfs_alloc_server.patch b/queue-7.1/nfs-prevent-resource-leak-in-nfs_alloc_server.patch
new file mode 100644 (file)
index 0000000..41481d8
--- /dev/null
@@ -0,0 +1,33 @@
+From d189f224308c8ac3feeea8e442c99922bd18f1b2 Mon Sep 17 00:00:00 2001
+From: Markus Elfring <elfring@users.sourceforge.net>
+Date: Sun, 14 Jun 2026 09:56:35 +0200
+Subject: NFS: Prevent resource leak in nfs_alloc_server()
+
+From: Markus Elfring <elfring@users.sourceforge.net>
+
+commit d189f224308c8ac3feeea8e442c99922bd18f1b2 upstream.
+
+It was overlooked to call ida_free() after a failed nfs_alloc_iostats() call.
+Thus add the missed function call in an if branch.
+
+Fixes: 1c7251187dc067a6d460cf33ca67da9c1dd87807 ("NFS: add superblock sysfs entries")
+Cc: stable@vger.kernel.org
+Reported-by: Christophe Jaillet <christophe.jaillet@wanadoo.fr>
+Closes: https://lore.kernel.org/linux-nfs/1c8e10c9-def7-4f0d-8aa1-23c8035a38c8@wanadoo.fr/
+Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
+Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfs/client.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/nfs/client.c
++++ b/fs/nfs/client.c
+@@ -1074,6 +1074,7 @@ struct nfs_server *nfs_alloc_server(void
+       server->io_stats = nfs_alloc_iostats();
+       if (!server->io_stats) {
++              ida_free(&s_sysfs_ids, server->s_sysfs_id);
+               kfree(server);
+               return NULL;
+       }
diff --git a/queue-7.1/nfsd-avoid-leaking-pre-allocated-openowner-on-unconfirmed-retry-race.patch b/queue-7.1/nfsd-avoid-leaking-pre-allocated-openowner-on-unconfirmed-retry-race.patch
new file mode 100644 (file)
index 0000000..d487aaf
--- /dev/null
@@ -0,0 +1,46 @@
+From 57aee7a35bb12753057c5b65d72d1f46c0e95b07 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@kernel.org>
+Date: Fri, 22 May 2026 10:36:14 -0400
+Subject: nfsd: avoid leaking pre-allocated openowner on unconfirmed retry race
+
+From: Jeff Layton <jlayton@kernel.org>
+
+commit 57aee7a35bb12753057c5b65d72d1f46c0e95b07 upstream.
+
+When find_or_alloc_open_stateowner() encounters an unconfirmed owner, it
+calls release_openowner() and sets oo = NULL. Control then falls through
+past the `if (oo)` guard -- which would have freed any pre-allocated
+`new` -- and unconditionally executes `new = alloc_stateowner(...)`. If
+`new` was already allocated on a prior iteration, the pointer is
+silently overwritten and the previous allocation (slab object + owner
+name buffer) is leaked.
+
+This requires a race: two NFSv4.0 OPEN threads with the same owner
+string, where a concurrent thread inserts a new unconfirmed owner into
+the hash between retry iterations. The window is narrow but repeatable
+under adversarial conditions.
+
+Fix by adding `goto retry` after `oo = NULL` so the already-allocated
+`new` is reused on the next iteration rather than overwritten.
+
+Reported-by: Chris Mason <clm@meta.com>
+Fixes: 23df17788c62 ("nfsd: perform all find_openstateowner_str calls in the one place.")
+Cc: stable@vger.kernel.org
+Assisted-by: kres:claude-opus-4-6
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfs4state.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -5169,6 +5169,7 @@ retry:
+               /* Replace unconfirmed owners without checking for replay. */
+               release_openowner(oo);
+               oo = NULL;
++              goto retry;
+       }
+       if (oo) {
+               if (new)
diff --git a/queue-7.1/nfsd-check-get_user-return-when-reading-princhashlen.patch b/queue-7.1/nfsd-check-get_user-return-when-reading-princhashlen.patch
new file mode 100644 (file)
index 0000000..2c798dc
--- /dev/null
@@ -0,0 +1,47 @@
+From e186fa1c057f5eccb22afb1e83e34c0627085868 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Dominik=20Wo=C5=BAniak?= <stalion@gmail.com>
+Date: Thu, 21 May 2026 17:46:56 +0200
+Subject: nfsd: check get_user() return when reading princhashlen
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dominik Woźniak <stalion@gmail.com>
+
+commit e186fa1c057f5eccb22afb1e83e34c0627085868 upstream.
+
+In __cld_pipe_inprogress_downcall(), the get_user() that reads
+princhashlen from the userspace cld_msg_v2 buffer does not check its
+return value. A failing copy leaves princhashlen with uninitialised
+stack contents, which are then used to drive memdup_user() and stored
+as princhash.len on the resulting reclaim record. The other get_user()
+calls in this function all check the return; only this one is missed,
+which is most likely a copy-paste oversight from when v2 upcalls were
+introduced.
+
+Mirror the existing pattern used a few lines above for namelen.
+namecopy is declared with __free(kfree) so the early return cleans up
+the already-allocated buffer automatically.
+
+Fixes: 6ee95d1c8991 ("nfsd: add support for upcall version 2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Dominik Woźniak <stalion@gmail.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfs4recover.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/nfsd/nfs4recover.c
++++ b/fs/nfsd/nfs4recover.c
+@@ -718,7 +718,8 @@ __cld_pipe_inprogress_downcall(const str
+                               return PTR_ERR(namecopy);
+                       name.data = namecopy;
+                       name.len = namelen;
+-                      get_user(princhashlen, &ci->cc_princhash.cp_len);
++                      if (get_user(princhashlen, &ci->cc_princhash.cp_len))
++                              return -EFAULT;
+                       if (princhashlen > 0) {
+                               princhashcopy = memdup_user(
+                                       &ci->cc_princhash.cp_data,
diff --git a/queue-7.1/nfsd-fix-dead-acl-conflict-guard-in-nfsd4_create.patch b/queue-7.1/nfsd-fix-dead-acl-conflict-guard-in-nfsd4_create.patch
new file mode 100644 (file)
index 0000000..7bf39c2
--- /dev/null
@@ -0,0 +1,49 @@
+From a60f25a800846ab8e5a13f8a9d05111f2aee55a7 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@kernel.org>
+Date: Thu, 21 May 2026 07:50:21 -0400
+Subject: nfsd: fix dead ACL conflict guard in nfsd4_create
+
+From: Jeff Layton <jlayton@kernel.org>
+
+commit a60f25a800846ab8e5a13f8a9d05111f2aee55a7 upstream.
+
+nfsd4_create() steals create->cr_dpacl/cr_pacl into the local
+nfsd_attrs via the designated initializer, then immediately sets the
+source pointers to NULL. The subsequent conflict guard tests the
+already-nilled source fields, making it permanently dead code:
+
+    if (create->cr_acl) {
+        if (create->cr_dpacl || create->cr_pacl)  /* always false */
+
+When a client encodes both FATTR4_WORD0_ACL and
+FATTR4_WORD2_POSIX_{DEFAULT,ACCESS}_ACL in the same CREATE fattr
+bitmap, nfsd4_acl_to_attr() overwrites attrs.na_pacl/na_dpacl without
+releasing the originals, leaking two posix_acl slab objects per
+request. Repeated requests cause unbounded slab exhaustion.
+
+Fix by checking attrs.na_dpacl/na_pacl (the stolen values) instead of
+the nilled create->cr_dpacl/cr_pacl, matching the correct pattern
+already used in nfsd4_setattr().
+
+Reported-by: Chris Mason <clm@meta.com>
+Assisted-by: kres:claude-opus-4-6
+Fixes: d2ca50606f5f ("NFSD: Add support for POSIX draft ACLs for file creation")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfs4proc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -840,7 +840,7 @@ nfsd4_create(struct svc_rqst *rqstp, str
+               goto out_aftermask;
+       if (create->cr_acl) {
+-              if (create->cr_dpacl || create->cr_pacl) {
++              if (attrs.na_dpacl || attrs.na_pacl) {
+                       status = nfserr_inval;
+                       goto out_aftermask;
+               }
diff --git a/queue-7.1/nfsd-fix-inverted-cp_ttl-check-in-async-copy-reaper.patch b/queue-7.1/nfsd-fix-inverted-cp_ttl-check-in-async-copy-reaper.patch
new file mode 100644 (file)
index 0000000..258c9af
--- /dev/null
@@ -0,0 +1,45 @@
+From 0150459b05490b88b7e7378a31550a9e07b5517c Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@kernel.org>
+Date: Thu, 21 May 2026 09:25:40 -0400
+Subject: nfsd: fix inverted cp_ttl check in async copy reaper
+
+From: Jeff Layton <jlayton@kernel.org>
+
+commit 0150459b05490b88b7e7378a31550a9e07b5517c upstream.
+
+nfsd4_async_copy_reaper() is supposed to keep completed async copy
+state around for NFSD_COPY_INITIAL_TTL (10) laundromat ticks so
+that OFFLOAD_STATUS can report the result, then reap the state once
+the countdown expires.
+
+The TTL predicate is inverted: `if (--copy->cp_ttl)` is true while
+ticks remain and false when the counter reaches zero.  This causes
+the copy to be reaped on the very first tick (cp_ttl goes from 10
+to 9, which is non-zero) instead of after all 10 ticks elapse.
+Once reaped, OFFLOAD_STATUS returns NFS4ERR_BAD_STATEID because
+the copy state has already been freed.
+
+Fix by negating the test so that cleanup runs when the TTL expires.
+
+Fixes: aa0ebd21df9c ("NFSD: Add nfsd4_copy time-to-live")
+Cc: stable@vger.kernel.org
+Reported-by: Chris Mason <clm@meta.com>
+Assisted-by: kres:claude-opus-4-6
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfs4proc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -1470,7 +1470,7 @@ void nfsd4_async_copy_reaper(struct nfsd
+               list_for_each_safe(pos, next, &clp->async_copies) {
+                       copy = list_entry(pos, struct nfsd4_copy, copies);
+                       if (test_bit(NFSD4_COPY_F_OFFLOAD_DONE, &copy->cp_flags)) {
+-                              if (--copy->cp_ttl) {
++                              if (!--copy->cp_ttl) {
+                                       list_del_init(&copy->copies);
+                                       list_add(&copy->copies, &reaplist);
+                               }
diff --git a/queue-7.1/nfsd-fix-posix_acl-leak-and-ignored-error-in-nfsd4_create_file.patch b/queue-7.1/nfsd-fix-posix_acl-leak-and-ignored-error-in-nfsd4_create_file.patch
new file mode 100644 (file)
index 0000000..ca105ca
--- /dev/null
@@ -0,0 +1,86 @@
+From 24c975bbdd564d7d0ad90294bfa69729830345de Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@kernel.org>
+Date: Thu, 21 May 2026 12:37:33 -0400
+Subject: nfsd: fix posix_acl leak and ignored error in nfsd4_create_file
+
+From: Jeff Layton <jlayton@kernel.org>
+
+commit 24c975bbdd564d7d0ad90294bfa69729830345de upstream.
+
+nfsd4_create_file() has two bugs in its ACL handling:
+
+The return value of nfsd4_acl_to_attr() is silently discarded.  When
+the NFSv4-to-POSIX ACL conversion fails (e.g., -EINVAL for
+unsupported ACE types), the file is created without any ACL and the
+client receives NFS4_OK.  This violates RFC 7530/8881 which require
+the server to reject unsupported attributes on CREATE.
+
+When start_creating() fails after ACL attributes have been populated
+in attrs (either via nfsd4_acl_to_attr or via ownership transfer from
+open->op_dpacl/op_pacl), the function jumps to out_write which skips
+nfsd_attrs_free().  The posix_acl allocations are leaked.  A client
+can trigger this repeatedly with OPEN(CREATE), ACL attributes, and an
+invalid filename (e.g., longer than NAME_MAX).
+
+Fix both by capturing the nfsd4_acl_to_attr() return value and by
+changing the early error paths to jump to out instead of out_write.
+Initialize child to ERR_PTR(-EINVAL) so that end_creating() is safe
+to call even if start_creating() was never reached.
+
+Reported-by: Chris Mason <clm@meta.com>
+Fixes: 7ab96df840e6 ("VFS/nfsd/cachefiles/ovl: add start_creating() and end_creating()")
+Cc: stable@vger.kernel.org
+Assisted-by: kres:claude-opus-4-6
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfs4proc.c |   15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -253,7 +253,7 @@ nfsd4_create_file(struct svc_rqst *rqstp
+               .na_iattr       = iap,
+               .na_seclabel    = &open->op_label,
+       };
+-      struct dentry *parent, *child;
++      struct dentry *parent, *child = ERR_PTR(-EINVAL);
+       __u32 v_mtime, v_atime;
+       struct inode *inode;
+       __be32 status;
+@@ -277,10 +277,14 @@ nfsd4_create_file(struct svc_rqst *rqstp
+       if (open->op_acl) {
+               if (open->op_dpacl || open->op_pacl) {
+                       status = nfserr_inval;
+-                      goto out_write;
++                      goto out;
++              }
++              if (is_create_with_attrs(open)) {
++                      status = nfsd4_acl_to_attr(NF4REG, open->op_acl,
++                                                 &attrs);
++                      if (status)
++                              goto out;
+               }
+-              if (is_create_with_attrs(open))
+-                      nfsd4_acl_to_attr(NF4REG, open->op_acl, &attrs);
+       } else if (is_create_with_attrs(open)) {
+               /* The dpacl and pacl will get released by nfsd_attrs_free(). */
+               attrs.na_dpacl = open->op_dpacl;
+@@ -293,7 +297,7 @@ nfsd4_create_file(struct svc_rqst *rqstp
+                              &QSTR_LEN(open->op_fname, open->op_fnamelen));
+       if (IS_ERR(child)) {
+               status = nfserrno(PTR_ERR(child));
+-              goto out_write;
++              goto out;
+       }
+       if (d_really_is_negative(child)) {
+@@ -407,7 +411,6 @@ set_attr:
+ out:
+       end_creating(child);
+       nfsd_attrs_free(&attrs);
+-out_write:
+       fh_drop_write(fhp);
+       return status;
+ }
diff --git a/queue-7.1/nfsd-fix-posix_acl-leak-on-setacl-decode-failure.patch b/queue-7.1/nfsd-fix-posix_acl-leak-on-setacl-decode-failure.patch
new file mode 100644 (file)
index 0000000..70d4cc5
--- /dev/null
@@ -0,0 +1,131 @@
+From 0853ac544c590880d797b04daa33fcb72b6be0e1 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@kernel.org>
+Date: Thu, 21 May 2026 13:51:43 -0400
+Subject: nfsd: fix posix_acl leak on SETACL decode failure
+
+From: Jeff Layton <jlayton@kernel.org>
+
+commit 0853ac544c590880d797b04daa33fcb72b6be0e1 upstream.
+
+nfsaclsvc_decode_setaclargs() and nfs3svc_decode_setaclargs() each
+call nfs_stream_decode_acl() twice, first for NFS_ACL and then for
+NFS_DFACL.  Each successful call transfers ownership of a freshly
+allocated posix_acl into argp->acl_access or argp->acl_default.  If
+the first call succeeds but the second fails, the decoder returns
+false and argp->acl_access is left dangling.
+
+ACLPROC2_SETACL.pc_release was wired to nfssvc_release_attrstat and
+ACLPROC3_SETACL.pc_release was wired to nfs3svc_release_fhandle.
+Both only call fh_put() and have no knowledge of the ACL fields on
+argp.  The posix_acl_release() pairs sat at the out: labels inside
+nfsacld_proc_setacl() and nfsd3_proc_setacl(), but svc_process()
+skips pc_func when pc_decode returns false, so that cleanup is
+unreachable on decode failure:
+
+    svc_process_common()
+      pc_decode()                  /* decode_setaclargs: false */
+      /* pc_func skipped */
+      pc_release()                 /* fh_put only -- ACLs leaked */
+
+The orphaned posix_acl is leaked for the lifetime of the server.
+
+Fix by adding nfsaclsvc_release_setacl() and nfs3svc_release_setacl(),
+which release both argp->acl_access and argp->acl_default in addition
+to fh_put(), and wiring them as pc_release for their respective SETACL
+procedures.  pc_release runs on every path svc_process() takes after
+decode, including decode failure, so the posix_acl_release() pairs are
+removed from the proc functions' out: labels to keep ownership in one
+place.  This matches the existing release_getacl() pattern used by
+the sibling GETACL procedures.
+
+Fixes: a257cdd0e217 ("[PATCH] NFSD: Add server support for NFSv3 ACLs.")
+Cc: stable@vger.kernel.org
+Assisted-by: kres:claude-opus-4-7
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfs2acl.c |   17 ++++++++++++-----
+ fs/nfsd/nfs3acl.c |   17 ++++++++++++-----
+ 2 files changed, 24 insertions(+), 10 deletions(-)
+
+--- a/fs/nfsd/nfs2acl.c
++++ b/fs/nfsd/nfs2acl.c
+@@ -131,10 +131,7 @@ static __be32 nfsacld_proc_setacl(struct
+       resp->status = fh_getattr(fh, &resp->stat);
+ out:
+-      /* argp->acl_{access,default} may have been allocated in
+-         nfssvc_decode_setaclargs. */
+-      posix_acl_release(argp->acl_access);
+-      posix_acl_release(argp->acl_default);
++      /* argp->acl_{access,default} are released in nfsaclsvc_release_setacl. */
+       return rpc_success;
+ out_drop_lock:
+@@ -310,6 +307,16 @@ static void nfsaclsvc_release_access(str
+       fh_put(&resp->fh);
+ }
++static void nfsaclsvc_release_setacl(struct svc_rqst *rqstp)
++{
++      struct nfsd3_setaclargs *argp = rqstp->rq_argp;
++      struct nfsd_attrstat *resp = rqstp->rq_resp;
++
++      fh_put(&resp->fh);
++      posix_acl_release(argp->acl_access);
++      posix_acl_release(argp->acl_default);
++}
++
+ #define ST 1          /* status*/
+ #define AT 21         /* attributes */
+ #define pAT (1+AT)    /* post attributes - conditional */
+@@ -343,7 +350,7 @@ static const struct svc_procedure nfsd_a
+               .pc_func = nfsacld_proc_setacl,
+               .pc_decode = nfsaclsvc_decode_setaclargs,
+               .pc_encode = nfssvc_encode_attrstatres,
+-              .pc_release = nfssvc_release_attrstat,
++              .pc_release = nfsaclsvc_release_setacl,
+               .pc_argsize = sizeof(struct nfsd3_setaclargs),
+               .pc_argzero = sizeof(struct nfsd3_setaclargs),
+               .pc_ressize = sizeof(struct nfsd_attrstat),
+--- a/fs/nfsd/nfs3acl.c
++++ b/fs/nfsd/nfs3acl.c
+@@ -118,10 +118,7 @@ out_drop_lock:
+ out_errno:
+       resp->status = nfserrno(error);
+ out:
+-      /* argp->acl_{access,default} may have been allocated in
+-         nfs3svc_decode_setaclargs. */
+-      posix_acl_release(argp->acl_access);
+-      posix_acl_release(argp->acl_default);
++      /* argp->acl_{access,default} are released in nfs3svc_release_setacl. */
+       return rpc_success;
+ }
+@@ -223,6 +220,16 @@ static void nfs3svc_release_getacl(struc
+       posix_acl_release(resp->acl_default);
+ }
++static void nfs3svc_release_setacl(struct svc_rqst *rqstp)
++{
++      struct nfsd3_setaclargs *argp = rqstp->rq_argp;
++      struct nfsd3_attrstat *resp = rqstp->rq_resp;
++
++      fh_put(&resp->fh);
++      posix_acl_release(argp->acl_access);
++      posix_acl_release(argp->acl_default);
++}
++
+ #define ST 1          /* status*/
+ #define AT 21         /* attributes */
+ #define pAT (1+AT)    /* post attributes - conditional */
+@@ -256,7 +263,7 @@ static const struct svc_procedure nfsd_a
+               .pc_func = nfsd3_proc_setacl,
+               .pc_decode = nfs3svc_decode_setaclargs,
+               .pc_encode = nfs3svc_encode_setaclres,
+-              .pc_release = nfs3svc_release_fhandle,
++              .pc_release = nfs3svc_release_setacl,
+               .pc_argsize = sizeof(struct nfsd3_setaclargs),
+               .pc_argzero = sizeof(struct nfsd3_setaclargs),
+               .pc_ressize = sizeof(struct nfsd3_attrstat),
diff --git a/queue-7.1/nfsd-fix-secinfo_no_name-decode-error-cleanup.patch b/queue-7.1/nfsd-fix-secinfo_no_name-decode-error-cleanup.patch
new file mode 100644 (file)
index 0000000..08909b3
--- /dev/null
@@ -0,0 +1,48 @@
+From 9e18e83b8846a5c3fe13fc8a464b4865d33996c6 Mon Sep 17 00:00:00 2001
+From: Guannan Wang <wgnbuaa@gmail.com>
+Date: Thu, 21 May 2026 16:03:32 +0800
+Subject: NFSD: Fix SECINFO_NO_NAME decode error cleanup
+
+From: Guannan Wang <wgnbuaa@gmail.com>
+
+commit 9e18e83b8846a5c3fe13fc8a464b4865d33996c6 upstream.
+
+nfsd4_decode_secinfo_no_name() currently initializes sin_exp after
+decoding sin_style. If the XDR stream is truncated, the decoder returns
+nfserr_bad_xdr before sin_exp is initialized.
+
+Since commit 3fdc54646234 ("NFSD: Reduce amount of struct
+nfsd4_compoundargs that needs clearing"), the inline iops array is not
+cleared between RPC calls. A failed SECINFO_NO_NAME decode can therefore
+leave sin_exp holding stale union contents from a previous operation.
+
+The error response path still invokes nfsd4_secinfo_no_name_release(),
+which calls exp_put() on a non-NULL sin_exp.
+
+Initialize sin_exp before the first failable decode step, matching
+nfsd4_decode_secinfo().
+
+Fixes: 3fdc54646234 ("NFSD: Reduce amount of struct nfsd4_compoundargs that needs clearing")
+Cc: stable@vger.kernel.org
+Signed-off-by: Guannan Wang <wgnbuaa@gmail.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfs4xdr.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/nfsd/nfs4xdr.c
++++ b/fs/nfsd/nfs4xdr.c
+@@ -2008,10 +2008,11 @@ static __be32 nfsd4_decode_secinfo_no_na
+                                          union nfsd4_op_u *u)
+ {
+       struct nfsd4_secinfo_no_name *sin = &u->secinfo_no_name;
++
++      sin->sin_exp = NULL;
+       if (xdr_stream_decode_u32(argp->xdr, &sin->sin_style) < 0)
+               return nfserr_bad_xdr;
+-      sin->sin_exp = NULL;
+       return nfs_ok;
+ }
diff --git a/queue-7.1/nfsd-release-layout-stid-on-setlease-failure.patch b/queue-7.1/nfsd-release-layout-stid-on-setlease-failure.patch
new file mode 100644 (file)
index 0000000..6eb5b4f
--- /dev/null
@@ -0,0 +1,84 @@
+From 30d55c8aabb261bc3f427d6b9aae7ef6206063f9 Mon Sep 17 00:00:00 2001
+From: Chris Mason <clm@meta.com>
+Date: Mon, 18 May 2026 13:16:36 -0700
+Subject: nfsd: release layout stid on setlease failure
+
+From: Chris Mason <clm@meta.com>
+
+commit 30d55c8aabb261bc3f427d6b9aae7ef6206063f9 upstream.
+
+nfs4_alloc_stid() publishes the new stid into cl->cl_stateids via
+idr_alloc_cyclic() under cl_lock before returning to
+nfsd4_alloc_layout_stateid(). When nfsd4_layout_setlease() then
+fails, the error path frees the layout stateid directly with
+kmem_cache_free() without ever calling idr_remove(), leaving the
+IDR slot pointing at freed slab memory. Any subsequent IDR walker
+(states_show, client teardown) dereferences the dangling pointer.
+
+The correct teardown for an IDR-published stid is nfs4_put_stid(),
+which removes the IDR slot under cl_lock, dispatches sc_free
+(nfsd4_free_layout_stateid) to release ls->ls_file via
+nfsd4_close_layout(), and drops the nfs4_file reference in its
+tail.
+
+A second issue blocks that switch: nfsd4_free_layout_stateid()
+unconditionally inspects ls->ls_fence_work via
+delayed_work_pending() under ls_lock, but
+INIT_DELAYED_WORK(&ls->ls_fence_work, ...) currently runs only
+after the setlease call. On the setlease-failure path the
+destructor would touch an uninitialized delayed_work.
+
+    nfsd4_alloc_layout_stateid()
+      nfs4_alloc_stid()           /* idr_alloc_cyclic under cl_lock */
+      nfsd4_layout_setlease()     /* fails */
+        nfs4_put_stid()
+          nfsd4_free_layout_stateid()
+            delayed_work_pending(&ls->ls_fence_work)  /* needs INIT */
+            nfsd4_close_layout()  /* nfsd_file_put(ls->ls_file) */
+          put_nfs4_file()
+
+Fix by hoisting the ls_fenced / ls_fence_delay / INIT_DELAYED_WORK
+initialization above the nfsd4_layout_setlease() call, and replace
+the manual nfsd_file_put + put_nfs4_file + kmem_cache_free cleanup
+with a single nfs4_put_stid(stp).
+
+Fixes: c5c707f96fc9 ("nfsd: implement pNFS layout recalls")
+Cc: stable@vger.kernel.org
+Assisted-by: kres (claude-opus-4-7)
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfs4layouts.c |   12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+--- a/fs/nfsd/nfs4layouts.c
++++ b/fs/nfsd/nfs4layouts.c
+@@ -264,10 +264,12 @@ nfsd4_alloc_layout_stateid(struct nfsd4_
+               ls->ls_file = find_any_file(fp);
+       BUG_ON(!ls->ls_file);
++      ls->ls_fenced = false;
++      ls->ls_fence_delay = 0;
++      INIT_DELAYED_WORK(&ls->ls_fence_work, nfsd4_layout_fence_worker);
++
+       if (nfsd4_layout_setlease(ls)) {
+-              nfsd_file_put(ls->ls_file);
+-              put_nfs4_file(fp);
+-              kmem_cache_free(nfs4_layout_stateid_cache, ls);
++              nfs4_put_stid(stp);
+               return NULL;
+       }
+@@ -280,10 +282,6 @@ nfsd4_alloc_layout_stateid(struct nfsd4_
+       list_add(&ls->ls_perfile, &fp->fi_lo_states);
+       spin_unlock(&fp->fi_lock);
+-      ls->ls_fenced = false;
+-      ls->ls_fence_delay = 0;
+-      INIT_DELAYED_WORK(&ls->ls_fence_work, nfsd4_layout_fence_worker);
+-
+       trace_nfsd_layoutstate_alloc(&ls->ls_stid.sc_stateid);
+       return ls;
+ }
diff --git a/queue-7.1/nfsd-reset-write-verifier-on-deferred-writeback-errors.patch b/queue-7.1/nfsd-reset-write-verifier-on-deferred-writeback-errors.patch
new file mode 100644 (file)
index 0000000..16ba67a
--- /dev/null
@@ -0,0 +1,63 @@
+From 2090b05803faab8a9fa62fbff871007862cac1b7 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@kernel.org>
+Date: Fri, 22 May 2026 12:44:19 -0400
+Subject: nfsd: reset write verifier on deferred writeback errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jeff Layton <jlayton@kernel.org>
+
+commit 2090b05803faab8a9fa62fbff871007862cac1b7 upstream.
+
+nfsd_vfs_write() and nfsd_commit() both call filemap_check_wb_err() to
+detect deferred writeback errors, but neither rotates the server's write
+verifier (nn->writeverf) when this check fails. Every other
+durable-storage-failure path in these functions calls
+commit_reset_write_verifier() before returning an error.
+
+The missing rotation means clients holding UNSTABLE write data under the
+current verifier will COMMIT, receive the unchanged verifier back, and
+conclude their data is durable â€” silently dropping data that failed
+writeback. This violates the UNSTABLE+COMMIT durability contract
+(RFC 1813 Â§3.3.7, RFC 8881 Â§18.32).
+
+Add commit_reset_write_verifier() calls at both filemap_check_wb_err()
+error sites, matching the pattern used by adjacent error paths in the
+same functions. The helper already filters -EAGAIN and -ESTALE
+internally, so the calls are unconditionally safe.
+
+Reported-by: Chris Mason <clm@meta.com>
+Fixes: 555dbf1a9aac ("nfsd: Replace use of rwsem with errseq_t")
+Cc: stable@vger.kernel.org
+Assisted-by: kres:claude-opus-4-6
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/vfs.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -1508,8 +1508,10 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s
+       nfsd_stats_io_write_add(nn, exp, *cnt);
+       fsnotify_modify(file);
+       host_err = filemap_check_wb_err(file->f_mapping, since);
+-      if (host_err < 0)
++      if (host_err < 0) {
++              commit_reset_write_verifier(nn, rqstp, host_err);
+               goto out_nfserr;
++      }
+       if (stable && fhp->fh_use_wgather) {
+               host_err = wait_for_concurrent_writes(file);
+@@ -1689,6 +1691,8 @@ nfsd_commit(struct svc_rqst *rqstp, stru
+                       nfsd_copy_write_verifier(verf, nn);
+                       err2 = filemap_check_wb_err(nf->nf_file->f_mapping,
+                                                   since);
++                      if (err2 < 0)
++                              commit_reset_write_verifier(nn, rqstp, err2);
+                       err = nfserrno(err2);
+                       break;
+               case -EINVAL:
diff --git a/queue-7.1/nfsv4-clear-exception-state-on-successful-mkdir-retry.patch b/queue-7.1/nfsv4-clear-exception-state-on-successful-mkdir-retry.patch
new file mode 100644 (file)
index 0000000..24bae0f
--- /dev/null
@@ -0,0 +1,82 @@
+From 238e9b51aa29f48b6243212a3b75c8e48d6b96fd Mon Sep 17 00:00:00 2001
+From: Igor Raits <igor.raits@gmail.com>
+Date: Wed, 29 Apr 2026 12:49:38 +0200
+Subject: NFSv4: clear exception state on successful mkdir retry
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Igor Raits <igor.raits@gmail.com>
+
+commit 238e9b51aa29f48b6243212a3b75c8e48d6b96fd upstream.
+
+After a server returns NFS4ERR_DELAY for an NFSv4 CREATE issued by
+mkdir(2), the client correctly waits and retries.  When the retry
+succeeds, however, mkdir(2) can still surface -EEXIST to userspace
+even though the directory was just created on the server.
+
+Reproducer (random 16-hex names so collisions are not the cause)
+against an in-kernel Linux nfsd; reproduces under both NFSv4.0 and
+NFSv4.2:
+
+  N=2000000; base=/var/gdc/export
+  for ((i=1; i<=N; i++)); do
+      d=$base/$(openssl rand -hex 8)
+      mkdir "$d" 2>/dev/null || echo "$(date +%T) failed loop=$i $d"
+      rmdir "$d" 2>/dev/null
+  done
+
+Failures cluster at the cadence at which the server-side auth/export
+cache refresh path causes nfsd to return NFS4ERR_DELAY for CREATE.
+
+A wire trace of one failure (the three CREATE RPCs all come from a
+single mkdir(2), generated by the do-while in nfs4_proc_mkdir()):
+
+  client -> server  CREATE name=...  -> NFS4ERR_DELAY
+  ~100 ms later
+  client -> server  CREATE name=...  -> NFS4_OK         (dir created)
+  ~80 us later
+  client -> server  CREATE name=...  -> NFS4ERR_EXIST   (correct)
+
+Since commit dd862da61e91 ("nfs: fix incorrect handling of large-number
+NFS errors in nfs4_do_mkdir()"), nfs4_handle_exception() is called only
+when _nfs4_proc_mkdir() returned an error.  That gate breaks retry-state
+hygiene: nfs4_do_handle_exception() resets exception.{delay,recovering,
+retry} to 0 on entry, so calling it on success is what previously
+cleared the retry flag set by the preceding NFS4ERR_DELAY iteration.
+With the gate in place, exception.retry stays at 1 after the successful
+retry, the loop runs once more, and the resulting CREATE for an
+already-created name yields NFS4ERR_EXIST -> -EEXIST to userspace.
+
+Drop the conditional and call nfs4_handle_exception() unconditionally,
+matching every other do-while in fs/nfs/nfs4proc.c (nfs4_proc_symlink(),
+nfs4_proc_link(), etc.).  The dentry/status separation introduced by
+that commit is preserved.
+
+Fixes: dd862da61e91 ("nfs: fix incorrect handling of large-number NFS errors in nfs4_do_mkdir()")
+Reported-and-tested-by: Jan ÄŒÃ­pa <jan.cipa@gooddata.com>
+Closes: https://lore.kernel.org/linux-nfs/CA+9S74hSp_tJu2Ffe2BPNC2T25gfkhgjjDkdgSsF5c2rnJq_wA@mail.gmail.com/
+Reviewed-by: NeilBrown <neil@brown.name>
+Cc: stable@vger.kernel.org
+Signed-off-by: Igor Raits <igor.raits@gmail.com>
+Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfs/nfs4proc.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -5302,10 +5302,9 @@ static struct dentry *nfs4_proc_mkdir(st
+       do {
+               alias = _nfs4_proc_mkdir(dir, dentry, sattr, label, &err);
+               trace_nfs4_mkdir(dir, &dentry->d_name, err);
++              err = nfs4_handle_exception(NFS_SERVER(dir), err, &exception);
+               if (err)
+-                      alias = ERR_PTR(nfs4_handle_exception(NFS_SERVER(dir),
+-                                                            err,
+-                                                            &exception));
++                      alias = ERR_PTR(err);
+       } while (exception.retry);
+       nfs4_label_release_security(label);
diff --git a/queue-7.1/nfsv4-flexfiles-reject-zero-filehandle-version-count.patch b/queue-7.1/nfsv4-flexfiles-reject-zero-filehandle-version-count.patch
new file mode 100644 (file)
index 0000000..da92ab7
--- /dev/null
@@ -0,0 +1,54 @@
+From 2c6bb3c40bc24f6aa8dfbe6fe98c3ad6389203f2 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Wed, 13 May 2026 12:26:56 -0400
+Subject: NFSv4/flexfiles: reject zero filehandle version count
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 2c6bb3c40bc24f6aa8dfbe6fe98c3ad6389203f2 upstream.
+
+ff_layout_alloc_lseg() decodes the filehandle-version array count
+from the flexfiles layout body. The value is used as the count for
+kzalloc_objs(), and the current code only rejects NULL.
+
+A zero count yields ZERO_SIZE_PTR, which can be stored in
+dss_info->fh_versions even though later flexfiles paths assume that at
+least one filehandle version exists.
+
+Reject fh_count == 0 before the allocation, matching the existing zero
+version_count validation in the flexfiles GETDEVICEINFO parser.
+
+A QEMU/KASAN run with a malformed flexfiles layout hit:
+
+  KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
+  RIP: 0010:ff_layout_encode_ff_layoutupdate.isra.0+0x15f/0x750
+  ff_layout_encode_layoutreturn+0x683/0x970
+  nfs4_xdr_enc_layoutreturn+0x278/0x3a0
+  Kernel panic - not syncing: Fatal exception
+
+The patched kernel rejects the malformed layout without KASAN/oops/panic,
+and a valid fh_count=1 regression still opens, reads, and unmounts cleanly.
+
+Cc: stable@vger.kernel.org
+Fixes: d67ae825a59d ("pnfs/flexfiles: Add the FlexFile Layout Driver")
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfs/flexfilelayout/flexfilelayout.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/nfs/flexfilelayout/flexfilelayout.c
++++ b/fs/nfs/flexfilelayout/flexfilelayout.c
+@@ -551,6 +551,10 @@ ff_layout_alloc_lseg(struct pnfs_layout_
+                       if (!p)
+                               goto out_err_free;
+                       fh_count = be32_to_cpup(p);
++                      if (fh_count == 0) {
++                              rc = -EINVAL;
++                              goto out_err_free;
++                      }
+                       dss_info->fh_versions =
+                           kzalloc_objs(struct nfs_fh, fh_count, gfp_flags);
diff --git a/queue-7.1/nfsv4-pnfs-reject-zero-length-r_addr-in-nfs4_decode_mp_ds_addr.patch b/queue-7.1/nfsv4-pnfs-reject-zero-length-r_addr-in-nfs4_decode_mp_ds_addr.patch
new file mode 100644 (file)
index 0000000..115979c
--- /dev/null
@@ -0,0 +1,56 @@
+From 41fe0f7b84f0cb822ae10ab08592996a592b2a25 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Wed, 27 May 2026 12:30:35 -0400
+Subject: NFSv4/pNFS: reject zero-length r_addr in nfs4_decode_mp_ds_addr
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 41fe0f7b84f0cb822ae10ab08592996a592b2a25 upstream.
+
+nfs4_decode_mp_ds_addr() decodes the r_netid and r_addr opaques of a
+netaddr4 from a GETDEVICEINFO multipath-DS body, then immediately
+calls strrchr(buf, '.') to locate the port separator. Both decodes
+use xdr_stream_decode_string_dup(), and the current code checks only
+"nlen < 0" / "rlen < 0" before dereferencing the returned string.
+
+When the on-wire opaque has length zero, xdr_stream_decode_opaque_inline()
+returns 0 and xdr_stream_decode_string_dup() falls through to its
+"*str = NULL; return ret" tail, leaving buf NULL with a return value
+of 0. The "< 0" check does not catch this, and the next line is
+strrchr(NULL, '.'), a kernel NULL pointer dereference reachable from
+any pNFS-flexfile client mounted against a malicious or compromised
+metadata server.
+
+Reject the zero-length cases explicitly so the decoder fails with
+-EBADMSG (treated as a malformed GETDEVICEINFO body) instead of
+panicking the client.
+
+Cc: stable@vger.kernel.org
+Fixes: 6b7f3cf96364 ("nfs41: pull decode_ds_addr from file layout to generic pnfs")
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfs/pnfs_nfs.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/nfs/pnfs_nfs.c
++++ b/fs/nfs/pnfs_nfs.c
+@@ -1075,14 +1075,14 @@ nfs4_decode_mp_ds_addr(struct net *net,
+       /* r_netid */
+       nlen = xdr_stream_decode_string_dup(xdr, &netid, XDR_MAX_NETOBJ,
+                                           gfp_flags);
+-      if (unlikely(nlen < 0))
++      if (unlikely(nlen <= 0))
+               goto out_err;
+       /* r_addr: ip/ip6addr with port in dec octets - see RFC 5665 */
+       /* port is ".ABC.DEF", 8 chars max */
+       rlen = xdr_stream_decode_string_dup(xdr, &buf, INET6_ADDRSTRLEN +
+                                           IPV6_SCOPE_ID_LEN + 8, gfp_flags);
+-      if (unlikely(rlen < 0))
++      if (unlikely(rlen <= 0))
+               goto out_free_netid;
+       /* replace port '.' with '-' */
diff --git a/queue-7.1/ntfs-serialize-volume-label-accesses.patch b/queue-7.1/ntfs-serialize-volume-label-accesses.patch
new file mode 100644 (file)
index 0000000..bf7dd55
--- /dev/null
@@ -0,0 +1,110 @@
+From e9e50ce4f13dc721014af622613409455c734942 Mon Sep 17 00:00:00 2001
+From: Hyunchul Lee <hyc.lee@gmail.com>
+Date: Tue, 2 Jun 2026 13:53:24 +0900
+Subject: ntfs: serialize volume label accesses
+
+From: Hyunchul Lee <hyc.lee@gmail.com>
+
+commit e9e50ce4f13dc721014af622613409455c734942 upstream.
+
+Protect vol->volume_label with a mutex and snaphost the label before
+copy_to_user. This prevent a use-after-free when FS_IOC_SETFSLABEL
+replaces the vol->volume_label and FS_IOC_GETTSLABEL reads it
+concurrently.
+
+Cc: stable@vger.kernel.org # v7.1
+Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ntfs/file.c   |   17 +++++++++++++----
+ fs/ntfs/super.c  |   19 +++++++++++++------
+ fs/ntfs/volume.h |    2 ++
+ 3 files changed, 28 insertions(+), 10 deletions(-)
+
+--- a/fs/ntfs/file.c
++++ b/fs/ntfs/file.c
+@@ -707,12 +707,21 @@ static int ntfs_ioctl_get_volume_label(s
+ {
+       struct ntfs_volume *vol = NTFS_SB(file_inode(filp)->i_sb);
+       char __user *buf = (char __user *)arg;
++      char label[FSLABEL_MAX];
++      ssize_t len;
++      mutex_lock(&vol->volume_label_lock);
+       if (!vol->volume_label) {
+-              if (copy_to_user(buf, "", 1))
+-                      return -EFAULT;
+-      } else if (copy_to_user(buf, vol->volume_label,
+-                              MIN(FSLABEL_MAX, strlen(vol->volume_label) + 1)))
++              label[0] = '\0';
++              len = 0;
++      } else {
++              len = strscpy(label, vol->volume_label, sizeof(label));
++              if (len == -E2BIG)
++                      len = FSLABEL_MAX - 1;
++      }
++      mutex_unlock(&vol->volume_label_lock);
++
++      if (copy_to_user(buf, label, len + 1))
+               return -EFAULT;
+       return 0;
+ }
+--- a/fs/ntfs/super.c
++++ b/fs/ntfs/super.c
+@@ -460,17 +460,23 @@ int ntfs_write_volume_label(struct ntfs_
+       ret = ntfs_resident_attr_record_add(vol_ni, AT_VOLUME_NAME, AT_UNNAMED, 0,
+                                           (u8 *)uname, uname_len * sizeof(__le16), 0);
+ out:
+-      mutex_unlock(&vol_ni->mrec_lock);
+-      kvfree(uname);
+-
+       if (ret >= 0) {
+-              kfree(vol->volume_label);
++              char *old_label;
++
++              mutex_lock(&vol->volume_label_lock);
++              old_label = vol->volume_label;
+               vol->volume_label = new_label;
++              mutex_unlock(&vol->volume_label_lock);
++
++              kfree(old_label);
+               mark_inode_dirty_sync(vol->vol_ino);
+               ret = 0;
+-      } else {
+-              kfree(new_label);
+       }
++      mutex_unlock(&vol_ni->mrec_lock);
++      kvfree(uname);
++
++      if (ret < 0)
++              kfree(new_label);
+       return ret;
+ }
+@@ -2631,6 +2637,7 @@ static int ntfs_init_fs_context(struct f
+       NVolSetCaseSensitive(vol);
+       init_rwsem(&vol->mftbmp_lock);
+       init_rwsem(&vol->lcnbmp_lock);
++      mutex_init(&vol->volume_label_lock);
+       fc->s_fs_info = vol;
+       fc->ops = &ntfs_context_ops;
+--- a/fs/ntfs/volume.h
++++ b/fs/ntfs/volume.h
+@@ -72,6 +72,7 @@
+  * @vol_flags: Volume flags.
+  * @major_ver: Ntfs major version of volume.
+  * @minor_ver: Ntfs minor version of volume.
++ * @volume_label_lock: protects @volume_label.
+  * @volume_label: volume label.
+  * @root_ino: The VFS inode of the root directory.
+  * @secure_ino: The VFS inode of $Secure (NTFS3.0+ only, otherwise NULL).
+@@ -133,6 +134,7 @@ struct ntfs_volume {
+       struct inode *logfile_ino;
+       struct inode *lcnbmp_ino;
+       struct rw_semaphore lcnbmp_lock;
++      struct mutex volume_label_lock;
+       struct inode *vol_ino;
+       __le16 vol_flags;
+       u8 major_ver;
diff --git a/queue-7.1/ocfs2-reject-oversized-group-bitmap-descriptors.patch b/queue-7.1/ocfs2-reject-oversized-group-bitmap-descriptors.patch
new file mode 100644 (file)
index 0000000..2d4bc9a
--- /dev/null
@@ -0,0 +1,128 @@
+From 9bd541e09dffff27e5bec0f9f45b0228173a5375 Mon Sep 17 00:00:00 2001
+From: Zhang Cen <rollkingzzc@gmail.com>
+Date: Sun, 24 May 2026 19:12:48 +0800
+Subject: ocfs2: reject oversized group bitmap descriptors
+
+From: Zhang Cen <rollkingzzc@gmail.com>
+
+commit 9bd541e09dffff27e5bec0f9f45b0228173a5375 upstream.
+
+ocfs2_validate_gd_parent() only bounds bg_bits against the parent
+allocator's chain geometry.  A malicious descriptor can still claim a
+bg_size/bg_bits pair that exceeds the bitmap bytes that physically fit in
+the group descriptor block, so later bitmap scans and bit updates can run
+past bg_bitmap.
+
+Add a physical-cap check based on ocfs2_group_bitmap_size() for the parent
+allocator type and reject descriptors whose bg_size or bg_bits exceed that
+capacity.  Keep the existing chain geometry check so both the on-disk
+bitmap layout and the allocator metadata must agree before the descriptor
+is used.
+
+Validation reproduced this kernel report:
+KASAN use-after-free in _find_next_bit+0x7f/0xc0
+Read of size 8
+Call trace:
+  dump_stack_lvl+0x66/0xa0 (?:?)
+  print_report+0xd0/0x630 (?:?)
+  _find_next_bit+0x7f/0xc0 (?:?)
+  srso_alias_return_thunk+0x5/0xfbef5 (?:?)
+  __virt_addr_valid+0x188/0x2f0 (?:?)
+  kasan_report+0xe4/0x120 (?:?)
+  ocfs2_find_max_contig_free_bits+0x35/0x70 (fs/ocfs2/suballoc.c:1375)
+  ocfs2_block_group_set_bits+0x472/0x4b0 (fs/ocfs2/suballoc.c:1457)
+  ocfs2_cluster_group_search+0x16b/0x440 (fs/ocfs2/suballoc.c:86)
+  ocfs2_bg_discontig_fix_result+0x1ef/0x230 (fs/ocfs2/suballoc.c:1786)
+  ocfs2_search_chain+0x8f8/0x10a0 (fs/ocfs2/suballoc.c:1886)
+  get_page_from_freelist+0x70e/0x2370 (?:?)
+  lock_release+0xc6/0x290 (?:?)
+  do_raw_spin_unlock+0x9a/0x100 (?:?)
+  kasan_unpoison+0x27/0x60 (?:?)
+  __bfs+0x147/0x240 (?:?)
+  get_page_from_freelist+0x83d/0x2370 (?:?)
+  ocfs2_claim_suballoc_bits+0x38c/0xe70 (fs/ocfs2/suballoc.c:96)
+  sched_domains_numa_masks_clear+0x70/0xd0 (?:?)
+  check_irq_usage+0xe8/0xb70 (?:?)
+  __ocfs2_claim_clusters+0x18d/0x4c0 (fs/ocfs2/suballoc.c:2497)
+  check_path+0x24/0x50 (?:?)
+  rcu_is_watching+0x20/0x50 (?:?)
+  check_prev_add+0xfd/0xd00 (?:?)
+  ocfs2_add_clusters_in_btree+0x17d/0x810 (fs/ocfs2/suballoc.c:?)
+  __folio_batch_add_and_move+0x1f5/0x3d0 (?:?)
+  ocfs2_add_inode_data+0xd9/0x120 (fs/ocfs2/suballoc.c:?)
+  filemap_add_folio+0x105/0x1f0 (?:?)
+  ocfs2_write_begin_nolock+0x29f7/0x2f80 (fs/ocfs2/suballoc.c:3043)
+  ocfs2_read_inode_block+0xb5/0x110 (fs/ocfs2/suballoc.c:?)
+  down_write+0xf5/0x180 (?:?)
+  ocfs2_write_begin+0x180/0x240 (fs/ocfs2/suballoc.c:?)
+  __mark_inode_dirty+0x758/0x9a0 (?:?)
+  inode_to_bdi+0x41/0x90 (?:?)
+  balance_dirty_pages_ratelimited_flags+0xf8/0x1d0 (?:?)
+  generic_perform_write+0x252/0x440 (?:?)
+  mnt_put_write_access_file+0x16/0x70 (?:?)
+  file_update_time_flags+0xe4/0x200 (?:?)
+  ocfs2_file_write_iter+0x80a/0x1320 (fs/ocfs2/suballoc.c:?)
+  lock_acquire+0x184/0x2f0 (?:?)
+  ksys_write+0xd2/0x170 (?:?)
+  apparmor_file_permission+0xf5/0x310 (?:?)
+  read_zero+0x8d/0x140 (?:?)
+  lock_is_held_type+0x8f/0x100 (?:?)
+
+Link: https://lore.kernel.org/20260524111248.1429884-1-rollkingzzc@gmail.com
+Fixes: ccd979bdbce9 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Zhang Cen <rollkingzzc@gmail.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Heming Zhao <heming.zhao@suse.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/suballoc.c |   22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+--- a/fs/ocfs2/suballoc.c
++++ b/fs/ocfs2/suballoc.c
+@@ -231,8 +231,16 @@ static int ocfs2_validate_gd_parent(stru
+                                   int resize)
+ {
+       unsigned int max_bits;
++      unsigned int max_bitmap_bits;
++      unsigned int max_bitmap_size;
++      int suballocator;
+       struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
++      suballocator = le64_to_cpu(di->i_blkno) != OCFS2_SB(sb)->bitmap_blkno;
++      max_bitmap_size = ocfs2_group_bitmap_size(sb, suballocator,
++                                                OCFS2_SB(sb)->s_feature_incompat);
++      max_bitmap_bits = max_bitmap_size * 8;
++
+       if (di->i_blkno != gd->bg_parent_dinode) {
+               do_error("Group descriptor #%llu has bad parent pointer (%llu, expected %llu)\n",
+                        (unsigned long long)bh->b_blocknr,
+@@ -240,6 +248,20 @@ static int ocfs2_validate_gd_parent(stru
+                        (unsigned long long)le64_to_cpu(di->i_blkno));
+       }
++      if (le16_to_cpu(gd->bg_size) > max_bitmap_size) {
++              do_error("Group descriptor #%llu has bitmap size %u but physical max of %u\n",
++                       (unsigned long long)bh->b_blocknr,
++                       le16_to_cpu(gd->bg_size),
++                       max_bitmap_size);
++      }
++
++      if (le16_to_cpu(gd->bg_bits) > max_bitmap_bits) {
++              do_error("Group descriptor #%llu has bit count %u but physical max of %u\n",
++                       (unsigned long long)bh->b_blocknr,
++                       le16_to_cpu(gd->bg_bits),
++                       max_bitmap_bits);
++      }
++
+       max_bits = le16_to_cpu(di->id2.i_chain.cl_cpg) * le16_to_cpu(di->id2.i_chain.cl_bpc);
+       if (le16_to_cpu(gd->bg_bits) > max_bits) {
+               do_error("Group descriptor #%llu has bit count of %u\n",
diff --git a/queue-7.1/pnfs-fix-use-after-free-in-pnfs_update_layout.patch b/queue-7.1/pnfs-fix-use-after-free-in-pnfs_update_layout.patch
new file mode 100644 (file)
index 0000000..4a6fc25
--- /dev/null
@@ -0,0 +1,41 @@
+From 13e198a90ca4050f4bee8a3f23680389a6563ccc Mon Sep 17 00:00:00 2001
+From: Wentao Liang <vulab@iscas.ac.cn>
+Date: Mon, 18 May 2026 13:10:36 +0000
+Subject: pNFS: Fix use-after-free in pnfs_update_layout()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+commit 13e198a90ca4050f4bee8a3f23680389a6563ccc upstream.
+
+When hitting the NFS_LAYOUT_RETURN branch in pnfs_update_layout(),
+the code calls pnfs_prepare_to_retry_layoutget(lo). If it succeeds,
+pnfs_put_layout_hdr(lo) is called before trace_pnfs_update_layout(),
+which still references 'lo'. This results in a use-after-free when the
+tracepoint accesses lo's fields.
+
+Fix this by moving the tracepoint call before pnfs_put_layout_hdr(lo).
+
+Fixes: 2c8d5fc37fe2 ("pNFS: Stricter ordering of layoutget and layoutreturn")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfs/pnfs.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/nfs/pnfs.c
++++ b/fs/nfs/pnfs.c
+@@ -2229,11 +2229,11 @@ lookup_again:
+               dprintk("%s wait for layoutreturn\n", __func__);
+               lseg = ERR_PTR(pnfs_prepare_to_retry_layoutget(lo));
+               if (!IS_ERR(lseg)) {
+-                      pnfs_put_layout_hdr(lo);
+                       dprintk("%s retrying\n", __func__);
+                       trace_pnfs_update_layout(ino, pos, count, iomode, lo,
+                                                lseg,
+                                                PNFS_UPDATE_LAYOUT_RETRY);
++                      pnfs_put_layout_hdr(lo);
+                       goto lookup_again;
+               }
+               trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
diff --git a/queue-7.1/power-reset-linkstation-poweroff-fix-use-after-free-in-the-linkstation_poweroff_init.patch b/queue-7.1/power-reset-linkstation-poweroff-fix-use-after-free-in-the-linkstation_poweroff_init.patch
new file mode 100644 (file)
index 0000000..ac2cca1
--- /dev/null
@@ -0,0 +1,36 @@
+From 8eec545cde69e46e9a1d2b7d915ce4f5df85b3bd Mon Sep 17 00:00:00 2001
+From: Wentao Liang <vulab@iscas.ac.cn>
+Date: Tue, 7 Apr 2026 07:30:25 +0000
+Subject: power: reset: linkstation-poweroff: fix use-after-free in the linkstation_poweroff_init()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+commit 8eec545cde69e46e9a1d2b7d915ce4f5df85b3bd upstream.
+
+Move of_node_put(dn) after the of_match_node() call, which still needs
+the node pointer. The node reference is correctly released after use.
+
+Fixes: e2f471efe1d6 ("power: reset: linkstation-poweroff: prepare for new devices")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Link: https://patch.msgid.link/20260407073025.271865-1-vulab@iscas.ac.cn
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/power/reset/linkstation-poweroff.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/power/reset/linkstation-poweroff.c
++++ b/drivers/power/reset/linkstation-poweroff.c
+@@ -163,10 +163,10 @@ static int __init linkstation_poweroff_i
+       dn = of_find_matching_node(NULL, ls_poweroff_of_match);
+       if (!dn)
+               return -ENODEV;
+-      of_node_put(dn);
+       match = of_match_node(ls_poweroff_of_match, dn);
+       cfg = match->data;
++      of_node_put(dn);
+       dn = of_find_node_by_name(NULL, cfg->mdio_node_name);
+       if (!dn)
diff --git a/queue-7.1/pwrseq-core-fix-use-after-free-in-pwrseq_debugfs_seq_next.patch b/queue-7.1/pwrseq-core-fix-use-after-free-in-pwrseq_debugfs_seq_next.patch
new file mode 100644 (file)
index 0000000..41d19c0
--- /dev/null
@@ -0,0 +1,85 @@
+From 257595adf9dac15ae1edd9d07753fbc576a7583d Mon Sep 17 00:00:00 2001
+From: Wentao Liang <vulab@iscas.ac.cn>
+Date: Tue, 16 Jun 2026 15:10:49 +0000
+Subject: pwrseq: core: fix use-after-free in pwrseq_debugfs_seq_next()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+commit 257595adf9dac15ae1edd9d07753fbc576a7583d upstream.
+
+pwrseq_debugfs_seq_next() declares 'next' with __free(put_device),
+which causes put_device() to be called on the returned pointer when
+the variable goes out of scope.  This results in a use-after-free
+since the seq_file framework receives a pointer whose reference has
+already been dropped.
+
+Simply removing __free(put_device) would fix the UAF but would leak
+the reference acquired by bus_find_next_device(), as stop() only
+calls up_read(&pwrseq_sem) and never releases the device reference.
+
+Fix this by making the reference counting consistent across all
+seq_file callbacks, matching the standard pattern used by PCI and
+SCSI:
+
+- start(): use get_device() so it returns a referenced pointer.
+- next(): explicitly put_device(curr) to release the previous
+  device's reference (no NULL check needed - the seq_file framework
+  only calls next() while the previous return was non-NULL).
+- stop(): put_device(data) to release the last iterated device's
+  reference, with a NULL guard since stop() may be called with NULL
+  when start() returned NULL or next() reached end-of-sequence.
+
+Cc: stable@vger.kernel.org
+Fixes: 249ebf3f65f8 ("power: sequencing: implement the pwrseq core")
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Link: https://patch.msgid.link/20260616151049.1705503-1-vulab@iscas.ac.cn
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/power/sequencing/core.c |   14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/power/sequencing/core.c
++++ b/drivers/power/sequencing/core.c
+@@ -989,8 +989,9 @@ static void *pwrseq_debugfs_seq_start(st
+       ctx.index = *pos;
+       /*
+-       * We're holding the lock for the entire printout so no need to fiddle
+-       * with device reference count.
++       * Hold the lock for the entire printout to prevent device removal.
++       * Reference counts are managed by start()/next()/stop() as required
++       * by the seq_file contract.
+        */
+       down_read(&pwrseq_sem);
+@@ -998,7 +999,7 @@ static void *pwrseq_debugfs_seq_start(st
+       if (!ctx.index)
+               return NULL;
+-      return ctx.dev;
++      return get_device(ctx.dev);
+ }
+ static void *pwrseq_debugfs_seq_next(struct seq_file *seq, void *data,
+@@ -1008,8 +1009,9 @@ static void *pwrseq_debugfs_seq_next(str
+       ++*pos;
+-      struct device *next __free(put_device) =
+-                      bus_find_next_device(&pwrseq_bus, curr);
++      struct device *next = bus_find_next_device(&pwrseq_bus, curr);
++
++      put_device(curr);
+       return next;
+ }
+@@ -1058,6 +1060,8 @@ static int pwrseq_debugfs_seq_show(struc
+ static void pwrseq_debugfs_seq_stop(struct seq_file *seq, void *data)
+ {
++      if (data)
++              put_device(data);
+       up_read(&pwrseq_sem);
+ }
diff --git a/queue-7.1/riscv-kfence-call-mark_new_valid_map-for-kfence_unprotect.patch b/queue-7.1/riscv-kfence-call-mark_new_valid_map-for-kfence_unprotect.patch
new file mode 100644 (file)
index 0000000..5c7c9d4
--- /dev/null
@@ -0,0 +1,77 @@
+From 8d6c8c40e733b3fcaf92fed0a078bba2f6941a3b Mon Sep 17 00:00:00 2001
+From: Vivian Wang <wangruikang@iscas.ac.cn>
+Date: Tue, 3 Mar 2026 13:29:46 +0800
+Subject: riscv: kfence: Call mark_new_valid_map() for kfence_unprotect()
+
+From: Vivian Wang <wangruikang@iscas.ac.cn>
+
+commit 8d6c8c40e733b3fcaf92fed0a078bba2f6941a3b upstream.
+
+In kfence_protect_page(), which kfence_unprotect() calls, we cannot send
+IPIs to other CPUs to ask them to flush TLB. This may lead to those CPUs
+spuriously faulting on a recently allocated kfence object despite it
+being valid, leading to false positive use-after-free reports.
+
+Fix this by calling mark_new_valid_map() so that the page fault handling
+code path notices the spurious fault and flushes TLB then retries the
+access.
+
+Update the comment in handle_exception to indicate that
+new_valid_map_cpus_check also handles kfence_unprotect() spurious
+faults.
+
+Note that kfence_protect() has the same stale TLB entries problem, but
+that leads to false negatives, which is fine with kfence.
+
+Cc: stable@vger.kernel.org
+Reported-by: Yanko Kaneti <yaneti@declera.com>
+Fixes: b3431a8bb336 ("riscv: Fix IPIs usage in kfence_protect_page()")
+Signed-off-by: Vivian Wang <wangruikang@iscas.ac.cn>
+Link: https://patch.msgid.link/20260303-handle-kfence-protect-spurious-fault-v2-2-f80d8354d79d@iscas.ac.cn
+Signed-off-by: Paul Walmsley <pjw@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/riscv/include/asm/kfence.h |    7 +++++--
+ arch/riscv/kernel/entry.S       |    6 ++++--
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+--- a/arch/riscv/include/asm/kfence.h
++++ b/arch/riscv/include/asm/kfence.h
+@@ -6,6 +6,7 @@
+ #include <linux/kfence.h>
+ #include <linux/pfn.h>
+ #include <asm-generic/pgalloc.h>
++#include <asm/cacheflush.h>
+ #include <asm/pgtable.h>
+ static inline bool arch_kfence_init_pool(void)
+@@ -17,10 +18,12 @@ static inline bool kfence_protect_page(u
+ {
+       pte_t *pte = virt_to_kpte(addr);
+-      if (protect)
++      if (protect) {
+               set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~_PAGE_PRESENT));
+-      else
++      } else {
+               set_pte(pte, __pte(pte_val(ptep_get(pte)) | _PAGE_PRESENT));
++              mark_new_valid_map();
++      }
+       preempt_disable();
+       local_flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+--- a/arch/riscv/kernel/entry.S
++++ b/arch/riscv/kernel/entry.S
+@@ -136,8 +136,10 @@ SYM_CODE_START(handle_exception)
+ #ifdef CONFIG_64BIT
+       /*
+-       * The RISC-V kernel does not eagerly emit a sfence.vma after each
+-       * new vmalloc mapping, which may result in exceptions:
++       * The RISC-V kernel does not flush TLBs on all CPUS after each new
++       * vmalloc mapping or kfence_unprotect(), which may result in
++       * exceptions:
++       *
+        * - if the uarch caches invalid entries, the new mapping would not be
+        *   observed by the page table walker and an invalidation is needed.
+        * - if the uarch does not cache invalid entries, a reordered access
diff --git a/queue-7.1/rpmsg-char-fix-use-after-free-on-probe-error-path.patch b/queue-7.1/rpmsg-char-fix-use-after-free-on-probe-error-path.patch
new file mode 100644 (file)
index 0000000..ab83661
--- /dev/null
@@ -0,0 +1,81 @@
+From 1ff3f528e67d20e2b1483dcaba899dc7832b2e6b Mon Sep 17 00:00:00 2001
+From: Yuho Choi <dbgh9129@gmail.com>
+Date: Mon, 1 Jun 2026 14:32:47 -0400
+Subject: rpmsg: char: Fix use-after-free on probe error path
+
+From: Yuho Choi <dbgh9129@gmail.com>
+
+commit 1ff3f528e67d20e2b1483dcaba899dc7832b2e6b upstream.
+
+rpmsg_chrdev_probe() stores the newly allocated eptdev in the default
+endpoint's priv pointer before calling rpmsg_chrdev_eptdev_add(). If
+rpmsg_chrdev_eptdev_add() then fails, its error path frees eptdev while
+the default endpoint may still dispatch callbacks with the stale priv
+pointer.
+
+Avoid publishing eptdev through the default endpoint until
+rpmsg_chrdev_eptdev_add() succeeds. Messages received before the priv
+pointer is published should be ignored by rpmsg_ept_cb(). Flow-control
+updates can hit rpmsg_ept_flow_cb() in the same window, so make both
+callbacks return success when priv is NULL.
+
+Fixes: bc69d1066569 ("rpmsg: char: Introduce the "rpmsg-raw" channel")
+Signed-off-by: Yuho Choi <dbgh9129@gmail.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20260601183247.1962010-1-dbgh9129@gmail.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/rpmsg/rpmsg_char.c |   15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+--- a/drivers/rpmsg/rpmsg_char.c
++++ b/drivers/rpmsg/rpmsg_char.c
+@@ -104,6 +104,9 @@ static int rpmsg_ept_cb(struct rpmsg_dev
+       struct rpmsg_eptdev *eptdev = priv;
+       struct sk_buff *skb;
++      if (!eptdev)
++              return 0;
++
+       skb = alloc_skb(len, GFP_ATOMIC);
+       if (!skb)
+               return -ENOMEM;
+@@ -124,6 +127,9 @@ static int rpmsg_ept_flow_cb(struct rpms
+ {
+       struct rpmsg_eptdev *eptdev = priv;
++      if (!eptdev)
++              return 0;
++
+       eptdev->remote_flow_restricted = enable;
+       eptdev->remote_flow_updated = true;
+@@ -490,6 +496,7 @@ static int rpmsg_chrdev_probe(struct rpm
+       struct rpmsg_channel_info chinfo;
+       struct rpmsg_eptdev *eptdev;
+       struct device *dev = &rpdev->dev;
++      int ret;
+       memcpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE);
+       chinfo.src = rpdev->src;
+@@ -502,13 +509,17 @@ static int rpmsg_chrdev_probe(struct rpm
+       /* Set the default_ept to the rpmsg device endpoint */
+       eptdev->default_ept = rpdev->ept;
++      ret = rpmsg_chrdev_eptdev_add(eptdev, chinfo);
++
++      if (ret)
++              return ret;
+       /*
+        * The rpmsg_ept_cb uses *priv parameter to get its rpmsg_eptdev context.
+-       * Storedit in default_ept *priv field.
++       * Stored it in default_ept *priv field.
+        */
+       eptdev->default_ept->priv = eptdev;
+-      return rpmsg_chrdev_eptdev_add(eptdev, chinfo);
++      return 0;
+ }
+ static void rpmsg_chrdev_remove(struct rpmsg_device *rpdev)
diff --git a/queue-7.1/sched-mmcid-fix-oob-clear_bit-when-cid-is-mm_cid_unset-in-fixup-path.patch b/queue-7.1/sched-mmcid-fix-oob-clear_bit-when-cid-is-mm_cid_unset-in-fixup-path.patch
new file mode 100644 (file)
index 0000000..93a3e59
--- /dev/null
@@ -0,0 +1,88 @@
+From de3ab9bd3133899efb92e4cd05ba4203e58fc0a3 Mon Sep 17 00:00:00 2001
+From: Rik van Riel <riel@surriel.com>
+Date: Tue, 16 Jun 2026 16:38:17 -0400
+Subject: sched/mmcid: Fix OOB clear_bit when CID is MM_CID_UNSET in fixup path
+
+From: Rik van Riel <riel@surriel.com>
+
+commit de3ab9bd3133899efb92e4cd05ba4203e58fc0a3 upstream.
+
+In mm_cid_fixup_cpus_to_tasks(), when rq->curr has the target mm and
+mm_cid.active is set, the CID is checked with cid_in_transit() before
+setting the transition bit.  In per-CPU mode a newly forked or exec'd
+task can be running with mm_cid.cid == MM_CID_UNSET because CIDs are
+assigned lazily on schedule-in.  With cid_in_transit() the guard passes
+for MM_CID_UNSET (no transit bit), converts it to MM_CID_UNSET |
+MM_CID_TRANSIT and stores it back; later mm_cid_schedout() feeds this
+to clear_bit() with MM_CID_UNSET as the bit number, triggering an
+out-of-bounds write.
+
+Symptoms: this is genuine memory corruption, but a bounded out-of-bounds
+write, not an arbitrary one.  MM_CID_UNSET is the fixed sentinel BIT(31),
+so once the bad value reaches mm_cid_schedout() the cid_from_transit_cid()
+strip leaves MM_CID_UNSET, which fails the "cid < max_cids" convergence
+test and falls into mm_drop_cid() -> clear_bit(MM_CID_UNSET,
+mm_cidmask(mm)).  The cid bitmap is embedded in the mm_struct slab object
+(after cpu_bitmap and mm_cpus_allowed) and is only num_possible_cpus()
+bits wide, so clearing bit 31 is a deterministic OOB bit-clear at a
+fixed offset of 2^31 / 8 == 256 MiB past the bitmap base.  The address is
+not attacker-influenced (fixed sentinel -> fixed offset) and the op only
+clears a single bit; what sits 256 MiB further along the direct map is
+whatever kernel object happens to live there, so this corrupts one bit of
+unpredictable kernel memory -- it is not an arbitrary-address or
+arbitrary-value write.
+
+It triggers only in per-CPU CID mode, when a CPU is running an active
+task of the target mm whose cid is still MM_CID_UNSET -- the
+fork()/execve() window before that task's next schedule-in assigns it a
+real CID -- and a per-CPU -> per-task fixup walks over it (the mode
+fallback driven by a thread exit, sched_mm_cid_exit(), or by the deferred
+max_cids recompute in mm_cid_work_fn()).
+
+In practice syzkaller surfaced it as a KASAN use-after-free reported in
+__schedule -> mm_cid_switch_to, where the offending clear_bit() is inlined
+via mm_cid_schedout() -> mm_drop_cid().
+
+Guard the transition-bit assignment against MM_CID_UNSET, in addition to
+the existing cid_in_transit() check, so the bit is only set on a genuine
+task-owned CID.  A CPU-owned (MM_CID_ONCPU) CID of a running active task
+is handled by the cid_on_cpu(pcp->cid) branch above and never reaches
+this path, so excluding MM_CID_UNSET (and the already-transitioning case)
+is sufficient.
+
+Fixes: fbd0e71dc370 ("sched/mmcid: Provide CID ownership mode fixup functions")
+Signed-off-by: Rik van Riel <riel@surriel.com>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Assisted-by: Claude:claude-opus-4-8 syzkaller
+Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260616203818.1516263-1-riel@surriel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/sched/core.c |   15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -10880,8 +10880,19 @@ static void mm_cid_fixup_cpus_to_tasks(s
+               } else if (rq->curr->mm == mm && rq->curr->mm_cid.active) {
+                       unsigned int cid = rq->curr->mm_cid.cid;
+-                      /* Ensure it has the transition bit set */
+-                      if (!cid_in_transit(cid)) {
++                      /*
++                       * Set the transition bit only on a genuine task-owned
++                       * CID. A running active task can legitimately have
++                       * MM_CID_UNSET here: in per-CPU mode CIDs are assigned
++                       * lazily on schedule-in, so the fork()/execve() window
++                       * leaves the task active with no owned CID. Setting the
++                       * transition bit on MM_CID_UNSET would later feed
++                       * clear_bit() an out-of-bounds bit number via
++                       * mm_cid_schedout(), so exclude it. A CPU-owned
++                       * (MM_CID_ONCPU) CID is handled by the cid_on_cpu()
++                       * branch above and never reaches here.
++                       */
++                      if (cid != MM_CID_UNSET && !cid_in_transit(cid)) {
+                               cid = cid_to_transit_cid(cid);
+                               rq->curr->mm_cid.cid = cid;
+                               pcp->cid = cid;
index 5b7049de9592192bdd0526cc1eade8e6b5d46bb0..ec4214421e9dbb18884f722738cae9913e81963f 100644 (file)
@@ -77,3 +77,42 @@ exfat-fix-potential-use-after-free-in-exfat_find_dir_entry.patch
 kvm-x86-mmu-ensure-hugepage-is-in-by-slot-before-checking-max-mapping-level.patch
 kvm-replace-guest-triggerable-bug_on-in-ioeventfd-datamatch-with-get_unaligned.patch
 crypto-nx-fix-nx_crypto_ctx_exit-argument.patch
+gfs2-fix-use-after-free-in-gfs2_qd_dealloc.patch
+pwrseq-core-fix-use-after-free-in-pwrseq_debugfs_seq_next.patch
+hdlc_ppp-sync-per-proto-timers-before-freeing-hdlc-state.patch
+blk-cgroup-fix-uaf-in-__blkcg_rstat_flush.patch
+tipc-fix-slab-use-after-free-read-in-tipc_aead_decrypt_done.patch
+loongarch-report-dying-cpu-to-rcu-in-stop_this_cpu.patch
+pnfs-fix-use-after-free-in-pnfs_update_layout.patch
+sched-mmcid-fix-oob-clear_bit-when-cid-is-mm_cid_unset-in-fixup-path.patch
+irqchip-imgpdc-fix-resource-leak-add-missing-chained-handler-cleanup-on-remove.patch
+fpga-region-fix-use-after-free-in-child_regions_with_firmware.patch
+rpmsg-char-fix-use-after-free-on-probe-error-path.patch
+ocfs2-reject-oversized-group-bitmap-descriptors.patch
+9p-avoid-putting-oldfid-in-p9_client_walk-error-path.patch
+mips-smp-report-dying-cpu-to-rcu-in-stop_this_cpu.patch
+kvm-x86-hyper-v-bound-the-bank-index-when-querying-sparse-banks.patch
+kvm-svm-fix-page-overflow-in-sev_dbg_crypt-for-encrypt-path.patch
+power-reset-linkstation-poweroff-fix-use-after-free-in-the-linkstation_poweroff_init.patch
+riscv-kfence-call-mark_new_valid_map-for-kfence_unprotect.patch
+ntfs-serialize-volume-label-accesses.patch
+fbdev-fix-fb_new_modelist-to-prevent-null-ptr-deref-in-fb_videomode_to_var.patch
+fbdev-fbcon-fix-out-of-bounds-read-in-err_out-of-fbcon_do_set_font.patch
+fbdev-omap2-fix-use-after-free-in-omapfb_mmap.patch
+fbdev-modedb-fix-a-possible-uaf-in-fb_find_mode.patch
+fbdev-modedb-fix-misaligned-fields-in-the-1920x1080-60-mode.patch
+i2c-core-fix-adapter-registration-race.patch
+nfsd-release-layout-stid-on-setlease-failure.patch
+nfsd-fix-secinfo_no_name-decode-error-cleanup.patch
+nfsd-fix-posix_acl-leak-on-setacl-decode-failure.patch
+nfsd-fix-inverted-cp_ttl-check-in-async-copy-reaper.patch
+nfsd-fix-posix_acl-leak-and-ignored-error-in-nfsd4_create_file.patch
+nfsd-check-get_user-return-when-reading-princhashlen.patch
+nfsd-fix-dead-acl-conflict-guard-in-nfsd4_create.patch
+nfsd-avoid-leaking-pre-allocated-openowner-on-unconfirmed-retry-race.patch
+nfsd-reset-write-verifier-on-deferred-writeback-errors.patch
+nfsv4-flexfiles-reject-zero-filehandle-version-count.patch
+nfsv4-pnfs-reject-zero-length-r_addr-in-nfs4_decode_mp_ds_addr.patch
+nfsv4-clear-exception-state-on-successful-mkdir-retry.patch
+nfs-prevent-resource-leak-in-nfs_alloc_server.patch
+ksmbd-fix-out-of-bounds-read-in-smb_check_perm_dacl.patch
diff --git a/queue-7.1/tipc-fix-slab-use-after-free-read-in-tipc_aead_decrypt_done.patch b/queue-7.1/tipc-fix-slab-use-after-free-read-in-tipc_aead_decrypt_done.patch
new file mode 100644 (file)
index 0000000..5ac16db
--- /dev/null
@@ -0,0 +1,124 @@
+From bda3348872a2ef0d19f2df6aa8cb5025adce2f20 Mon Sep 17 00:00:00 2001
+From: Doruk Tan Ozturk <doruk@0sec.ai>
+Date: Wed, 17 Jun 2026 09:58:18 +0200
+Subject: tipc: fix slab-use-after-free Read in tipc_aead_decrypt_done
+
+From: Doruk Tan Ozturk <doruk@0sec.ai>
+
+commit bda3348872a2ef0d19f2df6aa8cb5025adce2f20 upstream.
+
+tipc_aead_decrypt() goes straight from tipc_bearer_hold(b) to
+crypto_aead_decrypt(req) without taking a reference on the netns, unlike
+the encrypt path. When crypto_aead_decrypt() is offloaded asynchronously
+(e.g. the SIMD aead wrapper queuing to cryptd), the cryptd worker runs
+tipc_aead_decrypt_done() later. If the bearer's netns is torn down in the
+meantime, cleanup_net() -> tipc_exit_net() -> tipc_crypto_stop() frees the
+per-netns tipc_crypto, and the completion then reads it:
+tipc_aead_decrypt_done() dereferences aead->crypto->stats and
+aead->crypto->net, and tipc_crypto_rcv_complete() dereferences
+aead->crypto->aead[] and the node table -- reading freed memory.
+
+Decoded KASAN splat (v7.1-rc7, CONFIG_KASAN_INLINE + TIPC + TIPC_CRYPTO):
+
+  BUG: KASAN: slab-use-after-free in tipc_aead_decrypt_done (net/tipc/crypto.c:999)
+  Read of size 8 at addr ffff8881056258a8 by task kworker/u16:2/51
+  Workqueue: events_unbound
+  Call Trace:
+   tipc_aead_decrypt_done (net/tipc/crypto.c:999)
+   process_one_work (kernel/workqueue.c:3314)
+   worker_thread (kernel/workqueue.c:3397 kernel/workqueue.c:3478)
+   kthread (kernel/kthread.c:436)
+   ret_from_fork (arch/x86/kernel/process.c:158)
+   ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
+
+  Allocated by task 169:
+   __kasan_kmalloc (mm/kasan/common.c:398 mm/kasan/common.c:415)
+   tipc_crypto_start (net/tipc/crypto.c:1502)
+   tipc_init_net (net/tipc/core.c:72)
+   ops_init (net/core/net_namespace.c:137)
+   setup_net (net/core/net_namespace.c:446)
+   copy_net_ns (net/core/net_namespace.c:579)
+   create_new_namespaces (kernel/nsproxy.c:132)
+   __x64_sys_unshare (kernel/fork.c:3316)
+   do_syscall_64 (arch/x86/entry/syscall_64.c:63)
+   entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
+
+  Freed by task 8:
+   kfree (mm/slub.c:6566)
+   tipc_exit_net (net/tipc/core.c:119)
+   cleanup_net (net/core/net_namespace.c:704)
+   process_one_work (kernel/workqueue.c:3314)
+   kthread (kernel/kthread.c:436)
+
+This is the same class of bug that commit e279024617134 ("net/tipc: fix
+slab-use-after-free Read in tipc_aead_encrypt_done") fixed for the encrypt
+side. The encrypt path takes maybe_get_net(aead->crypto->net) before
+crypto_aead_encrypt() and drops it with put_net() on the synchronous
+return paths and in tipc_aead_encrypt_done(); the -EINPROGRESS/-EBUSY
+return keeps the reference for the async callback to release. The decrypt
+path was left without the equivalent guard.
+
+Mirror the encrypt-side fix on the decrypt path: take a net reference
+before crypto_aead_decrypt() (failing with -ENODEV and the matching
+bearer put if it cannot be acquired), keep it across the
+-EINPROGRESS/-EBUSY async return, and drop it with put_net() on the
+synchronous success/error return and at the end of
+tipc_aead_decrypt_done().
+
+Reproduced under KASAN on v7.1-rc7: a UDP bearer with a cluster key is
+flooded with crafted encrypted frames from an unknown peer (driving the
+cluster-key decrypt path) while the bearer's netns is repeatedly torn
+down. The completion must run asynchronously to outlive
+tipc_crypto_stop(); on x86 the stock aesni gcm(aes) now decrypts
+synchronously, so the async path was exercised via cryptd offload. The
+unguarded aead->crypto dereference in tipc_aead_decrypt_done() is the
+unpatched upstream path; tipc_aead_decrypt() still lacks
+maybe_get_net(aead->crypto->net), so the completion can outlive the free
+on any config where crypto_aead_decrypt() goes async.
+
+Found by 0sec automated security-research tooling (https://0sec.ai).
+
+Fixes: fc1b6d6de220 ("tipc: introduce TIPC encryption & authentication")
+Cc: stable@vger.kernel.org
+Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
+Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>
+Reviewed-by: Tung Nguyen <tung.quang.nguyen@est.tech>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260617075818.37431-1-doruk@0sec.ai
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/tipc/crypto.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/net/tipc/crypto.c
++++ b/net/tipc/crypto.c
+@@ -941,12 +941,20 @@ static int tipc_aead_decrypt(struct net
+               goto exit;
+       }
++      /* Get net to avoid freed tipc_crypto when delete namespace */
++      if (!maybe_get_net(net)) {
++              tipc_bearer_put(b);
++              rc = -ENODEV;
++              goto exit;
++      }
++
+       /* Now, do decrypt */
+       rc = crypto_aead_decrypt(req);
+       if (rc == -EINPROGRESS || rc == -EBUSY)
+               return rc;
+       tipc_bearer_put(b);
++      put_net(net);
+ exit:
+       kfree(ctx);
+@@ -984,6 +992,7 @@ static void tipc_aead_decrypt_done(void
+       }
+       tipc_bearer_put(b);
++      put_net(net);
+ }
+ static inline int tipc_ehdr_size(struct tipc_ehdr *ehdr)