[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20190720112014.GR3402@hirez.programming.kicks-ass.net>
Date: Sat, 20 Jul 2019 13:20:14 +0200
From: Peter Zijlstra <peterz@...radead.org>
To: Thomas Gleixner <tglx@...utronix.de>
Cc: Sean Christopherson <sean.j.christopherson@...el.com>,
Steven Rostedt <rostedt@...dmis.org>,
Eiichi Tsukata <devel@...ukata.com>, edwintorok@...il.com,
Ingo Molnar <mingo@...nel.org>, Borislav Petkov <bp@...en8.de>,
"H. Peter Anvin" <hpa@...or.com>, x86@...nel.org,
LKML <linux-kernel@...r.kernel.org>,
Josh Poimboeuf <jpoimboe@...hat.com>,
Joel Fernandes <joel@...lfernandes.org>,
Andy Lutomirski <luto@...nel.org>,
Dave Hansen <dave.hansen@...ux.intel.com>
Subject: Re: [PATCH] x86/entry/64: Prevent clobbering of saved CR2 value
On Sat, Jul 20, 2019 at 10:56:41AM +0200, Thomas Gleixner wrote:
> The recent fix for CR2 corruption introduced a new way to reliably corrupt
> the saved CR2 value.
>
> CR2 is saved early in the entry code in RDX, which is the third argument to
> the fault handling functions. But it missed that between saving and
> invoking the fault handler enter_from_user_mode() can be called. RDX is a
> caller saved register so the invoked function can freely clobber it with
> the obvious consequences.
>
> The TRACE_IRQS_OFF call is safe as it calls through the thunk which
> preserves RDX.
>
> Store CR2 in R12 instead which is a callee saved register and move R12 to
> RDX just before calling the fault handler.
>
> Fixes: a0d14b8909de ("x86/mm, tracing: Fix CR2 corruption")
> Reported-by: Sean Christopherson <sean.j.christopherson@...el.com>
> Signed-off-by: Thomas Gleixner <tglx@...utronix.de>
D'0h :-( Sorry about that.
Acked-by: Peter Zijlstra (Intel) <peterz@...radead.org>
> ---
> arch/x86/entry/entry_64.S | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> --- a/arch/x86/entry/entry_64.S
> +++ b/arch/x86/entry/entry_64.S
> @@ -875,7 +875,12 @@ apicinterrupt IRQ_WORK_VECTOR irq_work
> UNWIND_HINT_REGS
>
> .if \read_cr2
> - GET_CR2_INTO(%rdx); /* can clobber %rax */
> + /*
> + * Store CR2 early so subsequent faults cannot clobber it. Use R12 as
> + * intermediate storage as RDX can be clobbered in enter_from_user_mode().
> + * GET_CR2_INTO can clobber RAX.
> + */
> + GET_CR2_INTO(%r12);
> .endif
>
> .if \shift_ist != -1
> @@ -904,6 +909,10 @@ apicinterrupt IRQ_WORK_VECTOR irq_work
> subq $\ist_offset, CPU_TSS_IST(\shift_ist)
> .endif
>
> + .if \read_cr2
> + movq %r12, %rdx /* Move CR2 into 3rd argument */
> + .endif
> +
> call \do_sym
>
> .if \shift_ist != -1
Powered by blists - more mailing lists