Skip to content

Commit

Permalink
core: arm32: thread: invalidate branch predictor
Browse files Browse the repository at this point in the history
If build with CFG_CORE_WORKAROUND_SPECTRE_BP_SEC=y invalidate branch
predictor on all secure world exceptions.

Fixes CVE-2017-5715

Reviewed-by: Jerome Forissier <[email protected]>
Signed-off-by: Jens Wiklander <[email protected]>
  • Loading branch information
jenswi-linaro committed Jan 9, 2018
1 parent 60f9805 commit e985cb1
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
3 changes: 3 additions & 0 deletions core/arch/arm/arm.mk
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ endif
# See also https://developer.arm.com/-/media/Files/pdf/Cache_Speculation_Side-channels.pdf
# Variant 2
CFG_CORE_WORKAROUND_SPECTRE_BP ?= y
# Same as CFG_CORE_WORKAROUND_SPECTRE_BP but targetting exceptions from
# secure EL0 instead of non-secure world.
CFG_CORE_WORKAROUND_SPECTRE_BP_SEC ?= $(CFG_CORE_WORKAROUND_SPECTRE_BP)

CFG_CORE_RWDATA_NOEXEC ?= y
CFG_CORE_RODATA_NOEXEC ?= n
Expand Down
51 changes: 51 additions & 0 deletions core/arch/arm/kernel/thread_a32.S
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,56 @@ END_FUNC thread_unwind_user_mode
FUNC thread_vect_table , :
UNWIND( .fnstart)
UNWIND( .cantunwind)
#ifdef CFG_CORE_WORKAROUND_SPECTRE_BP_SEC
/*
* This depends on SP being 8 byte aligned, that is, the lowest
* three bits in SP are zero.
*
* To avoid unexpected speculation we need to invalidate the branch
* predictor before we do the first branch. It doesn't matter if
* it's a conditional or an unconditional branch speculation can
* still occur.
*
* The idea is to form a specific bit pattern in the lowest three
* bits of SP depending on which entry in the vector we enter via.
* This is done by adding 1 to SP in each entry but the last.
*/
add sp, sp, #1 /* 7:111 Reset */
add sp, sp, #1 /* 6:110 Undefined instruction */
add sp, sp, #1 /* 5:101 Secure monitor call */
add sp, sp, #1 /* 4:100 Prefetch abort */
add sp, sp, #1 /* 3:011 Data abort */
add sp, sp, #1 /* 2:010 Reserved */
add sp, sp, #1 /* 1:001 IRQ */
nop /* 0:000 FIQ */

/* Invalidate the branch predictor for the current processor. */
write_bpiall
isb

write_tpidrprw r0
and r0, sp, #(BIT(0) | BIT(1) | BIT(2))
bic sp, sp, #(BIT(0) | BIT(1) | BIT(2))
add pc, pc, r0, LSL #3
nop

read_tpidrprw r0
b thread_fiq_handler /* FIQ */
read_tpidrprw r0
b thread_irq_handler /* IRQ */
read_tpidrprw r0
b . /* Reserved */
read_tpidrprw r0
b thread_dabort_handler /* Data abort */
read_tpidrprw r0
b thread_pabort_handler /* Prefetch abort */
read_tpidrprw r0
b thread_svc_handler /* System call */
read_tpidrprw r0
b thread_und_handler /* Undefined instruction */
read_tpidrprw r0
b . /* Reset */
#else
b . /* Reset */
b thread_und_handler /* Undefined instruction */
b thread_svc_handler /* System call */
Expand All @@ -740,6 +790,7 @@ UNWIND( .cantunwind)
b . /* Reserved */
b thread_irq_handler /* IRQ */
b thread_fiq_handler /* FIQ */
#endif

thread_und_handler:
cpsid aif
Expand Down

0 comments on commit e985cb1

Please sign in to comment.