diff options
author | Sven Schnelle <svens@linux.ibm.com> | 2020-03-06 15:18:31 +0300 |
---|---|---|
committer | Vasily Gorbik <gor@linux.ibm.com> | 2020-06-16 14:44:04 +0300 |
commit | cd29fa798001075a554b978df3a64e6656c25794 (patch) | |
tree | 11424fe82870b0a810fe10a343bef880c06aa508 /arch | |
parent | 664f5f8de825648d1d31f6f5652e3cd117c77b50 (diff) | |
download | linux-cd29fa798001075a554b978df3a64e6656c25794.tar.xz |
s390/ptrace: return -ENOSYS when invalid syscall is supplied
The current code returns the syscall number which an invalid
syscall number is supplied and tracing is enabled. This makes
the strace testsuite fail.
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/kernel/ptrace.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index e319482da5f0..ceb8105a8086 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -837,6 +837,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { unsigned long mask = -1UL; + long ret = -1; if (is_compat_task()) mask = 0xffffffff; @@ -853,8 +854,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) * debugger stored an invalid system call number. Skip * the system call and the system call restart handling. */ - clear_pt_regs_flag(regs, PIF_SYSCALL); - return -1; + goto skip; } #ifdef CONFIG_SECCOMP @@ -870,7 +870,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) sd.arch = AUDIT_ARCH_S390X; } - sd.nr = regs->gprs[2] & 0xffff; + sd.nr = regs->int_code & 0xffff; sd.args[0] = regs->orig_gpr2 & mask; sd.args[1] = regs->gprs[3] & mask; sd.args[2] = regs->gprs[4] & mask; @@ -879,19 +879,26 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) sd.args[5] = regs->gprs[7] & mask; if (__secure_computing(&sd) == -1) - return -1; + goto skip; } #endif /* CONFIG_SECCOMP */ if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) - trace_sys_enter(regs, regs->gprs[2]); + trace_sys_enter(regs, regs->int_code & 0xffff); - audit_syscall_entry(regs->gprs[2], regs->orig_gpr2 & mask, + audit_syscall_entry(regs->int_code & 0xffff, regs->orig_gpr2 & mask, regs->gprs[3] &mask, regs->gprs[4] &mask, regs->gprs[5] &mask); + if ((signed long)regs->gprs[2] >= NR_syscalls) { + regs->gprs[2] = -ENOSYS; + ret = -ENOSYS; + } return regs->gprs[2]; +skip: + clear_pt_regs_flag(regs, PIF_SYSCALL); + return ret; } asmlinkage void do_syscall_trace_exit(struct pt_regs *regs) |