From 22feadbe4c455491be5725bc7a6073b98db5db99 Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Wed, 22 Jan 2014 14:39:58 +0000 Subject: MIPS: asm: syscall: Add the syscall_rollback function The syscall_rollback function is used by seccomp-bpf but it was never added for MIPS. It doesn't need to do anything as none of the registers are clobbered if the system call has been denied by the seccomp filter. Signed-off-by: Markos Chandras Reviewed-by: James Hogan Reviewed-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6403/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/syscall.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/mips/include/asm/syscall.h') diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h index 33e8dbfc1b63..2981ef5bb092 100644 --- a/arch/mips/include/asm/syscall.h +++ b/arch/mips/include/asm/syscall.h @@ -65,6 +65,12 @@ static inline long syscall_get_return_value(struct task_struct *task, return regs->regs[2]; } +static inline void syscall_rollback(struct task_struct *task, + struct pt_regs *regs) +{ + /* Do nothing */ +} + static inline void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, int error, long val) -- cgit v1.2.2 From 6e34574603f633fa67cf1037aa6374292469c74f Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Wed, 22 Jan 2014 14:39:59 +0000 Subject: MIPS: asm: syscall: Define syscall_get_arch This effectively renames __syscall_get_arch to syscall_get_arch and implements a compatible interface for the seccomp API. The seccomp code (kernel/seccomp.c) expects a syscall_get_arch function to be defined for every architecture, so we drop the leading underscores from the existing function. This also makes use of the 'task' argument to determine the type the process instead of assuming the process has the same characteristics as the kernel it's running on. Signed-off-by: Markos Chandras Reviewed-by: Paul Burton Reviewed-by: James Hogan Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6398/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/syscall.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/mips/include/asm/syscall.h') diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h index 2981ef5bb092..08b639b1ca78 100644 --- a/arch/mips/include/asm/syscall.h +++ b/arch/mips/include/asm/syscall.h @@ -107,11 +107,13 @@ extern const unsigned long sys_call_table[]; extern const unsigned long sys32_call_table[]; extern const unsigned long sysn32_call_table[]; -static inline int __syscall_get_arch(void) +static inline int syscall_get_arch(struct task_struct *task, + struct pt_regs *regs) { int arch = EM_MIPS; #ifdef CONFIG_64BIT - arch |= __AUDIT_ARCH_64BIT; + if (!test_tsk_thread_flag(task, TIF_32BIT_REGS)) + arch |= __AUDIT_ARCH_64BIT; #endif #if defined(__LITTLE_ENDIAN) arch |= __AUDIT_ARCH_LE; -- cgit v1.2.2 From 4c21b8fd8f146a22e1eaf92833a32e51f560e82a Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Wed, 22 Jan 2014 14:40:03 +0000 Subject: MIPS: seccomp: Handle indirect system calls (o32) When userland uses syscall() to perform an indirect system call the actually system call that needs to be checked by the filter is on the first argument. The kernel code needs to handle this case by looking at the original syscall number in v0 and if it's NR_syscall, then it needs to examine the first argument to identify the real system call that will be executed. Similarly, we need to 'virtually' shift the syscall() arguments so the syscall_get_arguments() function can fetch the correct arguments for the indirect system call. Signed-off-by: Markos Chandras Reviewed-by: James Hogan Reviewed-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6404/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/syscall.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'arch/mips/include/asm/syscall.h') diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h index 08b639b1ca78..9031745cec1b 100644 --- a/arch/mips/include/asm/syscall.h +++ b/arch/mips/include/asm/syscall.h @@ -19,11 +19,22 @@ #include #include #include +#include + +#ifndef __NR_syscall /* Only defined if _MIPS_SIM == _MIPS_SIM_ABI32 */ +#define __NR_syscall 4000 +#endif static inline long syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { - return regs->regs[2]; + /* O32 ABI syscall() - Either 64-bit with O32 or 32-bit */ + if ((config_enabled(CONFIG_32BIT) || + test_tsk_thread_flag(task, TIF_32BIT_REGS)) && + (regs->regs[2] == __NR_syscall)) + return regs->regs[4]; + else + return regs->regs[2]; } static inline unsigned long mips_get_syscall_arg(unsigned long *arg, @@ -91,6 +102,13 @@ static inline void syscall_get_arguments(struct task_struct *task, { unsigned long arg; int ret; + /* O32 ABI syscall() - Either 64-bit with O32 or 32-bit */ + if ((config_enabled(CONFIG_32BIT) || + test_tsk_thread_flag(task, TIF_32BIT_REGS)) && + (regs->regs[2] == __NR_syscall)) { + i++; + n++; + } while (n--) ret |= mips_get_syscall_arg(&arg, task, regs, i++); -- cgit v1.2.2