* gnu/packages/patches/qemu-CVE-2015-4037.patch, gnu/packages/patches/qemu-CVE-2015-4103.patch, gnu/packages/patches/qemu-CVE-2015-4104.patch, gnu/packages/patches/qemu-CVE-2015-4105.patch, gnu/packages/patches/qemu-CVE-2015-4106-pt1.patch, gnu/packages/patches/qemu-CVE-2015-4106-pt2.patch, gnu/packages/patches/qemu-CVE-2015-4106-pt3.patch, gnu/packages/patches/qemu-CVE-2015-4106-pt4.patch, gnu/packages/patches/qemu-CVE-2015-4106-pt5.patch, gnu/packages/patches/qemu-CVE-2015-4106-pt6.patch, gnu/packages/patches/qemu-CVE-2015-4106-pt7.patch, gnu/packages/patches/qemu-CVE-2015-4106-pt8.patch: New files. * gnu-system.am (dist_patch_DATA): Add them. * gnu/packages/qemu.scm (qemu-headless)[source]: Add patches.
		
			
				
	
	
		
			189 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 7611dae8a69f0f1775ba1a9a942961c2aa10d88e Mon Sep 17 00:00:00 2001
 | |
| From: Jan Beulich <jbeulich@suse.com>
 | |
| Date: Tue, 2 Jun 2015 15:07:00 +0000
 | |
| Subject: [PATCH] xen: don't allow guest to control MSI mask register
 | |
| 
 | |
| It's being used by the hypervisor. For now simply mimic a device not
 | |
| capable of masking, and fully emulate any accesses a guest may issue
 | |
| nevertheless as simple reads/writes without side effects.
 | |
| 
 | |
| This is XSA-129.
 | |
| 
 | |
| Signed-off-by: Jan Beulich <jbeulich@suse.com>
 | |
| Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
 | |
| ---
 | |
|  hw/pci/msi.c                |  4 --
 | |
|  hw/xen/xen_pt_config_init.c | 98 ++++++++++++++++++++++++++++++++++++++++-----
 | |
|  include/hw/pci/pci_regs.h   |  2 +
 | |
|  3 files changed, 90 insertions(+), 14 deletions(-)
 | |
| 
 | |
| diff --git a/hw/pci/msi.c b/hw/pci/msi.c
 | |
| index c111dba..f9c0484 100644
 | |
| --- a/hw/pci/msi.c
 | |
| +++ b/hw/pci/msi.c
 | |
| @@ -21,10 +21,6 @@
 | |
|  #include "hw/pci/msi.h"
 | |
|  #include "qemu/range.h"
 | |
|  
 | |
| -/* Eventually those constants should go to Linux pci_regs.h */
 | |
| -#define PCI_MSI_PENDING_32      0x10
 | |
| -#define PCI_MSI_PENDING_64      0x14
 | |
| -
 | |
|  /* PCI_MSI_ADDRESS_LO */
 | |
|  #define PCI_MSI_ADDRESS_LO_MASK         (~0x3)
 | |
|  
 | |
| diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
 | |
| index dae0519..68b8f22 100644
 | |
| --- a/hw/xen/xen_pt_config_init.c
 | |
| +++ b/hw/xen/xen_pt_config_init.c
 | |
| @@ -1016,13 +1016,9 @@ static XenPTRegInfo xen_pt_emu_reg_pm[] = {
 | |
|   */
 | |
|  
 | |
|  /* Helper */
 | |
| -static bool xen_pt_msgdata_check_type(uint32_t offset, uint16_t flags)
 | |
| -{
 | |
| -    /* check the offset whether matches the type or not */
 | |
| -    bool is_32 = (offset == PCI_MSI_DATA_32) && !(flags & PCI_MSI_FLAGS_64BIT);
 | |
| -    bool is_64 = (offset == PCI_MSI_DATA_64) &&  (flags & PCI_MSI_FLAGS_64BIT);
 | |
| -    return is_32 || is_64;
 | |
| -}
 | |
| +#define xen_pt_msi_check_type(offset, flags, what) \
 | |
| +        ((offset) == ((flags) & PCI_MSI_FLAGS_64BIT ? \
 | |
| +                      PCI_MSI_##what##_64 : PCI_MSI_##what##_32))
 | |
|  
 | |
|  /* Message Control register */
 | |
|  static int xen_pt_msgctrl_reg_init(XenPCIPassthroughState *s,
 | |
| @@ -1134,7 +1130,45 @@ static int xen_pt_msgdata_reg_init(XenPCIPassthroughState *s,
 | |
|      uint32_t offset = reg->offset;
 | |
|  
 | |
|      /* check the offset whether matches the type or not */
 | |
| -    if (xen_pt_msgdata_check_type(offset, flags)) {
 | |
| +    if (xen_pt_msi_check_type(offset, flags, DATA)) {
 | |
| +        *data = reg->init_val;
 | |
| +    } else {
 | |
| +        *data = XEN_PT_INVALID_REG;
 | |
| +    }
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +/* this function will be called twice (for 32 bit and 64 bit type) */
 | |
| +/* initialize Mask register */
 | |
| +static int xen_pt_mask_reg_init(XenPCIPassthroughState *s,
 | |
| +                                XenPTRegInfo *reg, uint32_t real_offset,
 | |
| +                                uint32_t *data)
 | |
| +{
 | |
| +    uint32_t flags = s->msi->flags;
 | |
| +
 | |
| +    /* check the offset whether matches the type or not */
 | |
| +    if (!(flags & PCI_MSI_FLAGS_MASKBIT)) {
 | |
| +        *data = XEN_PT_INVALID_REG;
 | |
| +    } else if (xen_pt_msi_check_type(reg->offset, flags, MASK)) {
 | |
| +        *data = reg->init_val;
 | |
| +    } else {
 | |
| +        *data = XEN_PT_INVALID_REG;
 | |
| +    }
 | |
| +    return 0;
 | |
| +}
 | |
| +
 | |
| +/* this function will be called twice (for 32 bit and 64 bit type) */
 | |
| +/* initialize Pending register */
 | |
| +static int xen_pt_pending_reg_init(XenPCIPassthroughState *s,
 | |
| +                                   XenPTRegInfo *reg, uint32_t real_offset,
 | |
| +                                   uint32_t *data)
 | |
| +{
 | |
| +    uint32_t flags = s->msi->flags;
 | |
| +
 | |
| +    /* check the offset whether matches the type or not */
 | |
| +    if (!(flags & PCI_MSI_FLAGS_MASKBIT)) {
 | |
| +        *data = XEN_PT_INVALID_REG;
 | |
| +    } else if (xen_pt_msi_check_type(reg->offset, flags, PENDING)) {
 | |
|          *data = reg->init_val;
 | |
|      } else {
 | |
|          *data = XEN_PT_INVALID_REG;
 | |
| @@ -1222,7 +1256,7 @@ static int xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,
 | |
|      uint32_t offset = reg->offset;
 | |
|  
 | |
|      /* check the offset whether matches the type or not */
 | |
| -    if (!xen_pt_msgdata_check_type(offset, msi->flags)) {
 | |
| +    if (!xen_pt_msi_check_type(offset, msi->flags, DATA)) {
 | |
|          /* exit I/O emulator */
 | |
|          XEN_PT_ERR(&s->dev, "the offset does not match the 32/64 bit type!\n");
 | |
|          return -1;
 | |
| @@ -1267,7 +1301,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
 | |
|          .size       = 2,
 | |
|          .init_val   = 0x0000,
 | |
|          .ro_mask    = 0xFF8E,
 | |
| -        .emu_mask   = 0x007F,
 | |
| +        .emu_mask   = 0x017F,
 | |
|          .init       = xen_pt_msgctrl_reg_init,
 | |
|          .u.w.read   = xen_pt_word_reg_read,
 | |
|          .u.w.write  = xen_pt_msgctrl_reg_write,
 | |
| @@ -1316,6 +1350,50 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
 | |
|          .u.w.read   = xen_pt_word_reg_read,
 | |
|          .u.w.write  = xen_pt_msgdata_reg_write,
 | |
|      },
 | |
| +    /* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */
 | |
| +    {
 | |
| +        .offset     = PCI_MSI_MASK_32,
 | |
| +        .size       = 4,
 | |
| +        .init_val   = 0x00000000,
 | |
| +        .ro_mask    = 0xFFFFFFFF,
 | |
| +        .emu_mask   = 0xFFFFFFFF,
 | |
| +        .init       = xen_pt_mask_reg_init,
 | |
| +        .u.dw.read  = xen_pt_long_reg_read,
 | |
| +        .u.dw.write = xen_pt_long_reg_write,
 | |
| +    },
 | |
| +    /* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */
 | |
| +    {
 | |
| +        .offset     = PCI_MSI_MASK_64,
 | |
| +        .size       = 4,
 | |
| +        .init_val   = 0x00000000,
 | |
| +        .ro_mask    = 0xFFFFFFFF,
 | |
| +        .emu_mask   = 0xFFFFFFFF,
 | |
| +        .init       = xen_pt_mask_reg_init,
 | |
| +        .u.dw.read  = xen_pt_long_reg_read,
 | |
| +        .u.dw.write = xen_pt_long_reg_write,
 | |
| +    },
 | |
| +    /* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */
 | |
| +    {
 | |
| +        .offset     = PCI_MSI_MASK_32 + 4,
 | |
| +        .size       = 4,
 | |
| +        .init_val   = 0x00000000,
 | |
| +        .ro_mask    = 0xFFFFFFFF,
 | |
| +        .emu_mask   = 0x00000000,
 | |
| +        .init       = xen_pt_pending_reg_init,
 | |
| +        .u.dw.read  = xen_pt_long_reg_read,
 | |
| +        .u.dw.write = xen_pt_long_reg_write,
 | |
| +    },
 | |
| +    /* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */
 | |
| +    {
 | |
| +        .offset     = PCI_MSI_MASK_64 + 4,
 | |
| +        .size       = 4,
 | |
| +        .init_val   = 0x00000000,
 | |
| +        .ro_mask    = 0xFFFFFFFF,
 | |
| +        .emu_mask   = 0x00000000,
 | |
| +        .init       = xen_pt_pending_reg_init,
 | |
| +        .u.dw.read  = xen_pt_long_reg_read,
 | |
| +        .u.dw.write = xen_pt_long_reg_write,
 | |
| +    },
 | |
|      {
 | |
|          .size = 0,
 | |
|      },
 | |
| diff --git a/include/hw/pci/pci_regs.h b/include/hw/pci/pci_regs.h
 | |
| index 56a404b..57e8c80 100644
 | |
| --- a/include/hw/pci/pci_regs.h
 | |
| +++ b/include/hw/pci/pci_regs.h
 | |
| @@ -298,8 +298,10 @@
 | |
|  #define PCI_MSI_ADDRESS_HI	8	/* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
 | |
|  #define PCI_MSI_DATA_32		8	/* 16 bits of data for 32-bit devices */
 | |
|  #define PCI_MSI_MASK_32		12	/* Mask bits register for 32-bit devices */
 | |
| +#define PCI_MSI_PENDING_32	16	/* Pending bits register for 32-bit devices */
 | |
|  #define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
 | |
|  #define PCI_MSI_MASK_64		16	/* Mask bits register for 64-bit devices */
 | |
| +#define PCI_MSI_PENDING_64	20	/* Pending bits register for 32-bit devices */
 | |
|  
 | |
|  /* MSI-X registers */
 | |
|  #define PCI_MSIX_FLAGS		2
 | |
| -- 
 | |
| 2.2.1
 | |
| 
 |