summaryrefslogtreecommitdiff
path: root/arch/mips
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2017-06-29 10:12:36 +0100
committerRalf Baechle <ralf@linux-mips.org>2017-07-11 14:13:06 +0200
commit828db212bf4b63c68c51f6519435c48e8d79bd00 (patch)
treea617cc1577b8824d7c7b9ffd06be40b1f0f6b517 /arch/mips
parentbecddba9f80f26a2b9ebe9bad2806304ed5e00e1 (diff)
downloadlwn-828db212bf4b63c68c51f6519435c48e8d79bd00.tar.gz
lwn-828db212bf4b63c68c51f6519435c48e8d79bd00.zip
MIPS: Traced negative syscalls should return -ENOSYS
If a negative system call number is used when system call tracing is enabled, syscall_trace_enter() will return that negative system call number without having written the return value and error flag into the pt_regs. The caller then treats it as a cancelled system call and assumes that the return value and error flag are already written, leaving the negative system call number in the return register ($v0), and the 4th system call argument in the error register ($a3). Add a special case to detect this at the end of syscall_trace_enter(), to set the return value to error -ENOSYS when this happens. Fixes: d218af78492a ("MIPS: scall: Always run the seccomp syscall filters") Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/16653/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/kernel/ptrace.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 8e2ea86dc23e..6dd13641a418 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -894,6 +894,13 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
audit_syscall_entry(syscall, regs->regs[4], regs->regs[5],
regs->regs[6], regs->regs[7]);
+
+ /*
+ * Negative syscall numbers are mistaken for rejected syscalls, but
+ * won't have had the return value set appropriately, so we do so now.
+ */
+ if (syscall < 0)
+ syscall_set_return_value(current, regs, -ENOSYS, 0);
return syscall;
}