diff options
author | Mark H Weaver <mhw@netris.org> | 2015-06-15 23:57:14 -0400 |
---|---|---|
committer | Mark H Weaver <mhw@netris.org> | 2015-06-16 00:29:28 -0400 |
commit | fef3cfaaab972b1f514724f90050aeb38516519b (patch) | |
tree | 89d58b467be5e59263c1f41d06dfa4e08187eaf3 /gnu/packages/patches/qemu-CVE-2015-4104.patch | |
parent | 77ff9e9a994a3a23d973d87456a0085ac53b23bc (diff) | |
download | guix-fef3cfaaab972b1f514724f90050aeb38516519b.tar.gz |
gnu: qemu: Add fixes for CVE-2015-{4037,4103,4104,4105,4106}.
* 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.
Diffstat (limited to 'gnu/packages/patches/qemu-CVE-2015-4104.patch')
-rw-r--r-- | gnu/packages/patches/qemu-CVE-2015-4104.patch | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/gnu/packages/patches/qemu-CVE-2015-4104.patch b/gnu/packages/patches/qemu-CVE-2015-4104.patch new file mode 100644 index 0000000000..811b0419a9 --- /dev/null +++ b/gnu/packages/patches/qemu-CVE-2015-4104.patch @@ -0,0 +1,189 @@ +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 + |