MIPS: scall: Always run the seccomp syscall filters

The MIPS syscall handler code used to return -ENOSYS on invalid
syscalls. Whilst this is expected, it caused problems for seccomp
filters because the said filters never had the change to run since
the code returned -ENOSYS before triggering them. This caused
problems on the chromium testsuite for filters looking for invalid
syscalls. This has now changed and the seccomp filters are always
run even if the syscall is invalid. We return -ENOSYS once we
return from the seccomp filters. Moreover, similar codepaths have
been merged in the process which simplifies somewhat the overall
syscall code.

Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/11236/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
Markos Chandras 2015-09-25 08:17:42 +01:00 committed by Ralf Baechle
parent 66803dd919
commit d218af7849
4 changed files with 42 additions and 73 deletions

View File

@ -36,16 +36,8 @@ NESTED(handle_sys, PT_SIZE, sp)
lw t1, PT_EPC(sp) # skip syscall on return
subu v0, v0, __NR_O32_Linux # check syscall number
sltiu t0, v0, __NR_O32_Linux_syscalls + 1
addiu t1, 4 # skip to next instruction
sw t1, PT_EPC(sp)
beqz t0, illegal_syscall
sll t0, v0, 2
la t1, sys_call_table
addu t1, t0
lw t2, (t1) # syscall routine
beqz t2, illegal_syscall
sw a3, PT_R26(sp) # save a3 for syscall restarting
@ -96,6 +88,16 @@ loads_done:
li t1, _TIF_WORK_SYSCALL_ENTRY
and t0, t1
bnez t0, syscall_trace_entry # -> yes
syscall_common:
sltiu t0, v0, __NR_O32_Linux_syscalls + 1
beqz t0, illegal_syscall
sll t0, v0, 2
la t1, sys_call_table
addu t1, t0
lw t2, (t1) # syscall routine
beqz t2, illegal_syscall
jalr t2 # Do The Real Thing (TM)
@ -116,7 +118,7 @@ o32_syscall_exit:
syscall_trace_entry:
SAVE_STATIC
move s0, t2
move s0, v0
move a0, sp
/*
@ -129,27 +131,18 @@ syscall_trace_entry:
1: jal syscall_trace_enter
bltz v0, 2f # seccomp failed? Skip syscall
bltz v0, 1f # seccomp failed? Skip syscall
move v0, s0 # restore syscall
move t0, s0
RESTORE_STATIC
lw a0, PT_R4(sp) # Restore argument registers
lw a1, PT_R5(sp)
lw a2, PT_R6(sp)
lw a3, PT_R7(sp)
jalr t0
j syscall_common
li t0, -EMAXERRNO - 1 # error?
sltu t0, t0, v0
sw t0, PT_R7(sp) # set error flag
beqz t0, 1f
lw t1, PT_R2(sp) # syscall number
negu v0 # error
sw t1, PT_R0(sp) # save it for syscall restarting
1: sw v0, PT_R2(sp) # result
2: j syscall_exit
1: j syscall_exit
/* ------------------------------------------------------------------------ */

View File

@ -39,18 +39,11 @@ NESTED(handle_sys64, PT_SIZE, sp)
.set at
#endif
dsubu t0, v0, __NR_64_Linux # check syscall number
sltiu t0, t0, __NR_64_Linux_syscalls + 1
#if !defined(CONFIG_MIPS32_O32) && !defined(CONFIG_MIPS32_N32)
ld t1, PT_EPC(sp) # skip syscall on return
daddiu t1, 4 # skip to next instruction
sd t1, PT_EPC(sp)
#endif
beqz t0, illegal_syscall
dsll t0, v0, 3 # offset into table
ld t2, (sys_call_table - (__NR_64_Linux * 8))(t0)
# syscall routine
sd a3, PT_R26(sp) # save a3 for syscall restarting
@ -59,6 +52,17 @@ NESTED(handle_sys64, PT_SIZE, sp)
and t0, t1, t0
bnez t0, syscall_trace_entry
syscall_common:
dsubu t2, v0, __NR_64_Linux
sltiu t0, t2, __NR_64_Linux_syscalls + 1
beqz t0, illegal_syscall
dsll t0, t2, 3 # offset into table
dla t2, sys_call_table
daddu t0, t2, t0
ld t2, (t0) # syscall routine
beqz t2, illegal_syscall
jalr t2 # Do The Real Thing (TM)
li t0, -EMAXERRNO - 1 # error?
@ -78,14 +82,14 @@ n64_syscall_exit:
syscall_trace_entry:
SAVE_STATIC
move s0, t2
move s0, v0
move a0, sp
move a1, v0
jal syscall_trace_enter
bltz v0, 2f # seccomp failed? Skip syscall
bltz v0, 1f # seccomp failed? Skip syscall
move t0, s0
move v0, s0
RESTORE_STATIC
ld a0, PT_R4(sp) # Restore argument registers
ld a1, PT_R5(sp)
@ -93,19 +97,9 @@ syscall_trace_entry:
ld a3, PT_R7(sp)
ld a4, PT_R8(sp)
ld a5, PT_R9(sp)
jalr t0
j syscall_common
li t0, -EMAXERRNO - 1 # error?
sltu t0, t0, v0
sd t0, PT_R7(sp) # set error flag
beqz t0, 1f
ld t1, PT_R2(sp) # syscall number
dnegu v0 # error
sd t1, PT_R0(sp) # save it for syscall restarting
1: sd v0, PT_R2(sp) # result
2: j syscall_exit
1: j syscall_exit
illegal_syscall:
/* This also isn't a 64-bit syscall, throw an error. */

View File

@ -52,6 +52,7 @@ NESTED(handle_sysn32, PT_SIZE, sp)
and t0, t1, t0
bnez t0, n32_syscall_trace_entry
syscall_common:
jalr t2 # Do The Real Thing (TM)
li t0, -EMAXERRNO - 1 # error?
@ -75,9 +76,9 @@ n32_syscall_trace_entry:
move a1, v0
jal syscall_trace_enter
bltz v0, 2f # seccomp failed? Skip syscall
bltz v0, 1f # seccomp failed? Skip syscall
move t0, s0
move t2, s0
RESTORE_STATIC
ld a0, PT_R4(sp) # Restore argument registers
ld a1, PT_R5(sp)
@ -85,19 +86,9 @@ n32_syscall_trace_entry:
ld a3, PT_R7(sp)
ld a4, PT_R8(sp)
ld a5, PT_R9(sp)
jalr t0
j syscall_common
li t0, -EMAXERRNO - 1 # error?
sltu t0, t0, v0
sd t0, PT_R7(sp) # set error flag
beqz t0, 1f
ld t1, PT_R2(sp) # syscall number
dnegu v0 # error
sd t1, PT_R0(sp) # save it for syscall restarting
1: sd v0, PT_R2(sp) # result
2: j syscall_exit
1: j syscall_exit
not_n32_scall:
/* This is not an n32 compatibility syscall, pass it on to

View File

@ -87,6 +87,7 @@ loads_done:
and t0, t1, t0
bnez t0, trace_a_syscall
syscall_common:
jalr t2 # Do The Real Thing (TM)
li t0, -EMAXERRNO - 1 # error?
@ -130,9 +131,9 @@ trace_a_syscall:
1: jal syscall_trace_enter
bltz v0, 2f # seccomp failed? Skip syscall
bltz v0, 1f # seccomp failed? Skip syscall
move t0, s0
move t2, s0
RESTORE_STATIC
ld a0, PT_R4(sp) # Restore argument registers
ld a1, PT_R5(sp)
@ -142,19 +143,9 @@ trace_a_syscall:
ld a5, PT_R9(sp)
ld a6, PT_R10(sp)
ld a7, PT_R11(sp) # For indirect syscalls
jalr t0
j syscall_common
li t0, -EMAXERRNO - 1 # error?
sltu t0, t0, v0
sd t0, PT_R7(sp) # set error flag
beqz t0, 1f
ld t1, PT_R2(sp) # syscall number
dnegu v0 # error
sd t1, PT_R0(sp) # save it for syscall restarting
1: sd v0, PT_R2(sp) # result
2: j syscall_exit
1: j syscall_exit
/* ------------------------------------------------------------------------ */