On Fri, Oct 30, 2020 at 5:53 PM Russell King - ARM Linux admin <linux@xxxxxxxxxxxxxxx> wrote: > > On Fri, Oct 30, 2020 at 04:49:14PM +0100, Arnd Bergmann wrote: > > From: Arnd Bergmann <arnd@xxxxxxxx> > > > > The system call number is used in a a couple of places, in particular > > ptrace, seccomp and /proc/<pid>/syscall. > > > > The last one apparently never worked reliably on ARM for tasks > > that are not currently getting traced. > > > > Storing the syscall number in the normal entry path makes it work, > > as well as allowing us to see if the current system call is for > > OABI compat mode, which is the next thing I want to hook into. > > I'm not sure this patch is correct. I'm not following where you still see a mismatch, I was hoping I had fixed them all after your previous review :( The thread_info->syscall entry should now consistently contain __NR_SYSCALL_BASE on an EABI kernel, and all users of that should consistently mask it out. > Tracing the existing code for OABI: > > asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) > { > current_thread_info()->syscall = scno; This no longer stores to current_thread_info()->syscall but instead reads the number from syscall_get_nr(). > /* Legacy ABI only. */ > USER( ldr scno, [saved_pc, #-4] ) @ get SWI instruction > bic scno, scno, #0xff000000 @ mask off SWI op-code > eor scno, scno, #__NR_SYSCALL_BASE @ check OS number > tst r10, #_TIF_SYSCALL_WORK @ are we tracing syscalls? > bne __sys_trace > > __sys_trace: > mov r1, scno > add r0, sp, #S_OFF > bl syscall_trace_enter > > So, thread_info->syscall does not include __NR_SYSCALL_BASE. The > reason for this is the code that makes use of that via syscall_get_nr(). > kernel/trace/trace_syscalls.c: On both CONFIG_OABI_COMPAT and on !CONFIG_AEABI kernels, I store the value before masking out __NR_SYSCALL_BASE after my change. For EABI-only kernels there is no need for the mask. > syscall_nr = trace_get_syscall_nr(current, regs); > if (syscall_nr < 0 || syscall_nr >= NR_syscalls) > return; > > and NR_syscalls is the number of syscalls, which doesn't include the > __NR_SYSCALL_BASE offset. > > So, I think this patch actually breaks OABI. The value returned from trace_get_syscall_nr() is always in the 0...NR_syscalls range without the __NR_SYSCALL_BASE for a valid syscall. because of the added static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { - return task_thread_info(task)->syscall; + return task_thread_info(task)->syscall & ~__NR_OABI_SYSCALL_BASE; } (plus the corresponding logic for OABI_COMPAT. Which of the above do you think I got wrong? Arnd