diff options
Diffstat (limited to 'sysutils/xenkernel411/patches/patch-XSA304')
-rw-r--r-- | sysutils/xenkernel411/patches/patch-XSA304 | 481 |
1 files changed, 0 insertions, 481 deletions
diff --git a/sysutils/xenkernel411/patches/patch-XSA304 b/sysutils/xenkernel411/patches/patch-XSA304 deleted file mode 100644 index 5a2b6fe1200..00000000000 --- a/sysutils/xenkernel411/patches/patch-XSA304 +++ /dev/null @@ -1,481 +0,0 @@ -$NetBSD: patch-XSA304,v 1.2 2019/11/13 15:00:06 bouyer Exp $ - -From: Andrew Cooper <andrew.cooper3@citrix.com> -Subject: x86/vtd: Hide superpage support for SandyBridge IOMMUs - -Something causes SandyBridge IOMMUs to choke when sharing EPT pagetables, and -an EPT superpage gets shattered. The root cause is still under investigation, -but the end result is unusable in combination with CVE-2018-12207 protections. - -This is part of XSA-304 / CVE-2018-12207 - -Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> -Reviewed-by: Jan Beulich <jbeulich@suse.com> - -diff --git a/xen/drivers/passthrough/vtd/extern.h b/xen/drivers/passthrough/vtd/extern.h -index fb7edfaef9..d698b1d50a 100644 ---- xen/drivers/passthrough/vtd/extern.h.orig -+++ xen/drivers/passthrough/vtd/extern.h -@@ -96,6 +96,8 @@ void vtd_ops_postamble_quirk(struct iommu* iommu); - int __must_check me_wifi_quirk(struct domain *domain, - u8 bus, u8 devfn, int map); - void pci_vtd_quirk(const struct pci_dev *); -+void quirk_iommu_caps(struct iommu *iommu); -+ - bool_t platform_supports_intremap(void); - bool_t platform_supports_x2apic(void); - -diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c -index f242e30caf..8712d3b4dc 100644 ---- xen/drivers/passthrough/vtd/iommu.c.orig -+++ xen/drivers/passthrough/vtd/iommu.c -@@ -1211,6 +1211,8 @@ int __init iommu_alloc(struct acpi_drhd_unit *drhd) - if ( !(iommu->cap + 1) || !(iommu->ecap + 1) ) - return -ENODEV; - -+ quirk_iommu_caps(iommu); -+ - if ( cap_fault_reg_offset(iommu->cap) + - cap_num_fault_regs(iommu->cap) * PRIMARY_FAULT_REG_LEN >= PAGE_SIZE || - ecap_iotlb_offset(iommu->ecap) >= PAGE_SIZE ) -diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c -index d6db862678..b02688e316 100644 ---- xen/drivers/passthrough/vtd/quirks.c.orig -+++ xen/drivers/passthrough/vtd/quirks.c -@@ -540,3 +540,28 @@ void pci_vtd_quirk(const struct pci_dev *pdev) - break; - } - } -+ -+void __init quirk_iommu_caps(struct iommu *iommu) -+{ -+ /* -+ * IOMMU Quirks: -+ * -+ * SandyBridge IOMMUs claim support for 2M and 1G superpages, but don't -+ * implement superpages internally. -+ * -+ * There are issues changing the walk length under in-flight DMA, which -+ * has manifested as incompatibility between EPT/IOMMU sharing and the -+ * workaround for CVE-2018-12207 / XSA-304. Hide the superpages -+ * capabilities in the IOMMU, which will prevent Xen from sharing the EPT -+ * and IOMMU pagetables. -+ * -+ * Detection of SandyBridge unfortunately has to be done by processor -+ * model because the client parts don't expose their IOMMUs as PCI devices -+ * we could match with a Device ID. -+ */ -+ if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && -+ boot_cpu_data.x86 == 6 && -+ (boot_cpu_data.x86_model == 0x2a || -+ boot_cpu_data.x86_model == 0x2d) ) -+ iommu->cap &= ~(0xful << 34); -+} -From: Andrew Cooper <andrew.cooper3@citrix.com> -Subject: x86/vtx: Disable executable EPT superpages to work around - CVE-2018-12207 - -CVE-2018-12207 covers a set of errata on various Intel processors, whereby a -machine check exception can be generated in a corner case when an executable -mapping changes size or cacheability without TLB invalidation. HVM guest -kernels can trigger this to DoS the host. - -To mitigate, in affected hardware, all EPT superpages are marked NX. When an -instruction fetch violation is observed against the superpage, the superpage -is shattered to 4k and has execute permissions restored. This prevents the -guest kernel from being able to create the necessary preconditions in the iTLB -to exploit the vulnerability. - -This does come with a workload-dependent performance overhead, caused by -increased TLB pressure. Performance can be restored, if guest kernels are -trusted not to mount an attack, by specifying ept=exec-sp on the command line. - -This is part of XSA-304 / CVE-2018-12207 - -Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> -Acked-by: George Dunlap <george.dunlap@citrix.com> -Reviewed-by: Jan Beulich <jbeulich@suse.com> - -diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown -index c63a07d29b..684671cb7b 100644 ---- docs/misc/xen-command-line.markdown.orig -+++ docs/misc/xen-command-line.markdown -@@ -828,7 +828,7 @@ effect the inverse meaning. - >> set as UC. - - ### ept (Intel) --> `= List of ( {no-}pml | {no-}ad )` -+> `= List of [ {no-}pml, {no-}ad, {no-}exec-sp ]` - - Controls EPT related features. - -@@ -851,6 +851,16 @@ Controls EPT related features. - - >> Have hardware keep accessed/dirty (A/D) bits updated. - -+* The `exec-sp` boolean controls whether EPT superpages with execute -+ permissions are permitted. In general this is good for performance. -+ -+ However, on processors vulnerable CVE-2018-12207, HVM guest kernels can -+ use executable superpages to crash the host. By default, executable -+ superpages are disabled on affected hardware. -+ -+ If HVM guest kernels are trusted not to mount a DoS against the system, -+ this option can enabled to regain performance. -+ - ### extra\_guest\_irqs - > `= [<domU number>][,<dom0 number>]` - -diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c -index f4a6a37149..1924434960 100644 ---- xen/arch/x86/hvm/hvm.c.orig -+++ xen/arch/x86/hvm/hvm.c -@@ -1706,6 +1706,7 @@ int hvm_hap_nested_page_fault(paddr_t gpa, unsigned long gla, - struct p2m_domain *p2m, *hostp2m; - int rc, fall_through = 0, paged = 0; - int sharing_enomem = 0; -+ unsigned int page_order = 0; - vm_event_request_t *req_ptr = NULL; - bool_t ap2m_active, sync = 0; - -@@ -1774,7 +1775,7 @@ int hvm_hap_nested_page_fault(paddr_t gpa, unsigned long gla, - hostp2m = p2m_get_hostp2m(currd); - mfn = get_gfn_type_access(hostp2m, gfn, &p2mt, &p2ma, - P2M_ALLOC | (npfec.write_access ? P2M_UNSHARE : 0), -- NULL); -+ &page_order); - - if ( ap2m_active ) - { -@@ -1786,7 +1787,7 @@ int hvm_hap_nested_page_fault(paddr_t gpa, unsigned long gla, - goto out; - } - -- mfn = get_gfn_type_access(p2m, gfn, &p2mt, &p2ma, 0, NULL); -+ mfn = get_gfn_type_access(p2m, gfn, &p2mt, &p2ma, 0, &page_order); - } - else - p2m = hostp2m; -@@ -1828,6 +1829,24 @@ int hvm_hap_nested_page_fault(paddr_t gpa, unsigned long gla, - break; - } - -+ /* -+ * Workaround for XSA-304 / CVE-2018-12207. If we take an execution -+ * fault against a non-executable superpage, shatter it to regain -+ * execute permissions. -+ */ -+ if ( page_order > 0 && npfec.insn_fetch && npfec.present && !violation ) -+ { -+ int res = p2m_set_entry(p2m, _gfn(gfn), mfn, PAGE_ORDER_4K, -+ p2mt, p2ma); -+ -+ if ( res ) -+ printk(XENLOG_ERR "Failed to shatter gfn %"PRI_gfn": %d\n", -+ gfn, res); -+ -+ rc = !res; -+ goto out_put_gfn; -+ } -+ - if ( violation ) - { - /* Should #VE be emulated for this fault? */ -diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c -index 493986e84a..8821a3b536 100644 ---- xen/arch/x86/hvm/vmx/vmcs.c.orig -+++ xen/arch/x86/hvm/vmx/vmcs.c -@@ -67,6 +67,7 @@ integer_param("ple_window", ple_window); - - static bool_t __read_mostly opt_pml_enabled = 1; - static s8 __read_mostly opt_ept_ad = -1; -+int8_t __read_mostly opt_ept_exec_sp = -1; - - /* - * The 'ept' parameter controls functionalities that depend on, or impact the -@@ -94,6 +95,8 @@ static int __init parse_ept_param(const char *s) - opt_pml_enabled = val; - else if ( !cmdline_strcmp(s, "ad") ) - opt_ept_ad = val; -+ else if ( !cmdline_strcmp(s, "exec-sp") ) -+ opt_ept_exec_sp = val; - else - rc = -EINVAL; - -diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c -index 840dc2b44d..a568d62643 100644 ---- xen/arch/x86/hvm/vmx/vmx.c.orig -+++ xen/arch/x86/hvm/vmx/vmx.c -@@ -2415,6 +2415,102 @@ static void pi_notification_interrupt(struct cpu_user_regs *regs) - static void __init lbr_tsx_fixup_check(void); - static void __init bdw_erratum_bdf14_fixup_check(void); - -+/* -+ * Calculate whether the CPU is vulnerable to Instruction Fetch page -+ * size-change MCEs. -+ */ -+static bool __init has_if_pschange_mc(void) -+{ -+ uint64_t caps = 0; -+ -+ /* -+ * If we are virtualised, there is nothing we can do. Our EPT tables are -+ * shadowed by our hypervisor, and not walked by hardware. -+ */ -+ if ( cpu_has_hypervisor ) -+ return false; -+ -+ if ( boot_cpu_has(X86_FEATURE_ARCH_CAPS) ) -+ rdmsrl(MSR_ARCH_CAPABILITIES, caps); -+ -+ if ( caps & ARCH_CAPS_IF_PSCHANGE_MC_NO ) -+ return false; -+ -+ /* -+ * IF_PSCHANGE_MC is only known to affect Intel Family 6 processors at -+ * this time. -+ */ -+ if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL || -+ boot_cpu_data.x86 != 6 ) -+ return false; -+ -+ switch ( boot_cpu_data.x86_model ) -+ { -+ /* -+ * Core processors since at least Nehalem are vulnerable. -+ */ -+ case 0x1f: /* Auburndale / Havendale */ -+ case 0x1e: /* Nehalem */ -+ case 0x1a: /* Nehalem EP */ -+ case 0x2e: /* Nehalem EX */ -+ case 0x25: /* Westmere */ -+ case 0x2c: /* Westmere EP */ -+ case 0x2f: /* Westmere EX */ -+ case 0x2a: /* SandyBridge */ -+ case 0x2d: /* SandyBridge EP/EX */ -+ case 0x3a: /* IvyBridge */ -+ case 0x3e: /* IvyBridge EP/EX */ -+ case 0x3c: /* Haswell */ -+ case 0x3f: /* Haswell EX/EP */ -+ case 0x45: /* Haswell D */ -+ case 0x46: /* Haswell H */ -+ case 0x3d: /* Broadwell */ -+ case 0x47: /* Broadwell H */ -+ case 0x4f: /* Broadwell EP/EX */ -+ case 0x56: /* Broadwell D */ -+ case 0x4e: /* Skylake M */ -+ case 0x5e: /* Skylake D */ -+ case 0x55: /* Skylake-X / Cascade Lake */ -+ case 0x8e: /* Kaby / Coffee / Whiskey Lake M */ -+ case 0x9e: /* Kaby / Coffee / Whiskey Lake D */ -+ return true; -+ -+ /* -+ * Atom processors are not vulnerable. -+ */ -+ case 0x1c: /* Pineview */ -+ case 0x26: /* Lincroft */ -+ case 0x27: /* Penwell */ -+ case 0x35: /* Cloverview */ -+ case 0x36: /* Cedarview */ -+ case 0x37: /* Baytrail / Valleyview (Silvermont) */ -+ case 0x4d: /* Avaton / Rangely (Silvermont) */ -+ case 0x4c: /* Cherrytrail / Brasswell */ -+ case 0x4a: /* Merrifield */ -+ case 0x5a: /* Moorefield */ -+ case 0x5c: /* Goldmont */ -+ case 0x5d: /* SoFIA 3G Granite/ES2.1 */ -+ case 0x65: /* SoFIA LTE AOSP */ -+ case 0x5f: /* Denverton */ -+ case 0x6e: /* Cougar Mountain */ -+ case 0x75: /* Lightning Mountain */ -+ case 0x7a: /* Gemini Lake */ -+ case 0x86: /* Jacobsville */ -+ -+ /* -+ * Knights processors are not vulnerable. -+ */ -+ case 0x57: /* Knights Landing */ -+ case 0x85: /* Knights Mill */ -+ return false; -+ -+ default: -+ printk("Unrecognised CPU model %#x - assuming vulnerable to IF_PSCHANGE_MC\n", -+ boot_cpu_data.x86_model); -+ return true; -+ } -+} -+ - const struct hvm_function_table * __init start_vmx(void) - { - set_in_cr4(X86_CR4_VMXE); -@@ -2435,6 +2531,17 @@ const struct hvm_function_table * __init start_vmx(void) - */ - if ( cpu_has_vmx_ept && (cpu_has_vmx_pat || opt_force_ept) ) - { -+ bool cpu_has_bug_pschange_mc = has_if_pschange_mc(); -+ -+ if ( opt_ept_exec_sp == -1 ) -+ { -+ /* Default to non-executable superpages on vulnerable hardware. */ -+ opt_ept_exec_sp = !cpu_has_bug_pschange_mc; -+ -+ if ( cpu_has_bug_pschange_mc ) -+ printk("VMX: Disabling executable EPT superpages due to CVE-2018-12207\n"); -+ } -+ - vmx_function_table.hap_supported = 1; - vmx_function_table.altp2m_supported = 1; - -diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c -index ce46201d45..93e08f89a2 100644 ---- xen/arch/x86/mm/p2m-ept.c.orig -+++ xen/arch/x86/mm/p2m-ept.c -@@ -215,6 +215,12 @@ static void ept_p2m_type_to_flags(struct p2m_domain *p2m, ept_entry_t *entry, - break; - } - -+ /* -+ * Don't create executable superpages if we need to shatter them to -+ * protect against CVE-2018-12207. -+ */ -+ if ( !opt_ept_exec_sp && is_epte_superpage(entry) ) -+ entry->x = 0; - } - - #define GUEST_TABLE_MAP_FAILED 0 -diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h -index 89619e4afd..20eb7f6082 100644 ---- xen/include/asm-x86/hvm/vmx/vmx.h.orig -+++ xen/include/asm-x86/hvm/vmx/vmx.h -@@ -28,6 +28,8 @@ - #include <asm/hvm/trace.h> - #include <asm/hvm/vmx/vmcs.h> - -+extern int8_t opt_ept_exec_sp; -+ - typedef union { - struct { - u64 r : 1, /* bit 0 - Read permission */ -diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h -index b8151d2d9f..89ae3e03f1 100644 ---- xen/include/asm-x86/msr-index.h.orig -+++ xen/include/asm-x86/msr-index.h -@@ -54,6 +54,7 @@ - #define ARCH_CAPS_SKIP_L1DFL (_AC(1, ULL) << 3) - #define ARCH_CAPS_SSB_NO (_AC(1, ULL) << 4) - #define ARCH_CAPS_MDS_NO (_AC(1, ULL) << 5) -+#define ARCH_CAPS_IF_PSCHANGE_MC_NO (_AC(1, ULL) << 6) - - #define MSR_FLUSH_CMD 0x0000010b - #define FLUSH_CMD_L1D (_AC(1, ULL) << 0) -From: Andrew Cooper <andrew.cooper3@citrix.com> -Subject: x86/vtx: Allow runtime modification of the exec-sp setting - -See patch for details. - -Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> -Reviewed-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: George Dunlap <george.dunlap@citrix.com> - -diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown -index 684671cb7b..33ed1ffc40 100644 ---- docs/misc/xen-command-line.markdown.orig -+++ docs/misc/xen-command-line.markdown -@@ -861,6 +861,21 @@ Controls EPT related features. - If HVM guest kernels are trusted not to mount a DoS against the system, - this option can enabled to regain performance. - -+ This boolean may be modified at runtime using `xl set-parameters -+ ept=[no-]exec-sp` to switch between fast and secure. -+ -+ * When switching from secure to fast, preexisting HVM domains will run -+ at their current performance until they are rebooted; new domains will -+ run without any overhead. -+ -+ * When switching from fast to secure, all HVM domains will immediately -+ suffer a performance penalty. -+ -+ **Warning: No guarantee is made that this runtime option will be retained -+ indefinitely, or that it will retain this exact behaviour. It is -+ intended as an emergency option for people who first chose fast, then -+ change their minds to secure, and wish not to reboot.** -+ - ### extra\_guest\_irqs - > `= [<domU number>][,<dom0 number>]` - -diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c -index 8821a3b536..15376e25ba 100644 ---- xen/arch/x86/hvm/vmx/vmcs.c.orig -+++ xen/arch/x86/hvm/vmx/vmcs.c -@@ -107,6 +107,41 @@ static int __init parse_ept_param(const char *s) - } - custom_param("ept", parse_ept_param); - -+static int parse_ept_param_runtime(const char *s) -+{ -+ int val; -+ -+ if ( !cpu_has_vmx_ept || !hvm_funcs.hap_supported || -+ !(hvm_funcs.hap_capabilities & -+ (HVM_HAP_SUPERPAGE_2MB | HVM_HAP_SUPERPAGE_1GB)) ) -+ { -+ printk("VMX: EPT not available, or not in use - ignoring\n"); -+ return 0; -+ } -+ -+ if ( (val = parse_boolean("exec-sp", s, NULL)) < 0 ) -+ return -EINVAL; -+ -+ if ( val != opt_ept_exec_sp ) -+ { -+ struct domain *d; -+ -+ opt_ept_exec_sp = val; -+ -+ rcu_read_lock(&domlist_read_lock); -+ for_each_domain ( d ) -+ if ( paging_mode_hap(d) ) -+ p2m_change_entry_type_global(d, p2m_ram_rw, p2m_ram_rw); -+ rcu_read_unlock(&domlist_read_lock); -+ } -+ -+ printk("VMX: EPT executable superpages %sabled\n", -+ val ? "en" : "dis"); -+ -+ return 0; -+} -+custom_runtime_only_param("ept", parse_ept_param_runtime); -+ - /* Dynamic (run-time adjusted) execution control flags. */ - u32 vmx_pin_based_exec_control __read_mostly; - u32 vmx_cpu_based_exec_control __read_mostly; -diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c -index 2b62bc61dd..97c417fc3e 100644 ---- xen/arch/x86/mm/p2m.c.orig -+++ xen/arch/x86/mm/p2m.c -@@ -257,17 +257,22 @@ int p2m_is_logdirty_range(struct p2m_domain *p2m, unsigned long start, - return 0; - } - -+/* -+ * May be called with ot = nt = p2m_ram_rw for its side effect of -+ * recalculating all PTEs in the p2m. -+ */ - void p2m_change_entry_type_global(struct domain *d, - p2m_type_t ot, p2m_type_t nt) - { - struct p2m_domain *p2m = p2m_get_hostp2m(d); - -- ASSERT(ot != nt); - ASSERT(p2m_is_changeable(ot) && p2m_is_changeable(nt)); - - p2m_lock(p2m); - p2m->change_entry_type_global(p2m, ot, nt); -- p2m->global_logdirty = (nt == p2m_ram_logdirty); -+ /* Don't allow 'recalculate' operations to change the logdirty state. */ -+ if ( ot != nt ) -+ p2m->global_logdirty = (nt == p2m_ram_logdirty); - p2m_unlock(p2m); - } - |