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-4106-pt8.patch | |
parent | 77ff9e9a994a3a23d973d87456a0085ac53b23bc (diff) | |
download | guix-fef3cfaaab972b1f514724f90050aeb38516519b.tar 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-4106-pt8.patch')
-rw-r--r-- | gnu/packages/patches/qemu-CVE-2015-4106-pt8.patch | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/gnu/packages/patches/qemu-CVE-2015-4106-pt8.patch b/gnu/packages/patches/qemu-CVE-2015-4106-pt8.patch new file mode 100644 index 0000000000..bc3e03217f --- /dev/null +++ b/gnu/packages/patches/qemu-CVE-2015-4106-pt8.patch @@ -0,0 +1,132 @@ +From c25bbf1545a53ac051f9e51d4140e397660c10ae Mon Sep 17 00:00:00 2001 +From: Jan Beulich <jbeulich@suse.com> +Date: Tue, 2 Jun 2015 15:07:01 +0000 +Subject: [PATCH] xen/pt: unknown PCI config space fields should be read-only + +... by default. Add a per-device "permissive" mode similar to pciback's +to allow restoring previous behavior (and hence break security again, +i.e. should be used only for trusted guests). + +This is part of XSA-131. + +Signed-off-by: Jan Beulich <jbeulich@suse.com> +Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> +Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>) +--- + hw/xen/xen_pt.c | 32 +++++++++++++++++++++++++++++--- + hw/xen/xen_pt.h | 2 ++ + hw/xen/xen_pt_config_init.c | 4 ++++ + 3 files changed, 35 insertions(+), 3 deletions(-) + +diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c +index 8923582..9afcda8 100644 +--- a/hw/xen/xen_pt.c ++++ b/hw/xen/xen_pt.c +@@ -239,6 +239,7 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr, + XenPTReg *reg_entry = NULL; + uint32_t find_addr = addr; + XenPTRegInfo *reg = NULL; ++ bool wp_flag = false; + + if (xen_pt_pci_config_access_check(d, addr, len)) { + return; +@@ -278,6 +279,10 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr, + + /* pass directly to the real device for passthrough type register group */ + if (reg_grp_entry == NULL) { ++ if (!s->permissive) { ++ wb_mask = 0; ++ wp_flag = true; ++ } + goto out; + } + +@@ -298,12 +303,15 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr, + uint32_t real_offset = reg_grp_entry->base_offset + reg->offset; + uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3); + uint8_t *ptr_val = NULL; ++ uint32_t wp_mask = reg->emu_mask | reg->ro_mask; + + 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)) ++ if (!s->permissive) { ++ wp_mask |= reg->res_mask; ++ } ++ if (wp_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) { ++ wb_mask &= ~((wp_mask >> ((find_addr - real_offset) << 3)) + << ((len - emul_len) << 3)); + } + +@@ -347,6 +355,16 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr, + } else { + /* nothing to do with passthrough type register, + * continue to find next byte */ ++ if (!s->permissive) { ++ wb_mask &= ~(0xff << ((len - emul_len) << 3)); ++ /* Unused BARs will make it here, but we don't want to issue ++ * warnings for writes to them (bogus writes get dealt with ++ * above). ++ */ ++ if (index < 0) { ++ wp_flag = true; ++ } ++ } + emul_len--; + find_addr++; + } +@@ -358,6 +376,13 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr, + memory_region_transaction_commit(); + + out: ++ if (wp_flag && !s->permissive_warned) { ++ s->permissive_warned = true; ++ xen_pt_log(d, "Write-back to unknown field 0x%02x (partially) inhibited (0x%0*x)\n", ++ addr, len * 2, wb_mask); ++ xen_pt_log(d, "If the device doesn't work, try enabling permissive mode\n"); ++ xen_pt_log(d, "(unsafe) and if it helps report the problem to xen-devel\n"); ++ } + for (index = 0; wb_mask; index += len) { + /* unknown regs are passed through */ + while (!(wb_mask & 0xff)) { +@@ -824,6 +849,7 @@ static void xen_pt_unregister_device(PCIDevice *d) + + static Property xen_pci_passthrough_properties[] = { + DEFINE_PROP_PCI_HOST_DEVADDR("hostaddr", XenPCIPassthroughState, hostaddr), ++ DEFINE_PROP_BOOL("permissive", XenPCIPassthroughState, permissive, false), + DEFINE_PROP_END_OF_LIST(), + }; + +diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h +index f9795eb..4bba559 100644 +--- a/hw/xen/xen_pt.h ++++ b/hw/xen/xen_pt.h +@@ -197,6 +197,8 @@ struct XenPCIPassthroughState { + + PCIHostDeviceAddress hostaddr; + bool is_virtfn; ++ bool permissive; ++ bool permissive_warned; + XenHostPCIDevice real_device; + XenPTRegion bases[PCI_NUM_REGIONS]; /* Access regions */ + QLIST_HEAD(, XenPTRegGroup) reg_grps; +diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c +index 19f926b..f3cf069 100644 +--- a/hw/xen/xen_pt_config_init.c ++++ b/hw/xen/xen_pt_config_init.c +@@ -101,6 +101,10 @@ static uint32_t get_throughable_mask(const XenPCIPassthroughState *s, + { + uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask); + ++ if (!s->permissive) { ++ throughable_mask &= ~reg->res_mask; ++ } ++ + return throughable_mask & valid_mask; + } + +-- +2.2.1 + |