From: Juergen Gross <jgross@suse.com>
To: Andrew Cooper <andrew.cooper3@citrix.com>,
Xen-devel <xen-devel@lists.xen.org>
Cc: Wei Liu <wei.liu2@citrix.com>, Jan Beulich <JBeulich@suse.com>
Subject: Re: [PATCH] x86/xpti: Hide almost all of .text and all .data/.rodata/.bss mappings
Date: Wed, 14 Feb 2018 08:54:37 +0100 [thread overview]
Message-ID: <b545e520-d15a-fa32-a6ca-879c400eaa2e@suse.com> (raw)
In-Reply-To: <1518551106-10073-1-git-send-email-andrew.cooper3@citrix.com>
On 13/02/18 20:45, Andrew Cooper wrote:
> The current XPTI implementation isolates the directmap (and therefore a lot of
> guest data), but a large quantity of CPU0's state (including its stack)
> remains visible.
>
> Furthermore, an attacker able to read .text is in a vastly superior position
> to normal when it comes to fingerprinting Xen for known vulnerabilities, or
> scanning for ROP/Spectre gadgets.
>
> Collect together the entrypoints in .text.entry (currently 3x4k frames, but
> can almost certainly be slimmed down), and create a common mapping which is
> inserted into each per-cpu shadow. The stubs are also inserted into this
> mapping by pointing at the in-use L2. This allows stubs allocated later (SMP
> boot, or CPU hotplug) to work without further changes to the common mappings.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Jan Beulich <JBeulich@suse.com>
> CC: Wei Liu <wei.liu2@citrix.com>
> CC: Juergen Gross <jgross@suse.com>
>
> RFC, because I don't think the stubs handling is particularly sensible.
>
> We allocate 4k of virtual address space per CPU, but squash loads of CPUs
> together onto a single MFN. The stubs ought to be isolated as well (as they
> leak the virtual addresses of each stack), which can be done by allocating an
> MFN per CPU (and simplifies cpu_smpboot_alloc() somewhat). At this point, we
> can't use a common set of mappings, and will have to clone the single stub and
> .entry.text into each PCPUs copy of the pagetables.
>
> Also, my plan to cause .text.entry to straddle a 512TB boundary (and therefore
> avoid any further pagetable allocations) has come a little unstuck because of
> CONFIG_BIGMEM. I'm still working out whether there is a sensible way to
> rearrange the virtual layout for this plan to work.
> ---
> xen/arch/x86/smpboot.c | 37 ++++++++++++++++++++++++++++++++-----
> xen/arch/x86/x86_64/compat/entry.S | 2 ++
> xen/arch/x86/x86_64/entry.S | 4 +++-
> xen/arch/x86/xen.lds.S | 7 +++++++
> 4 files changed, 44 insertions(+), 6 deletions(-)
>
> diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
> index 2ebef03..2519141 100644
> --- a/xen/arch/x86/smpboot.c
> +++ b/xen/arch/x86/smpboot.c
> @@ -622,6 +622,9 @@ unsigned long alloc_stub_page(unsigned int cpu, unsigned long *mfn)
> unmap_domain_page(memset(__map_domain_page(pg), 0xcc, PAGE_SIZE));
> }
>
> + /* Confirm that all stubs fit in a single L2 pagetable. */
> + BUILD_BUG_ON(NR_CPUS * PAGE_SIZE > (1u << L2_PAGETABLE_SHIFT));
So we limit NR_CPUS to be max 512 now?
Maybe you should use STUB_BUF_SIZE instead of PAGE_SIZE?
BTW: Is there any reason we don't use a common stub page mapped to each
per-cpu stack area? The stack address can easily be obtained via %rip
relative addressing then (see my patch for the per-vcpu stacks:
https://lists.xen.org/archives/html/xen-devel/2018-02/msg00773.html )
Juergen
> +
> stub_va = XEN_VIRT_END - (cpu + 1) * PAGE_SIZE;
> if ( map_pages_to_xen(stub_va, mfn_x(page_to_mfn(pg)), 1,
> PAGE_HYPERVISOR_RX | MAP_SMALL_PAGES) )
> @@ -651,9 +654,6 @@ static int clone_mapping(const void *ptr, root_pgentry_t *rpt)
> l2_pgentry_t *pl2e;
> l1_pgentry_t *pl1e;
>
> - if ( linear < DIRECTMAP_VIRT_START )
> - return 0;
> -
> flags = l3e_get_flags(*pl3e);
> ASSERT(flags & _PAGE_PRESENT);
> if ( flags & _PAGE_PSE )
> @@ -744,6 +744,9 @@ static __read_mostly int8_t opt_xpti = -1;
> boolean_param("xpti", opt_xpti);
> DEFINE_PER_CPU(root_pgentry_t *, root_pgt);
>
> +static root_pgentry_t common_pgt;
> +extern char _stextentry[], _etextentry[];
> +
> static int setup_cpu_root_pgt(unsigned int cpu)
> {
> root_pgentry_t *rpt;
> @@ -764,8 +767,32 @@ static int setup_cpu_root_pgt(unsigned int cpu)
> idle_pg_table[root_table_offset(RO_MPT_VIRT_START)];
> /* SH_LINEAR_PT inserted together with guest mappings. */
> /* PERDOMAIN inserted during context switch. */
> - rpt[root_table_offset(XEN_VIRT_START)] =
> - idle_pg_table[root_table_offset(XEN_VIRT_START)];
> +
> + /* One-time setup of common_pgt, which maps .text.entry and the stubs. */
> + if ( unlikely(!root_get_intpte(common_pgt)) )
> + {
> + unsigned long stubs_linear = XEN_VIRT_END - 1;
> + l3_pgentry_t *stubs_main, *stubs_shadow;
> + char *ptr;
> +
> + for ( rc = 0, ptr = _stextentry;
> + !rc && ptr < _etextentry; ptr += PAGE_SIZE )
> + rc = clone_mapping(ptr, rpt);
> +
> + if ( rc )
> + return rc;
> +
> + stubs_main = l4e_to_l3e(idle_pg_table[l4_table_offset(stubs_linear)]);
> + stubs_shadow = l4e_to_l3e(rpt[l4_table_offset(stubs_linear)]);
> +
> + /* Splice into the regular L2 mapping the stubs. */
> + stubs_shadow[l3_table_offset(stubs_linear)] =
> + stubs_main[l3_table_offset(stubs_linear)];
> +
> + common_pgt = rpt[root_table_offset(XEN_VIRT_START)];
> + }
> +
> + rpt[root_table_offset(XEN_VIRT_START)] = common_pgt;
>
> /* Install direct map page table entries for stack, IDT, and TSS. */
> for ( off = rc = 0; !rc && off < STACK_SIZE; off += PAGE_SIZE )
> diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S
> index 707c746..b001e79 100644
> --- a/xen/arch/x86/x86_64/compat/entry.S
> +++ b/xen/arch/x86/x86_64/compat/entry.S
> @@ -13,6 +13,8 @@
> #include <public/xen.h>
> #include <irq_vectors.h>
>
> + .section .text.entry, "ax", @progbits
> +
> ENTRY(entry_int82)
> ASM_CLAC
> pushq $0
> diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
> index 58f652d..5c5310d 100644
> --- a/xen/arch/x86/x86_64/entry.S
> +++ b/xen/arch/x86/x86_64/entry.S
> @@ -14,6 +14,8 @@
> #include <public/xen.h>
> #include <irq_vectors.h>
>
> + .section .text.entry, "ax", @progbits
> +
> /* %rbx: struct vcpu */
> ENTRY(switch_to_kernel)
> leaq VCPU_trap_bounce(%rbx),%rdx
> @@ -854,7 +856,7 @@ GLOBAL(autogen_entrypoints)
> .popsection
> .endm
>
> - .text
> + .previous
> autogen_stubs: /* Automatically generated stubs. */
>
> vec = 0
> diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
> index 0952980..25c6cbc 100644
> --- a/xen/arch/x86/xen.lds.S
> +++ b/xen/arch/x86/xen.lds.S
> @@ -67,6 +67,13 @@ SECTIONS
> *(.text)
> *(.text.__x86_indirect_thunk_*)
> *(.text.page_aligned)
> +
> + . = ALIGN(PAGE_SIZE);
> + _stextentry = .;
> + *(.text.entry)
> + . = ALIGN(PAGE_SIZE);
> + _etextentry = .;
> +
> *(.text.cold)
> *(.text.unlikely)
> *(.fixup)
>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2018-02-14 7:54 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-13 19:45 [PATCH] x86/xpti: Hide almost all of .text and all .data/.rodata/.bss mappings Andrew Cooper
2018-02-14 7:54 ` Juergen Gross [this message]
2018-02-14 11:48 ` Andrew Cooper
2018-02-14 12:03 ` Juergen Gross
2018-02-14 12:15 ` Juergen Gross
2018-02-14 12:19 ` Andrew Cooper
2018-02-14 12:27 ` Juergen Gross
2018-02-14 12:36 ` Andrew Cooper
2018-02-14 9:14 ` Jan Beulich
2018-02-14 12:34 ` Andrew Cooper
2018-02-14 12:58 ` Jan Beulich
-- strict thread matches above, loose matches on Subject: below --
2018-02-14 16:23 Andrew Cooper
2018-02-15 10:18 ` Jan Beulich
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=b545e520-d15a-fa32-a6ca-879c400eaa2e@suse.com \
--to=jgross@suse.com \
--cc=JBeulich@suse.com \
--cc=andrew.cooper3@citrix.com \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xen.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).