From 348f5a4627eebc4f10415cd5a63500cd00af495b Mon Sep 17 00:00:00 2001
From: Tim Chen <tim.c.chen@linux.intel.com>
Date: Tue, 14 Nov 2017 17:16:30 -0800
Subject: [PATCH 116/131] UBUNTU: SAUCE: x86/entry: Stuff RSB for entry to
 kernel for non-SMEP platform

CVE-2017-5715 (Spectre v2 Intel)

Stuff RSB to prevent RSB underflow on non-SMEP platform.

Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>

(backported (medium risk))
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
Signed-off-by: Andy Whitcroft <apw@canonical.com>
---
 arch/x86/ia32/ia32entry.S        |  3 ++
 arch/x86/include/asm/spec_ctrl.h | 71 ++++++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/entry_64.S       |  8 +++++
 3 files changed, 82 insertions(+)

diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index bcc4a027401d..5cbe05b87adf 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -126,6 +126,7 @@ ENTRY(ia32_sysenter_target)
 	SWAPGS_UNSAFE_STACK
 	SWITCH_KERNEL_CR3_NO_STACK
 	ENABLE_IBRS
+	STUFF_RSB
 	movq	PER_CPU_VAR(kernel_stack), %rsp
 	addq	$(KERNEL_STACK_OFFSET),%rsp
 	/*
@@ -305,6 +306,7 @@ ENTRY(ia32_cstar_target)
 	SWAPGS_UNSAFE_STACK
 	SWITCH_KERNEL_CR3_NO_STACK
 	ENABLE_IBRS
+	STUFF_RSB
 	movl	%esp,%r8d
 	CFI_REGISTER	rsp,r8
 	movq	PER_CPU_VAR(kernel_stack),%rsp
@@ -437,6 +439,7 @@ ENTRY(ia32_syscall)
 	SWAPGS
 	SWITCH_KERNEL_CR3_NO_STACK
 	ENABLE_IBRS
+	STUFF_RSB
 	/*
 	 * No need to follow this irqs on/off section: the syscall
 	 * disabled irqs and here we enable it straight after entry:
diff --git a/arch/x86/include/asm/spec_ctrl.h b/arch/x86/include/asm/spec_ctrl.h
index e791f6d949ba..10f5b3b55d8d 100644
--- a/arch/x86/include/asm/spec_ctrl.h
+++ b/arch/x86/include/asm/spec_ctrl.h
@@ -35,6 +35,73 @@
 	popq %rdx;				\
 	popq %rcx;				\
 	popq %rax
+#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
@@ -48,5 +115,9 @@ ALTERNATIVE "", __stringify(__ASM_ENABLE_IBRS_CLOBBER), X86_FEATURE_SPEC_CTRL
 ALTERNATIVE "", __stringify(__ASM_DISABLE_IBRS), 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 44f423552bf9..05785e06f721 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -504,6 +504,8 @@ ENDPROC(native_usergs_sysret64)
 	/* Save previous stack value */
 	movq %rsp, %rsi
 
+	STUFF_RSB
+
 	leaq -RBP(%rsp),%rdi	/* arg1 for handler */
 	testl $3, CS-RBP(%rsi)
 	je 1f
@@ -557,6 +559,10 @@ ENTRY(save_paranoid)
 	movq_cfi r13, R13+8
 	movq_cfi r14, R14+8
 	movq_cfi r15, R15+8
+	/*
+	 * Do the stuffing unconditionally from user/kernel to be safe
+	 */
+	STUFF_RSB
 	movl $1,%ebx
 	movl $MSR_GS_BASE,%ecx
 	rdmsr
@@ -690,6 +696,7 @@ GLOBAL(system_call_after_swapgs)
 	CFI_REL_OFFSET rip,RIP-ARGOFFSET
 
 	ENABLE_IBRS	/* Hoping Xen calls in with right CR3 */
+	STUFF_RSB
 
 	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
 	jnz tracesys
@@ -1721,6 +1728,7 @@ ENTRY(error_entry)
 	movq_cfi r13, R13+8
 	movq_cfi r14, R14+8
 	movq_cfi r15, R15+8
+	STUFF_RSB
 	/*
 	 * error_entry() always returns with a kernel gsbase and
 	 * CR3.  We must also have a kernel CR3/gsbase before
-- 
2.15.1

