From 589c20c50d8a1c83184accbce79ea075921bb13d Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 4 Jan 2018 10:31:05 -0500 Subject: [PATCH] x86/entry: Stuff RSB for entry to kernel for non-SMEP platform Stuff RSB to prevent RSB underflow on non-SMEP platform. Orabug: 27344012 CVE: CVE-2017-5715 Signed-off-by: Tim Chen Signed-off-by: Konrad Rzeszutek Wilk Reviewed-by: John Haxby Signed-off-by: Kirtikar Kashyap --- arch/x86/ia32/ia32entry.S | 2 + arch/x86/include/asm/spec_ctrl.h | 72 ++++++++++++++++++++++++++++++++ arch/x86/kernel/entry_64.S | 20 +++++++++ 3 files changed, 94 insertions(+) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 961ae5a05599..520c442bd248 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -149,6 +149,7 @@ ENTRY(ia32_sysenter_target) CFI_ADJUST_CFA_OFFSET 10*8 ENABLE_IBRS + STUFF_RSB /* * no need to do an access_ok check here because rbp has been @@ -533,6 +534,7 @@ ENTRY(ia32_syscall) CFI_ADJUST_CFA_OFFSET 10*8 ENABLE_IBRS + STUFF_RSB orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS) testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS) diff --git a/arch/x86/include/asm/spec_ctrl.h b/arch/x86/include/asm/spec_ctrl.h index 712f12deea32..9bf0e8e99642 100644 --- a/arch/x86/include/asm/spec_ctrl.h +++ b/arch/x86/include/asm/spec_ctrl.h @@ -54,6 +54,74 @@ movl $0, %eax; \ wrmsr; +#define __ASM_STUFF_RSB \ + call 1f; \ + pause; \ +1: call 2f; \ + pause; \ +2: call 3f; \ + pause; \ +3: call 4f; \ + pause; \ +4: call 5f; \ + pause; \ +5: call 6f; \ + pause; \ +6: call 7f; \ + pause; \ +7: call 8f; \ + pause; \ +8: call 9f; \ + pause; \ +9: call 10f; \ + pause; \ +10: call 11f; \ + pause; \ +11: call 12f; \ + pause; \ +12: call 13f; \ + pause; \ +13: call 14f; \ + pause; \ +14: call 15f; \ + pause; \ +15: call 16f; \ + pause; \ +16: call 17f; \ + pause; \ +17: call 18f; \ + pause; \ +18: call 19f; \ + pause; \ +19: call 20f; \ + pause; \ +20: call 21f; \ + pause; \ +21: call 22f; \ + pause; \ +22: call 23f; \ + pause; \ +23: call 24f; \ + pause; \ +24: call 25f; \ + pause; \ +25: call 26f; \ + pause; \ +26: call 27f; \ + pause; \ +27: call 28f; \ + pause; \ +28: call 29f; \ + pause; \ +29: call 30f; \ + pause; \ +30: call 31f; \ + pause; \ +31: call 32f; \ + pause; \ +32: \ + add $(32*8), %rsp; + .macro ENABLE_IBRS ALTERNATIVE "", __stringify(__ASM_ENABLE_IBRS), X86_FEATURE_SPEC_CTRL .endm @@ -111,5 +179,9 @@ ALTERNATIVE "", __stringify(__ASM_SET_IBPB), X86_FEATURE_SPEC_CTRL ALTERNATIVE "", __stringify(__ASM_DISABLE_IBRS_CLOBBER), X86_FEATURE_SPEC_CTRL .endm +.macro STUFF_RSB +ALTERNATIVE __stringify(__ASM_STUFF_RSB), "", X86_FEATURE_SMEP +.endm + #endif /* __ASSEMBLY__ */ #endif /* _ASM_X86_SPEC_CTRL_H */ diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 157c53c82031..15fef9cdbade 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -250,6 +250,10 @@ GLOBAL(system_call_after_swapgs) sub $(6*8),%rsp /* pt_regs->bp,bx,r12-15 not saved */ CFI_ADJUST_CFA_OFFSET 6*8 + STUFF_RSB + + TRACE_IRQS_OFF + testl $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS) jnz tracesys system_call_fastpath: @@ -689,6 +693,13 @@ END(irq_entries_start) /* this goes to 0(%rsp) for unwinder, not for saving the value: */ SAVE_EXTRA_REGS_RBP -RBP + /* + * Have to do stuffing before encoding frame pointer. + * Could add some unnecessary RSB clearing if coming + * from kernel for non-SMEP platform. + */ + STUFF_RSB + leaq -RBP(%rsp),%rdi /* arg1 for \func (pointer to pt_regs) */ testl $3, CS-RBP(%rsp) @@ -1430,6 +1441,14 @@ ENTRY(paranoid_entry) cld SAVE_C_REGS 8 SAVE_EXTRA_REGS 8 + + /* + * Have to do stuffing before encoding frame pointer. + * Could add some unnecessary RSB clearing if coming + * from kernel for non-SMEP platform. + */ + STUFF_RSB + movl $1,%ebx movl $MSR_GS_BASE,%ecx rdmsr @@ -1482,6 +1501,7 @@ ENTRY(error_entry) cld SAVE_C_REGS 8 SAVE_EXTRA_REGS 8 + STUFF_RSB xorl %ebx,%ebx testl $3,CS+8(%rsp) je error_kernelspace -- 2.50.1