MIPS: scall: Always run the seccomp syscall filters
authorMarkos Chandras <markos.chandras@imgtec.com>
Fri, 25 Sep 2015 07:17:42 +0000 (08:17 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Sun, 4 Oct 2015 10:10:56 +0000 (12:10 +0200)
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>
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/scall64-64.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S

index d06e30c1e4cda2e05e4f3541e6a8e31d825ce58f..65a74e4f0f456d1de9d29ed83a62e1bcc6e644fc 100644 (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
-
-       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
 
 /* ------------------------------------------------------------------------ */
 
index 428c2cd2326ce310328df7a99cde15b09cb9a9ae..e732981cf99fde26181f1db3bcb65ebd86ea4a0d 100644 (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
-
-       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.  */
index 3868cf4c83df2929980f843206c8781383e6a2bd..c794843975845df2e0a9d9c0c0fd14dad1ed17ec 100644 (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
index 6622980d82ea1b112308797c0a04bd1222ab416e..6369cfd390c6330269b05eb095020dafa6cdc048 100644 (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
 
 /* ------------------------------------------------------------------------ */