diff options
Diffstat (limited to 'gnu/packages/patches/qemu-CVE-2015-4105.patch')
-rw-r--r-- | gnu/packages/patches/qemu-CVE-2015-4105.patch | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/gnu/packages/patches/qemu-CVE-2015-4105.patch b/gnu/packages/patches/qemu-CVE-2015-4105.patch new file mode 100644 index 0000000000..f1b349f1e5 --- /dev/null +++ b/gnu/packages/patches/qemu-CVE-2015-4105.patch @@ -0,0 +1,85 @@ +From b38ec5ee7a581776bbce0bdaecb397632c3c4791 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/MSI-X: limit error messages + +Limit error messages resulting from bad guest behavior to avoid allowing +the guest to cause the control domain's disk to fill. + +The first message in pci_msix_write() can simply be deleted, as this +is indeed bad guest behavior, but such out of bounds writes don't +really need to be logged. + +The second one is more problematic, as there guest behavior may only +appear to be wrong: For one, the old logic didn't take the mask-all bit +into account. And then this shouldn't depend on host device state (i.e. +the host may have masked the entry without the guest having done so). +Plus these writes shouldn't be dropped even when an entry is unmasked. +Instead, if they can't be made take effect right away, they should take +effect on the next unmasking or enabling operation - the specification +explicitly describes such caching behavior. Until we can validly drop +the message (implementing such caching/latching behavior), issue the +message just once per MSI-X table entry. + +Note that the log message in pci_msix_read() similar to the one being +removed here is not an issue: "addr" being of unsigned type, and the +maximum size of the MSI-X table being 32k, entry_nr simply can't be +negative and hence the conditonal guarding issuing of the message will +never be true. + +This is XSA-130. + +Signed-off-by: Jan Beulich <jbeulich@suse.com> +Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> +--- + hw/xen/xen_pt.h | 1 + + hw/xen/xen_pt_msi.c | 12 +++++++----- + 2 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h +index 52ceb85..8c9b6c2 100644 +--- a/hw/xen/xen_pt.h ++++ b/hw/xen/xen_pt.h +@@ -175,6 +175,7 @@ typedef struct XenPTMSIXEntry { + uint32_t data; + uint32_t vector_ctrl; + bool updated; /* indicate whether MSI ADDR or DATA is updated */ ++ bool warned; /* avoid issuing (bogus) warning more than once */ + } XenPTMSIXEntry; + typedef struct XenPTMSIX { + uint32_t ctrl_offset; +diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c +index 9ed9321..68db623 100644 +--- a/hw/xen/xen_pt_msi.c ++++ b/hw/xen/xen_pt_msi.c +@@ -434,11 +434,10 @@ static void pci_msix_write(void *opaque, hwaddr addr, + XenPCIPassthroughState *s = opaque; + XenPTMSIX *msix = s->msix; + XenPTMSIXEntry *entry; +- int entry_nr, offset; ++ unsigned int entry_nr, offset; + + entry_nr = addr / PCI_MSIX_ENTRY_SIZE; +- if (entry_nr < 0 || entry_nr >= msix->total_entries) { +- XEN_PT_ERR(&s->dev, "asked MSI-X entry '%i' invalid!\n", entry_nr); ++ if (entry_nr >= msix->total_entries) { + return; + } + entry = &msix->msix_entry[entry_nr]; +@@ -460,8 +459,11 @@ static void pci_msix_write(void *opaque, hwaddr addr, + + PCI_MSIX_ENTRY_VECTOR_CTRL; + + if (msix->enabled && !(*vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT)) { +- XEN_PT_ERR(&s->dev, "Can't update msix entry %d since MSI-X is" +- " already enabled.\n", entry_nr); ++ if (!entry->warned) { ++ entry->warned = true; ++ XEN_PT_ERR(&s->dev, "Can't update msix entry %d since MSI-X is" ++ " already enabled.\n", entry_nr); ++ } + return; + } + +-- +2.2.1 + |