Skip to content

Commit

Permalink
MIPS: scall: Always run the seccomp syscall filters
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Markos Chandras authored and Ralf Baechle committed Oct 4, 2015
1 parent 66803dd commit d218af7
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 73 deletions.
39 changes: 16 additions & 23 deletions arch/mips/kernel/scall32-o32.S
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)

Expand All @@ -116,7 +118,7 @@ o32_syscall_exit:

syscall_trace_entry:
SAVE_STATIC
move s0, t2
move s0, v0
move a0, sp

/*
Expand All @@ -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

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
j syscall_common

2: j syscall_exit
1: j syscall_exit

/* ------------------------------------------------------------------------ */

Expand Down
38 changes: 16 additions & 22 deletions arch/mips/kernel/scall64-64.S
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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?
Expand All @@ -78,34 +82,24 @@ 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)
ld a2, PT_R6(sp)
ld a3, PT_R7(sp)
ld a4, PT_R8(sp)
ld a5, PT_R9(sp)
jalr t0

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
j syscall_common

2: j syscall_exit
1: j syscall_exit

illegal_syscall:
/* This also isn't a 64-bit syscall, throw an error. */
Expand Down
19 changes: 5 additions & 14 deletions arch/mips/kernel/scall64-n32.S
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand All @@ -75,29 +76,19 @@ 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)
ld a2, PT_R6(sp)
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
Expand Down
19 changes: 5 additions & 14 deletions arch/mips/kernel/scall64-o32.S
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down Expand Up @@ -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)
Expand All @@ -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

/* ------------------------------------------------------------------------ */

Expand Down

0 comments on commit d218af7

Please sign in to comment.