From d3978bf9dc42f00c8d05d8eac255f93ef154b503 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 1 Jun 2013 16:12:19 -0500 Subject: main/xen: remove obsolete XSA patches. --- main/xen/xsa33-4.2-unstable.patch | 21 --- main/xen/xsa34-4.2.patch | 30 ---- main/xen/xsa35-4.2-with-xsa34.patch | 24 --- main/xen/xsa36-4.2.patch | 323 ------------------------------------ main/xen/xsa38.patch | 73 -------- main/xen/xsa44-4.2.patch | 77 --------- main/xen/xsa46-4.2.patch | 293 -------------------------------- main/xen/xsa47-4.2-unstable.patch | 31 ---- 8 files changed, 872 deletions(-) delete mode 100644 main/xen/xsa33-4.2-unstable.patch delete mode 100644 main/xen/xsa34-4.2.patch delete mode 100644 main/xen/xsa35-4.2-with-xsa34.patch delete mode 100644 main/xen/xsa36-4.2.patch delete mode 100644 main/xen/xsa38.patch delete mode 100644 main/xen/xsa44-4.2.patch delete mode 100644 main/xen/xsa46-4.2.patch delete mode 100644 main/xen/xsa47-4.2-unstable.patch (limited to 'main/xen') diff --git a/main/xen/xsa33-4.2-unstable.patch b/main/xen/xsa33-4.2-unstable.patch deleted file mode 100644 index 369d65bba9..0000000000 --- a/main/xen/xsa33-4.2-unstable.patch +++ /dev/null @@ -1,21 +0,0 @@ -VT-d: fix interrupt remapping source validation for devices behind -legacy bridges - -Using SVT_VERIFY_BUS here doesn't make sense; native Linux also -uses SVT_VERIFY_SID_SQ here instead. - -This is XSA-33 / CVE-2012-5634. - -Signed-off-by: Jan Beulich - ---- a/xen/drivers/passthrough/vtd/intremap.c -+++ b/xen/drivers/passthrough/vtd/intremap.c -@@ -466,7 +466,7 @@ static void set_msi_source_id(struct pci_dev *pdev, struct iremap_entry *ire) - set_ire_sid(ire, SVT_VERIFY_BUS, SQ_ALL_16, - (bus << 8) | pdev->bus); - else if ( pdev_type(seg, bus, devfn) == DEV_TYPE_LEGACY_PCI_BRIDGE ) -- set_ire_sid(ire, SVT_VERIFY_BUS, SQ_ALL_16, -+ set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16, - PCI_BDF2(bus, devfn)); - } - break; diff --git a/main/xen/xsa34-4.2.patch b/main/xen/xsa34-4.2.patch deleted file mode 100644 index f5328eff9f..0000000000 --- a/main/xen/xsa34-4.2.patch +++ /dev/null @@ -1,30 +0,0 @@ -x86_32: don't allow use of nested HVM - -There are (indirect) uses of map_domain_page() in the nested HVM code -that are unsafe when not just using the 1:1 mapping. - -This is XSA-34 / CVE-2013-0151. - -Signed-off-by: Jan Beulich - ---- a/xen/arch/x86/hvm/hvm.c -+++ b/xen/arch/x86/hvm/hvm.c -@@ -3926,6 +3926,10 @@ long do_hvm_op(unsigned long op, XEN_GUE - rc = -EINVAL; - break; - case HVM_PARAM_NESTEDHVM: -+#ifdef __i386__ -+ if ( a.value ) -+ rc = -EINVAL; -+#else - if ( a.value > 1 ) - rc = -EINVAL; - if ( !is_hvm_domain(d) ) -@@ -3940,6 +3944,7 @@ long do_hvm_op(unsigned long op, XEN_GUE - for_each_vcpu(d, v) - if ( rc == 0 ) - rc = nestedhvm_vcpu_initialise(v); -+#endif - break; - case HVM_PARAM_BUFIOREQ_EVTCHN: - rc = -EINVAL; diff --git a/main/xen/xsa35-4.2-with-xsa34.patch b/main/xen/xsa35-4.2-with-xsa34.patch deleted file mode 100644 index 89230e2a46..0000000000 --- a/main/xen/xsa35-4.2-with-xsa34.patch +++ /dev/null @@ -1,24 +0,0 @@ -xen: Do not allow guests to enable nested HVM on themselves - -There is no reason for this and doing so exposes a memory leak to -guests. Only toolstacks need write access to this HVM param. - -This is XSA-35 / CVE-2013-0152. - -Signed-off-by: Ian Campbell -Acked-by: Jan Beulich - ---- a/xen/arch/x86/hvm/hvm.c -+++ b/xen/arch/x86/hvm/hvm.c -@@ -3862,6 +3862,11 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg) - rc = -EINVAL; - break; - case HVM_PARAM_NESTEDHVM: -+ if ( !IS_PRIV(current->domain) ) -+ { -+ rc = -EPERM; -+ break; -+ } - #ifdef __i386__ - if ( a.value ) - rc = -EINVAL; diff --git a/main/xen/xsa36-4.2.patch b/main/xen/xsa36-4.2.patch deleted file mode 100644 index 8477701a22..0000000000 --- a/main/xen/xsa36-4.2.patch +++ /dev/null @@ -1,323 +0,0 @@ -ACPI: acpi_table_parse() should return handler's error code - -Currently, the error code returned by acpi_table_parse()'s handler -is ignored. This patch will propagate handler's return value to -acpi_table_parse()'s caller. - -AMD,IOMMU: Clean up old entries in remapping tables when creating new -interrupt mapping. - -When changing the affinity of an IRQ associated with a passed -through PCI device, clear previous mapping. - -In addition, because some BIOSes may incorrectly program IVRS -entries for IOAPIC try to check for entry's consistency. Specifically, -if conflicting entries are found disable IOMMU if per-device -remapping table is used. If entries refer to bogus IOAPIC IDs -disable IOMMU unconditionally - -AMD,IOMMU: Disable IOMMU if SATA Combined mode is on - -AMD's SP5100 chipset can be placed into SATA Combined mode -that may cause prevent dom0 from booting when IOMMU is -enabled and per-device interrupt remapping table is used. -While SP5100 erratum 28 requires BIOSes to disable this mode, -some may still use it. - -This patch checks whether this mode is on and, if per-device -table is in use, disables IOMMU. - -AMD,IOMMU: Make per-device interrupt remapping table default - -Using global interrupt remapping table may be insecure, as -described by XSA-36. This patch makes per-device mode default. - -This is XSA-36 / CVE-2013-0153. - -Signed-off-by: Jan Beulich -Signed-off-by: Boris Ostrovsky - ---- a/xen/arch/x86/irq.c -+++ b/xen/arch/x86/irq.c -@@ -1942,9 +1942,6 @@ int map_domain_pirq( - spin_lock_irqsave(&desc->lock, flags); - set_domain_irq_pirq(d, irq, info); - spin_unlock_irqrestore(&desc->lock, flags); -- -- if ( opt_irq_vector_map == OPT_IRQ_VECTOR_MAP_PERDEV ) -- printk(XENLOG_INFO "Per-device vector maps for GSIs not implemented yet.\n"); - } - - done: ---- a/xen/drivers/acpi/tables.c -+++ b/xen/drivers/acpi/tables.c -@@ -267,7 +267,7 @@ acpi_table_parse_madt(enum acpi_madt_typ - * @handler: handler to run - * - * Scan the ACPI System Descriptor Table (STD) for a table matching @id, -- * run @handler on it. Return 0 if table found, return on if not. -+ * run @handler on it. - */ - int __init acpi_table_parse(char *id, acpi_table_handler handler) - { -@@ -282,8 +282,7 @@ int __init acpi_table_parse(char *id, ac - acpi_get_table(id, 0, &table); - - if (table) { -- handler(table); -- return 0; -+ return handler(table); - } else - return 1; - } ---- a/xen/drivers/passthrough/amd/iommu_acpi.c -+++ b/xen/drivers/passthrough/amd/iommu_acpi.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -635,6 +636,7 @@ static u16 __init parse_ivhd_device_spec - u16 header_length, u16 block_length, struct amd_iommu *iommu) - { - u16 dev_length, bdf; -+ int apic; - - dev_length = sizeof(*special); - if ( header_length < (block_length + dev_length) ) -@@ -651,10 +653,59 @@ static u16 __init parse_ivhd_device_spec - } - - add_ivrs_mapping_entry(bdf, bdf, special->header.data_setting, iommu); -- /* set device id of ioapic */ -- ioapic_sbdf[special->handle].bdf = bdf; -- ioapic_sbdf[special->handle].seg = seg; -- return dev_length; -+ -+ if ( special->variety != ACPI_IVHD_IOAPIC ) -+ { -+ if ( special->variety != ACPI_IVHD_HPET ) -+ printk(XENLOG_ERR "Unrecognized IVHD special variety %#x\n", -+ special->variety); -+ return dev_length; -+ } -+ -+ /* -+ * Some BIOSes have IOAPIC broken entries so we check for IVRS -+ * consistency here --- whether entry's IOAPIC ID is valid and -+ * whether there are conflicting/duplicated entries. -+ */ -+ for ( apic = 0; apic < nr_ioapics; apic++ ) -+ { -+ if ( IO_APIC_ID(apic) != special->handle ) -+ continue; -+ -+ if ( ioapic_sbdf[special->handle].pin_setup ) -+ { -+ if ( ioapic_sbdf[special->handle].bdf == bdf && -+ ioapic_sbdf[special->handle].seg == seg ) -+ AMD_IOMMU_DEBUG("IVHD Warning: Duplicate IO-APIC %#x entries\n", -+ special->handle); -+ else -+ { -+ printk(XENLOG_ERR "IVHD Error: Conflicting IO-APIC %#x entries\n", -+ special->handle); -+ if ( amd_iommu_perdev_intremap ) -+ return 0; -+ } -+ } -+ else -+ { -+ /* set device id of ioapic */ -+ ioapic_sbdf[special->handle].bdf = bdf; -+ ioapic_sbdf[special->handle].seg = seg; -+ -+ ioapic_sbdf[special->handle].pin_setup = xzalloc_array( -+ unsigned long, BITS_TO_LONGS(nr_ioapic_entries[apic])); -+ if ( nr_ioapic_entries[apic] && -+ !ioapic_sbdf[IO_APIC_ID(apic)].pin_setup ) -+ { -+ printk(XENLOG_ERR "IVHD Error: Out of memory\n"); -+ return 0; -+ } -+ } -+ return dev_length; -+ } -+ -+ printk(XENLOG_ERR "IVHD Error: Invalid IO-APIC %#x\n", special->handle); -+ return 0; - } - - static int __init parse_ivhd_block(const struct acpi_ivrs_hardware *ivhd_block) ---- a/xen/drivers/passthrough/amd/iommu_init.c -+++ b/xen/drivers/passthrough/amd/iommu_init.c -@@ -1126,12 +1126,45 @@ static int __init amd_iommu_setup_device - return 0; - } - -+/* Check whether SP5100 SATA Combined mode is on */ -+static bool_t __init amd_sp5100_erratum28(void) -+{ -+ u32 bus, id; -+ u16 vendor_id, dev_id; -+ u8 byte; -+ -+ for (bus = 0; bus < 256; bus++) -+ { -+ id = pci_conf_read32(0, bus, 0x14, 0, PCI_VENDOR_ID); -+ -+ vendor_id = id & 0xffff; -+ dev_id = (id >> 16) & 0xffff; -+ -+ /* SP5100 SMBus module sets Combined mode on */ -+ if (vendor_id != 0x1002 || dev_id != 0x4385) -+ continue; -+ -+ byte = pci_conf_read8(0, bus, 0x14, 0, 0xad); -+ if ( (byte >> 3) & 1 ) -+ { -+ printk(XENLOG_WARNING "AMD-Vi: SP5100 erratum 28 detected, disabling IOMMU.\n" -+ "If possible, disable SATA Combined mode in BIOS or contact your vendor for BIOS update.\n"); -+ return 1; -+ } -+ } -+ -+ return 0; -+} -+ - int __init amd_iommu_init(void) - { - struct amd_iommu *iommu; - - BUG_ON( !iommu_found() ); - -+ if ( amd_iommu_perdev_intremap && amd_sp5100_erratum28() ) -+ goto error_out; -+ - ivrs_bdf_entries = amd_iommu_get_ivrs_dev_entries(); - - if ( !ivrs_bdf_entries ) ---- a/xen/drivers/passthrough/amd/iommu_intr.c -+++ b/xen/drivers/passthrough/amd/iommu_intr.c -@@ -99,12 +99,12 @@ static void update_intremap_entry(u32* e - static void update_intremap_entry_from_ioapic( - int bdf, - struct amd_iommu *iommu, -- struct IO_APIC_route_entry *ioapic_rte) -+ const struct IO_APIC_route_entry *rte, -+ const struct IO_APIC_route_entry *old_rte) - { - unsigned long flags; - u32* entry; - u8 delivery_mode, dest, vector, dest_mode; -- struct IO_APIC_route_entry *rte = ioapic_rte; - int req_id; - spinlock_t *lock; - int offset; -@@ -120,6 +120,14 @@ static void update_intremap_entry_from_i - spin_lock_irqsave(lock, flags); - - offset = get_intremap_offset(vector, delivery_mode); -+ if ( old_rte ) -+ { -+ int old_offset = get_intremap_offset(old_rte->vector, -+ old_rte->delivery_mode); -+ -+ if ( offset != old_offset ) -+ free_intremap_entry(iommu->seg, bdf, old_offset); -+ } - entry = (u32*)get_intremap_entry(iommu->seg, req_id, offset); - update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest); - -@@ -188,6 +196,7 @@ int __init amd_iommu_setup_ioapic_remapp - amd_iommu_flush_intremap(iommu, req_id); - spin_unlock_irqrestore(&iommu->lock, flags); - } -+ set_bit(pin, ioapic_sbdf[IO_APIC_ID(apic)].pin_setup); - } - } - return 0; -@@ -199,6 +208,7 @@ void amd_iommu_ioapic_update_ire( - struct IO_APIC_route_entry old_rte = { 0 }; - struct IO_APIC_route_entry new_rte = { 0 }; - unsigned int rte_lo = (reg & 1) ? reg - 1 : reg; -+ unsigned int pin = (reg - 0x10) / 2; - int saved_mask, seg, bdf; - struct amd_iommu *iommu; - -@@ -236,6 +246,14 @@ void amd_iommu_ioapic_update_ire( - *(((u32 *)&new_rte) + 1) = value; - } - -+ if ( new_rte.mask && -+ !test_bit(pin, ioapic_sbdf[IO_APIC_ID(apic)].pin_setup) ) -+ { -+ ASSERT(saved_mask); -+ __io_apic_write(apic, reg, value); -+ return; -+ } -+ - /* mask the interrupt while we change the intremap table */ - if ( !saved_mask ) - { -@@ -244,7 +262,11 @@ void amd_iommu_ioapic_update_ire( - } - - /* Update interrupt remapping entry */ -- update_intremap_entry_from_ioapic(bdf, iommu, &new_rte); -+ update_intremap_entry_from_ioapic( -+ bdf, iommu, &new_rte, -+ test_and_set_bit(pin, -+ ioapic_sbdf[IO_APIC_ID(apic)].pin_setup) ? &old_rte -+ : NULL); - - /* Forward write access to IO-APIC RTE */ - __io_apic_write(apic, reg, value); -@@ -354,6 +376,12 @@ void amd_iommu_msi_msg_update_ire( - return; - } - -+ if ( msi_desc->remap_index >= 0 ) -+ update_intremap_entry_from_msi_msg(iommu, pdev, msi_desc, NULL); -+ -+ if ( !msg ) -+ return; -+ - update_intremap_entry_from_msi_msg(iommu, pdev, msi_desc, msg); - } - ---- a/xen/drivers/passthrough/amd/pci_amd_iommu.c -+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c -@@ -205,6 +205,8 @@ int __init amd_iov_detect(void) - { - printk("AMD-Vi: Not overriding irq_vector_map setting\n"); - } -+ if ( !amd_iommu_perdev_intremap ) -+ printk(XENLOG_WARNING "AMD-Vi: Using global interrupt remap table is not recommended (see XSA-36)!\n"); - return scan_pci_devices(); - } - ---- a/xen/drivers/passthrough/iommu.c -+++ b/xen/drivers/passthrough/iommu.c -@@ -52,7 +52,7 @@ bool_t __read_mostly iommu_qinval = 1; - bool_t __read_mostly iommu_intremap = 1; - bool_t __read_mostly iommu_hap_pt_share = 1; - bool_t __read_mostly iommu_debug; --bool_t __read_mostly amd_iommu_perdev_intremap; -+bool_t __read_mostly amd_iommu_perdev_intremap = 1; - - DEFINE_PER_CPU(bool_t, iommu_dont_flush_iotlb); - ---- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h -+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h -@@ -100,6 +100,7 @@ void amd_iommu_read_msi_from_ire( - - extern struct ioapic_sbdf { - u16 bdf, seg; -+ unsigned long *pin_setup; - } ioapic_sbdf[MAX_IO_APICS]; - extern void *shared_intremap_table; - diff --git a/main/xen/xsa38.patch b/main/xen/xsa38.patch deleted file mode 100644 index f4a5dc0881..0000000000 --- a/main/xen/xsa38.patch +++ /dev/null @@ -1,73 +0,0 @@ -diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml -index 3558889..d4d1c7b 100644 ---- a/tools/ocaml/libs/xb/partial.ml -+++ b/tools/ocaml/libs/xb/partial.ml -@@ -27,8 +27,15 @@ external header_size: unit -> int = "stub_header_size" - external header_of_string_internal: string -> int * int * int * int - = "stub_header_of_string" - -+let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *) -+ - let of_string s = - let tid, rid, opint, dlen = header_of_string_internal s in -+ (* A packet which is bigger than xenstore_payload_max is illegal. -+ This will leave the guest connection is a bad state and will -+ be hard to recover from without restarting the connection -+ (ie rebooting the guest) *) -+ let dlen = min xenstore_payload_max dlen in - { - tid = tid; - rid = rid; -@@ -38,6 +45,7 @@ let of_string s = - } - - let append pkt s sz = -+ if pkt.len > 4096 then failwith "Buffer.add: cannot grow buffer"; - Buffer.add_string pkt.buf (String.sub s 0 sz) - - let to_complete pkt = -diff --git a/tools/ocaml/libs/xb/xs_ring_stubs.c b/tools/ocaml/libs/xb/xs_ring_stubs.c -index 00414c5..4888ac5 100644 ---- a/tools/ocaml/libs/xb/xs_ring_stubs.c -+++ b/tools/ocaml/libs/xb/xs_ring_stubs.c -@@ -39,21 +39,23 @@ static int xs_ring_read(struct mmap_interface *interface, - char *buffer, int len) - { - struct xenstore_domain_interface *intf = interface->addr; -- XENSTORE_RING_IDX cons, prod; -+ XENSTORE_RING_IDX cons, prod; /* offsets only */ - int to_read; - -- cons = intf->req_cons; -- prod = intf->req_prod; -+ cons = *(volatile uint32*)&intf->req_cons; -+ prod = *(volatile uint32*)&intf->req_prod; - xen_mb(); -+ cons = MASK_XENSTORE_IDX(cons); -+ prod = MASK_XENSTORE_IDX(prod); - if (prod == cons) - return 0; -- if (MASK_XENSTORE_IDX(prod) > MASK_XENSTORE_IDX(cons)) -+ if (prod > cons) - to_read = prod - cons; - else -- to_read = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons); -+ to_read = XENSTORE_RING_SIZE - cons; - if (to_read < len) - len = to_read; -- memcpy(buffer, intf->req + MASK_XENSTORE_IDX(cons), len); -+ memcpy(buffer, intf->req + cons, len); - xen_mb(); - intf->req_cons += len; - return len; -@@ -66,8 +68,8 @@ static int xs_ring_write(struct mmap_interface *interface, - XENSTORE_RING_IDX cons, prod; - int can_write; - -- cons = intf->rsp_cons; -- prod = intf->rsp_prod; -+ cons = *(volatile uint32*)&intf->rsp_cons; -+ prod = *(volatile uint32*)&intf->rsp_prod; - xen_mb(); - if ( (prod - cons) >= XENSTORE_RING_SIZE ) - return 0; diff --git a/main/xen/xsa44-4.2.patch b/main/xen/xsa44-4.2.patch deleted file mode 100644 index 07ed9386f6..0000000000 --- a/main/xen/xsa44-4.2.patch +++ /dev/null @@ -1,77 +0,0 @@ -x86: clear EFLAGS.NT in SYSENTER entry path - -... as it causes problems if we happen to exit back via IRET: In the -course of trying to handle the fault, the hypervisor creates a stack -frame by hand, and uses PUSHFQ to set the respective EFLAGS field, but -expects to be able to IRET through that stack frame to the second -portion of the fixup code (which causes a #GP due to the stored EFLAGS -having NT set). - -And even if this worked (e.g if we cleared NT in that path), it would -then (through the fail safe callback) cause a #GP in the guest with the -SYSENTER handler's first instruction as the source, which in turn would -allow guest user mode code to crash the guest kernel. - -Inject a #GP on the fake (NULL) address of the SYSENTER instruction -instead, just like in the case where the guest kernel didn't register -a corresponding entry point. - -On 32-bit we also need to make sure we clear SYSENTER_CS for all CPUs -(neither #RESET nor #INIT guarantee this). - -This is CVE-2013-1917 / XSA-44. - -Reported-by: Andrew Cooper -Signed-off-by: Jan Beulich -Tested-by: Andrew Cooper -Acked-by: Andrew Cooper - ---- a/xen/arch/x86/acpi/suspend.c -+++ b/xen/arch/x86/acpi/suspend.c -@@ -81,8 +81,12 @@ void restore_rest_processor_state(void) - } - - #else /* !defined(CONFIG_X86_64) */ -- if ( supervisor_mode_kernel && cpu_has_sep ) -- wrmsr(MSR_IA32_SYSENTER_ESP, &this_cpu(init_tss).esp1, 0); -+ if ( cpu_has_sep ) -+ { -+ wrmsr(MSR_IA32_SYSENTER_CS, 0, 0); -+ if ( supervisor_mode_kernel ) -+ wrmsr(MSR_IA32_SYSENTER_ESP, &this_cpu(init_tss).esp1, 0); -+ } - #endif - - /* Maybe load the debug registers. */ ---- a/xen/arch/x86/cpu/common.c -+++ b/xen/arch/x86/cpu/common.c -@@ -655,8 +655,11 @@ void __cpuinit cpu_init(void) - #if defined(CONFIG_X86_32) - t->ss0 = __HYPERVISOR_DS; - t->esp0 = get_stack_bottom(); -- if ( supervisor_mode_kernel && cpu_has_sep ) -+ if ( cpu_has_sep ) { -+ wrmsr(MSR_IA32_SYSENTER_CS, 0, 0); -+ if ( supervisor_mode_kernel ) - wrmsr(MSR_IA32_SYSENTER_ESP, &t->esp1, 0); -+ } - #elif defined(CONFIG_X86_64) - /* Bottom-of-stack must be 16-byte aligned! */ - BUG_ON((get_stack_bottom() & 15) != 0); ---- a/xen/arch/x86/x86_64/entry.S -+++ b/xen/arch/x86/x86_64/entry.S -@@ -284,7 +284,14 @@ sysenter_eflags_saved: - cmpb $0,VCPU_sysenter_disables_events(%rbx) - movq VCPU_sysenter_addr(%rbx),%rax - setne %cl -+ testl $X86_EFLAGS_NT,UREGS_eflags(%rsp) - leaq VCPU_trap_bounce(%rbx),%rdx -+UNLIKELY_START(nz, sysenter_nt_set) -+ pushfq -+ andl $~X86_EFLAGS_NT,(%rsp) -+ popfq -+ xorl %eax,%eax -+UNLIKELY_END(sysenter_nt_set) - testq %rax,%rax - leal (,%rcx,TBF_INTERRUPT),%ecx - UNLIKELY_START(z, sysenter_gpf) diff --git a/main/xen/xsa46-4.2.patch b/main/xen/xsa46-4.2.patch deleted file mode 100644 index 9448ea9c67..0000000000 --- a/main/xen/xsa46-4.2.patch +++ /dev/null @@ -1,293 +0,0 @@ -x86: fix various issues with handling guest IRQs - -- properly revoke IRQ access in map_domain_pirq() error path -- don't permit replacing an in use IRQ -- don't accept inputs in the GSI range for MAP_PIRQ_TYPE_MSI -- track IRQ access permission in host IRQ terms, not guest IRQ ones - (and with that, also disallow Dom0 access to IRQ0) - -This is CVE-2013-1919 / XSA-46. - -Signed-off-by: Jan Beulich -Acked-by: Stefano Stabellini - ---- a/tools/libxl/libxl_create.c -+++ b/tools/libxl/libxl_create.c -@@ -968,14 +968,16 @@ static void domcreate_launch_dm(libxl__e - } - - for (i = 0; i < d_config->b_info.num_irqs; i++) { -- uint32_t irq = d_config->b_info.irqs[i]; -+ int irq = d_config->b_info.irqs[i]; - -- LOG(DEBUG, "dom%d irq %"PRIx32, domid, irq); -+ LOG(DEBUG, "dom%d irq %d", domid, irq); - -- ret = xc_domain_irq_permission(CTX->xch, domid, irq, 1); -+ ret = irq >= 0 ? xc_physdev_map_pirq(CTX->xch, domid, irq, &irq) -+ : -EOVERFLOW; -+ if (!ret) -+ ret = xc_domain_irq_permission(CTX->xch, domid, irq, 1); - if ( ret<0 ){ -- LOGE(ERROR, -- "failed give dom%d access to irq %"PRId32, domid, irq); -+ LOGE(ERROR, "failed give dom%d access to irq %d", domid, irq); - ret = ERROR_FAIL; - } - } ---- a/tools/python/xen/xend/server/irqif.py -+++ b/tools/python/xen/xend/server/irqif.py -@@ -73,6 +73,12 @@ class IRQController(DevController): - - pirq = get_param('irq') - -+ rc = xc.physdev_map_pirq(domid = self.getDomid(), -+ index = pirq, -+ pirq = pirq) -+ if rc < 0: -+ raise VmError('irq: Failed to map irq %x' % (pirq)) -+ - rc = xc.domain_irq_permission(domid = self.getDomid(), - pirq = pirq, - allow_access = True) -@@ -81,12 +87,6 @@ class IRQController(DevController): - #todo non-fatal - raise VmError( - 'irq: Failed to configure irq: %d' % (pirq)) -- rc = xc.physdev_map_pirq(domid = self.getDomid(), -- index = pirq, -- pirq = pirq) -- if rc < 0: -- raise VmError( -- 'irq: Failed to map irq %x' % (pirq)) - back = dict([(k, config[k]) for k in self.valid_cfg if k in config]) - return (self.allocateDeviceID(), back, {}) - ---- a/xen/arch/x86/domain_build.c -+++ b/xen/arch/x86/domain_build.c -@@ -1219,7 +1219,7 @@ int __init construct_dom0( - /* DOM0 is permitted full I/O capabilities. */ - rc |= ioports_permit_access(dom0, 0, 0xFFFF); - rc |= iomem_permit_access(dom0, 0UL, ~0UL); -- rc |= irqs_permit_access(dom0, 0, d->nr_pirqs - 1); -+ rc |= irqs_permit_access(dom0, 1, nr_irqs_gsi - 1); - - /* - * Modify I/O port access permissions. ---- a/xen/arch/x86/domctl.c -+++ b/xen/arch/x86/domctl.c -@@ -772,9 +772,13 @@ long arch_do_domctl( - goto bind_out; - - ret = -EPERM; -- if ( !IS_PRIV(current->domain) && -- !irq_access_permitted(current->domain, bind->machine_irq) ) -- goto bind_out; -+ if ( !IS_PRIV(current->domain) ) -+ { -+ int irq = domain_pirq_to_irq(d, bind->machine_irq); -+ -+ if ( irq <= 0 || !irq_access_permitted(current->domain, irq) ) -+ goto bind_out; -+ } - - ret = -ESRCH; - if ( iommu_enabled ) -@@ -803,9 +807,13 @@ long arch_do_domctl( - bind = &(domctl->u.bind_pt_irq); - - ret = -EPERM; -- if ( !IS_PRIV(current->domain) && -- !irq_access_permitted(current->domain, bind->machine_irq) ) -- goto unbind_out; -+ if ( !IS_PRIV(current->domain) ) -+ { -+ int irq = domain_pirq_to_irq(d, bind->machine_irq); -+ -+ if ( irq <= 0 || !irq_access_permitted(current->domain, irq) ) -+ goto unbind_out; -+ } - - if ( iommu_enabled ) - { ---- a/xen/arch/x86/irq.c -+++ b/xen/arch/x86/irq.c -@@ -184,6 +184,14 @@ int create_irq(int node) - desc->arch.used = IRQ_UNUSED; - irq = ret; - } -+ else if ( dom0 ) -+ { -+ ret = irq_permit_access(dom0, irq); -+ if ( ret ) -+ printk(XENLOG_G_ERR -+ "Could not grant Dom0 access to IRQ%d (error %d)\n", -+ irq, ret); -+ } - - return irq; - } -@@ -280,6 +288,17 @@ void clear_irq_vector(int irq) - void destroy_irq(unsigned int irq) - { - BUG_ON(!MSI_IRQ(irq)); -+ -+ if ( dom0 ) -+ { -+ int err = irq_deny_access(dom0, irq); -+ -+ if ( err ) -+ printk(XENLOG_G_ERR -+ "Could not revoke Dom0 access to IRQ%u (error %d)\n", -+ irq, err); -+ } -+ - dynamic_irq_cleanup(irq); - clear_irq_vector(irq); - } -@@ -1858,7 +1877,7 @@ int map_domain_pirq( - - if ( !IS_PRIV(current->domain) && - !(IS_PRIV_FOR(current->domain, d) && -- irq_access_permitted(current->domain, pirq))) -+ irq_access_permitted(current->domain, irq))) - return -EPERM; - - if ( pirq < 0 || pirq >= d->nr_pirqs || irq < 0 || irq >= nr_irqs ) -@@ -1887,17 +1906,18 @@ int map_domain_pirq( - return ret; - } - -- ret = irq_permit_access(d, pirq); -+ ret = irq_permit_access(d, irq); - if ( ret ) - { -- dprintk(XENLOG_G_ERR, "dom%d: could not permit access to irq %d\n", -- d->domain_id, pirq); -+ printk(XENLOG_G_ERR -+ "dom%d: could not permit access to IRQ%d (pirq %d)\n", -+ d->domain_id, irq, pirq); - return ret; - } - - ret = prepare_domain_irq_pirq(d, irq, pirq, &info); - if ( ret ) -- return ret; -+ goto revoke; - - desc = irq_to_desc(irq); - -@@ -1921,8 +1941,14 @@ int map_domain_pirq( - spin_lock_irqsave(&desc->lock, flags); - - if ( desc->handler != &no_irq_type ) -+ { -+ spin_unlock_irqrestore(&desc->lock, flags); - dprintk(XENLOG_G_ERR, "dom%d: irq %d in use\n", - d->domain_id, irq); -+ pci_disable_msi(msi_desc); -+ ret = -EBUSY; -+ goto done; -+ } - setup_msi_handler(desc, msi_desc); - - if ( opt_irq_vector_map == OPT_IRQ_VECTOR_MAP_PERDEV -@@ -1951,7 +1977,14 @@ int map_domain_pirq( - - done: - if ( ret ) -+ { - cleanup_domain_irq_pirq(d, irq, info); -+ revoke: -+ if ( irq_deny_access(d, irq) ) -+ printk(XENLOG_G_ERR -+ "dom%d: could not revoke access to IRQ%d (pirq %d)\n", -+ d->domain_id, irq, pirq); -+ } - return ret; - } - -@@ -2017,10 +2050,11 @@ int unmap_domain_pirq(struct domain *d, - if ( !forced_unbind ) - cleanup_domain_irq_pirq(d, irq, info); - -- ret = irq_deny_access(d, pirq); -+ ret = irq_deny_access(d, irq); - if ( ret ) -- dprintk(XENLOG_G_ERR, "dom%d: could not deny access to irq %d\n", -- d->domain_id, pirq); -+ printk(XENLOG_G_ERR -+ "dom%d: could not deny access to IRQ%d (pirq %d)\n", -+ d->domain_id, irq, pirq); - - done: - return ret; ---- a/xen/arch/x86/physdev.c -+++ b/xen/arch/x86/physdev.c -@@ -147,7 +147,7 @@ int physdev_map_pirq(domid_t domid, int - if ( irq == -1 ) - irq = create_irq(NUMA_NO_NODE); - -- if ( irq < 0 || irq >= nr_irqs ) -+ if ( irq < nr_irqs_gsi || irq >= nr_irqs ) - { - dprintk(XENLOG_G_ERR, "dom%d: can't create irq for msi!\n", - d->domain_id); ---- a/xen/common/domctl.c -+++ b/xen/common/domctl.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -897,9 +898,9 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc - else if ( xsm_irq_permission(d, pirq, allow) ) - ret = -EPERM; - else if ( allow ) -- ret = irq_permit_access(d, pirq); -+ ret = pirq_permit_access(d, pirq); - else -- ret = irq_deny_access(d, pirq); -+ ret = pirq_deny_access(d, pirq); - - rcu_unlock_domain(d); - } ---- a/xen/common/event_channel.c -+++ b/xen/common/event_channel.c -@@ -369,7 +369,7 @@ static long evtchn_bind_pirq(evtchn_bind - if ( (pirq < 0) || (pirq >= d->nr_pirqs) ) - return -EINVAL; - -- if ( !is_hvm_domain(d) && !irq_access_permitted(d, pirq) ) -+ if ( !is_hvm_domain(d) && !pirq_access_permitted(d, pirq) ) - return -EPERM; - - spin_lock(&d->event_lock); ---- a/xen/include/xen/iocap.h -+++ b/xen/include/xen/iocap.h -@@ -28,4 +28,22 @@ - #define irq_access_permitted(d, i) \ - rangeset_contains_singleton((d)->irq_caps, i) - -+#define pirq_permit_access(d, i) ({ \ -+ struct domain *d__ = (d); \ -+ int i__ = domain_pirq_to_irq(d__, i); \ -+ i__ > 0 ? rangeset_add_singleton(d__->irq_caps, i__)\ -+ : -EINVAL; \ -+}) -+#define pirq_deny_access(d, i) ({ \ -+ struct domain *d__ = (d); \ -+ int i__ = domain_pirq_to_irq(d__, i); \ -+ i__ > 0 ? rangeset_remove_singleton(d__->irq_caps, i__)\ -+ : -EINVAL; \ -+}) -+#define pirq_access_permitted(d, i) ({ \ -+ struct domain *d__ = (d); \ -+ rangeset_contains_singleton(d__->irq_caps, \ -+ domain_pirq_to_irq(d__, i));\ -+}) -+ - #endif /* __XEN_IOCAP_H__ */ diff --git a/main/xen/xsa47-4.2-unstable.patch b/main/xen/xsa47-4.2-unstable.patch deleted file mode 100644 index 7ebb8c8a31..0000000000 --- a/main/xen/xsa47-4.2-unstable.patch +++ /dev/null @@ -1,31 +0,0 @@ -defer event channel bucket pointer store until after XSM checks - -Otherwise a dangling pointer can be left, which would cause subsequent -memory corruption as soon as the space got re-allocated for some other -purpose. - -This is CVE-2013-1920 / XSA-47. - -Reported-by: Wei Liu -Signed-off-by: Jan Beulich -Reviewed-by: Tim Deegan - ---- a/xen/common/event_channel.c -+++ b/xen/common/event_channel.c -@@ -140,7 +140,6 @@ static int get_free_port(struct domain * - chn = xzalloc_array(struct evtchn, EVTCHNS_PER_BUCKET); - if ( unlikely(chn == NULL) ) - return -ENOMEM; -- bucket_from_port(d, port) = chn; - - for ( i = 0; i < EVTCHNS_PER_BUCKET; i++ ) - { -@@ -153,6 +152,8 @@ static int get_free_port(struct domain * - } - } - -+ bucket_from_port(d, port) = chn; -+ - return port; - } - -- cgit v1.2.3