From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tim Chen Date: Fri, 15 Sep 2017 19:41:24 -0700 Subject: [PATCH] x86/syscall: Clear unused extra registers on 32-bit compatible 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 %r8-%r15, from being used speculatively, we clear them upon syscall entrance for code hygiene in 32 bit compatible mode. Signed-off-by: Tim Chen Signed-off-by: Andy Whitcroft Signed-off-by: Kleber Sacilotto de Souza (cherry picked from commit 725ad2ef81ccceb3e31a7263faae2059d05e2c48) Signed-off-by: Fabian Grünbichler --- arch/x86/entry/calling.h | 11 +++++++++++ arch/x86/entry/entry_64_compat.S | 18 ++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h index d537818ad285..0e34002bc801 100644 --- a/arch/x86/entry/calling.h +++ b/arch/x86/entry/calling.h @@ -155,6 +155,17 @@ For 32-bit we have the following conventions - kernel is built with popq %rbx .endm + .macro CLEAR_R8_TO_R15 + xorq %r15, %r15 + xorq %r14, %r14 + xorq %r13, %r13 + xorq %r12, %r12 + xorq %r11, %r11 + xorq %r10, %r10 + xorq %r9, %r9 + xorq %r8, %r8 + .endm + .macro CLEAR_EXTRA_REGS xorq %r15, %r15 xorq %r14, %r14 diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index 1480222bae02..8d7ae9657375 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -99,6 +99,8 @@ ENTRY(entry_SYSENTER_compat) ENABLE_IBRS STUFF_RSB + CLEAR_R8_TO_R15 + /* * SYSENTER doesn't filter flags, so we need to clear NT and AC * ourselves. To save a few cycles, we can check whether @@ -223,10 +225,12 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe) pushq $0 /* pt_regs->r11 = 0 */ pushq %rbx /* pt_regs->rbx */ pushq %rbp /* pt_regs->rbp (will be overwritten) */ - pushq $0 /* pt_regs->r12 = 0 */ - pushq $0 /* pt_regs->r13 = 0 */ - pushq $0 /* pt_regs->r14 = 0 */ - pushq $0 /* pt_regs->r15 = 0 */ + pushq %r12 /* pt_regs->r12 */ + pushq %r13 /* pt_regs->r13 */ + pushq %r14 /* pt_regs->r14 */ + pushq %r15 /* pt_regs->r15 */ + + CLEAR_R8_TO_R15 STUFF_RSB @@ -245,6 +249,10 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe) /* Opportunistic SYSRET */ sysret32_from_system_call: TRACE_IRQS_ON /* User mode traces as IRQs on. */ + movq R15(%rsp), %r15 /* pt_regs->r15 */ + movq R14(%rsp), %r14 /* pt_regs->r14 */ + movq R13(%rsp), %r13 /* pt_regs->r13 */ + movq R12(%rsp), %r12 /* pt_regs->r12 */ movq RBX(%rsp), %rbx /* pt_regs->rbx */ movq RBP(%rsp), %rbp /* pt_regs->rbp */ movq EFLAGS(%rsp), %r11 /* pt_regs->flags (in r11) */ @@ -359,6 +367,8 @@ ENTRY(entry_INT80_compat) ENABLE_IBRS STUFF_RSB + CLEAR_R8_TO_R15 + /* * User mode is traced as though IRQs are on, and the interrupt * gate turned them off. -- 2.14.2