From 9e6d9e3207552db0459804a3a508d464f5852224 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 30 Jun 2024 20:09:10 -0400 Subject: [PATCH] Fixes for 6.9 Signed-off-by: Sasha Levin --- ...ric-sys_fanotify_mark-implementation.patch | 99 +++++++++++++++++++ queue-6.9/series | 2 + ...op-playing-stack-games-in-profile_pc.patch | 95 ++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 queue-6.9/parisc-use-generic-sys_fanotify_mark-implementation.patch create mode 100644 queue-6.9/x86-stop-playing-stack-games-in-profile_pc.patch diff --git a/queue-6.9/parisc-use-generic-sys_fanotify_mark-implementation.patch b/queue-6.9/parisc-use-generic-sys_fanotify_mark-implementation.patch new file mode 100644 index 00000000000..4998d709296 --- /dev/null +++ b/queue-6.9/parisc-use-generic-sys_fanotify_mark-implementation.patch @@ -0,0 +1,99 @@ +From 3d427aa57b0a8a17670a3a7a32fe557f6b8a2814 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 daafeb20f9937..dc9b902de8ea9 100644 +--- a/arch/parisc/Kconfig ++++ b/arch/parisc/Kconfig +@@ -16,6 +16,7 @@ config PARISC + select ARCH_HAS_UBSAN + 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 58ecf687d98da..0f631cb2cdea7 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-6.9/series b/queue-6.9/series index cdad06adc4f..5e9fc16c49d 100644 --- a/queue-6.9/series +++ b/queue-6.9/series @@ -109,3 +109,5 @@ gpiolib-cdev-disallow-reconfiguration-without-direct.patch gpiolib-cdev-ignore-reconfiguration-without-directio.patch tools-power-turbostat-option-n-is-ambiguous.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.9/x86-stop-playing-stack-games-in-profile_pc.patch b/queue-6.9/x86-stop-playing-stack-games-in-profile_pc.patch new file mode 100644 index 00000000000..2bd18c7a27b --- /dev/null +++ b/queue-6.9/x86-stop-playing-stack-games-in-profile_pc.patch @@ -0,0 +1,95 @@ +From 950882177c98d4d4ca10d35f85ad9780b5c63f20 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 + -- 2.47.3