MIPS: scall: Handle seccomp filters which redirect syscalls
Commitd218af7849
("MIPS: scall: Always run the seccomp syscall filters") modified the syscall code to always call the seccomp filters, but missed the case where a filter may redirect the syscall, as revealed by the seccomp_bpf self test. The syscall path now restores the syscall from the stack after the filter rather than saving it locally. Syscall number checking and syscall function table lookup is done after the filter may have run such that redirected syscalls are also checked, and executed. The regular path of syscall number checking and pointer lookup is also made more consistent between ABIs with scall64-64.S being the reference. With this patch in place, the seccomp_bpf self test now passes TRACE_syscall.syscall_redirected and TRACE_syscall.syscall_dropped on all MIPS ABIs. Fixes:d218af7849
("MIPS: scall: Always run the seccomp syscall filters") Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> Acked-by: Kees Cook <keescook@chromium.org> Cc: Eric B Munson <emunson@akamai.com> Cc: James Hogan <james.hogan@imgtec.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: linux-mips@linux-mips.org Cc: IMG-MIPSLinuxKerneldevelopers@imgtec.com Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/12916/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
5050e91fa6
commit
a400bed6d1
|
@ -35,7 +35,6 @@ NESTED(handle_sys, PT_SIZE, sp)
|
|||
|
||||
lw t1, PT_EPC(sp) # skip syscall on return
|
||||
|
||||
subu v0, v0, __NR_O32_Linux # check syscall number
|
||||
addiu t1, 4 # skip to next instruction
|
||||
sw t1, PT_EPC(sp)
|
||||
|
||||
|
@ -89,6 +88,7 @@ loads_done:
|
|||
and t0, t1
|
||||
bnez t0, syscall_trace_entry # -> yes
|
||||
syscall_common:
|
||||
subu v0, v0, __NR_O32_Linux # check syscall number
|
||||
sltiu t0, v0, __NR_O32_Linux_syscalls + 1
|
||||
beqz t0, illegal_syscall
|
||||
|
||||
|
@ -118,24 +118,23 @@ o32_syscall_exit:
|
|||
|
||||
syscall_trace_entry:
|
||||
SAVE_STATIC
|
||||
move s0, v0
|
||||
move a0, sp
|
||||
|
||||
/*
|
||||
* syscall number is in v0 unless we called syscall(__NR_###)
|
||||
* where the real syscall number is in a0
|
||||
*/
|
||||
addiu a1, v0, __NR_O32_Linux
|
||||
bnez v0, 1f /* __NR_syscall at offset 0 */
|
||||
move a1, v0
|
||||
subu t2, v0, __NR_O32_Linux
|
||||
bnez t2, 1f /* __NR_syscall at offset 0 */
|
||||
lw a1, PT_R4(sp)
|
||||
|
||||
1: jal syscall_trace_enter
|
||||
|
||||
bltz v0, 1f # seccomp failed? Skip syscall
|
||||
|
||||
move v0, s0 # restore syscall
|
||||
|
||||
RESTORE_STATIC
|
||||
lw v0, PT_R2(sp) # Restore syscall (maybe modified)
|
||||
lw a0, PT_R4(sp) # Restore argument registers
|
||||
lw a1, PT_R5(sp)
|
||||
lw a2, PT_R6(sp)
|
||||
|
|
|
@ -82,15 +82,14 @@ n64_syscall_exit:
|
|||
|
||||
syscall_trace_entry:
|
||||
SAVE_STATIC
|
||||
move s0, v0
|
||||
move a0, sp
|
||||
move a1, v0
|
||||
jal syscall_trace_enter
|
||||
|
||||
bltz v0, 1f # seccomp failed? Skip syscall
|
||||
|
||||
move v0, s0
|
||||
RESTORE_STATIC
|
||||
ld v0, PT_R2(sp) # Restore syscall (maybe modified)
|
||||
ld a0, PT_R4(sp) # Restore argument registers
|
||||
ld a1, PT_R5(sp)
|
||||
ld a2, PT_R6(sp)
|
||||
|
|
|
@ -42,9 +42,6 @@ NESTED(handle_sysn32, PT_SIZE, sp)
|
|||
#endif
|
||||
beqz t0, not_n32_scall
|
||||
|
||||
dsll t0, v0, 3 # offset into table
|
||||
ld t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0)
|
||||
|
||||
sd a3, PT_R26(sp) # save a3 for syscall restarting
|
||||
|
||||
li t1, _TIF_WORK_SYSCALL_ENTRY
|
||||
|
@ -53,6 +50,9 @@ NESTED(handle_sysn32, PT_SIZE, sp)
|
|||
bnez t0, n32_syscall_trace_entry
|
||||
|
||||
syscall_common:
|
||||
dsll t0, v0, 3 # offset into table
|
||||
ld t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0)
|
||||
|
||||
jalr t2 # Do The Real Thing (TM)
|
||||
|
||||
li t0, -EMAXERRNO - 1 # error?
|
||||
|
@ -71,21 +71,25 @@ syscall_common:
|
|||
|
||||
n32_syscall_trace_entry:
|
||||
SAVE_STATIC
|
||||
move s0, t2
|
||||
move a0, sp
|
||||
move a1, v0
|
||||
jal syscall_trace_enter
|
||||
|
||||
bltz v0, 1f # seccomp failed? Skip syscall
|
||||
|
||||
move t2, s0
|
||||
RESTORE_STATIC
|
||||
ld v0, PT_R2(sp) # Restore syscall (maybe modified)
|
||||
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)
|
||||
|
||||
dsubu t2, v0, __NR_N32_Linux # check (new) syscall number
|
||||
sltiu t0, t2, __NR_N32_Linux_syscalls + 1
|
||||
beqz t0, not_n32_scall
|
||||
|
||||
j syscall_common
|
||||
|
||||
1: j syscall_exit
|
||||
|
|
|
@ -52,9 +52,6 @@ NESTED(handle_sys, PT_SIZE, sp)
|
|||
sll a2, a2, 0
|
||||
sll a3, a3, 0
|
||||
|
||||
dsll t0, v0, 3 # offset into table
|
||||
ld t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
|
||||
|
||||
sd a3, PT_R26(sp) # save a3 for syscall restarting
|
||||
|
||||
/*
|
||||
|
@ -88,6 +85,9 @@ loads_done:
|
|||
bnez t0, trace_a_syscall
|
||||
|
||||
syscall_common:
|
||||
dsll t0, v0, 3 # offset into table
|
||||
ld t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
|
||||
|
||||
jalr t2 # Do The Real Thing (TM)
|
||||
|
||||
li t0, -EMAXERRNO - 1 # error?
|
||||
|
@ -112,7 +112,6 @@ trace_a_syscall:
|
|||
sd a6, PT_R10(sp)
|
||||
sd a7, PT_R11(sp) # For indirect syscalls
|
||||
|
||||
move s0, t2 # Save syscall pointer
|
||||
move a0, sp
|
||||
/*
|
||||
* absolute syscall number is in v0 unless we called syscall(__NR_###)
|
||||
|
@ -133,8 +132,8 @@ trace_a_syscall:
|
|||
|
||||
bltz v0, 1f # seccomp failed? Skip syscall
|
||||
|
||||
move t2, s0
|
||||
RESTORE_STATIC
|
||||
ld v0, PT_R2(sp) # Restore syscall (maybe modified)
|
||||
ld a0, PT_R4(sp) # Restore argument registers
|
||||
ld a1, PT_R5(sp)
|
||||
ld a2, PT_R6(sp)
|
||||
|
@ -143,6 +142,11 @@ trace_a_syscall:
|
|||
ld a5, PT_R9(sp)
|
||||
ld a6, PT_R10(sp)
|
||||
ld a7, PT_R11(sp) # For indirect syscalls
|
||||
|
||||
dsubu t0, v0, __NR_O32_Linux # check (new) syscall number
|
||||
sltiu t0, t0, __NR_O32_Linux_syscalls + 1
|
||||
beqz t0, not_o32_scall
|
||||
|
||||
j syscall_common
|
||||
|
||||
1: j syscall_exit
|
||||
|
|
Loading…
Reference in New Issue