arch: x86: Use retpolines in core assembly routines
In order to mitigate Spectre variant 2 (branch target injection), use retpolines for indirect jumps and calls. The newly-added hidden CONFIG_X86_NO_SPECTRE flag, which is disabled by default, must be set by a x86 SoC if its CPU performs speculative execution. Most targets supported by Zephyr do not, so this is set to "y" by default. A new setting, CONFIG_RETPOLINE, has been added to the "Security Options" sections, and that will be enabled by default if CONFIG_X86_NO_SPECTRE is disabled. Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
This commit is contained in:
parent
8a4b2e8cf2
commit
16472cafcf
7 changed files with 75 additions and 4 deletions
|
@ -89,6 +89,13 @@ config X86_NO_MELTDOWN
|
||||||
help
|
help
|
||||||
This hidden option should be set on a per-SOC basis to indicate that
|
This hidden option should be set on a per-SOC basis to indicate that
|
||||||
a particular SOC is not vulnerable to the Meltdown CPU vulnerability.
|
a particular SOC is not vulnerable to the Meltdown CPU vulnerability.
|
||||||
|
|
||||||
|
config X86_NO_SPECTRE
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
This hidden option should be set on a per-SOC basis to indicate that
|
||||||
|
a particular SOC is not vulnerable to the Spectre V2 CPU vulnerability.
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
config X86_ENABLE_TSS
|
config X86_ENABLE_TSS
|
||||||
|
|
|
@ -151,7 +151,7 @@ allDone:
|
||||||
#else
|
#else
|
||||||
pushl %esp /* push NANO_ESF * parameter */
|
pushl %esp /* push NANO_ESF * parameter */
|
||||||
#endif
|
#endif
|
||||||
call *%ecx /* call exception handler */
|
INDIRECT_CALL(%ecx) /* call exception handler */
|
||||||
|
|
||||||
#ifndef CONFIG_X86_IAMCU
|
#ifndef CONFIG_X86_IAMCU
|
||||||
addl $0x4, %esp
|
addl $0x4, %esp
|
||||||
|
|
|
@ -230,7 +230,7 @@ alreadyOnIntStack:
|
||||||
sti /* re-enable interrupts */
|
sti /* re-enable interrupts */
|
||||||
#endif
|
#endif
|
||||||
/* Now call the interrupt handler */
|
/* Now call the interrupt handler */
|
||||||
call *%edx
|
INDIRECT_CALL(%edx)
|
||||||
#ifndef CONFIG_X86_IAMCU
|
#ifndef CONFIG_X86_IAMCU
|
||||||
/* Discard ISR argument */
|
/* Discard ISR argument */
|
||||||
addl $0x4, %esp
|
addl $0x4, %esp
|
||||||
|
|
|
@ -466,5 +466,5 @@ SECTION_FUNC(TEXT, _x86_thread_entry_wrapper)
|
||||||
push $0 /* Null return address */
|
push $0 /* Null return address */
|
||||||
#endif
|
#endif
|
||||||
movl $0, (%esp)
|
movl $0, (%esp)
|
||||||
jmp *%edi
|
INDIRECT_JMP(%edi)
|
||||||
#endif /* _THREAD_WRAPPER_REQUIRED */
|
#endif /* _THREAD_WRAPPER_REQUIRED */
|
||||||
|
|
|
@ -51,7 +51,7 @@ _id_ok:
|
||||||
mov _k_syscall_table(%edi, %esi, 4), %ebx
|
mov _k_syscall_table(%edi, %esi, 4), %ebx
|
||||||
|
|
||||||
/* Run the handler, which is some entry in _k_syscall_table */
|
/* Run the handler, which is some entry in _k_syscall_table */
|
||||||
call *%ebx
|
INDIRECT_CALL(%ebx)
|
||||||
|
|
||||||
/* EAX now contains return value. Pop or xor everything else to prevent
|
/* EAX now contains return value. Pop or xor everything else to prevent
|
||||||
* information leak from kernel mode.
|
* information leak from kernel mode.
|
||||||
|
|
|
@ -25,4 +25,55 @@
|
||||||
#define SP_ARG7 28
|
#define SP_ARG7 28
|
||||||
#define SP_ARG8 32
|
#define SP_ARG8 32
|
||||||
|
|
||||||
|
#if defined(_ASMLANGUAGE)
|
||||||
|
|
||||||
|
#if defined(CONFIG_RETPOLINE)
|
||||||
|
/*
|
||||||
|
* For a description of how retpolines are constructed for both indirect
|
||||||
|
* jumps and indirect calls, please refer to this documentation:
|
||||||
|
* https://support.google.com/faqs/answer/7625886
|
||||||
|
*
|
||||||
|
* Since these macros are used in a few places in arch/x86/core assembly
|
||||||
|
* routines, with different reg parameters, it's not possible to use
|
||||||
|
* the "out of line" construction technique to share a trampoline.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define INDIRECT_JMP_IMPL(reg, id) \
|
||||||
|
call .set_up_target ## id; \
|
||||||
|
.speculative_trap ## id: \
|
||||||
|
pause; \
|
||||||
|
jmp .speculative_trap ## id; \
|
||||||
|
.set_up_target ## id: \
|
||||||
|
mov reg, (%esp); \
|
||||||
|
ret
|
||||||
|
|
||||||
|
#define INDIRECT_CALL_IMPL(reg, id) \
|
||||||
|
call .set_up_return ## id; \
|
||||||
|
.inner_indirect_branch ## id: \
|
||||||
|
call .set_up_target ## id; \
|
||||||
|
.speculative_trap ## id: \
|
||||||
|
pause; \
|
||||||
|
jmp .speculative_trap ## id; \
|
||||||
|
.set_up_target ## id: \
|
||||||
|
mov reg, (%esp); \
|
||||||
|
ret; \
|
||||||
|
.set_up_return ## id: \
|
||||||
|
call .inner_indirect_branch ## id
|
||||||
|
|
||||||
|
|
||||||
|
#define INDIRECT_CALL_IMPL1(reg, id) INDIRECT_CALL_IMPL(reg, id)
|
||||||
|
#define INDIRECT_JMP_IMPL1(reg, id) INDIRECT_JMP_IMPL(reg, id)
|
||||||
|
|
||||||
|
#define INDIRECT_CALL(reg) INDIRECT_CALL_IMPL1(reg, __COUNTER__)
|
||||||
|
#define INDIRECT_JMP(reg) INDIRECT_JMP_IMPL1(reg, __COUNTER__)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define INDIRECT_CALL(reg) call *reg
|
||||||
|
#define INDIRECT_JMP(reg) jmp *reg
|
||||||
|
|
||||||
|
#endif /* CONFIG_RETPOLINE */
|
||||||
|
|
||||||
|
#endif /* _ASMLANGUAGE */
|
||||||
|
|
||||||
#endif /* __INCsysX86Asmh */
|
#endif /* __INCsysX86Asmh */
|
||||||
|
|
|
@ -491,6 +491,19 @@ endmenu
|
||||||
|
|
||||||
menu "Security Options"
|
menu "Security Options"
|
||||||
|
|
||||||
|
config RETPOLINE
|
||||||
|
bool
|
||||||
|
prompt "Build with retpolines enabled"
|
||||||
|
default y if !X86_NO_SPECTRE
|
||||||
|
help
|
||||||
|
This is recommended on platforms with speculative exeuctions, to protect
|
||||||
|
against branch target injection (AKA Spectre-V2). Full description of
|
||||||
|
how retpolines work can be found here[1].
|
||||||
|
|
||||||
|
Currently only the x86 port
|
||||||
|
|
||||||
|
[1] https://support.google.com/faqs/answer/7625886
|
||||||
|
|
||||||
config STACK_CANARIES
|
config STACK_CANARIES
|
||||||
bool
|
bool
|
||||||
prompt "Compiler stack canaries"
|
prompt "Compiler stack canaries"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue