Re: [PATCH v12 8/8] x86: Disallow vsyscall emulation when CET is enabled
From: Sean Christopherson <hidden>
Date: 2020-09-23 21:29:29
Also in:
linux-arch, linux-doc, linux-mm, lkml
On Mon, Sep 21, 2020 at 04:48:25PM -0700, Andy Lutomirski wrote:
On Mon, Sep 21, 2020 at 3:37 PM Yu-cheng Yu [off-list ref] wrote:quoted
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.cb/arch/x86/entry/vsyscall/vsyscall_64.c index 44c33103a955..0131c9f7f9c5 100644--- a/arch/x86/entry/vsyscall/vsyscall_64.c +++ b/arch/x86/entry/vsyscall/vsyscall_64.c@@ -38,6 +38,9 @@ #include <asm/fixmap.h> #include <asm/traps.h> #include <asm/paravirt.h> +#include <asm/fpu/xstate.h> +#include <asm/fpu/types.h> +#include <asm/fpu/internal.h> #define CREATE_TRACE_POINTS #include "vsyscall_trace.h"@@ -286,6 +289,32 @@ bool emulate_vsyscall(unsigned long error_code, /* Emulate a ret instruction. */ regs->ip = caller; regs->sp += 8; + + if (current->thread.cet.shstk_size || + current->thread.cet.ibt_enabled) { + u64 r; + + fpregs_lock(); + if (test_thread_flag(TIF_NEED_FPU_LOAD)) + __fpregs_load_activate();Wouldn't this be nicer if you operated on the memory image, not the registers?quoted
+ +#ifdef CONFIG_X86_INTEL_BRANCH_TRACKING_USER + /* Fixup branch tracking */ + if (current->thread.cet.ibt_enabled) { + rdmsrl(MSR_IA32_U_CET, r); + wrmsrl(MSR_IA32_U_CET, r & ~CET_WAIT_ENDBR); + } +#endifSeems reasonable on first glance.quoted
+ +#ifdef CONFIG_X86_INTEL_SHADOW_STACK_USER + /* Unwind shadow stack. */ + if (current->thread.cet.shstk_size) { + rdmsrl(MSR_IA32_PL3_SSP, r); + wrmsrl(MSR_IA32_PL3_SSP, r + 8); + } +#endifWhat happens if the result is noncanonical? A quick skim of the SDM didn't find anything. This latter issue goes away if you operate on the memory image, though -- writing a bogus value is just fine, since the FP restore will handle it.
#GP, the SSP MSRs do canonical checks.