changes since Xen 4.6.5: mostly bug fixes, including security fixes for XSA206, XSA211 to XSA244. PKGREVISION set to 1 to account for the fact that it's not a stock Xen 4.6.6. Note that, unlike upstream, pv-linear-pt defaults to true, so that NetBSD PV guests (including dom0) will continue to boot without changes to boot.cfg
132 lines
5.2 KiB
Text
132 lines
5.2 KiB
Text
$NetBSD: patch-XSA243,v 1.1 2017/10/17 10:57:34 bouyer Exp $
|
|
|
|
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
Subject: x86: Disable the use of auto-translated PV guests
|
|
|
|
This is a minimal backport of c/s 92942fd3d469 "x86/mm: drop
|
|
guest_{map,get_eff}_l1e() hooks" from Xen 4.7, which stated:
|
|
|
|
Disallow the unmaintained and presumed broken translated-but-not-external
|
|
paging mode combination ...
|
|
|
|
It turns out that this mode is insecure to run with, as opposed to just simply
|
|
broken.
|
|
|
|
This is part of XSA-243.
|
|
|
|
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
|
|
diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c
|
|
index dcff4fb..945bb61 100644
|
|
--- xen/arch/x86/mm/paging.c.orig
|
|
+++ xen/arch/x86/mm/paging.c
|
|
@@ -835,6 +835,15 @@ void paging_final_teardown(struct domain *d)
|
|
* creation. */
|
|
int paging_enable(struct domain *d, u32 mode)
|
|
{
|
|
+ switch ( mode & (PG_external | PG_translate) )
|
|
+ {
|
|
+ case 0:
|
|
+ case PG_external | PG_translate:
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
if ( hap_enabled(d) )
|
|
return hap_enable(d, mode | PG_HAP_enable);
|
|
else
|
|
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
Subject: x86/shadow: Don't create self-linear shadow mappings for 4-level translated guests
|
|
|
|
When initially creating a monitor table for 4-level translated guests, don't
|
|
install a shadow-linear mapping. This mapping is actually self-linear, and
|
|
trips up the writeable heuristic logic into following Xen's mappings, not the
|
|
guests' shadows it was expecting to follow.
|
|
|
|
A consequence of this is that sh_guess_wrmap() needs to cope with there being
|
|
no shadow-linear mapping present, which in practice occurs once each time a
|
|
vcpu switches to 4-level paging from a different paging mode.
|
|
|
|
An appropriate shadow-linear slot will be inserted into the monitor table
|
|
either while constructing lower level monitor tables, or by sh_update_cr3().
|
|
|
|
While fixing this, clarify the safety of the other mappings. Despite
|
|
appearing unsafe, it is correct to create a guest-linear mapping for
|
|
translated domains; this is self-linear and doesn't point into the translated
|
|
domain. Drop a dead clause for translate != external guests.
|
|
|
|
This is part of XSA-243.
|
|
|
|
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
Acked-by: Tim Deegan <tim@xen.org>
|
|
|
|
diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c
|
|
index c34ebe0..cb8ddde 100644
|
|
--- xen/arch/x86/mm/shadow/multi.c.orig
|
|
+++ xen/arch/x86/mm/shadow/multi.c
|
|
@@ -1456,26 +1456,38 @@ void sh_install_xen_entries_in_l4(struct domain *d, mfn_t gl4mfn, mfn_t sl4mfn)
|
|
sl4e[shadow_l4_table_offset(RO_MPT_VIRT_START)] = shadow_l4e_empty();
|
|
}
|
|
|
|
- /* Shadow linear mapping for 4-level shadows. N.B. for 3-level
|
|
- * shadows on 64-bit xen, this linear mapping is later replaced by the
|
|
- * monitor pagetable structure, which is built in make_monitor_table
|
|
- * and maintained by sh_update_linear_entries. */
|
|
- sl4e[shadow_l4_table_offset(SH_LINEAR_PT_VIRT_START)] =
|
|
- shadow_l4e_from_mfn(sl4mfn, __PAGE_HYPERVISOR);
|
|
-
|
|
- /* Self linear mapping. */
|
|
- if ( shadow_mode_translate(d) && !shadow_mode_external(d) )
|
|
- {
|
|
- // linear tables may not be used with translated PV guests
|
|
- sl4e[shadow_l4_table_offset(LINEAR_PT_VIRT_START)] =
|
|
+ /*
|
|
+ * Linear mapping slots:
|
|
+ *
|
|
+ * Calling this function with gl4mfn == sl4mfn is used to construct a
|
|
+ * monitor table for translated domains. In this case, gl4mfn forms the
|
|
+ * self-linear mapping (i.e. not pointing into the translated domain), and
|
|
+ * the shadow-linear slot is skipped. The shadow-linear slot is either
|
|
+ * filled when constructing lower level monitor tables, or via
|
|
+ * sh_update_cr3() for 4-level guests.
|
|
+ *
|
|
+ * Calling this function with gl4mfn != sl4mfn is used for non-translated
|
|
+ * guests, where the shadow-linear slot is actually self-linear, and the
|
|
+ * guest-linear slot points into the guests view of its pagetables.
|
|
+ */
|
|
+ if ( shadow_mode_translate(d) )
|
|
+ {
|
|
+ ASSERT(mfn_x(gl4mfn) == mfn_x(sl4mfn));
|
|
+
|
|
+ sl4e[shadow_l4_table_offset(SH_LINEAR_PT_VIRT_START)] =
|
|
shadow_l4e_empty();
|
|
}
|
|
else
|
|
{
|
|
- sl4e[shadow_l4_table_offset(LINEAR_PT_VIRT_START)] =
|
|
- shadow_l4e_from_mfn(gl4mfn, __PAGE_HYPERVISOR);
|
|
+ ASSERT(mfn_x(gl4mfn) != mfn_x(sl4mfn));
|
|
+
|
|
+ sl4e[shadow_l4_table_offset(SH_LINEAR_PT_VIRT_START)] =
|
|
+ shadow_l4e_from_mfn(sl4mfn, __PAGE_HYPERVISOR);
|
|
}
|
|
|
|
+ sl4e[shadow_l4_table_offset(LINEAR_PT_VIRT_START)] =
|
|
+ shadow_l4e_from_mfn(gl4mfn, __PAGE_HYPERVISOR);
|
|
+
|
|
unmap_domain_page(sl4e);
|
|
}
|
|
#endif
|
|
@@ -4270,6 +4282,11 @@ static int sh_guess_wrmap(struct vcpu *v, unsigned long vaddr, mfn_t gmfn)
|
|
|
|
/* Carefully look in the shadow linear map for the l1e we expect */
|
|
#if SHADOW_PAGING_LEVELS >= 4
|
|
+ /* Is a shadow linear map is installed in the first place? */
|
|
+ sl4p = v->arch.paging.shadow.guest_vtable;
|
|
+ sl4p += shadow_l4_table_offset(SH_LINEAR_PT_VIRT_START);
|
|
+ if ( !(shadow_l4e_get_flags(*sl4p) & _PAGE_PRESENT) )
|
|
+ return 0;
|
|
sl4p = sh_linear_l4_table(v) + shadow_l4_linear_offset(vaddr);
|
|
if ( !(shadow_l4e_get_flags(*sl4p) & _PAGE_PRESENT) )
|
|
return 0;
|