[Pkg-xen-changes] r1143 - in branches/wheezy/xen/debian: . patches

Bastian Blank waldi at alioth.debian.org
Wed Feb 6 11:56:04 UTC 2013


Author: waldi
Date: Wed Feb  6 11:56:03 2013
New Revision: 1143

Log:
* debian/changelog: Update.
* debian/patches: Add fix for CVE-2013-0153.

Added:
   branches/wheezy/xen/debian/patches/CVE-2013-0153-1
   branches/wheezy/xen/debian/patches/CVE-2013-0153-2
   branches/wheezy/xen/debian/patches/CVE-2013-0153-3
   branches/wheezy/xen/debian/patches/CVE-2013-0153-4
Modified:
   branches/wheezy/xen/debian/changelog
   branches/wheezy/xen/debian/patches/series

Modified: branches/wheezy/xen/debian/changelog
==============================================================================
--- branches/wheezy/xen/debian/changelog	Thu Jan 31 15:12:06 2013	(r1142)
+++ branches/wheezy/xen/debian/changelog	Wed Feb  6 11:56:03 2013	(r1143)
@@ -1,3 +1,11 @@
+xen (4.1.4-2) UNRELEASED; urgency=low
+
+  * Use pre-device interrupt remapping mode per default. Clean removing old
+    remappings.
+    CVE-2013-0153
+
+ -- Bastian Blank <waldi at debian.org>  Wed, 06 Feb 2013 12:52:01 +0100
+
 xen (4.1.4-1) unstable; urgency=low
 
   * New upstream release.

Added: branches/wheezy/xen/debian/patches/CVE-2013-0153-1
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/wheezy/xen/debian/patches/CVE-2013-0153-1	Wed Feb  6 11:56:03 2013	(r1143)
@@ -0,0 +1,29 @@
+Description: 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.
+From: Boris Ostrovsky <boris.ostrovsky at amd.com>
+Origin: upstream, commit:23448:dd6694df1a31
+Id: CVE-2013-0153
+---
+--- a/xen/drivers/acpi/tables.c	Thu Jan 17 16:11:02 2013 +0000
++++ b/xen/drivers/acpi/tables.c	Tue Feb 05 15:34:55 2013 +0100
+@@ -267,7 +267,7 @@
+  * @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 acpi_table_parse(char *id, acpi_table_handler handler)
+ {
+@@ -282,8 +282,7 @@
+ 		acpi_get_table(id, 0, &table);
+ 
+ 	if (table) {
+-		handler(table);
+-		return 0;
++		return handler(table);
+ 	} else
+ 		return 1;
+ }

Added: branches/wheezy/xen/debian/patches/CVE-2013-0153-2
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/wheezy/xen/debian/patches/CVE-2013-0153-2	Wed Feb  6 11:56:03 2013	(r1143)
@@ -0,0 +1,234 @@
+Description: AMD,IOMMU: Clean up old entries in remapping tables when creating new one
+ 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
+From: Jan Beulich <jbeulich at suse.com>
+From: Boris Ostrovsky <boris.ostrovsky at amd.com>
+Origin: upstream, commit:23449:cac6ae5e5dc6
+Id: CVE-2013-0153
+---
+--- a/xen/drivers/passthrough/amd/iommu_acpi.c	Tue Feb 05 15:34:55 2013 +0100
++++ b/xen/drivers/passthrough/amd/iommu_acpi.c	Tue Feb 05 15:35:44 2013 +0100
+@@ -21,6 +21,7 @@
+ #include <xen/config.h>
+ #include <xen/errno.h>
+ #include <asm/apicdef.h>
++#include <asm/io_apic.h>
+ #include <asm/amd-iommu.h>
+ #include <asm/hvm/svm/amd-iommu-proto.h>
+ #include <asm/hvm/svm/amd-iommu-acpi.h>
+@@ -29,7 +30,6 @@
+ extern unsigned short ivrs_bdf_entries;
+ extern struct ivrs_mappings *ivrs_mappings;
+ extern unsigned short last_bdf;
+-extern int ioapic_bdf[MAX_IO_APICS];
+ extern void *shared_intremap_table;
+ 
+ static void add_ivrs_mapping_entry(
+@@ -636,6 +636,7 @@
+     u16 header_length, u16 block_length, struct amd_iommu *iommu)
+ {
+     u16 dev_length, bdf;
++    int apic;
+ 
+     dev_length = sizeof(struct acpi_ivhd_device_special);
+     if ( header_length < (block_length + dev_length) )
+@@ -652,9 +653,58 @@
+     }
+ 
+     add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+-    /* set device id of ioapic */
+-    ioapic_bdf[ivhd_device->special.handle] = bdf;
+-    return dev_length;
++
++    if ( ivhd_device->special.variety != 1 /* ACPI_IVHD_IOAPIC */ )
++    {
++        if ( ivhd_device->special.variety != 2 /* ACPI_IVHD_HPET */ )
++            printk(XENLOG_ERR "Unrecognized IVHD special variety %#x\n",
++                   ivhd_device->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) != ivhd_device->special.handle )
++            continue;
++
++        if ( ioapic_bdf[ivhd_device->special.handle].pin_setup )
++        {
++            if ( ioapic_bdf[ivhd_device->special.handle].bdf == bdf )
++                AMD_IOMMU_DEBUG("IVHD Warning: Duplicate IO-APIC %#x entries\n",
++                                ivhd_device->special.handle);
++            else
++            {
++                printk(XENLOG_ERR "IVHD Error: Conflicting IO-APIC %#x entries\n",
++                       ivhd_device->special.handle);
++                if ( amd_iommu_perdev_intremap )
++                    return 0;
++            }
++        }
++        else
++        {
++            /* set device id of ioapic */
++            ioapic_bdf[ivhd_device->special.handle].bdf = bdf;
++
++            ioapic_bdf[ivhd_device->special.handle].pin_setup = xzalloc_array(
++                unsigned long, BITS_TO_LONGS(nr_ioapic_registers[apic]));
++            if ( nr_ioapic_registers[apic] &&
++                 !ioapic_bdf[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",
++           ivhd_device->special.handle);
++    return 0;
+ }
+ 
+ static int __init parse_ivhd_block(struct acpi_ivhd_block_header *ivhd_block)
+diff -r dd6694df1a31 -r cac6ae5e5dc6 xen/drivers/passthrough/amd/iommu_intr.c
+--- a/xen/drivers/passthrough/amd/iommu_intr.c	Tue Feb 05 15:34:55 2013 +0100
++++ b/xen/drivers/passthrough/amd/iommu_intr.c	Tue Feb 05 15:35:44 2013 +0100
+@@ -27,7 +27,7 @@
+ #define INTREMAP_LENGTH 0xB
+ #define INTREMAP_ENTRIES (1 << INTREMAP_LENGTH)
+ 
+-int ioapic_bdf[MAX_IO_APICS];
++struct ioapic_bdf ioapic_bdf[MAX_IO_APICS];
+ extern struct ivrs_mappings *ivrs_mappings;
+ extern unsigned short ivrs_bdf_entries;
+ void *shared_intremap_table;
+@@ -117,12 +117,12 @@
+ 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;
+@@ -138,6 +138,14 @@
+     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(bdf, old_offset);
++    }
+     entry = (u32*)get_intremap_entry(req_id, offset);
+     update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
+ 
+@@ -176,7 +184,7 @@
+                 continue;
+ 
+             /* get device id of ioapic devices */
+-            bdf = ioapic_bdf[IO_APIC_ID(apic)];
++            bdf = ioapic_bdf[IO_APIC_ID(apic)].bdf;
+             iommu = find_iommu_for_device(bdf);
+             if ( !iommu )
+             {
+@@ -207,6 +215,7 @@
+                 flush_command_buffer(iommu);
+                 spin_unlock_irqrestore(&iommu->lock, flags);
+             }
++            set_bit(pin, ioapic_bdf[IO_APIC_ID(apic)].pin_setup);
+         }
+     }
+     return 0;
+@@ -218,6 +227,7 @@
+     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, bdf;
+     struct amd_iommu *iommu;
+ 
+@@ -228,7 +238,7 @@
+     }
+ 
+     /* get device id of ioapic devices */
+-    bdf = ioapic_bdf[IO_APIC_ID(apic)];
++    bdf = ioapic_bdf[IO_APIC_ID(apic)].bdf;
+     iommu = find_iommu_for_device(bdf);
+     if ( !iommu )
+     {
+@@ -254,6 +264,14 @@
+         *(((u32 *)&new_rte) + 1) = value;
+     }
+ 
++    if ( new_rte.mask &&
++         !test_bit(pin, ioapic_bdf[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 )
+     {
+@@ -262,7 +280,11 @@
+     }
+ 
+     /* 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_bdf[IO_APIC_ID(apic)].pin_setup) ? &old_rte
++                                                                 : NULL);
+ 
+     /* Forward write access to IO-APIC RTE */
+     __io_apic_write(apic, reg, value);
+@@ -373,6 +395,12 @@
+         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);
+ }
+ 
+diff -r dd6694df1a31 -r cac6ae5e5dc6 xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
+--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h	Tue Feb 05 15:34:55 2013 +0100
++++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h	Tue Feb 05 15:35:44 2013 +0100
+@@ -88,6 +88,11 @@
+ unsigned int amd_iommu_read_ioapic_from_ire(
+     unsigned int apic, unsigned int reg);
+ 
++extern struct ioapic_bdf {
++    u16 bdf;
++    unsigned long *pin_setup;
++} ioapic_bdf[];
++
+ /* power management support */
+ void amd_iommu_resume(void);
+ void amd_iommu_suspend(void);

Added: branches/wheezy/xen/debian/patches/CVE-2013-0153-3
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/wheezy/xen/debian/patches/CVE-2013-0153-3	Wed Feb  6 11:56:03 2013	(r1143)
@@ -0,0 +1,62 @@
+Description: 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.
+From: Jan Beulich <jbeulich at suse.com>
+From: Boris Ostrovsky <boris.ostrovsky at amd.com>
+Origin: upstream, commit:23450:5c0fe82d6060
+Id: CVE-2013-0153
+---
+--- a/xen/drivers/passthrough/amd/iommu_init.c	Tue Feb 05 15:35:44 2013 +0100
++++ b/xen/drivers/passthrough/amd/iommu_init.c	Tue Feb 05 15:36:11 2013 +0100
+@@ -897,12 +897,45 @@
+     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(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(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;
++
+     irq_to_iommu = xmalloc_array(struct amd_iommu *, nr_irqs);
+     if ( irq_to_iommu == NULL )
+         goto error_out;

Added: branches/wheezy/xen/debian/patches/CVE-2013-0153-4
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/wheezy/xen/debian/patches/CVE-2013-0153-4	Wed Feb  6 11:56:03 2013	(r1143)
@@ -0,0 +1,51 @@
+Description: 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.
+From: Boris Ostrovsky <boris.ostrovsky at amd.com>
+From: Jan Beulich <jbeulich at suse.com>
+Origin: upstream, commit:23451:e5ed73d172eb
+Id: CVE-2013-0153
+---
+--- a/xen/arch/x86/irq.c	Tue Feb 05 15:36:11 2013 +0100
++++ b/xen/arch/x86/irq.c	Tue Feb 05 15:36:34 2013 +0100
+@@ -1677,9 +1677,6 @@
+         d->arch.pirq_irq[pirq] = irq;
+         d->arch.irq_pirq[irq] = pirq;
+         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/passthrough/amd/pci_amd_iommu.c	Tue Feb 05 15:36:11 2013 +0100
++++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c	Tue Feb 05 15:36:34 2013 +0100
+@@ -195,6 +195,8 @@
+     {
+         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	Tue Feb 05 15:36:11 2013 +0100
++++ b/xen/drivers/passthrough/iommu.c	Tue Feb 05 15:36:34 2013 +0100
+@@ -49,7 +49,7 @@
+ bool_t __read_mostly iommu_intremap = 1;
+ bool_t __read_mostly iommu_hap_pt_share;
+ bool_t __read_mostly amd_iommu_debug;
+-bool_t __read_mostly amd_iommu_perdev_intremap;
++bool_t __read_mostly amd_iommu_perdev_intremap = 1;
+ 
+ static void __init parse_iommu_param(char *s)
+ {
+@@ -78,6 +78,8 @@
+             amd_iommu_debug = 1;
+         else if ( !strcmp(s, "amd-iommu-perdev-intremap") )
+             amd_iommu_perdev_intremap = 1;
++        else if ( !strcmp(s, "amd-iommu-global-intremap") )
++            amd_iommu_perdev_intremap = 0;
+         else if ( !strcmp(s, "dom0-passthrough") )
+             iommu_passthrough = 1;
+         else if ( !strcmp(s, "dom0-strict") )

Modified: branches/wheezy/xen/debian/patches/series
==============================================================================
--- branches/wheezy/xen/debian/patches/series	Thu Jan 31 15:12:06 2013	(r1142)
+++ branches/wheezy/xen/debian/patches/series	Wed Feb  6 11:56:03 2013	(r1143)
@@ -7,6 +7,10 @@
 CVE-2012-5634
 CVE-2012-6075-1
 CVE-2012-6075-2
+CVE-2013-0153-1
+CVE-2013-0153-2
+CVE-2013-0153-3
+CVE-2013-0153-4
 
 upstream-23001:9eb9948904cd
 upstream-23002:eb64b8f8eebb



More information about the Pkg-xen-changes mailing list