ARM: spectre-v1: fix syscall entry
authorRussell King <rmk+kernel@armlinux.org.uk>
Mon, 15 Oct 2018 15:32:12 +0000 (11:32 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 Oct 2018 07:16:27 +0000 (09:16 +0200)
Commit 10573ae547c85b2c61417ff1a106cffbfceada35 upstream.

Prevent speculation at the syscall table decoding by clamping the index
used to zero on invalid system call numbers, and using the csdb
speculative barrier.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Boot-tested-by: Tony Lindgren <tony@atomide.com>
Reviewed-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: David A. Long <dave.long@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/arm/kernel/entry-common.S
arch/arm/kernel/entry-header.S

index 99c9082..54c1050 100644 (file)
@@ -241,9 +241,7 @@ local_restart:
        tst     r10, #_TIF_SYSCALL_WORK         @ are we tracing syscalls?
        bne     __sys_trace
 
-       cmp     scno, #NR_syscalls              @ check upper syscall limit
-       badr    lr, ret_fast_syscall            @ return address
-       ldrcc   pc, [tbl, scno, lsl #2]         @ call sys_* routine
+       invoke_syscall tbl, scno, r10, ret_fast_syscall
 
        add     r1, sp, #S_OFF
 2:     cmp     scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
@@ -277,14 +275,8 @@ __sys_trace:
        mov     r1, scno
        add     r0, sp, #S_OFF
        bl      syscall_trace_enter
-
-       badr    lr, __sys_trace_return          @ return address
-       mov     scno, r0                        @ syscall number (possibly new)
-       add     r1, sp, #S_R0 + S_OFF           @ pointer to regs
-       cmp     scno, #NR_syscalls              @ check upper syscall limit
-       ldmccia r1, {r0 - r6}                   @ have to reload r0 - r6
-       stmccia sp, {r4, r5}                    @ and update the stack args
-       ldrcc   pc, [tbl, scno, lsl #2]         @ call sys_* routine
+       mov     scno, r0
+       invoke_syscall tbl, scno, r10, __sys_trace_return, reload=1
        cmp     scno, #-1                       @ skip the syscall?
        bne     2b
        add     sp, sp, #S_OFF                  @ restore stack
@@ -362,6 +354,10 @@ sys_syscall:
                bic     scno, r0, #__NR_OABI_SYSCALL_BASE
                cmp     scno, #__NR_syscall - __NR_SYSCALL_BASE
                cmpne   scno, #NR_syscalls      @ check range
+#ifdef CONFIG_CPU_SPECTRE
+               movhs   scno, #0
+               csdb
+#endif
                stmloia sp, {r5, r6}            @ shuffle args
                movlo   r0, r1
                movlo   r1, r2
index 0f07579..7734248 100644 (file)
 #endif
        .endm
 
+       .macro  invoke_syscall, table, nr, tmp, ret, reload=0
+#ifdef CONFIG_CPU_SPECTRE
+       mov     \tmp, \nr
+       cmp     \tmp, #NR_syscalls              @ check upper syscall limit
+       movcs   \tmp, #0
+       csdb
+       badr    lr, \ret                        @ return address
+       .if     \reload
+       add     r1, sp, #S_R0 + S_OFF           @ pointer to regs
+       ldmccia r1, {r0 - r6}                   @ reload r0-r6
+       stmccia sp, {r4, r5}                    @ update stack arguments
+       .endif
+       ldrcc   pc, [\table, \tmp, lsl #2]      @ call sys_* routine
+#else
+       cmp     \nr, #NR_syscalls               @ check upper syscall limit
+       badr    lr, \ret                        @ return address
+       .if     \reload
+       add     r1, sp, #S_R0 + S_OFF           @ pointer to regs
+       ldmccia r1, {r0 - r6}                   @ reload r0-r6
+       stmccia sp, {r4, r5}                    @ update stack arguments
+       .endif
+       ldrcc   pc, [\table, \nr, lsl #2]       @ call sys_* routine
+#endif
+       .endm
+
 /*
  * These are the registers used in the syscall handler, and allow us to
  * have in theory up to 7 arguments to a function - r0 to r6.