* [PATCH 0/3] Initial Spectre variant 1 patches
@ 2018-05-31 13:30 Russell King - ARM Linux
2018-05-31 13:31 ` [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros Russell King
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Russell King - ARM Linux @ 2018-05-31 13:30 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This series adds initial support for the Spectre variant 1 workarounds
to the kernel. This does _not_ cover the user accessors, which are
still in development.
The series adds support for the array_index_mask_nospec() macro, used
by generic kernel code to mask out of bounds pointers, and also adds
the syscall table hardening.
arch/arm/include/asm/assembler.h | 8 ++++++++
arch/arm/include/asm/barrier.h | 31 +++++++++++++++++++++++++++++++
arch/arm/kernel/entry-common.S | 14 +++-----------
arch/arm/kernel/entry-header.S | 25 +++++++++++++++++++++++++
4 files changed, 67 insertions(+), 11 deletions(-)
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros
2018-05-31 13:30 [PATCH 0/3] Initial Spectre variant 1 patches Russell King - ARM Linux
@ 2018-05-31 13:31 ` Russell King
2018-05-31 14:17 ` Mark Rutland
2018-05-31 13:31 ` [PATCH 2/3] ARM: spectre-v1: add array_index_mask_nospec() implementation Russell King
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Russell King @ 2018-05-31 13:31 UTC (permalink / raw)
To: linux-arm-kernel
Add assembly and C macros for the new CSDB instruction.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
arch/arm/include/asm/assembler.h | 8 ++++++++
arch/arm/include/asm/barrier.h | 13 +++++++++++++
2 files changed, 21 insertions(+)
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index bc8d4bbd82e2..ef1386b1af9b 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -447,6 +447,14 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
.size \name , . - \name
.endm
+ .macro csdb
+#ifdef CONFIG_THUMB2_KERNEL
+ .inst.w 0xf3af8014
+#else
+ .inst 0xe320f014
+#endif
+ .endm
+
.macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req
#ifndef CONFIG_CPU_USE_DOMAINS
adds \tmp, \addr, #\size - 1
diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
index 40f5c410fd8c..3d9c1d4b7e75 100644
--- a/arch/arm/include/asm/barrier.h
+++ b/arch/arm/include/asm/barrier.h
@@ -17,6 +17,12 @@
#define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory")
#define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory")
#define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
+#ifdef CONFIG_THUMB2_KERNEL
+#define CSDB ".inst.w 0xf3af8014"
+#else
+#define CSDB ".inst 0xe320f014"
+#endif
+#define csdb() __asm__ __volatile__(CSDB : : : "memory")
#elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6
#define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
: : "r" (0) : "memory")
@@ -37,6 +43,13 @@
#define dmb(x) __asm__ __volatile__ ("" : : : "memory")
#endif
+#ifndef CSDB
+#define CSDB
+#endif
+#ifndef csdb
+#define csdb()
+#endif
+
#ifdef CONFIG_ARM_HEAVY_MB
extern void (*soc_mb)(void);
extern void arm_heavy_mb(void);
--
2.7.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/3] ARM: spectre-v1: add array_index_mask_nospec() implementation
2018-05-31 13:30 [PATCH 0/3] Initial Spectre variant 1 patches Russell King - ARM Linux
2018-05-31 13:31 ` [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros Russell King
@ 2018-05-31 13:31 ` Russell King
2018-05-31 14:22 ` Mark Rutland
2018-05-31 13:31 ` [PATCH 3/3] ARM: spectre-v1: fix syscall entry Russell King
2018-05-31 18:04 ` [PATCH 0/3] Initial Spectre variant 1 patches Tony Lindgren
3 siblings, 1 reply; 10+ messages in thread
From: Russell King @ 2018-05-31 13:31 UTC (permalink / raw)
To: linux-arm-kernel
Add an implementation of the array_index_mask_nospec() function for
mitigating Spectre variant 1 throughout the kernel.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
arch/arm/include/asm/barrier.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
index 3d9c1d4b7e75..a89adcf53b99 100644
--- a/arch/arm/include/asm/barrier.h
+++ b/arch/arm/include/asm/barrier.h
@@ -76,6 +76,24 @@ extern void arm_heavy_mb(void);
#define __smp_rmb() __smp_mb()
#define __smp_wmb() dmb(ishst)
+#ifdef CONFIG_CPU_SPECTRE
+static inline unsigned long array_index_mask_nospec(unsigned long idx,
+ unsigned long sz)
+{
+ unsigned long mask;
+
+ asm( "cmp %1, %2\n"
+ " sbc %0, %1, %1\n"
+ CSDB
+ : "=r" (mask)
+ : "r" (idx), "Ir" (sz)
+ : "cc");
+
+ return mask;
+}
+#define array_index_mask_nospec array_index_mask_nospec
+#endif
+
#include <asm-generic/barrier.h>
#endif /* !__ASSEMBLY__ */
--
2.7.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] ARM: spectre-v1: fix syscall entry
2018-05-31 13:30 [PATCH 0/3] Initial Spectre variant 1 patches Russell King - ARM Linux
2018-05-31 13:31 ` [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros Russell King
2018-05-31 13:31 ` [PATCH 2/3] ARM: spectre-v1: add array_index_mask_nospec() implementation Russell King
@ 2018-05-31 13:31 ` Russell King
2018-05-31 15:55 ` Mark Rutland
2018-05-31 18:04 ` [PATCH 0/3] Initial Spectre variant 1 patches Tony Lindgren
3 siblings, 1 reply; 10+ messages in thread
From: Russell King @ 2018-05-31 13:31 UTC (permalink / raw)
To: linux-arm-kernel
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>
---
arch/arm/kernel/entry-common.S | 14 +++-----------
| 25 +++++++++++++++++++++++++
2 files changed, 28 insertions(+), 11 deletions(-)
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 3c4f88701f22..78b9f20dd6a3 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -242,9 +242,7 @@ ENTRY(vector_swi)
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 @@ ENDPROC(vector_swi)
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
--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 @@
#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.
--
2.7.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros
2018-05-31 13:31 ` [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros Russell King
@ 2018-05-31 14:17 ` Mark Rutland
0 siblings, 0 replies; 10+ messages in thread
From: Mark Rutland @ 2018-05-31 14:17 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, May 31, 2018 at 02:31:12PM +0100, Russell King wrote:
> Add assembly and C macros for the new CSDB instruction.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Looks correct to me per the Cache Speculation Side-chaneels 2.1
document.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Mark.
> ---
> arch/arm/include/asm/assembler.h | 8 ++++++++
> arch/arm/include/asm/barrier.h | 13 +++++++++++++
> 2 files changed, 21 insertions(+)
>
> diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
> index bc8d4bbd82e2..ef1386b1af9b 100644
> --- a/arch/arm/include/asm/assembler.h
> +++ b/arch/arm/include/asm/assembler.h
> @@ -447,6 +447,14 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
> .size \name , . - \name
> .endm
>
> + .macro csdb
> +#ifdef CONFIG_THUMB2_KERNEL
> + .inst.w 0xf3af8014
> +#else
> + .inst 0xe320f014
> +#endif
> + .endm
> +
> .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req
> #ifndef CONFIG_CPU_USE_DOMAINS
> adds \tmp, \addr, #\size - 1
> diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
> index 40f5c410fd8c..3d9c1d4b7e75 100644
> --- a/arch/arm/include/asm/barrier.h
> +++ b/arch/arm/include/asm/barrier.h
> @@ -17,6 +17,12 @@
> #define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory")
> #define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory")
> #define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
> +#ifdef CONFIG_THUMB2_KERNEL
> +#define CSDB ".inst.w 0xf3af8014"
> +#else
> +#define CSDB ".inst 0xe320f014"
> +#endif
> +#define csdb() __asm__ __volatile__(CSDB : : : "memory")
> #elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6
> #define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
> : : "r" (0) : "memory")
> @@ -37,6 +43,13 @@
> #define dmb(x) __asm__ __volatile__ ("" : : : "memory")
> #endif
>
> +#ifndef CSDB
> +#define CSDB
> +#endif
> +#ifndef csdb
> +#define csdb()
> +#endif
> +
> #ifdef CONFIG_ARM_HEAVY_MB
> extern void (*soc_mb)(void);
> extern void arm_heavy_mb(void);
> --
> 2.7.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/3] ARM: spectre-v1: add array_index_mask_nospec() implementation
2018-05-31 13:31 ` [PATCH 2/3] ARM: spectre-v1: add array_index_mask_nospec() implementation Russell King
@ 2018-05-31 14:22 ` Mark Rutland
0 siblings, 0 replies; 10+ messages in thread
From: Mark Rutland @ 2018-05-31 14:22 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, May 31, 2018 at 02:31:17PM +0100, Russell King wrote:
> Add an implementation of the array_index_mask_nospec() function for
> mitigating Spectre variant 1 throughout the kernel.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
> arch/arm/include/asm/barrier.h | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
> index 3d9c1d4b7e75..a89adcf53b99 100644
> --- a/arch/arm/include/asm/barrier.h
> +++ b/arch/arm/include/asm/barrier.h
> @@ -76,6 +76,24 @@ extern void arm_heavy_mb(void);
> #define __smp_rmb() __smp_mb()
> #define __smp_wmb() dmb(ishst)
>
> +#ifdef CONFIG_CPU_SPECTRE
> +static inline unsigned long array_index_mask_nospec(unsigned long idx,
> + unsigned long sz)
> +{
> + unsigned long mask;
> +
> + asm( "cmp %1, %2\n"
> + " sbc %0, %1, %1\n"
> + CSDB
> + : "=r" (mask)
> + : "r" (idx), "Ir" (sz)
> + : "cc");
> +
> + return mask;
> +}
> +#define array_index_mask_nospec array_index_mask_nospec
> +#endif
I believe that the asm should be volatile, otherwise there are cases
where the compiler could remove an invocation that's redundant under
architectural execution, but required under speculation [1].
With that made volatile:
Acked-by: Mark Rutland <mark.rutland@arm.com>
Thanks,
Mark.
[1] https://lkml.kernel.org/r/20180530060546.jnjoltsturoduohh at salmiak
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/3] ARM: spectre-v1: fix syscall entry
2018-05-31 13:31 ` [PATCH 3/3] ARM: spectre-v1: fix syscall entry Russell King
@ 2018-05-31 15:55 ` Mark Rutland
2018-05-31 16:06 ` [PATCH v2 " Russell King
0 siblings, 1 reply; 10+ messages in thread
From: Mark Rutland @ 2018-05-31 15:55 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, May 31, 2018 at 02:31:23PM +0100, Russell King wrote:
> 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>
> ---
> arch/arm/kernel/entry-common.S | 14 +++-----------
> arch/arm/kernel/entry-header.S | 25 +++++++++++++++++++++++++
> 2 files changed, 28 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
> index 3c4f88701f22..78b9f20dd6a3 100644
> --- a/arch/arm/kernel/entry-common.S
> +++ b/arch/arm/kernel/entry-common.S
> @@ -242,9 +242,7 @@ ENTRY(vector_swi)
> 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 @@ ENDPROC(vector_swi)
> 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
I *think* you might also need to adjust sys_syscall.
> 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 @@
> #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
To the best of my understanding, this sequence is sufficient.
> + 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
I couldn't find a nice way to avoid dupliacting the body without more
ifdeffery, given the nr parameter can't be clobbered.
So modulo sys_syscall, this looks good to me.
Mark.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 3/3] ARM: spectre-v1: fix syscall entry
2018-05-31 15:55 ` Mark Rutland
@ 2018-05-31 16:06 ` Russell King
2018-05-31 16:08 ` Mark Rutland
0 siblings, 1 reply; 10+ messages in thread
From: Russell King @ 2018-05-31 16:06 UTC (permalink / raw)
To: linux-arm-kernel
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>
---
arch/arm/kernel/entry-common.S | 18 +++++++-----------
| 25 +++++++++++++++++++++++++
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 @@ ENTRY(vector_swi)
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 @@ ENDPROC(vector_swi)
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 @@ ENTRY(\sym)
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
--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 @@
#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.
--
2.7.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 3/3] ARM: spectre-v1: fix syscall entry
2018-05-31 16:06 ` [PATCH v2 " Russell King
@ 2018-05-31 16:08 ` Mark Rutland
0 siblings, 0 replies; 10+ messages in thread
From: Mark Rutland @ 2018-05-31 16:08 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, May 31, 2018 at 05:06:32PM +0100, Russell King wrote:
> 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>
Mark.
> ---
> arch/arm/kernel/entry-common.S | 18 +++++++-----------
> arch/arm/kernel/entry-header.S | 25 +++++++++++++++++++++++++
> 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 @@ ENTRY(vector_swi)
> 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 @@ ENDPROC(vector_swi)
> 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 @@ ENTRY(\sym)
> 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
> 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 @@
> #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.
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 0/3] Initial Spectre variant 1 patches
2018-05-31 13:30 [PATCH 0/3] Initial Spectre variant 1 patches Russell King - ARM Linux
` (2 preceding siblings ...)
2018-05-31 13:31 ` [PATCH 3/3] ARM: spectre-v1: fix syscall entry Russell King
@ 2018-05-31 18:04 ` Tony Lindgren
3 siblings, 0 replies; 10+ messages in thread
From: Tony Lindgren @ 2018-05-31 18:04 UTC (permalink / raw)
To: linux-arm-kernel
* Russell King - ARM Linux <linux@armlinux.org.uk> [180531 13:34]:
> Hi,
>
> This series adds initial support for the Spectre variant 1 workarounds
> to the kernel. This does _not_ cover the user accessors, which are
> still in development.
>
> The series adds support for the array_index_mask_nospec() macro, used
> by generic kernel code to mask out of bounds pointers, and also adds
> the syscall table hardening.
For the series including v2 patch of 3/3:
Boot-tested-by: Tony Lindgren <tony@atomide.com>
Reviewed-by: Tony Lindgren <tony@atomide.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2018-05-31 18:04 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-31 13:30 [PATCH 0/3] Initial Spectre variant 1 patches Russell King - ARM Linux
2018-05-31 13:31 ` [PATCH 1/3] ARM: spectre-v1: add speculation barrier (csdb) macros Russell King
2018-05-31 14:17 ` Mark Rutland
2018-05-31 13:31 ` [PATCH 2/3] ARM: spectre-v1: add array_index_mask_nospec() implementation Russell King
2018-05-31 14:22 ` Mark Rutland
2018-05-31 13:31 ` [PATCH 3/3] ARM: spectre-v1: fix syscall entry Russell King
2018-05-31 15:55 ` Mark Rutland
2018-05-31 16:06 ` [PATCH v2 " Russell King
2018-05-31 16:08 ` Mark Rutland
2018-05-31 18:04 ` [PATCH 0/3] Initial Spectre variant 1 patches Tony Lindgren
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.