All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xenproject.org>
Cc: "Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Wei Liu" <wl@xen.org>, "Jan Beulich" <JBeulich@suse.com>,
	"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [PATCH v2 10/14] x86/extable: Adjust extable handling to be shadow stack compatible
Date: Wed, 27 May 2020 20:18:43 +0100	[thread overview]
Message-ID: <20200527191847.17207-11-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <20200527191847.17207-1-andrew.cooper3@citrix.com>

When adjusting an IRET frame to recover from a fault, and equivalent
adjustment needs making in the shadow IRET frame.

The adjustment in exception_with_ints_disabled() could in principle be an
alternative block rather than an ifdef, as the only two current users of
_PRE_EXTABLE() are IRET-to-guest instructions.  However, this is not a
fastpath, and this form is more robust to future changes.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Wei Liu <wl@xen.org>
CC: Roger Pau Monné <roger.pau@citrix.com>

v2:
 * Break extable_shstk_fixup() out into a separate function.
 * Guard from shstk underflows, and unrealistic call traces.
---
 xen/arch/x86/traps.c        | 67 ++++++++++++++++++++++++++++++++++++++++++++-
 xen/arch/x86/x86_64/entry.S | 11 +++++++-
 2 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 235a72cf4a..ce910294ea 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -363,7 +363,7 @@ static void show_guest_stack(struct vcpu *v, const struct cpu_user_regs *regs)
 }
 
 /*
- * Notes for get_stack_trace_bottom() and get_stack_dump_bottom()
+ * Notes for get_{stack,shstk}*_bottom() helpers
  *
  * Stack pages 1 - 4:
  *   These are all 1-page IST stacks.  Each of these stacks have an exception
@@ -400,6 +400,18 @@ unsigned long get_stack_trace_bottom(unsigned long sp)
     }
 }
 
+static unsigned long get_shstk_bottom(unsigned long sp)
+{
+    switch ( get_stack_page(sp) )
+    {
+#ifdef CONFIG_XEN_SHSTK
+    case 0:  return ROUNDUP(sp, IST_SHSTK_SIZE) - sizeof(unsigned long);
+    case 5:  return ROUNDUP(sp, PAGE_SIZE)      - sizeof(unsigned long);
+#endif
+    default: return sp - sizeof(unsigned long);
+    }
+}
+
 unsigned long get_stack_dump_bottom(unsigned long sp)
 {
     switch ( get_stack_page(sp) )
@@ -763,6 +775,56 @@ static void do_reserved_trap(struct cpu_user_regs *regs)
           trapnr, vec_name(trapnr), regs->error_code);
 }
 
+static void extable_shstk_fixup(struct cpu_user_regs *regs, unsigned long fixup)
+{
+    unsigned long ssp, *ptr, *base;
+
+    asm ( "rdsspq %0" : "=r" (ssp) : "0" (1) );
+    if ( ssp == 1 )
+        return;
+
+    ptr = _p(ssp);
+    base = _p(get_shstk_bottom(ssp));
+
+    for ( ; ptr < base; ++ptr )
+    {
+        /*
+         * Search for %rip.  The shstk currently looks like this:
+         *
+         *   ...  [Likely pointed to by SSP]
+         *   %cs  [== regs->cs]
+         *   %rip [== regs->rip]
+         *   SSP  [Likely points to 3 slots higher, above %cs]
+         *   ...  [call tree to this function, likely 2/3 slots]
+         *
+         * and we want to overwrite %rip with fixup.  There are two
+         * complications:
+         *   1) We cant depend on SSP values, because they won't differ by 3
+         *      slots if the exception is taken on an IST stack.
+         *   2) There are synthetic (unrealistic but not impossible) scenarios
+         *      where %rip can end up in the call tree to this function, so we
+         *      can't check against regs->rip alone.
+         *
+         * Check for both reg->rip and regs->cs matching.
+         */
+
+        if ( ptr[0] == regs->rip && ptr[1] == regs->cs )
+        {
+            asm ( "wrssq %[fix], %[stk]"
+                  : [stk] "=m" (*ptr)
+                  : [fix] "r" (fixup) );
+            return;
+        }
+    }
+
+    /*
+     * We failed to locate and fix up the shadow IRET frame.  This could be
+     * due to shadow stack corruption, or bad logic above.  We cannot continue
+     * executing the interrupted context.
+     */
+    BUG();
+}
+
 static bool extable_fixup(struct cpu_user_regs *regs, bool print)
 {
     unsigned long fixup = search_exception_table(regs);
@@ -779,6 +841,9 @@ static bool extable_fixup(struct cpu_user_regs *regs, bool print)
                vec_name(regs->entry_vector), regs->error_code,
                _p(regs->rip), _p(regs->rip), _p(fixup));
 
+    if ( IS_ENABLED(CONFIG_XEN_SHSTK) )
+        extable_shstk_fixup(regs, fixup);
+
     regs->rip = fixup;
     this_cpu(last_extable_addr) = regs->rip;
 
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index f7ee3dce91..78ac0df49f 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -708,7 +708,16 @@ exception_with_ints_disabled:
         call  search_pre_exception_table
         testq %rax,%rax                 # no fixup code for faulting EIP?
         jz    1b
-        movq  %rax,UREGS_rip(%rsp)
+        movq  %rax,UREGS_rip(%rsp)      # fixup regular stack
+
+#ifdef CONFIG_XEN_SHSTK
+        mov    $1, %edi
+        rdsspq %rdi
+        cmp    $1, %edi
+        je     .L_exn_shstk_done
+        wrssq  %rax, (%rdi)             # fixup shadow stack
+.L_exn_shstk_done:
+#endif
         subq  $8,UREGS_rsp(%rsp)        # add ec/ev to previous stack frame
         testb $15,UREGS_rsp(%rsp)       # return %rsp is now aligned?
         jz    1f                        # then there is a pad quadword already
-- 
2.11.0



  parent reply	other threads:[~2020-05-27 19:34 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-27 19:18 [PATCH v2 00/14] x86: Support for CET Supervisor Shadow Stacks Andrew Cooper
2020-05-27 19:18 ` [PATCH v2 01/14] x86/traps: Clean up printing in {do_reserved, fatal}_trap() Andrew Cooper
2020-05-28  9:45   ` [PATCH v2 01/14] x86/traps: Clean up printing in {do_reserved,fatal}_trap() Jan Beulich
2020-05-27 19:18 ` [PATCH v2 02/14] x86/traps: Factor out extable_fixup() and make printing consistent Andrew Cooper
2020-05-28  9:50   ` Jan Beulich
2020-05-28 17:26     ` Andrew Cooper
2020-05-27 19:18 ` [PATCH v2 03/14] x86/shstk: Introduce Supervisor Shadow Stack support Andrew Cooper
2020-05-28 10:25   ` Jan Beulich
2020-05-28 18:10     ` Andrew Cooper
2020-05-29 11:59       ` Jan Beulich
2020-05-29 15:51         ` Anthony PERARD
2020-05-29 18:39           ` Andrew Cooper
2020-06-02 12:09             ` Jan Beulich
2020-05-29 18:36         ` Andrew Cooper
2020-06-02 12:06           ` Jan Beulich
2020-06-02 12:26             ` Anthony PERARD
2020-06-02 12:41               ` Jan Beulich
2020-06-02 13:50                 ` Anthony PERARD
2020-06-02 14:13                   ` Jan Beulich
2020-05-27 19:18 ` [PATCH v2 04/14] x86/traps: Implement #CP handler and extend #PF for shadow stacks Andrew Cooper
2020-05-28 12:03   ` Jan Beulich
2020-05-28 13:22     ` Andrew Cooper
2020-05-28 13:31       ` Jan Beulich
2020-05-29 18:50         ` Andrew Cooper
2020-05-27 19:18 ` [PATCH v2 05/14] x86/shstk: Re-layout the stack block " Andrew Cooper
2020-05-28 12:33   ` Jan Beulich
2020-05-29 19:21     ` Andrew Cooper
2020-05-27 19:18 ` [PATCH v2 06/14] x86/shstk: Create " Andrew Cooper
2020-05-28 12:50   ` Jan Beulich
2020-05-29 19:35     ` Andrew Cooper
2020-05-29 21:45       ` Andrew Cooper
2020-06-02 12:32         ` Jan Beulich
2020-06-02 12:35       ` Jan Beulich
2020-05-27 19:18 ` [PATCH v2 07/14] x86/cpu: Adjust enable_nmis() to be shadow stack compatible Andrew Cooper
2020-05-27 19:18 ` [PATCH v2 08/14] x86/cpu: Adjust reset_stack_and_jump() " Andrew Cooper
2020-05-28 14:41   ` Jan Beulich
2020-05-27 19:18 ` [PATCH v2 09/14] x86/spec-ctrl: Adjust DO_OVERWRITE_RSB " Andrew Cooper
2020-05-27 19:18 ` Andrew Cooper [this message]
2020-05-28 16:15   ` [PATCH v2 10/14] x86/extable: Adjust extable handling " Jan Beulich
2020-05-29 19:43     ` Andrew Cooper
2020-05-29 21:17       ` Andrew Cooper
2020-06-02 13:11         ` Jan Beulich
2020-06-02 12:57       ` Jan Beulich
2020-05-27 19:18 ` [PATCH v2 11/14] x86/alt: Adjust _alternative_instructions() to not create shadow stacks Andrew Cooper
2020-05-29 12:23   ` Jan Beulich
2020-05-29 19:46     ` Andrew Cooper
2020-05-27 19:18 ` [PATCH v2 12/14] x86/entry: Adjust guest paths to be shadow stack compatible Andrew Cooper
2020-05-29 12:40   ` Jan Beulich
2020-05-29 19:58     ` Andrew Cooper
2020-05-27 19:18 ` [PATCH v2 13/14] x86/S3: Save and restore Shadow Stack configuration Andrew Cooper
2020-05-29 12:52   ` Jan Beulich
2020-05-29 20:00     ` Andrew Cooper
2020-05-27 19:18 ` [PATCH v2 14/14] x86/shstk: Activate Supervisor Shadow Stacks Andrew Cooper
2020-05-29 13:09   ` Jan Beulich
2020-05-29 20:28     ` Andrew Cooper
2020-05-29 22:28 ` [PATCH v2 00/14] x86: Support for CET " Andrew Cooper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200527191847.17207-11-andrew.cooper3@citrix.com \
    --to=andrew.cooper3@citrix.com \
    --cc=JBeulich@suse.com \
    --cc=roger.pau@citrix.com \
    --cc=wl@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.