From: Sasha Levin Date: Mon, 1 Jul 2024 00:09:12 +0000 (-0400) Subject: Fixes for 5.15 X-Git-Tag: v4.19.317~115 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e2483df69602786ad1f2c76e95820ba0261a8bf3;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/parisc-use-generic-sys_fanotify_mark-implementation.patch b/queue-5.15/parisc-use-generic-sys_fanotify_mark-implementation.patch new file mode 100644 index 00000000000..ececf027814 --- /dev/null +++ b/queue-5.15/parisc-use-generic-sys_fanotify_mark-implementation.patch @@ -0,0 +1,99 @@ +From c5abcae9146e760a1a59006b2e85bbb36d403804 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Jun 2024 13:40:45 +0200 +Subject: parisc: use generic sys_fanotify_mark implementation + +From: Arnd Bergmann + +[ 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 +Tested-by: Helge Deller +Acked-by: Helge Deller +Signed-off-by: Arnd Bergmann +--- +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 +--- + 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 117b0f882750a..6ac0c4b98e281 100644 +--- a/arch/parisc/Kconfig ++++ b/arch/parisc/Kconfig +@@ -12,6 +12,7 @@ config PARISC + select ARCH_HAS_STRICT_MODULE_RWX + select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_NO_SG_CHAIN ++ select ARCH_SPLIT_ARG64 if !64BIT + select ARCH_SUPPORTS_HUGETLBFS if PA20 + select ARCH_SUPPORTS_MEMORY_FAILURE + select DMA_OPS +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 3e7ded09e00a5..5774509ea4a3b 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 + diff --git a/queue-5.15/series b/queue-5.15/series index aad6ca26c19..0ca783be9f5 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -332,3 +332,5 @@ nvme-fixup-comment-for-nvme-rdma-provider-type.patch drm-panel-simple-add-missing-display-timing-flags-fo.patch gpio-davinci-validate-the-obtained-number-of-irqs.patch gpiolib-cdev-disallow-reconfiguration-without-direct.patch +x86-stop-playing-stack-games-in-profile_pc.patch +parisc-use-generic-sys_fanotify_mark-implementation.patch diff --git a/queue-5.15/x86-stop-playing-stack-games-in-profile_pc.patch b/queue-5.15/x86-stop-playing-stack-games-in-profile_pc.patch new file mode 100644 index 00000000000..cc2f2848001 --- /dev/null +++ b/queue-5.15/x86-stop-playing-stack-games-in-profile_pc.patch @@ -0,0 +1,95 @@ +From 6da90b6e70119f8b2b2e7f15f9b72d7e06557dc4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Jun 2024 14:27:22 -0700 +Subject: x86: stop playing stack games in profile_pc() + +From: Linus Torvalds + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 +