summaryrefslogtreecommitdiff
path: root/gnu/packages/patches/qemu-CVE-2015-4103.patch
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2015-06-15 23:57:14 -0400
committerMark H Weaver <mhw@netris.org>2015-06-16 00:29:28 -0400
commitfef3cfaaab972b1f514724f90050aeb38516519b (patch)
tree89d58b467be5e59263c1f41d06dfa4e08187eaf3 /gnu/packages/patches/qemu-CVE-2015-4103.patch
parent77ff9e9a994a3a23d973d87456a0085ac53b23bc (diff)
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-4103.patch')
-rw-r--r--gnu/packages/patches/qemu-CVE-2015-4103.patch135
1 files changed, 135 insertions, 0 deletions
diff --git a/gnu/packages/patches/qemu-CVE-2015-4103.patch b/gnu/packages/patches/qemu-CVE-2015-4103.patch
new file mode 100644
index 0000000000..74333fd672
--- /dev/null
+++ b/gnu/packages/patches/qemu-CVE-2015-4103.patch
@@ -0,0 +1,135 @@
+From 5c83b2f5b4b956e91dd6e5711f14df7ab800aefb 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: properly gate host writes of modified PCI CFG contents
+
+The old logic didn't work as intended when an access spanned multiple
+fields (for example a 32-bit access to the location of the MSI Message
+Data field with the high 16 bits not being covered by any known field).
+Remove it and derive which fields not to write to from the accessed
+fields' emulation masks: When they're all ones, there's no point in
+doing any host write.
+
+This fixes a secondary issue at once: We obviously shouldn't make any
+host write attempt when already the host read failed.
+
+This is XSA-128.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+---
+ hw/xen/xen_pt.c | 25 +++++++++++++++++++++----
+ hw/xen/xen_pt.h | 2 --
+ hw/xen/xen_pt_config_init.c | 4 ----
+ 3 files changed, 21 insertions(+), 10 deletions(-)
+
+diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
+index d095c08..8923582 100644
+--- a/hw/xen/xen_pt.c
++++ b/hw/xen/xen_pt.c
+@@ -234,7 +234,7 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
+ int index = 0;
+ XenPTRegGroup *reg_grp_entry = NULL;
+ int rc = 0;
+- uint32_t read_val = 0;
++ uint32_t read_val = 0, wb_mask;
+ int emul_len = 0;
+ XenPTReg *reg_entry = NULL;
+ uint32_t find_addr = addr;
+@@ -271,6 +271,9 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
+ if (rc < 0) {
+ XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc);
+ memset(&read_val, 0xff, len);
++ wb_mask = 0;
++ } else {
++ wb_mask = 0xFFFFFFFF >> ((4 - len) << 3);
+ }
+
+ /* pass directly to the real device for passthrough type register group */
+@@ -298,6 +301,11 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
+
+ valid_mask <<= (find_addr - real_offset) << 3;
+ ptr_val = (uint8_t *)&val + (real_offset & 3);
++ if (reg->emu_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) {
++ wb_mask &= ~((reg->emu_mask
++ >> ((find_addr - real_offset) << 3))
++ << ((len - emul_len) << 3));
++ }
+
+ /* do emulation based on register size */
+ switch (reg->size) {
+@@ -350,10 +358,19 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
+ memory_region_transaction_commit();
+
+ out:
+- if (!(reg && reg->no_wb)) {
++ for (index = 0; wb_mask; index += len) {
+ /* unknown regs are passed through */
+- rc = xen_host_pci_set_block(&s->real_device, addr,
+- (uint8_t *)&val, len);
++ while (!(wb_mask & 0xff)) {
++ index++;
++ wb_mask >>= 8;
++ }
++ len = 0;
++ do {
++ len++;
++ wb_mask >>= 8;
++ } while (wb_mask & 0xff);
++ rc = xen_host_pci_set_block(&s->real_device, addr + index,
++ (uint8_t *)&val + index, len);
+
+ if (rc < 0) {
+ XEN_PT_ERR(d, "pci_write_block failed. return value: %d.\n", rc);
+diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
+index 942dc60..52ceb85 100644
+--- a/hw/xen/xen_pt.h
++++ b/hw/xen/xen_pt.h
+@@ -105,8 +105,6 @@ struct XenPTRegInfo {
+ uint32_t ro_mask;
+ /* reg emulate field mask (ON:emu, OFF:passthrough) */
+ uint32_t emu_mask;
+- /* no write back allowed */
+- uint32_t no_wb;
+ xen_pt_conf_reg_init init;
+ /* read/write function pointer
+ * for double_word/word/byte size */
+diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
+index 95a51db..dae0519 100644
+--- a/hw/xen/xen_pt_config_init.c
++++ b/hw/xen/xen_pt_config_init.c
+@@ -1279,7 +1279,6 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
+ .init_val = 0x00000000,
+ .ro_mask = 0x00000003,
+ .emu_mask = 0xFFFFFFFF,
+- .no_wb = 1,
+ .init = xen_pt_common_reg_init,
+ .u.dw.read = xen_pt_long_reg_read,
+ .u.dw.write = xen_pt_msgaddr32_reg_write,
+@@ -1291,7 +1290,6 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
+ .init_val = 0x00000000,
+ .ro_mask = 0x00000000,
+ .emu_mask = 0xFFFFFFFF,
+- .no_wb = 1,
+ .init = xen_pt_msgaddr64_reg_init,
+ .u.dw.read = xen_pt_long_reg_read,
+ .u.dw.write = xen_pt_msgaddr64_reg_write,
+@@ -1303,7 +1301,6 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
+ .init_val = 0x0000,
+ .ro_mask = 0x0000,
+ .emu_mask = 0xFFFF,
+- .no_wb = 1,
+ .init = xen_pt_msgdata_reg_init,
+ .u.w.read = xen_pt_word_reg_read,
+ .u.w.write = xen_pt_msgdata_reg_write,
+@@ -1315,7 +1312,6 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
+ .init_val = 0x0000,
+ .ro_mask = 0x0000,
+ .emu_mask = 0xFFFF,
+- .no_wb = 1,
+ .init = xen_pt_msgdata_reg_init,
+ .u.w.read = xen_pt_word_reg_read,
+ .u.w.write = xen_pt_msgdata_reg_write,
+--
+2.2.1
+