diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 1963f59daf9..02a475acf20 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -89,6 +89,13 @@ config X86_NO_MELTDOWN help 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. + +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 config X86_ENABLE_TSS diff --git a/arch/x86/core/excstub.S b/arch/x86/core/excstub.S index b77d1bf16de..3870f69f50a 100644 --- a/arch/x86/core/excstub.S +++ b/arch/x86/core/excstub.S @@ -151,7 +151,7 @@ allDone: #else pushl %esp /* push NANO_ESF * parameter */ #endif - call *%ecx /* call exception handler */ + INDIRECT_CALL(%ecx) /* call exception handler */ #ifndef CONFIG_X86_IAMCU addl $0x4, %esp diff --git a/arch/x86/core/intstub.S b/arch/x86/core/intstub.S index 644ebecf73a..151b090da13 100644 --- a/arch/x86/core/intstub.S +++ b/arch/x86/core/intstub.S @@ -230,7 +230,7 @@ alreadyOnIntStack: sti /* re-enable interrupts */ #endif /* Now call the interrupt handler */ - call *%edx + INDIRECT_CALL(%edx) #ifndef CONFIG_X86_IAMCU /* Discard ISR argument */ addl $0x4, %esp diff --git a/arch/x86/core/swap.S b/arch/x86/core/swap.S index c7b8bfb7034..80abcdc4d73 100644 --- a/arch/x86/core/swap.S +++ b/arch/x86/core/swap.S @@ -466,5 +466,5 @@ SECTION_FUNC(TEXT, _x86_thread_entry_wrapper) push $0 /* Null return address */ #endif movl $0, (%esp) - jmp *%edi + INDIRECT_JMP(%edi) #endif /* _THREAD_WRAPPER_REQUIRED */ diff --git a/arch/x86/core/userspace.S b/arch/x86/core/userspace.S index 188441af0c1..cfb9fb13c87 100644 --- a/arch/x86/core/userspace.S +++ b/arch/x86/core/userspace.S @@ -51,7 +51,7 @@ _id_ok: mov _k_syscall_table(%edi, %esi, 4), %ebx /* 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 * information leak from kernel mode. diff --git a/include/arch/x86/asm.h b/include/arch/x86/asm.h index 5d0eb3473c5..ed8c4c6d119 100644 --- a/include/arch/x86/asm.h +++ b/include/arch/x86/asm.h @@ -25,4 +25,55 @@ #define SP_ARG7 28 #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 */ diff --git a/kernel/Kconfig b/kernel/Kconfig index 1a1002de05b..5876df350eb 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -491,6 +491,19 @@ endmenu 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 bool prompt "Compiler stack canaries"