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 06/14] x86/shstk: Create shadow stacks
Date: Wed, 27 May 2020 20:18:39 +0100	[thread overview]
Message-ID: <20200527191847.17207-7-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <20200527191847.17207-1-andrew.cooper3@citrix.com>

Introduce HYPERVISOR_SHSTK pagetable constants, which are Read-Only + Dirty.
Use these in place of _PAGE_NONE for memguard_guard_stack().

Supervisor shadow stacks need a token written at the top, which is most easily
done before making the frame read only.

Allocate the shadow IST stack block in struct tss_page.  It doesn't strictly
need to live here, but it is a convenient location (and XPTI-safe, for testing
purposes), and placing it ahead of the TSS doesn't risk colliding with a bad
IO Bitmap offset and turning into some IO port permissions.

Have load_system_tables() set up the shadow IST stack table when setting up
the regular IST in the TSS.

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:
 * Introduce IST_SHSTK_SIZE (Name subject to improvement).
 * Skip writing the shadow stack token for !XEN_SHSTK builds.
 * Tweak clobbering to be correct and safe.
---
 xen/arch/x86/cpu/common.c         | 24 ++++++++++++++++++++++++
 xen/arch/x86/mm.c                 | 25 +++++++++++++++++++++++--
 xen/include/asm-x86/config.h      |  2 ++
 xen/include/asm-x86/page.h        |  1 +
 xen/include/asm-x86/processor.h   |  3 ++-
 xen/include/asm-x86/x86_64/page.h |  1 +
 6 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index 690fd8baa8..dcc9ee08de 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -769,6 +769,30 @@ void load_system_tables(void)
 	tss->rsp1 = 0x8600111111111111ul;
 	tss->rsp2 = 0x8600111111111111ul;
 
+	/* Set up the shadow stack IST. */
+	if (cpu_has_xen_shstk) {
+		volatile uint64_t *ist_ssp = this_cpu(tss_page).ist_ssp;
+
+		/*
+		 * Used entries must point at the supervisor stack token.
+		 * Unused entries are poisoned.
+		 *
+		 * This IST Table may be live, and the NMI/#MC entries must
+		 * remain valid on every instruction boundary, hence the
+		 * volatile qualifier.
+		 */
+		ist_ssp[0] = 0x8600111111111111ul;
+		ist_ssp[IST_MCE] = stack_top + (IST_MCE * IST_SHSTK_SIZE) - 8;
+		ist_ssp[IST_NMI] = stack_top + (IST_NMI * IST_SHSTK_SIZE) - 8;
+		ist_ssp[IST_DB]	 = stack_top + (IST_DB	* IST_SHSTK_SIZE) - 8;
+		ist_ssp[IST_DF]	 = stack_top + (IST_DF	* IST_SHSTK_SIZE) - 8;
+		for ( i = IST_DF + 1;
+		      i < ARRAY_SIZE(this_cpu(tss_page).ist_ssp); ++i )
+			ist_ssp[i] = 0x8600111111111111ul;
+
+		wrmsrl(MSR_INTERRUPT_SSP_TABLE, (unsigned long)ist_ssp);
+	}
+
 	BUILD_BUG_ON(sizeof(*tss) <= 0x67); /* Mandated by the architecture. */
 
 	_set_tssldt_desc(gdt + TSS_ENTRY, (unsigned long)tss,
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 2f1e716b6d..4d6d22cc41 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -5994,12 +5994,33 @@ void memguard_unguard_range(void *p, unsigned long l)
 
 #endif
 
+static void write_sss_token(unsigned long *ptr)
+{
+    /*
+     * A supervisor shadow stack token is its own linear address, with the
+     * busy bit (0) clear.
+     */
+    *ptr = (unsigned long)ptr;
+}
+
 void memguard_guard_stack(void *p)
 {
-    map_pages_to_xen((unsigned long)p, virt_to_mfn(p), 1, _PAGE_NONE);
+    /* IST Shadow stacks.  4x 1k in stack page 0. */
+    if ( IS_ENABLED(CONFIG_XEN_SHSTK) )
+    {
+        write_sss_token(p + (IST_MCE * IST_SHSTK_SIZE) - 8);
+        write_sss_token(p + (IST_NMI * IST_SHSTK_SIZE) - 8);
+        write_sss_token(p + (IST_DB  * IST_SHSTK_SIZE) - 8);
+        write_sss_token(p + (IST_DF  * IST_SHSTK_SIZE) - 8);
+    }
+    map_pages_to_xen((unsigned long)p, virt_to_mfn(p), 1, PAGE_HYPERVISOR_SHSTK);
 
+    /* Primary Shadow Stack.  1x 4k in stack page 5. */
     p += PRIMARY_SHSTK_SLOT * PAGE_SIZE;
-    map_pages_to_xen((unsigned long)p, virt_to_mfn(p), 1, _PAGE_NONE);
+    if ( IS_ENABLED(CONFIG_XEN_SHSTK) )
+        write_sss_token(p + PAGE_SIZE - 8);
+
+    map_pages_to_xen((unsigned long)p, virt_to_mfn(p), 1, PAGE_HYPERVISOR_SHSTK);
 }
 
 void memguard_unguard_stack(void *p)
diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h
index f3cf5df462..2ba234383d 100644
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -66,6 +66,8 @@
 #define STACK_ORDER 3
 #define STACK_SIZE  (PAGE_SIZE << STACK_ORDER)
 
+#define IST_SHSTK_SIZE 1024
+
 #define TRAMPOLINE_STACK_SPACE  PAGE_SIZE
 #define TRAMPOLINE_SPACE        (KB(64) - TRAMPOLINE_STACK_SPACE)
 #define WAKEUP_STACK_MIN        3072
diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
index 5acf3d3d5a..f632affaef 100644
--- a/xen/include/asm-x86/page.h
+++ b/xen/include/asm-x86/page.h
@@ -364,6 +364,7 @@ void efi_update_l4_pgtable(unsigned int l4idx, l4_pgentry_t);
                                    _PAGE_DIRTY | _PAGE_RW)
 #define __PAGE_HYPERVISOR_UCMINUS (__PAGE_HYPERVISOR | _PAGE_PCD)
 #define __PAGE_HYPERVISOR_UC      (__PAGE_HYPERVISOR | _PAGE_PCD | _PAGE_PWT)
+#define __PAGE_HYPERVISOR_SHSTK   (__PAGE_HYPERVISOR_RO | _PAGE_DIRTY)
 
 #define MAP_SMALL_PAGES _PAGE_AVAIL0 /* don't use superpages mappings */
 
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index 8ab09cf7ed..859bd9e2ec 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -435,7 +435,8 @@ struct __packed tss64 {
     uint16_t :16, bitmap;
 };
 struct tss_page {
-    struct tss64 __aligned(PAGE_SIZE) tss;
+    uint64_t __aligned(PAGE_SIZE) ist_ssp[8];
+    struct tss64 tss;
 };
 DECLARE_PER_CPU(struct tss_page, tss_page);
 
diff --git a/xen/include/asm-x86/x86_64/page.h b/xen/include/asm-x86/x86_64/page.h
index 9876634881..26621f9519 100644
--- a/xen/include/asm-x86/x86_64/page.h
+++ b/xen/include/asm-x86/x86_64/page.h
@@ -171,6 +171,7 @@ static inline intpte_t put_pte_flags(unsigned int x)
 #define PAGE_HYPERVISOR_RW      (__PAGE_HYPERVISOR_RW      | _PAGE_GLOBAL)
 #define PAGE_HYPERVISOR_RX      (__PAGE_HYPERVISOR_RX      | _PAGE_GLOBAL)
 #define PAGE_HYPERVISOR_RWX     (__PAGE_HYPERVISOR         | _PAGE_GLOBAL)
+#define PAGE_HYPERVISOR_SHSTK   (__PAGE_HYPERVISOR_SHSTK   | _PAGE_GLOBAL)
 
 #define PAGE_HYPERVISOR         PAGE_HYPERVISOR_RW
 #define PAGE_HYPERVISOR_UCMINUS (__PAGE_HYPERVISOR_UCMINUS | \
-- 
2.11.0



  parent reply	other threads:[~2020-05-27 19:20 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 ` Andrew Cooper [this message]
2020-05-28 12:50   ` [PATCH v2 06/14] x86/shstk: Create " 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 ` [PATCH v2 10/14] x86/extable: Adjust extable handling " Andrew Cooper
2020-05-28 16:15   ` 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-7-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.