[packages/xen] security fixes
jajcus
jajcus at pld-linux.org
Wed Jun 18 10:47:04 CEST 2014
commit 9ed49310c49191170b5761ca9959414e91e6f5c9
Author: Jacek Konieczny <j.konieczny at eggsoft.pl>
Date: Wed Jun 18 10:23:42 2014 +0200
security fixes
- XSA-92 – CVE-2014-3124
- XSA-96 – CVE-2014-3967, CVE-2014-3968
- XSA-99 – none (yet) assigned
xen.spec | 7 ++
xsa92.patch | 36 +++++++++
xsa96.patch | 38 +++++++++
xsa99.patch | 257 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 338 insertions(+)
---
diff --git a/xen.spec b/xen.spec
index 9f8155b..2ffa5ed 100644
--- a/xen.spec
+++ b/xen.spec
@@ -111,6 +111,10 @@ Patch14: %{name}-no_fetcher.patch
Patch15: odd-glib2-fix.patch
Patch16: CVE-2014-2599.patch
Patch17: %{name}-pvh_fixes.patch
+Patch18: http://xenbits.xen.org/xsa/xsa92.patch
+Patch19: http://xenbits.xen.org/xsa/xsa96.patch
+# based on: http://xenbits.xen.org/xsa/xsa99.patch
+Patch20: xsa99.patch
URL: http://www.xen.org/products/xenhyp.html
%if %{with qemu_traditional}
%{?with_opengl:BuildRequires: OpenGL-devel}
@@ -417,6 +421,9 @@ Nadzorca Xen w postaci, która może być uruchomiona wprost z firmware
%patch15 -p1
%patch16 -p1
%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
# stubdom sources
ln -s %{SOURCE10} %{SOURCE11} %{SOURCE12} %{SOURCE13} %{SOURCE14} stubdom
diff --git a/xsa92.patch b/xsa92.patch
new file mode 100644
index 0000000..60ef934
--- /dev/null
+++ b/xsa92.patch
@@ -0,0 +1,36 @@
+x86/HVM: restrict HVMOP_set_mem_type
+
+Permitting arbitrary type changes here has the potential of creating
+present P2M (and hence EPT/NPT/IOMMU) entries pointing to an invalid
+MFN (INVALID_MFN truncated to the respective hardware structure field's
+width). This would become a problem the latest when something real sat
+at the end of the physical address space; I'm suspecting though that
+other things might break with such bogus entries.
+
+Along with that drop a bogus (and otherwise becoming stale) log
+message.
+
+Afaict the similar operation in p2m_set_mem_access() is safe.
+
+This is XSA-92.
+
+Signed-off-by: Jan Beulich <jbeulich at suse.com>
+Reviewed-by: Tim Deegan <tim at xen.org>
+
+--- a/xen/arch/x86/hvm/hvm.c
++++ b/xen/arch/x86/hvm/hvm.c
+@@ -4541,12 +4541,10 @@ long do_hvm_op(unsigned long op, XEN_GUE
+ rc = -EINVAL;
+ goto param_fail4;
+ }
+- if ( p2m_is_grant(t) )
++ if ( !p2m_is_ram(t) &&
++ (!p2m_is_hole(t) || a.hvmmem_type != HVMMEM_mmio_dm) )
+ {
+ put_gfn(d, pfn);
+- gdprintk(XENLOG_WARNING,
+- "type for pfn %#lx changed to grant while "
+- "we were working?\n", pfn);
+ goto param_fail4;
+ }
+ else
diff --git a/xsa96.patch b/xsa96.patch
new file mode 100644
index 0000000..ef6443f
--- /dev/null
+++ b/xsa96.patch
@@ -0,0 +1,38 @@
+x86/HVM: eliminate vulnerabilities from hvm_inject_msi()
+
+- pirq_info() returns NULL for a non-allocated pIRQ, and hence we
+ mustn't unconditionally de-reference it, and we need to invoke it
+ another time after having called map_domain_emuirq_pirq()
+- don't use printk(), namely without XENLOG_GUEST, for error reporting
+
+This is XSA-96.
+
+Signed-off-by: Jan Beulich <jbeulich at suse.com>
+
+--- a/xen/arch/x86/hvm/irq.c
++++ b/xen/arch/x86/hvm/irq.c
+@@ -289,20 +289,18 @@ void hvm_inject_msi(struct domain *d, ui
+ struct pirq *info = pirq_info(d, pirq);
+
+ /* if it is the first time, allocate the pirq */
+- if (info->arch.hvm.emuirq == IRQ_UNBOUND)
++ if ( !info || info->arch.hvm.emuirq == IRQ_UNBOUND )
+ {
+ spin_lock(&d->event_lock);
+ map_domain_emuirq_pirq(d, pirq, IRQ_MSI_EMU);
+ spin_unlock(&d->event_lock);
++ info = pirq_info(d, pirq);
++ if ( !info )
++ return;
+ } else if (info->arch.hvm.emuirq != IRQ_MSI_EMU)
+- {
+- printk("%s: pirq %d does not correspond to an emulated MSI\n", __func__, pirq);
+ return;
+- }
+ send_guest_pirq(d, info);
+ return;
+- } else {
+- printk("%s: error getting pirq from MSI: pirq = %d\n", __func__, pirq);
+ }
+ }
+
diff --git a/xsa99.patch b/xsa99.patch
new file mode 100644
index 0000000..14e58f4
--- /dev/null
+++ b/xsa99.patch
@@ -0,0 +1,257 @@
+diff -durN -x '*~' -x '*.orig' -x '*.rej' xen-4.4.0.orig/tools/libxc/xc_mem_access.c xen-4.4.0/tools/libxc/xc_mem_access.c
+--- xen-4.4.0.orig/tools/libxc/xc_mem_access.c 2014-03-10 11:43:57.000000000 +0100
++++ xen-4.4.0/tools/libxc/xc_mem_access.c 2014-06-18 10:19:54.000000000 +0200
+@@ -24,19 +24,9 @@
+ #include "xc_private.h"
+
+
+-int xc_mem_access_enable(xc_interface *xch, domid_t domain_id,
+- uint32_t *port)
++void *xc_mem_access_enable(xc_interface *xch, domid_t domain_id, uint32_t *port)
+ {
+- if ( !port )
+- {
+- errno = EINVAL;
+- return -1;
+- }
+-
+- return xc_mem_event_control(xch, domain_id,
+- XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE,
+- XEN_DOMCTL_MEM_EVENT_OP_ACCESS,
+- port);
++ return xc_mem_event_enable(xch, domain_id, HVM_PARAM_ACCESS_RING_PFN, port);
+ }
+
+ int xc_mem_access_disable(xc_interface *xch, domid_t domain_id)
+diff -durN -x '*~' -x '*.orig' -x '*.rej' xen-4.4.0.orig/tools/libxc/xc_mem_event.c xen-4.4.0/tools/libxc/xc_mem_event.c
+--- xen-4.4.0.orig/tools/libxc/xc_mem_event.c 2014-03-10 11:43:57.000000000 +0100
++++ xen-4.4.0/tools/libxc/xc_mem_event.c 2014-06-18 10:19:54.000000000 +0200
+@@ -56,3 +56,118 @@
+ return do_memory_op(xch, mode, &meo, sizeof(meo));
+ }
+
++void *xc_mem_event_enable(xc_interface *xch, domid_t domain_id, int param,
++ uint32_t *port)
++{
++ void *ring_page = NULL;
++ unsigned long ring_pfn, mmap_pfn;
++ unsigned int op, mode;
++ int rc1, rc2, saved_errno;
++
++ if ( !port )
++ {
++ errno = EINVAL;
++ return NULL;
++ }
++
++ /* Pause the domain for ring page setup */
++ rc1 = xc_domain_pause(xch, domain_id);
++ if ( rc1 != 0 )
++ {
++ PERROR("Unable to pause domain\n");
++ return NULL;
++ }
++
++ /* Get the pfn of the ring page */
++ rc1 = xc_get_hvm_param(xch, domain_id, param, &ring_pfn);
++ if ( rc1 != 0 )
++ {
++ PERROR("Failed to get pfn of ring page\n");
++ goto out;
++ }
++
++ mmap_pfn = ring_pfn;
++ ring_page = xc_map_foreign_batch(xch, domain_id, PROT_READ | PROT_WRITE,
++ &mmap_pfn, 1);
++ if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB )
++ {
++ /* Map failed, populate ring page */
++ rc1 = xc_domain_populate_physmap_exact(xch, domain_id, 1, 0, 0,
++ &ring_pfn);
++ if ( rc1 != 0 )
++ {
++ PERROR("Failed to populate ring pfn\n");
++ goto out;
++ }
++
++ mmap_pfn = ring_pfn;
++ ring_page = xc_map_foreign_batch(xch, domain_id, PROT_READ | PROT_WRITE,
++ &mmap_pfn, 1);
++ if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB )
++ {
++ PERROR("Could not map the ring page\n");
++ goto out;
++ }
++ }
++
++ switch ( param )
++ {
++ case HVM_PARAM_PAGING_RING_PFN:
++ op = XEN_DOMCTL_MEM_EVENT_OP_PAGING_ENABLE;
++ mode = XEN_DOMCTL_MEM_EVENT_OP_PAGING;
++ break;
++
++ case HVM_PARAM_ACCESS_RING_PFN:
++ op = XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE;
++ mode = XEN_DOMCTL_MEM_EVENT_OP_ACCESS;
++ break;
++
++ case HVM_PARAM_SHARING_RING_PFN:
++ op = XEN_DOMCTL_MEM_EVENT_OP_SHARING_ENABLE;
++ mode = XEN_DOMCTL_MEM_EVENT_OP_SHARING;
++ break;
++
++ /*
++ * This is for the outside chance that the HVM_PARAM is valid but is invalid
++ * as far as mem_event goes.
++ */
++ default:
++ errno = EINVAL;
++ rc1 = -1;
++ goto out;
++ }
++
++ rc1 = xc_mem_event_control(xch, domain_id, op, mode, port);
++ if ( rc1 != 0 )
++ {
++ PERROR("Failed to enable mem_event\n");
++ goto out;
++ }
++
++ /* Remove the ring_pfn from the guest's physmap */
++ rc1 = xc_domain_decrease_reservation_exact(xch, domain_id, 1, 0, &ring_pfn);
++ if ( rc1 != 0 )
++ PERROR("Failed to remove ring page from guest physmap");
++
++ out:
++ saved_errno = errno;
++
++ rc2 = xc_domain_unpause(xch, domain_id);
++ if ( rc1 != 0 || rc2 != 0 )
++ {
++ if ( rc2 != 0 )
++ {
++ if ( rc1 == 0 )
++ saved_errno = errno;
++ PERROR("Unable to unpause domain");
++ }
++
++ if ( ring_page )
++ munmap(ring_page, XC_PAGE_SIZE);
++ ring_page = NULL;
++
++ errno = saved_errno;
++ }
++
++ return ring_page;
++}
+diff -durN -x '*~' -x '*.orig' -x '*.rej' xen-4.4.0.orig/tools/libxc/xenctrl.h xen-4.4.0/tools/libxc/xenctrl.h
+--- xen-4.4.0.orig/tools/libxc/xenctrl.h 2014-03-10 11:43:57.000000000 +0100
++++ xen-4.4.0/tools/libxc/xenctrl.h 2014-06-18 10:19:54.000000000 +0200
+@@ -2040,6 +2040,12 @@
+ int xc_mem_event_memop(xc_interface *xch, domid_t domain_id,
+ unsigned int op, unsigned int mode,
+ uint64_t gfn, void *buffer);
++/*
++ * Enables mem_event and returns the mapped ring page indicated by param.
++ * param can be HVM_PARAM_PAGING/ACCESS/SHARING_RING_PFN
++ */
++void *xc_mem_event_enable(xc_interface *xch, domid_t domain_id, int param,
++ uint32_t *port);
+
+ /**
+ * Mem paging operations.
+@@ -2060,7 +2066,13 @@
+ * Access tracking operations.
+ * Supported only on Intel EPT 64 bit processors.
+ */
+-int xc_mem_access_enable(xc_interface *xch, domid_t domain_id, uint32_t *port);
++
++/*
++ * Enables mem_access and returns the mapped ring page.
++ * Will return NULL on error.
++ * Caller has to unmap this page when done.
++ */
++void *xc_mem_access_enable(xc_interface *xch, domid_t domain_id, uint32_t *port);
+ int xc_mem_access_disable(xc_interface *xch, domid_t domain_id);
+ int xc_mem_access_resume(xc_interface *xch, domid_t domain_id,
+ unsigned long gfn);
+diff -durN -x '*~' -x '*.orig' -x '*.rej' xen-4.4.0.orig/tools/tests/xen-access/xen-access.c xen-4.4.0/tools/tests/xen-access/xen-access.c
+--- xen-4.4.0.orig/tools/tests/xen-access/xen-access.c 2014-03-10 11:43:57.000000000 +0100
++++ xen-4.4.0/tools/tests/xen-access/xen-access.c 2014-06-18 10:20:55.000000000 +0200
+@@ -231,7 +231,6 @@
+ xenaccess_t *xenaccess = 0;
+ xc_interface *xch;
+ int rc;
+- unsigned long ring_pfn, mmap_pfn;
+
+ xch = xc_interface_open(NULL, NULL, 0);
+ if ( !xch )
+@@ -253,40 +252,12 @@
+ /* Initialise lock */
+ mem_event_ring_lock_init(&xenaccess->mem_event);
+
+- /* Map the ring page */
+- xc_get_hvm_param(xch, xenaccess->mem_event.domain_id,
+- HVM_PARAM_ACCESS_RING_PFN, &ring_pfn);
+- mmap_pfn = ring_pfn;
+- xenaccess->mem_event.ring_page =
+- xc_map_foreign_batch(xch, xenaccess->mem_event.domain_id,
+- PROT_READ | PROT_WRITE, &mmap_pfn, 1);
+- if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB )
+- {
+- /* Map failed, populate ring page */
+- rc = xc_domain_populate_physmap_exact(xenaccess->xc_handle,
+- xenaccess->mem_event.domain_id,
+- 1, 0, 0, &ring_pfn);
+- if ( rc != 0 )
+- {
+- PERROR("Failed to populate ring gfn\n");
+- goto err;
+- }
+-
+- mmap_pfn = ring_pfn;
+- xenaccess->mem_event.ring_page =
+- xc_map_foreign_batch(xch, xenaccess->mem_event.domain_id,
+- PROT_READ | PROT_WRITE, &mmap_pfn, 1);
+- if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB )
+- {
+- PERROR("Could not map the ring page\n");
+- goto err;
+- }
+- }
+-
+- /* Initialise Xen */
+- rc = xc_mem_access_enable(xenaccess->xc_handle, xenaccess->mem_event.domain_id,
+- &xenaccess->mem_event.evtchn_port);
+- if ( rc != 0 )
++ /* Enable mem_access */
++ xenaccess->mem_event.ring_page =
++ xc_mem_access_enable(xenaccess->xc_handle,
++ xenaccess->mem_event.domain_id,
++ &xenaccess->mem_event.evtchn_port);
++ if ( xenaccess->mem_event.ring_page == NULL )
+ {
+ switch ( errno ) {
+ case EBUSY:
+@@ -296,7 +267,7 @@
+ ERROR("EPT not supported for this guest");
+ break;
+ default:
+- perror("Error initialising shared page");
++ perror("Error enabling mem_access");
+ break;
+ }
+ goto err;
+@@ -330,11 +301,6 @@
+ (mem_event_sring_t *)xenaccess->mem_event.ring_page,
+ PAGE_SIZE);
+
+- /* Now that the ring is set, remove it from the guest's physmap */
+- if ( xc_domain_decrease_reservation_exact(xch,
+- xenaccess->mem_event.domain_id, 1, 0, &ring_pfn) )
+- PERROR("Failed to remove ring from guest physmap");
+-
+ /* Get platform info */
+ xenaccess->platform_info = malloc(sizeof(xc_platform_info_t));
+ if ( xenaccess->platform_info == NULL )
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/xen.git/commitdiff/9ed49310c49191170b5761ca9959414e91e6f5c9
More information about the pld-cvs-commit
mailing list