aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2018-05-11 06:16:22 -0400
committerRussell King <rmk+kernel@armlinux.org.uk>2018-05-31 18:27:26 -0400
commit10573ae547c85b2c61417ff1a106cffbfceada35 (patch)
treedbc21a6b8a94eaa26fdc73b4440affa5ad082e4c
parent1d4238c56f9816ce0f9c8dbe42d7f2ad81cb6613 (diff)
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>
-rw-r--r--arch/arm/kernel/entry-common.S18
-rw-r--r--arch/arm/kernel/entry-header.S25
2 files changed, 32 insertions, 11 deletions
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 3c4f88701f22..20df608bf343 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -242,9 +242,7 @@ local_restart:
242 tst r10, #_TIF_SYSCALL_WORK @ are we tracing syscalls? 242 tst r10, #_TIF_SYSCALL_WORK @ are we tracing syscalls?
243 bne __sys_trace 243 bne __sys_trace
244 244
245 cmp scno, #NR_syscalls @ check upper syscall limit 245 invoke_syscall tbl, scno, r10, ret_fast_syscall
246 badr lr, ret_fast_syscall @ return address
247 ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
248 246
249 add r1, sp, #S_OFF 247 add r1, sp, #S_OFF
2502: cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE) 2482: cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
@@ -278,14 +276,8 @@ __sys_trace:
278 mov r1, scno 276 mov r1, scno
279 add r0, sp, #S_OFF 277 add r0, sp, #S_OFF
280 bl syscall_trace_enter 278 bl syscall_trace_enter
281 279 mov scno, r0
282 badr lr, __sys_trace_return @ return address 280 invoke_syscall tbl, scno, r10, __sys_trace_return, reload=1
283 mov scno, r0 @ syscall number (possibly new)
284 add r1, sp, #S_R0 + S_OFF @ pointer to regs
285 cmp scno, #NR_syscalls @ check upper syscall limit
286 ldmccia r1, {r0 - r6} @ have to reload r0 - r6
287 stmccia sp, {r4, r5} @ and update the stack args
288 ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
289 cmp scno, #-1 @ skip the syscall? 281 cmp scno, #-1 @ skip the syscall?
290 bne 2b 282 bne 2b
291 add sp, sp, #S_OFF @ restore stack 283 add sp, sp, #S_OFF @ restore stack
@@ -363,6 +355,10 @@ sys_syscall:
363 bic scno, r0, #__NR_OABI_SYSCALL_BASE 355 bic scno, r0, #__NR_OABI_SYSCALL_BASE
364 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE 356 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
365 cmpne scno, #NR_syscalls @ check range 357 cmpne scno, #NR_syscalls @ check range
358#ifdef CONFIG_CPU_SPECTRE
359 movhs scno, #0
360 csdb
361#endif
366 stmloia sp, {r5, r6} @ shuffle args 362 stmloia sp, {r5, r6} @ shuffle args
367 movlo r0, r1 363 movlo r0, r1
368 movlo r1, r2 364 movlo r1, r2
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 0f07579af472..773424843d6e 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -378,6 +378,31 @@
378#endif 378#endif
379 .endm 379 .endm
380 380
381 .macro invoke_syscall, table, nr, tmp, ret, reload=0
382#ifdef CONFIG_CPU_SPECTRE
383 mov \tmp, \nr
384 cmp \tmp, #NR_syscalls @ check upper syscall limit
385 movcs \tmp, #0
386 csdb
387 badr lr, \ret @ return address
388 .if \reload
389 add r1, sp, #S_R0 + S_OFF @ pointer to regs
390 ldmccia r1, {r0 - r6} @ reload r0-r6
391 stmccia sp, {r4, r5} @ update stack arguments
392 .endif
393 ldrcc pc, [\table, \tmp, lsl #2] @ call sys_* routine
394#else
395 cmp \nr, #NR_syscalls @ check upper syscall limit
396 badr lr, \ret @ return address
397 .if \reload
398 add r1, sp, #S_R0 + S_OFF @ pointer to regs
399 ldmccia r1, {r0 - r6} @ reload r0-r6
400 stmccia sp, {r4, r5} @ update stack arguments
401 .endif
402 ldrcc pc, [\table, \nr, lsl #2] @ call sys_* routine
403#endif
404 .endm
405
381/* 406/*
382 * These are the registers used in the syscall handler, and allow us to 407 * These are the registers used in the syscall handler, and allow us to
383 * have in theory up to 7 arguments to a function - r0 to r6. 408 * have in theory up to 7 arguments to a function - r0 to r6.