ARM: spectre-v1: fix syscall entry
authorRussell King <rmk+kernel@armlinux.org.uk>
Wed, 7 Nov 2018 16:43:56 +0000 (11:43 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 23 Nov 2018 07:20:39 +0000 (08:20 +0100)
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 10c3283d6c196b85bcab35264f80851eddcf0663..56be67ecf0fa109c51e9d435471fcbbe913597f4 100644 (file)
@@ -223,9 +223,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)
@@ -258,14 +256,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
@@ -317,6 +309,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 e056c9a9aa9db178ba47ec421f2e8d1f53d3cab4..fa7c6e5c17e787187a1f8f39c9617b4b4f9b0638 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.