--- /dev/null
+From 009727e6d42137a33cde7f38c811281fb576b80f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Mar 2024 10:03:12 -0400
+Subject: ima: Fix use-after-free on a dentry's dname.name
+
+From: Stefan Berger <stefanb@linux.ibm.com>
+
+[ Upstream commit be84f32bb2c981ca670922e047cdde1488b233de ]
+
+->d_name.name can change on rename and the earlier value can be freed;
+there are conditions sufficient to stabilize it (->d_lock on dentry,
+->d_lock on its parent, ->i_rwsem exclusive on the parent's inode,
+rename_lock), but none of those are met at any of the sites. Take a stable
+snapshot of the name instead.
+
+Link: https://lore.kernel.org/all/20240202182732.GE2087318@ZenIV/
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/ima_api.c | 16 ++++++++++++----
+ security/integrity/ima/ima_template_lib.c | 17 ++++++++++++++---
+ 2 files changed, 26 insertions(+), 7 deletions(-)
+
+diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
+index 7a244e8ce65a5..cea8df0115a28 100644
+--- a/security/integrity/ima/ima_api.c
++++ b/security/integrity/ima/ima_api.c
+@@ -243,8 +243,8 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
+ const char *audit_cause = "failed";
+ struct inode *inode = file_inode(file);
+ struct inode *real_inode = d_real_inode(file_dentry(file));
+- const char *filename = file->f_path.dentry->d_name.name;
+ struct ima_max_digest_data hash;
++ struct name_snapshot filename;
+ struct kstat stat;
+ int result = 0;
+ int length;
+@@ -322,9 +322,13 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
+ if (file->f_flags & O_DIRECT)
+ audit_cause = "failed(directio)";
+
++ take_dentry_name_snapshot(&filename, file->f_path.dentry);
++
+ integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
+- filename, "collect_data", audit_cause,
+- result, 0);
++ filename.name.name, "collect_data",
++ audit_cause, result, 0);
++
++ release_dentry_name_snapshot(&filename);
+ }
+ return result;
+ }
+@@ -437,6 +441,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
+ */
+ const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf)
+ {
++ struct name_snapshot filename;
+ char *pathname = NULL;
+
+ *pathbuf = __getname();
+@@ -450,7 +455,10 @@ const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf)
+ }
+
+ if (!pathname) {
+- strscpy(namebuf, path->dentry->d_name.name, NAME_MAX);
++ take_dentry_name_snapshot(&filename, path->dentry);
++ strscpy(namebuf, filename.name.name, NAME_MAX);
++ release_dentry_name_snapshot(&filename);
++
+ pathname = namebuf;
+ }
+
+diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
+index 7bf9b15072202..41ec31debe870 100644
+--- a/security/integrity/ima/ima_template_lib.c
++++ b/security/integrity/ima/ima_template_lib.c
+@@ -483,7 +483,10 @@ static int ima_eventname_init_common(struct ima_event_data *event_data,
+ bool size_limit)
+ {
+ const char *cur_filename = NULL;
++ struct name_snapshot filename;
+ u32 cur_filename_len = 0;
++ bool snapshot = false;
++ int ret;
+
+ BUG_ON(event_data->filename == NULL && event_data->file == NULL);
+
+@@ -496,7 +499,10 @@ static int ima_eventname_init_common(struct ima_event_data *event_data,
+ }
+
+ if (event_data->file) {
+- cur_filename = event_data->file->f_path.dentry->d_name.name;
++ take_dentry_name_snapshot(&filename,
++ event_data->file->f_path.dentry);
++ snapshot = true;
++ cur_filename = filename.name.name;
+ cur_filename_len = strlen(cur_filename);
+ } else
+ /*
+@@ -505,8 +511,13 @@ static int ima_eventname_init_common(struct ima_event_data *event_data,
+ */
+ cur_filename_len = IMA_EVENT_NAME_LEN_MAX;
+ out:
+- return ima_write_template_field_data(cur_filename, cur_filename_len,
+- DATA_FMT_STRING, field_data);
++ ret = ima_write_template_field_data(cur_filename, cur_filename_len,
++ DATA_FMT_STRING, field_data);
++
++ if (snapshot)
++ release_dentry_name_snapshot(&filename);
++
++ return ret;
+ }
+
+ /*
+--
+2.43.0
+
--- /dev/null
+From 1ecfaeacb62b0e0c7cbe178410b6bd5dc2a394b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 12:55:51 -0400
+Subject: IMA: use vfs_getattr_nosec to get the i_version
+
+From: Jeff Layton <jlayton@kernel.org>
+
+[ Upstream commit db1d1e8b9867aae5c3e61ad7859abfcc4a6fd6c7 ]
+
+IMA currently accesses the i_version out of the inode directly when it
+does a measurement. This is fine for most simple filesystems, but can be
+problematic with more complex setups (e.g. overlayfs).
+
+Make IMA instead call vfs_getattr_nosec to get this info. This allows
+the filesystem to determine whether and how to report the i_version, and
+should allow IMA to work properly with a broader class of filesystems in
+the future.
+
+Reported-and-Tested-by: Stefan Berger <stefanb@linux.ibm.com>
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Stable-dep-of: be84f32bb2c9 ("ima: Fix use-after-free on a dentry's dname.name")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/ima_api.c | 9 ++++++---
+ security/integrity/ima/ima_main.c | 12 ++++++++----
+ 2 files changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
+index 026c8c9db9920..7a244e8ce65a5 100644
+--- a/security/integrity/ima/ima_api.c
++++ b/security/integrity/ima/ima_api.c
+@@ -13,7 +13,6 @@
+ #include <linux/fs.h>
+ #include <linux/xattr.h>
+ #include <linux/evm.h>
+-#include <linux/iversion.h>
+ #include <linux/fsverity.h>
+
+ #include "ima.h"
+@@ -246,10 +245,11 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
+ struct inode *real_inode = d_real_inode(file_dentry(file));
+ const char *filename = file->f_path.dentry->d_name.name;
+ struct ima_max_digest_data hash;
++ struct kstat stat;
+ int result = 0;
+ int length;
+ void *tmpbuf;
+- u64 i_version;
++ u64 i_version = 0;
+
+ /*
+ * Always collect the modsig, because IMA might have already collected
+@@ -268,7 +268,10 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
+ * to an initial measurement/appraisal/audit, but was modified to
+ * assume the file changed.
+ */
+- i_version = inode_query_iversion(inode);
++ result = vfs_getattr_nosec(&file->f_path, &stat, STATX_CHANGE_COOKIE,
++ AT_STATX_SYNC_AS_STAT);
++ if (!result && (stat.result_mask & STATX_CHANGE_COOKIE))
++ i_version = stat.change_cookie;
+ hash.hdr.algo = algo;
+ hash.hdr.length = hash_digest_size[algo];
+
+diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
+index 185666d90eebc..bba421f617312 100644
+--- a/security/integrity/ima/ima_main.c
++++ b/security/integrity/ima/ima_main.c
+@@ -24,7 +24,6 @@
+ #include <linux/slab.h>
+ #include <linux/xattr.h>
+ #include <linux/ima.h>
+-#include <linux/iversion.h>
+ #include <linux/fs.h>
+ #include <linux/iversion.h>
+
+@@ -164,11 +163,16 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,
+
+ mutex_lock(&iint->mutex);
+ if (atomic_read(&inode->i_writecount) == 1) {
++ struct kstat stat;
++
+ update = test_and_clear_bit(IMA_UPDATE_XATTR,
+ &iint->atomic_flags);
+- if (!IS_I_VERSION(inode) ||
+- !inode_eq_iversion(inode, iint->version) ||
+- (iint->flags & IMA_NEW_FILE)) {
++ if ((iint->flags & IMA_NEW_FILE) ||
++ vfs_getattr_nosec(&file->f_path, &stat,
++ STATX_CHANGE_COOKIE,
++ AT_STATX_SYNC_AS_STAT) ||
++ !(stat.result_mask & STATX_CHANGE_COOKIE) ||
++ stat.change_cookie != iint->version) {
+ iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE);
+ iint->measured_pcrs = 0;
+ if (update)
+--
+2.43.0
+
--- /dev/null
+From dddb1721bbdc9c1c3a77aa91200ff51db17ed729 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jun 2024 13:40:45 +0200
+Subject: parisc: use generic sys_fanotify_mark implementation
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 403f17a330732a666ae793f3b15bc75bb5540524 ]
+
+The sys_fanotify_mark() syscall on parisc uses the reverse word order
+for the two halves of the 64-bit argument compared to all syscalls on
+all 32-bit architectures. As far as I can tell, the problem is that
+the function arguments on parisc are sorted backwards (26, 25, 24, 23,
+...) compared to everyone else, so the calling conventions of using an
+even/odd register pair in native word order result in the lower word
+coming first in function arguments, matching the expected behavior
+on little-endian architectures. The system call conventions however
+ended up matching what the other 32-bit architectures do.
+
+A glibc cleanup in 2020 changed the userspace behavior in a way that
+handles all architectures consistently, but this inadvertently broke
+parisc32 by changing to the same method as everyone else.
+
+The change made it into glibc-2.35 and subsequently into debian 12
+(bookworm), which is the latest stable release. This means we
+need to choose between reverting the glibc change or changing the
+kernel to match it again, but either hange will leave some systems
+broken.
+
+Pick the option that is more likely to help current and future
+users and change the kernel to match current glibc. This also
+means the behavior is now consistent across architectures, but
+it breaks running new kernels with old glibc builds before 2.35.
+
+Link: https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d150181d73d9
+Link: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/arch/parisc/kernel/sys_parisc.c?h=57b1dfbd5b4a39d
+Cc: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Tested-by: Helge Deller <deller@gmx.de>
+Acked-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+I found this through code inspection, please double-check to make
+sure I got the bug and the fix right.
+
+The alternative is to fix this by reverting glibc back to the
+unusual behavior.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/Kconfig | 1 +
+ arch/parisc/kernel/sys_parisc32.c | 9 ---------
+ arch/parisc/kernel/syscalls/syscall.tbl | 2 +-
+ 3 files changed, 2 insertions(+), 10 deletions(-)
+
+diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
+index abf39ecda6fb1..5762633ea95e4 100644
+--- a/arch/parisc/Kconfig
++++ b/arch/parisc/Kconfig
+@@ -14,6 +14,7 @@ config PARISC
+ select ARCH_HAS_UBSAN_SANITIZE_ALL
+ select ARCH_HAS_PTE_SPECIAL
+ select ARCH_NO_SG_CHAIN
++ select ARCH_SPLIT_ARG64 if !64BIT
+ select ARCH_SUPPORTS_HUGETLBFS if PA20
+ select ARCH_SUPPORTS_MEMORY_FAILURE
+ select ARCH_STACKWALK
+diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
+index 2a12a547b447b..826c8e51b5853 100644
+--- a/arch/parisc/kernel/sys_parisc32.c
++++ b/arch/parisc/kernel/sys_parisc32.c
+@@ -23,12 +23,3 @@ asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23,
+ current->comm, current->pid, r20);
+ return -ENOSYS;
+ }
+-
+-asmlinkage long sys32_fanotify_mark(compat_int_t fanotify_fd, compat_uint_t flags,
+- compat_uint_t mask0, compat_uint_t mask1, compat_int_t dfd,
+- const char __user * pathname)
+-{
+- return sys_fanotify_mark(fanotify_fd, flags,
+- ((__u64)mask1 << 32) | mask0,
+- dfd, pathname);
+-}
+diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
+index ba4884eaa5057..42702f5d49f28 100644
+--- a/arch/parisc/kernel/syscalls/syscall.tbl
++++ b/arch/parisc/kernel/syscalls/syscall.tbl
+@@ -364,7 +364,7 @@
+ 320 common accept4 sys_accept4
+ 321 common prlimit64 sys_prlimit64
+ 322 common fanotify_init sys_fanotify_init
+-323 common fanotify_mark sys_fanotify_mark sys32_fanotify_mark
++323 common fanotify_mark sys_fanotify_mark compat_sys_fanotify_mark
+ 324 32 clock_adjtime sys_clock_adjtime32
+ 324 64 clock_adjtime sys_clock_adjtime
+ 325 common name_to_handle_at sys_name_to_handle_at
+--
+2.43.0
+
riscv-stacktrace-convert-arch_stack_walk-to-noinstr.patch
gpiolib-cdev-disallow-reconfiguration-without-direct.patch
randomize_kstack-remove-non-functional-per-arch-entr.patch
+vfs-plumb-i_version-handling-into-struct-kstat.patch
+ima-use-vfs_getattr_nosec-to-get-the-i_version.patch
+ima-fix-use-after-free-on-a-dentry-s-dname.name.patch
+x86-stop-playing-stack-games-in-profile_pc.patch
+parisc-use-generic-sys_fanotify_mark-implementation.patch
--- /dev/null
+From 72aa39d07c4636965c9a8c7e965476f103d8a398 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Dec 2016 09:29:46 -0500
+Subject: vfs: plumb i_version handling into struct kstat
+
+From: Jeff Layton <jlayton@redhat.com>
+
+[ Upstream commit a1175d6b1bdaf4f74eda47ab18eb44194f9cb796 ]
+
+The NFS server has a lot of special handling for different types of
+change attribute access, depending on the underlying filesystem. In
+most cases, it's doing a getattr anyway and then fetching that value
+after the fact.
+
+Rather that do that, add a new STATX_CHANGE_COOKIE flag that is a
+kernel-only symbol (for now). If requested and getattr can implement it,
+it can fill out this field. For IS_I_VERSION inodes, add a generic
+implementation in vfs_getattr_nosec. Take care to mask
+STATX_CHANGE_COOKIE off in requests from userland and in the result
+mask.
+
+Since not all filesystems can give the same guarantees of monotonicity,
+claim a STATX_ATTR_CHANGE_MONOTONIC flag that filesystems can set to
+indicate that they offer an i_version value that can never go backward.
+
+Eventually if we decide to make the i_version available to userland, we
+can just designate a field for it in struct statx, and move the
+STATX_CHANGE_COOKIE definition to the uapi header.
+
+Reviewed-by: NeilBrown <neilb@suse.de>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Stable-dep-of: be84f32bb2c9 ("ima: Fix use-after-free on a dentry's dname.name")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/stat.c | 17 +++++++++++++++--
+ include/linux/stat.h | 9 +++++++++
+ 2 files changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/fs/stat.c b/fs/stat.c
+index ef50573c72a26..06fd3fc1ab84b 100644
+--- a/fs/stat.c
++++ b/fs/stat.c
+@@ -18,6 +18,7 @@
+ #include <linux/syscalls.h>
+ #include <linux/pagemap.h>
+ #include <linux/compat.h>
++#include <linux/iversion.h>
+
+ #include <linux/uaccess.h>
+ #include <asm/unistd.h>
+@@ -119,6 +120,11 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
+ stat->attributes_mask |= (STATX_ATTR_AUTOMOUNT |
+ STATX_ATTR_DAX);
+
++ if ((request_mask & STATX_CHANGE_COOKIE) && IS_I_VERSION(inode)) {
++ stat->result_mask |= STATX_CHANGE_COOKIE;
++ stat->change_cookie = inode_query_iversion(inode);
++ }
++
+ mnt_userns = mnt_user_ns(path->mnt);
+ if (inode->i_op->getattr)
+ return inode->i_op->getattr(mnt_userns, path, stat,
+@@ -599,9 +605,11 @@ cp_statx(const struct kstat *stat, struct statx __user *buffer)
+
+ memset(&tmp, 0, sizeof(tmp));
+
+- tmp.stx_mask = stat->result_mask;
++ /* STATX_CHANGE_COOKIE is kernel-only for now */
++ tmp.stx_mask = stat->result_mask & ~STATX_CHANGE_COOKIE;
+ tmp.stx_blksize = stat->blksize;
+- tmp.stx_attributes = stat->attributes;
++ /* STATX_ATTR_CHANGE_MONOTONIC is kernel-only for now */
++ tmp.stx_attributes = stat->attributes & ~STATX_ATTR_CHANGE_MONOTONIC;
+ tmp.stx_nlink = stat->nlink;
+ tmp.stx_uid = from_kuid_munged(current_user_ns(), stat->uid);
+ tmp.stx_gid = from_kgid_munged(current_user_ns(), stat->gid);
+@@ -640,6 +648,11 @@ int do_statx(int dfd, struct filename *filename, unsigned int flags,
+ if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_SYNC_TYPE)
+ return -EINVAL;
+
++ /* STATX_CHANGE_COOKIE is kernel-only for now. Ignore requests
++ * from userland.
++ */
++ mask &= ~STATX_CHANGE_COOKIE;
++
+ error = vfs_statx(dfd, filename, flags, &stat, mask);
+ if (error)
+ return error;
+diff --git a/include/linux/stat.h b/include/linux/stat.h
+index ff277ced50e9f..52150570d37a5 100644
+--- a/include/linux/stat.h
++++ b/include/linux/stat.h
+@@ -52,6 +52,15 @@ struct kstat {
+ u64 mnt_id;
+ u32 dio_mem_align;
+ u32 dio_offset_align;
++ u64 change_cookie;
+ };
+
++/* These definitions are internal to the kernel for now. Mainly used by nfsd. */
++
++/* mask values */
++#define STATX_CHANGE_COOKIE 0x40000000U /* Want/got stx_change_attr */
++
++/* file attribute values */
++#define STATX_ATTR_CHANGE_MONOTONIC 0x8000000000000000ULL /* version monotonically increases */
++
+ #endif
+--
+2.43.0
+
--- /dev/null
+From fb6bdc56f4055594ee4da1fcf0ca9c0400fab475 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jun 2024 14:27:22 -0700
+Subject: x86: stop playing stack games in profile_pc()
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+[ Upstream commit 093d9603b60093a9aaae942db56107f6432a5dca ]
+
+The 'profile_pc()' function is used for timer-based profiling, which
+isn't really all that relevant any more to begin with, but it also ends
+up making assumptions based on the stack layout that aren't necessarily
+valid.
+
+Basically, the code tries to account the time spent in spinlocks to the
+caller rather than the spinlock, and while I support that as a concept,
+it's not worth the code complexity or the KASAN warnings when no serious
+profiling is done using timers anyway these days.
+
+And the code really does depend on stack layout that is only true in the
+simplest of cases. We've lost the comment at some point (I think when
+the 32-bit and 64-bit code was unified), but it used to say:
+
+ Assume the lock function has either no stack frame or a copy
+ of eflags from PUSHF.
+
+which explains why it just blindly loads a word or two straight off the
+stack pointer and then takes a minimal look at the values to just check
+if they might be eflags or the return pc:
+
+ Eflags always has bits 22 and up cleared unlike kernel addresses
+
+but that basic stack layout assumption assumes that there isn't any lock
+debugging etc going on that would complicate the code and cause a stack
+frame.
+
+It causes KASAN unhappiness reported for years by syzkaller [1] and
+others [2].
+
+With no real practical reason for this any more, just remove the code.
+
+Just for historical interest, here's some background commits relating to
+this code from 2006:
+
+ 0cb91a229364 ("i386: Account spinlocks to the caller during profiling for !FP kernels")
+ 31679f38d886 ("Simplify profile_pc on x86-64")
+
+and a code unification from 2009:
+
+ ef4512882dbe ("x86: time_32/64.c unify profile_pc")
+
+but the basics of this thing actually goes back to before the git tree.
+
+Link: https://syzkaller.appspot.com/bug?extid=84fe685c02cd112a2ac3 [1]
+Link: https://lore.kernel.org/all/CAK55_s7Xyq=nh97=K=G1sxueOFrJDAvPOJAL4TPTCAYvmxO9_A@mail.gmail.com/ [2]
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/time.c | 20 +-------------------
+ 1 file changed, 1 insertion(+), 19 deletions(-)
+
+diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c
+index e42faa792c079..52e1f3f0b361c 100644
+--- a/arch/x86/kernel/time.c
++++ b/arch/x86/kernel/time.c
+@@ -27,25 +27,7 @@
+
+ unsigned long profile_pc(struct pt_regs *regs)
+ {
+- unsigned long pc = instruction_pointer(regs);
+-
+- if (!user_mode(regs) && in_lock_functions(pc)) {
+-#ifdef CONFIG_FRAME_POINTER
+- return *(unsigned long *)(regs->bp + sizeof(long));
+-#else
+- unsigned long *sp = (unsigned long *)regs->sp;
+- /*
+- * Return address is either directly at stack pointer
+- * or above a saved flags. Eflags has bits 22-31 zero,
+- * kernel addresses don't.
+- */
+- if (sp[0] >> 22)
+- return sp[0];
+- if (sp[1] >> 22)
+- return sp[1];
+-#endif
+- }
+- return pc;
++ return instruction_pointer(regs);
+ }
+ EXPORT_SYMBOL(profile_pc);
+
+--
+2.43.0
+