ARM: spectre-v1: fix syscall entry
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>
This commit is contained in:
parent
1d4238c56f
commit
10573ae547
|
@ -242,9 +242,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)
|
||||
|
@ -278,14 +276,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
|
||||
|
@ -363,6 +355,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
|
||||
|
|
|
@ -378,6 +378,31 @@
|
|||
#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.
|
||||
|
|
Loading…
Reference in New Issue