Re: [PATCH v2 0/9] ARM: remove set_fs callers and implementation
From: Arnd Bergmann <arnd@arndb.de>
Date: 2020-09-25 15:31:00
Also in:
linux-arch, linux-mm, lkml
Subsystem:
arm port, the rest · Maintainers:
Russell King, Linus Torvalds
On Fri, Sep 25, 2020 at 4:08 PM Arnd Bergmann [off-list ref] wrote:
On Sat, Sep 19, 2020 at 10:19 AM Russell King - ARM Linux admin [off-list ref] wrote:quoted
On Fri, Sep 18, 2020 at 02:46:15PM +0200, Arnd Bergmann wrote:quoted
Hi Christoph, Russell, Here is an updated series for removing set_fs() from arch/arm, based on the previous feedback. I have tested the oabi-compat changes using the LTP tests for the three modified syscalls using an Armv7 kernel and a Debian 5 OABI user space, and I have lightly tested the get_kernel_nofault infrastructure by loading the test_lockup.ko module after setting CONFIG_DEBUG_SPINLOCK.I'm not too keen on always saving the syscall number, but for the gain of getting rid of set_fs() I think it's worth it. However... I think there are some things to check - what value do you end up with as the first number in /proc/self/syscall when you do: strace cat /proc/self/syscall ?quoted
It should be 3, not 0x900003. I suspect you're getting the latter with these changes. IIRC, task_thread_info(task)->syscall needs to be the value _without_ the offset, otherwise tracing will break.It seems broken in different ways, depending on the combination of kernel and userland: 1. EABI armv5-versatile kernel, EABI Debian 5: $ cat /proc/self/syscall 0 0x1500000000003 0x1500000000400 0x1500000000400 0x60000013c7800480 0xc0008668c0112f8c 0xc0112d14c68e1f68 0xbeab06f8 0xb6e80d4c $ strace -f cat /proc/self/syscall execve("/bin/cat", ["cat", "/proc/self/syscall"], [/* 16 vars */]) = -1 EINTR (Interrupted system call) dup(2) = -1 EINTR (Interrupted system call) write(2, "strace: exec: Interrupted system "..., 38) = -1 EINTR (Interrupted system call) exit_group(1) = ?
Both the missing number and the broken strace are fixed with
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 610e32273c81..2c0bde14fba6 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S@@ -226,7 +226,8 @@ ENTRY(vector_swi) * get the old ABI syscall table address. */ bics r10, r10, #0xff000000 - str r10, [tsk, #TI_SYSCALL] + strne r10, [tsk, #TI_SYSCALL] + streq scno, [tsk, #TI_SYSCALL] eorne scno, r10, #__NR_OABI_SYSCALL_BASE ldrne tbl, =sys_oabi_call_table #elif !defined(CONFIG_AEABI)
It was already working with CONFIG_AEABI=y and CONFIG_OABI_COMPAT=n
quoted hunk ↗ jump to hunk
2. EABI kernel, OABI Debian 5: $ cat /proc/self/syscall 3 0x1500000000003 0x13ccc00000400 0x1500000000400 0x60000013c7800480 0xc0008de0c0112f8c 0xc0112d14c7313f68 0xbeed27d0 0xb6eab324 $ strace cat /proc/self/syscall execve("/bin/cat", ["cat", "/proc/self/syscall"], [/* 16 vars */]) = -1090648236--- SIGILL (Illegal instruction) @ 0 (0) --- +++ killed by SIGILL +++
This was caused by me after all, here is my fix:
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c@@ -25,6 +25,7 @@ #include <linux/tracehook.h> #include <linux/unistd.h> +#include <asm/syscall.h> #include <asm/traps.h> #define CREATE_TRACE_POINTS
@@ -898,11 +899,11 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) return -1; #else /* XXX: remove this once OABI gets fixed */ - secure_computing_strict(current_thread_info()->syscall); + secure_computing_strict(syscall_get_nr(current, regs)); #endif /* Tracer or seccomp may have changed syscall. */ - scno = current_thread_info()->syscall; + scno = syscall_get_nr(current, regs); if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) trace_sys_enter(regs, scno);
3. OABI kernel, OABI Debian 5: cat /proc/self/syscall 9437187 0x1500000000003 0x13ccc00000400 0x1500000000400 0x100060000013 0x15000c72cff6c 0xc72cfe9000000000 0xbece27d0 0xb6f2f324
This one is fixed by
--- a/arch/arm/include/asm/syscall.h
+++ b/arch/arm/include/asm/syscall.h@@ -22,7 +22,7 @@ extern const unsigned long sys_call_table[]; static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { - if (!IS_ENABLED(CONFIG_OABI_COMPAT)) + if (IS_ENABLED(CONFIG_AEABI) && !IS_ENABLED(CONFIG_OABI_COMPAT)) return task_thread_info(task)->syscall; return task_thread_info(task)->syscall & ~__NR_OABI_SYSCALL_BASE;
I'll send an updated patch once I've addressed Christoph's comments.
Arnd
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel