]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.6
authorSasha Levin <sashal@kernel.org>
Mon, 1 Jul 2024 00:09:11 +0000 (20:09 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 1 Jul 2024 00:09:11 +0000 (20:09 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.6/parisc-use-generic-sys_fanotify_mark-implementation.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/x86-stop-playing-stack-games-in-profile_pc.patch [new file with mode: 0644]

diff --git a/queue-6.6/parisc-use-generic-sys_fanotify_mark-implementation.patch b/queue-6.6/parisc-use-generic-sys_fanotify_mark-implementation.patch
new file mode 100644 (file)
index 0000000..e6d9cf1
--- /dev/null
@@ -0,0 +1,99 @@
+From d83e8e06fde6d71c77417f4acc9d5d3397224e76 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 4adeb73d5885c..722e83edad282 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 47b3bb90080de..73f560e309573 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
+
index 098f6eb086acf883dfe183bed159d219ee066aad..f88b29776442016eeac6c56143bb15edb4161a9c 100644 (file)
@@ -76,3 +76,5 @@ drm-amdgpu-fix-pci-state-save-during-mode-1-reset.patch
 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
+x86-stop-playing-stack-games-in-profile_pc.patch
+parisc-use-generic-sys_fanotify_mark-implementation.patch
diff --git a/queue-6.6/x86-stop-playing-stack-games-in-profile_pc.patch b/queue-6.6/x86-stop-playing-stack-games-in-profile_pc.patch
new file mode 100644 (file)
index 0000000..4539b10
--- /dev/null
@@ -0,0 +1,95 @@
+From 01cfec9c56fa253c3dc3529ee0e9f71a1c6a1678 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
+