From b5231bddba35ce2daf5df35532b14017b3cda8a2 Mon Sep 17 00:00:00 2001 From: Michael Young Date: Nov 14 2023 22:32:53 +0000 Subject: 2 security issues x86/AMD: mismatch in IOMMU quarantine page table levels [XSA-445, CVE-2023-46835] x86: BTC/SRSO fixes not fully effective [XSA-446, CVE-2023-46836] --- diff --git a/xen.spec b/xen.spec index fde47fb..1845570 100644 --- a/xen.spec +++ b/xen.spec @@ -55,7 +55,7 @@ Summary: Xen is a virtual machine monitor Name: xen Version: 4.17.2 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv2+ and LGPLv2+ and BSD URL: http://xen.org/ Source0: https://downloads.xenproject.org/release/xen/%{version}/xen-%{version}.tar.gz @@ -139,6 +139,8 @@ Patch74: xsa443-4.17-10.patch Patch75: xsa443-4.17-11.patch Patch76: xsa444-4.17-1.patch Patch77: xsa444-4.17-2.patch +Patch78: xsa445-4.17.patch +Patch79: xsa446.patch %if %build_qemutrad @@ -382,6 +384,8 @@ manage Xen virtual machines. %patch 75 -p1 %patch 76 -p1 %patch 77 -p1 +%patch 78 -p1 +%patch 79 -p1 # qemu-xen-traditional patches pushd tools/qemu-xen-traditional @@ -989,6 +993,11 @@ fi %endif %changelog +* Tue Nov 14 2023 Michael Young - 4.17.2-5 +- x86/AMD: mismatch in IOMMU quarantine page table levels [XSA-445, + CVE-2023-46835] +- x86: BTC/SRSO fixes not fully effective [XSA-446, CVE-2023-46836] + * Tue Oct 10 2023 Michael Young - 4.17.2-4 - xenstored: A transaction conflict can crash C Xenstored [XSA-440, CVE-2023-34323] diff --git a/xsa445-4.17.patch b/xsa445-4.17.patch new file mode 100644 index 0000000..db66d7c --- /dev/null +++ b/xsa445-4.17.patch @@ -0,0 +1,63 @@ +From a43127d4f1f9a364334fe16b6239c211b35fd238 Mon Sep 17 00:00:00 2001 +From: Roger Pau Monne +Date: Wed, 11 Oct 2023 13:14:21 +0200 +Subject: [PATCH] iommu/amd-vi: use correct level for quarantine domain page + tables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The current setup of the quarantine page tables assumes that the quarantine +domain (dom_io) has been initialized with an address width of +DEFAULT_DOMAIN_ADDRESS_WIDTH (48). + +However dom_io being a PV domain gets the AMD-Vi IOMMU page tables levels based +on the maximum (hot pluggable) RAM address, and hence on systems with no RAM +above the 512GB mark only 3 page-table levels are configured in the IOMMU. + +On systems without RAM above the 512GB boundary amd_iommu_quarantine_init() +will setup page tables for the scratch page with 4 levels, while the IOMMU will +be configured to use 3 levels only. The page destined to be used as level 1, +and to contain a directory of PTEs ends up being the address in a PTE itself, +and thus level 1 page becomes the leaf page. Without the level mismatch it's +level 0 page that should be the leaf page instead. + +The level 1 page won't be used as such, and hence it's not possible to use it +to gain access to other memory on the system. However that page is not cleared +in amd_iommu_quarantine_init() as part of re-initialization of the device +quarantine page tables, and hence data on the level 1 page can be leaked +between device usages. + +Fix this by making sure the paging levels setup by amd_iommu_quarantine_init() +match the number configured on the IOMMUs. + +Note that IVMD regions are not affected by this issue, as those areas are +mapped taking the configured paging levels into account. + +This is XSA-445 / CVE-2023-46835 + +Fixes: ea38867831da ('x86 / iommu: set up a scratch page in the quarantine domain') +Signed-off-by: Roger Pau Monné +Reviewed-by: Jan Beulich +--- + xen/drivers/passthrough/amd/iommu_map.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/xen/drivers/passthrough/amd/iommu_map.c b/xen/drivers/passthrough/amd/iommu_map.c +index 993bac6f8878..e0f4fe736a8d 100644 +--- a/xen/drivers/passthrough/amd/iommu_map.c ++++ b/xen/drivers/passthrough/amd/iommu_map.c +@@ -837,9 +837,7 @@ static int fill_qpt(union amd_iommu_pte *this, unsigned int level, + int cf_check amd_iommu_quarantine_init(struct pci_dev *pdev, bool scratch_page) + { + struct domain_iommu *hd = dom_iommu(dom_io); +- unsigned long end_gfn = +- 1ul << (DEFAULT_DOMAIN_ADDRESS_WIDTH - PAGE_SHIFT); +- unsigned int level = amd_iommu_get_paging_mode(end_gfn); ++ unsigned int level = hd->arch.amd.paging_mode; + unsigned int req_id = get_dma_requestor_id(pdev->seg, pdev->sbdf.bdf); + const struct ivrs_mappings *ivrs_mappings = get_ivrs_mappings(pdev->seg); + int rc; +-- +2.42.0 + diff --git a/xsa446.patch b/xsa446.patch new file mode 100644 index 0000000..acf1d0f --- /dev/null +++ b/xsa446.patch @@ -0,0 +1,115 @@ +From 80d5aada598c3a800a350003d5d582931545e13c Mon Sep 17 00:00:00 2001 +From: Andrew Cooper +Date: Thu, 26 Oct 2023 14:37:38 +0100 +Subject: [PATCH] x86/spec-ctrl: Remove conditional IRQs-on-ness for INT + $0x80/0x82 paths +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Before speculation defences, some paths in Xen could genuinely get away with +being IRQs-on at entry. But XPTI invalidated this property on most paths, and +attempting to maintain it on the remaining paths was a mistake. + +Fast forward, and DO_SPEC_CTRL_COND_IBPB (protection for AMD BTC/SRSO) is not +IRQ-safe, running with IRQs enabled in some cases. The other actions taken on +these paths happen to be IRQ-safe. + +Make entry_int82() and int80_direct_trap() unconditionally Interrupt Gates +rather than Trap Gates. Remove the conditional re-adjustment of +int80_direct_trap() in smp_prepare_cpus(), and have entry_int82() explicitly +enable interrupts when safe to do so. + +In smp_prepare_cpus(), with the conditional re-adjustment removed, the +clearing of pv_cr3 is the only remaining action gated on XPTI, and it is out +of place anyway, repeating work already done by smp_prepare_boot_cpu(). Drop +the entire if() condition to avoid leaving an incorrect vestigial remnant. + +Also drop comments which make incorrect statements about when its safe to +enable interrupts. + +This is XSA-446 / CVE-2023-46836 + +Signed-off-by: Andrew Cooper +Reviewed-by: Roger Pau Monné +--- + xen/arch/x86/pv/traps.c | 4 ++-- + xen/arch/x86/smpboot.c | 14 -------------- + xen/arch/x86/x86_64/compat/entry.S | 2 ++ + xen/arch/x86/x86_64/entry.S | 1 - + 4 files changed, 4 insertions(+), 17 deletions(-) + +diff --git a/xen/arch/x86/pv/traps.c b/xen/arch/x86/pv/traps.c +index 74f333da7e1c..240d1a2db7a3 100644 +--- a/xen/arch/x86/pv/traps.c ++++ b/xen/arch/x86/pv/traps.c +@@ -139,11 +139,11 @@ void __init pv_trap_init(void) + #ifdef CONFIG_PV32 + /* The 32-on-64 hypercall vector is only accessible from ring 1. */ + _set_gate(idt_table + HYPERCALL_VECTOR, +- SYS_DESC_trap_gate, 1, entry_int82); ++ SYS_DESC_irq_gate, 1, entry_int82); + #endif + + /* Fast trap for int80 (faster than taking the #GP-fixup path). */ +- _set_gate(idt_table + LEGACY_SYSCALL_VECTOR, SYS_DESC_trap_gate, 3, ++ _set_gate(idt_table + LEGACY_SYSCALL_VECTOR, SYS_DESC_irq_gate, 3, + &int80_direct_trap); + + open_softirq(NMI_SOFTIRQ, nmi_softirq); +diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c +index 3a1a659082c6..4c54ecbc91d7 100644 +--- a/xen/arch/x86/smpboot.c ++++ b/xen/arch/x86/smpboot.c +@@ -1158,20 +1158,6 @@ void __init smp_prepare_cpus(void) + + stack_base[0] = (void *)((unsigned long)stack_start & ~(STACK_SIZE - 1)); + +- if ( opt_xpti_hwdom || opt_xpti_domu ) +- { +- get_cpu_info()->pv_cr3 = 0; +- +-#ifdef CONFIG_PV +- /* +- * All entry points which may need to switch page tables have to start +- * with interrupts off. Re-write what pv_trap_init() has put there. +- */ +- _set_gate(idt_table + LEGACY_SYSCALL_VECTOR, SYS_DESC_irq_gate, 3, +- &int80_direct_trap); +-#endif +- } +- + set_nr_sockets(); + + socket_cpumask = xzalloc_array(cpumask_t *, nr_sockets); +diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S +index bd5abd8040bd..fcc3a721f147 100644 +--- a/xen/arch/x86/x86_64/compat/entry.S ++++ b/xen/arch/x86/x86_64/compat/entry.S +@@ -21,6 +21,8 @@ ENTRY(entry_int82) + SPEC_CTRL_ENTRY_FROM_PV /* Req: %rsp=regs/cpuinfo, %rdx=0, Clob: acd */ + /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */ + ++ sti ++ + CR4_PV32_RESTORE + + GET_CURRENT(bx) +diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S +index 5ca74f5f62b2..9a7b129aa7e4 100644 +--- a/xen/arch/x86/x86_64/entry.S ++++ b/xen/arch/x86/x86_64/entry.S +@@ -327,7 +327,6 @@ ENTRY(sysenter_entry) + #ifdef CONFIG_XEN_SHSTK + ALTERNATIVE "", "setssbsy", X86_FEATURE_XEN_SHSTK + #endif +- /* sti could live here when we don't switch page tables below. */ + pushq $FLAT_USER_SS + pushq $0 + pushfq + +base-commit: 7befef87cc9b1bb8ca15d866ce1ecd9165ccb58c +prerequisite-patch-id: 142a87c707411d49e136c3fb76f1b14963ec6dc8 +-- +2.30.2 +