From 30f2ec4b6ca91786459f8ad9257140b2a6dfa11f Mon Sep 17 00:00:00 2001 From: Michael Young Date: Nov 10 2020 20:21:03 +0000 Subject: Information leak via power sidechannel [XSA-351] add make as build requires --- diff --git a/xen.spec b/xen.spec index a1b2011..1f9d6fc 100644 --- a/xen.spec +++ b/xen.spec @@ -58,7 +58,7 @@ Summary: Xen is a virtual machine monitor Name: xen Version: 4.14.0 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv2+ and LGPLv2+ and BSD URL: http://xen.org/ Source0: https://downloads.xenproject.org/release/xen/%{version}/xen-%{version}.tar.gz @@ -138,6 +138,9 @@ Patch69: xsa347-4.14-3.patch Patch70: xen.gcc11.fixes.patch Patch71: xsa286-4.14-0001-x86-pv-Drop-FLUSH_TLB_GLOBAL-in-do_mmu_update-for-XP.patch Patch72: xsa286-4.14-0002-x86-pv-Flush-TLB-in-response-to-paging-structure-cha.patch +Patch73: xsa351-arm.patch +Patch74: xsa351-x86-4.14-1.patch +Patch75: xsa351-x86-4.14-2.patch %if %build_qemutrad @@ -181,7 +184,7 @@ BuildRequires: checkpolicy m4 # cross compiler for building 64-bit hypervisor on ix86 BuildRequires: gcc-x86_64-linux-gnu %endif -BuildRequires: gcc +BuildRequires: gcc make Requires: iproute Requires: python3-lxml Requires: xen-runtime = %{version}-%{release} @@ -365,6 +368,9 @@ manage Xen virtual machines. %patch70 -p1 %patch71 -p1 %patch72 -p1 +%patch73 -p1 +%patch74 -p1 +%patch75 -p1 # qemu-xen-traditional patches pushd tools/qemu-xen-traditional @@ -958,6 +964,10 @@ fi %endif %changelog +* Tue Nov 10 2020 Michael Young - 4.14.0-10 +- Information leak via power sidechannel [XSA-351] +- add make as build requires + * Tue Nov 03 2020 Michael Young - 4.14.0-9 - revised patch for XSA-286 (mitigating performance impact) diff --git a/xsa351-arm.patch b/xsa351-arm.patch new file mode 100644 index 0000000..d0d1941 --- /dev/null +++ b/xsa351-arm.patch @@ -0,0 +1,58 @@ +From: Julien Grall +Subject: xen/arm: Always trap AMU system registers + +The Activity Monitors Unit (AMU) has been introduced by ARMv8.4. It is +considered to be unsafe to be expose to guests as they might expose +information about code executed by other guests or the host. + +Arm provided a way to trap all the AMU system registers by setting +CPTR_EL2.TAM to 1. + +Unfortunately, on older revision of the specification, the bit 30 (now +CPTR_EL1.TAM) was RES0. Because of that, Xen is setting it to 0 and +therefore the system registers would be exposed to the guest when it is +run on processors with AMU. + +As the bit is mark as UNKNOWN at boot in Armv8.4, the only safe solution +for us is to always set CPTR_EL1.TAM to 1. + +Guest trying to access the AMU system registers will now receive an +undefined instruction. Unfortunately, this means that even well-behaved +guest may fail to boot because we don't sanitize the ID registers. + +This is a known issues with other Armv8.0+ features (e.g. SVE, Pointer +Auth). This will taken care separately. + +This is part of XSA-351 (or XSA-93 re-born). + +Signed-off-by: Julien Grall +Reviewed-by: Andre Przywara +Reviewed-by: Stefano Stabellini +Reviewed-by: Bertrand Marquis + +diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c +index a36f145e67..22bd1bd4c6 100644 +--- a/xen/arch/arm/traps.c ++++ b/xen/arch/arm/traps.c +@@ -151,7 +151,8 @@ void init_traps(void) + * On ARM64 the TCPx bits which we set here (0..9,12,13) are all + * RES1, i.e. they would trap whether we did this write or not. + */ +- WRITE_SYSREG((HCPTR_CP_MASK & ~(HCPTR_CP(10) | HCPTR_CP(11))) | HCPTR_TTA, ++ WRITE_SYSREG((HCPTR_CP_MASK & ~(HCPTR_CP(10) | HCPTR_CP(11))) | ++ HCPTR_TTA | HCPTR_TAM, + CPTR_EL2); + + /* +diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h +index 3ca67f8157..d3d12a9d19 100644 +--- a/xen/include/asm-arm/processor.h ++++ b/xen/include/asm-arm/processor.h +@@ -351,6 +351,7 @@ + #define VTCR_RES1 (_AC(1,UL)<<31) + + /* HCPTR Hyp. Coprocessor Trap Register */ ++#define HCPTR_TAM ((_AC(1,U)<<30)) + #define HCPTR_TTA ((_AC(1,U)<<20)) /* Trap trace registers */ + #define HCPTR_CP(x) ((_AC(1,U)<<(x))) /* Trap Coprocessor x */ + #define HCPTR_CP_MASK ((_AC(1,U)<<14)-1) diff --git a/xsa351-x86-4.14-1.patch b/xsa351-x86-4.14-1.patch new file mode 100644 index 0000000..1be14fb --- /dev/null +++ b/xsa351-x86-4.14-1.patch @@ -0,0 +1,155 @@ +From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= +Subject: x86/msr: fix handling of MSR_IA32_PERF_{STATUS/CTL} +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently a PV hardware domain can also be given control over the CPU +frequency, and such guest is allowed to write to MSR_IA32_PERF_CTL. +However since commit 322ec7c89f6 the default behavior has been changed +to reject accesses to not explicitly handled MSRs, preventing PV +guests that manage CPU frequency from reading +MSR_IA32_PERF_{STATUS/CTL}. + +Additionally some HVM guests (Windows at least) will attempt to read +MSR_IA32_PERF_CTL and will panic if given back a #GP fault: + + vmx.c:3035:d8v0 RDMSR 0x00000199 unimplemented + d8v0 VIRIDIAN CRASH: 3b c0000096 fffff806871c1651 ffffda0253683720 0 + +Move the handling of MSR_IA32_PERF_{STATUS/CTL} to the common MSR +handling shared between HVM and PV guests, and add an explicit case +for reads to MSR_IA32_PERF_{STATUS/CTL}. + +Restore previous behavior and allow PV guests with the required +permissions to read the contents of the mentioned MSRs. Non privileged +guests will get 0 when trying to read those registers, as writes to +MSR_IA32_PERF_CTL by such guest will already be silently dropped. + +Fixes: 322ec7c89f6 ('x86/pv: disallow access to unknown MSRs') +Fixes: 84e848fd7a1 ('x86/hvm: disallow access to unknown MSRs') +Signed-off-by: Roger Pau Monné +Signed-off-by: Andrew Cooper +Reviewed-by: Roger Pau Monné +Reviewed-by: Jan Beulich +(cherry picked from commit 3059178798a23ba870ff86ff54d442a07e6651fc) + +diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c +index d72ab0fa1f..3db26faf08 100644 +--- a/xen/arch/x86/msr.c ++++ b/xen/arch/x86/msr.c +@@ -245,6 +245,25 @@ int guest_rdmsr(struct vcpu *v, uint32_t msr, uint64_t *val) + *val = msrs->misc_features_enables.raw; + break; + ++ /* ++ * These MSRs are not enumerated in CPUID. They have been around ++ * since the Pentium 4, and implemented by other vendors. ++ * ++ * Some versions of Windows try reading these before setting up a #GP ++ * handler, and Linux has several unguarded reads as well. Provide ++ * RAZ semantics, in general, but permit a cpufreq controller dom0 to ++ * have full access. ++ */ ++ case MSR_IA32_PERF_STATUS: ++ case MSR_IA32_PERF_CTL: ++ if ( !(cp->x86_vendor & (X86_VENDOR_INTEL | X86_VENDOR_CENTAUR)) ) ++ goto gp_fault; ++ ++ *val = 0; ++ if ( likely(!is_cpufreq_controller(d)) || rdmsr_safe(msr, *val) == 0 ) ++ break; ++ goto gp_fault; ++ + case MSR_X2APIC_FIRST ... MSR_X2APIC_LAST: + if ( !is_hvm_domain(d) || v != curr ) + goto gp_fault; +@@ -343,6 +362,7 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val) + case MSR_INTEL_CORE_THREAD_COUNT: + case MSR_INTEL_PLATFORM_INFO: + case MSR_ARCH_CAPABILITIES: ++ case MSR_IA32_PERF_STATUS: + /* Read-only */ + case MSR_TEST_CTRL: + case MSR_TSX_FORCE_ABORT: +@@ -454,6 +474,21 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val) + break; + } + ++ /* ++ * This MSR is not enumerated in CPUID. It has been around since the ++ * Pentium 4, and implemented by other vendors. ++ * ++ * To match the RAZ semantics, implement as write-discard, except for ++ * a cpufreq controller dom0 which has full access. ++ */ ++ case MSR_IA32_PERF_CTL: ++ if ( !(cp->x86_vendor & (X86_VENDOR_INTEL | X86_VENDOR_CENTAUR)) ) ++ goto gp_fault; ++ ++ if ( likely(!is_cpufreq_controller(d)) || wrmsr_safe(msr, val) == 0 ) ++ break; ++ goto gp_fault; ++ + case MSR_X2APIC_FIRST ... MSR_X2APIC_LAST: + if ( !is_hvm_domain(d) || v != curr ) + goto gp_fault; +diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c +index 85a9fd4767..5c7b9117ae 100644 +--- a/xen/arch/x86/pv/emul-priv-op.c ++++ b/xen/arch/x86/pv/emul-priv-op.c +@@ -820,12 +820,6 @@ static inline uint64_t guest_misc_enable(uint64_t val) + return val; + } + +-static inline bool is_cpufreq_controller(const struct domain *d) +-{ +- return ((cpufreq_controller == FREQCTL_dom0_kernel) && +- is_hardware_domain(d)); +-} +- + static int read_msr(unsigned int reg, uint64_t *val, + struct x86_emulate_ctxt *ctxt) + { +@@ -1070,14 +1064,6 @@ static int write_msr(unsigned int reg, uint64_t val, + return X86EMUL_OKAY; + break; + +- case MSR_IA32_PERF_CTL: +- if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ) +- break; +- if ( likely(!is_cpufreq_controller(currd)) || +- wrmsr_safe(reg, val) == 0 ) +- return X86EMUL_OKAY; +- break; +- + case MSR_IA32_THERM_CONTROL: + case MSR_IA32_ENERGY_PERF_BIAS: + if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ) +diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h +index a0d87ef9d0..97ba8e0795 100644 +--- a/xen/include/xen/sched.h ++++ b/xen/include/xen/sched.h +@@ -1071,6 +1071,22 @@ extern enum cpufreq_controller { + FREQCTL_none, FREQCTL_dom0_kernel, FREQCTL_xen + } cpufreq_controller; + ++static always_inline bool is_cpufreq_controller(const struct domain *d) ++{ ++ /* ++ * A PV dom0 can be nominated as the cpufreq controller, instead of using ++ * Xen's cpufreq driver, at which point dom0 gets direct access to certain ++ * MSRs. ++ * ++ * This interface only works when dom0 is identity pinned and has the same ++ * number of vCPUs as pCPUs on the system. ++ * ++ * It would be far better to paravirtualise the interface. ++ */ ++ return (is_pv_domain(d) && is_hardware_domain(d) && ++ cpufreq_controller == FREQCTL_dom0_kernel); ++} ++ + int cpupool_move_domain(struct domain *d, struct cpupool *c); + int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op); + int cpupool_get_id(const struct domain *d); diff --git a/xsa351-x86-4.14-2.patch b/xsa351-x86-4.14-2.patch new file mode 100644 index 0000000..2c0f4e7 --- /dev/null +++ b/xsa351-x86-4.14-2.patch @@ -0,0 +1,126 @@ +From: Andrew Cooper +Subject: x86/msr: Disallow guest access to the RAPL MSRs + +Researchers have demonstrated using the RAPL interface to perform a +differential power analysis attack to recover AES keys used by other cores in +the system. + +Furthermore, even privileged guests cannot use this interface correctly, due +to MSR scope and vcpu scheduling issues. The interface would want to be +paravirtualised to be used sensibly. + +Disallow access to the RAPL MSRs completely, as well as other MSRs which +potentially access fine grain power information. + +This is part of XSA-351. + +Signed-off-by: Andrew Cooper +Reviewed-by: Jan Beulich + +diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c +index 3db26faf08..aa107823ac 100644 +--- a/xen/arch/x86/msr.c ++++ b/xen/arch/x86/msr.c +@@ -185,6 +185,13 @@ int guest_rdmsr(struct vcpu *v, uint32_t msr, uint64_t *val) + case MSR_TSX_CTRL: + case MSR_MCU_OPT_CTRL: + case MSR_RTIT_OUTPUT_BASE ... MSR_RTIT_ADDR_B(7): ++ case MSR_RAPL_POWER_UNIT: ++ case MSR_PKG_POWER_LIMIT ... MSR_PKG_POWER_INFO: ++ case MSR_DRAM_POWER_LIMIT ... MSR_DRAM_POWER_INFO: ++ case MSR_PP0_POWER_LIMIT ... MSR_PP0_POLICY: ++ case MSR_PP1_POWER_LIMIT ... MSR_PP1_POLICY: ++ case MSR_PLATFORM_ENERGY_COUNTER: ++ case MSR_PLATFORM_POWER_LIMIT: + case MSR_U_CET: + case MSR_S_CET: + case MSR_PL0_SSP ... MSR_INTERRUPT_SSP_TABLE: +@@ -192,6 +199,8 @@ int guest_rdmsr(struct vcpu *v, uint32_t msr, uint64_t *val) + case MSR_AMD64_LWP_CBADDR: + case MSR_PPIN_CTL: + case MSR_PPIN: ++ case MSR_F15H_CU_POWER ... MSR_F15H_CU_MAX_POWER: ++ case MSR_AMD_RAPL_POWER_UNIT ... MSR_AMD_PKG_ENERGY_STATUS: + case MSR_AMD_PPIN_CTL: + case MSR_AMD_PPIN: + /* Not offered to guests. */ +@@ -369,6 +378,13 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val) + case MSR_TSX_CTRL: + case MSR_MCU_OPT_CTRL: + case MSR_RTIT_OUTPUT_BASE ... MSR_RTIT_ADDR_B(7): ++ case MSR_RAPL_POWER_UNIT: ++ case MSR_PKG_POWER_LIMIT ... MSR_PKG_POWER_INFO: ++ case MSR_DRAM_POWER_LIMIT ... MSR_DRAM_POWER_INFO: ++ case MSR_PP0_POWER_LIMIT ... MSR_PP0_POLICY: ++ case MSR_PP1_POWER_LIMIT ... MSR_PP1_POLICY: ++ case MSR_PLATFORM_ENERGY_COUNTER: ++ case MSR_PLATFORM_POWER_LIMIT: + case MSR_U_CET: + case MSR_S_CET: + case MSR_PL0_SSP ... MSR_INTERRUPT_SSP_TABLE: +@@ -376,6 +392,8 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val) + case MSR_AMD64_LWP_CBADDR: + case MSR_PPIN_CTL: + case MSR_PPIN: ++ case MSR_F15H_CU_POWER ... MSR_F15H_CU_MAX_POWER: ++ case MSR_AMD_RAPL_POWER_UNIT ... MSR_AMD_PKG_ENERGY_STATUS: + case MSR_AMD_PPIN_CTL: + case MSR_AMD_PPIN: + /* Not offered to guests. */ +diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h +index 0fe98af923..5e64ecff91 100644 +--- a/xen/include/asm-x86/msr-index.h ++++ b/xen/include/asm-x86/msr-index.h +@@ -77,6 +77,38 @@ + #define MSR_RTIT_ADDR_A(n) (0x00000580 + (n) * 2) + #define MSR_RTIT_ADDR_B(n) (0x00000581 + (n) * 2) + ++/* ++ * Intel Runtime Average Power Limiting (RAPL) interface. Power plane base ++ * addresses (MSR_*_POWER_LIMIT) are model specific, but have so-far been ++ * consistent since their introduction in SandyBridge. ++ * ++ * Offsets of functionality from the power plane base is architectural, but ++ * not all power planes support all functionality. ++ */ ++#define MSR_RAPL_POWER_UNIT 0x00000606 ++ ++#define MSR_PKG_POWER_LIMIT 0x00000610 ++#define MSR_PKG_ENERGY_STATUS 0x00000611 ++#define MSR_PKG_PERF_STATUS 0x00000613 ++#define MSR_PKG_POWER_INFO 0x00000614 ++ ++#define MSR_DRAM_POWER_LIMIT 0x00000618 ++#define MSR_DRAM_ENERGY_STATUS 0x00000619 ++#define MSR_DRAM_PERF_STATUS 0x0000061b ++#define MSR_DRAM_POWER_INFO 0x0000061c ++ ++#define MSR_PP0_POWER_LIMIT 0x00000638 ++#define MSR_PP0_ENERGY_STATUS 0x00000639 ++#define MSR_PP0_POLICY 0x0000063a ++ ++#define MSR_PP1_POWER_LIMIT 0x00000640 ++#define MSR_PP1_ENERGY_STATUS 0x00000641 ++#define MSR_PP1_POLICY 0x00000642 ++ ++/* Intel Platform-wide power interface. */ ++#define MSR_PLATFORM_ENERGY_COUNTER 0x0000064d ++#define MSR_PLATFORM_POWER_LIMIT 0x0000065c ++ + #define MSR_U_CET 0x000006a0 + #define MSR_S_CET 0x000006a2 + #define CET_SHSTK_EN (_AC(1, ULL) << 0) +@@ -92,6 +124,13 @@ + #define PASID_PASID_MASK 0x000fffff + #define PASID_VALID (_AC(1, ULL) << 31) + ++#define MSR_F15H_CU_POWER 0xc001007a ++#define MSR_F15H_CU_MAX_POWER 0xc001007b ++ ++#define MSR_AMD_RAPL_POWER_UNIT 0xc0010299 ++#define MSR_AMD_CORE_ENERGY_STATUS 0xc001029a ++#define MSR_AMD_PKG_ENERGY_STATUS 0xc001029b ++ + /* + * Legacy MSR constants in need of cleanup. No new MSRs below this comment. + */