From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tim Chen <tim.c.chen@linux.intel.com>
Date: Tue, 19 Sep 2017 15:21:40 -0700
Subject: [PATCH] x86/syscall: Clear unused extra registers on syscall entrance
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

CVE-2017-5753
CVE-2017-5715

To prevent the unused registers %r12-%r15, %rbp and %rbx from
being used speculatively, we clear them upon syscall entrance
for code hygiene.

Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Andy Whitcroft <apw@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
(cherry picked from commit 7b5ea16f42b5e4860cf9033897bcdfa3e1209033)
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
---
 arch/x86/entry/calling.h  |  9 +++++++++
 arch/x86/entry/entry_64.S | 12 ++++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index 015e0a84bb99..d537818ad285 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -155,6 +155,15 @@ For 32-bit we have the following conventions - kernel is built with
 	popq %rbx
 	.endm
 
+	.macro CLEAR_EXTRA_REGS
+	xorq %r15, %r15
+	xorq %r14, %r14
+	xorq %r13, %r13
+	xorq %r12, %r12
+	xorq %rbp, %rbp
+	xorq %rbx, %rbx
+	.endm
+
 	.macro POP_C_REGS
 	popq %r11
 	popq %r10
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index f6ec4ad5b114..1118a6256c69 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -231,10 +231,16 @@ GLOBAL(entry_SYSCALL_64_after_hwframe)
 	pushq	%r9				/* pt_regs->r9 */
 	pushq	%r10				/* pt_regs->r10 */
 	pushq	%r11				/* pt_regs->r11 */
-	sub	$(6*8), %rsp			/* pt_regs->bp, bx, r12-15 not saved */
+	sub	$(6*8), %rsp			/* pt_regs->bp, bx, r12-15 not used */
 	UNWIND_HINT_REGS extra=0
 
 	ENABLE_IBRS
+	/*
+	 * Clear the unused extra regs for code hygiene.
+	 * Will restore the callee saved extra regs at end of syscall.
+	 */
+	SAVE_EXTRA_REGS
+	CLEAR_EXTRA_REGS
 
 	STUFF_RSB
 
@@ -292,7 +298,7 @@ entry_SYSCALL_64_fastpath:
 	movq	RIP(%rsp), %rcx
 	movq	EFLAGS(%rsp), %r11
 	DISABLE_IBRS
-	addq	$6*8, %rsp	/* skip extra regs -- they were preserved */
+	POP_EXTRA_REGS
 	UNWIND_HINT_EMPTY
 	jmp	.Lpop_c_regs_except_rcx_r11_and_sysret
 
@@ -304,14 +310,12 @@ entry_SYSCALL_64_fastpath:
 	 */
 	TRACE_IRQS_ON
 	ENABLE_INTERRUPTS(CLBR_ANY)
-	SAVE_EXTRA_REGS
 	movq	%rsp, %rdi
 	call	syscall_return_slowpath	/* returns with IRQs disabled */
 	jmp	return_from_SYSCALL_64
 
 entry_SYSCALL64_slow_path:
 	/* IRQs are off. */
-	SAVE_EXTRA_REGS
 	movq	%rsp, %rdi
 	call	do_syscall_64		/* returns with IRQs disabled */
 
-- 
2.14.2

