3cfbbfbd64
XSA-125 Long latency MMIO mapping operations are not preemptible XSA-126 Unmediated PCI command register access in qemu
108 lines
3.4 KiB
Text
108 lines
3.4 KiB
Text
$NetBSD: patch-CVE-2015-2752,v 1.1 2015/04/19 13:13:20 spz Exp $
|
|
|
|
Patch for CVE-2015-2752 aka XSA-125 from
|
|
http://xenbits.xenproject.org/xsa/xsa125-4.2.patch
|
|
|
|
--- tools/libxc/xc_domain.c.orig 2014-09-02 06:22:57.000000000 +0000
|
|
+++ tools/libxc/xc_domain.c
|
|
@@ -1352,6 +1352,13 @@ int xc_domain_bind_pt_isa_irq(
|
|
PT_IRQ_TYPE_ISA, 0, 0, 0, machine_irq));
|
|
}
|
|
|
|
+#ifndef min
|
|
+#define min(X, Y) ({ \
|
|
+ const typeof (X) _x = (X); \
|
|
+ const typeof (Y) _y = (Y); \
|
|
+ (void) (&_x == &_y); \
|
|
+ (_x < _y) ? _x : _y; })
|
|
+#endif
|
|
int xc_domain_memory_mapping(
|
|
xc_interface *xch,
|
|
uint32_t domid,
|
|
@@ -1361,17 +1368,55 @@ int xc_domain_memory_mapping(
|
|
uint32_t add_mapping)
|
|
{
|
|
DECLARE_DOMCTL;
|
|
+ int ret = 0, err;
|
|
+ unsigned long done = 0, nr, max_batch_sz;
|
|
+
|
|
+ if ( !nr_mfns )
|
|
+ return 0;
|
|
|
|
domctl.cmd = XEN_DOMCTL_memory_mapping;
|
|
domctl.domain = domid;
|
|
- domctl.u.memory_mapping.first_gfn = first_gfn;
|
|
- domctl.u.memory_mapping.first_mfn = first_mfn;
|
|
- domctl.u.memory_mapping.nr_mfns = nr_mfns;
|
|
domctl.u.memory_mapping.add_mapping = add_mapping;
|
|
+ max_batch_sz = nr_mfns;
|
|
+ do
|
|
+ {
|
|
+ nr = min(nr_mfns - done, max_batch_sz);
|
|
+ domctl.u.memory_mapping.nr_mfns = nr;
|
|
+ domctl.u.memory_mapping.first_gfn = first_gfn + done;
|
|
+ domctl.u.memory_mapping.first_mfn = first_mfn + done;
|
|
+ err = do_domctl(xch, &domctl);
|
|
+ if ( err && errno == E2BIG )
|
|
+ {
|
|
+ if ( max_batch_sz <= 1 )
|
|
+ break;
|
|
+ max_batch_sz >>= 1;
|
|
+ continue;
|
|
+ }
|
|
+ /* Save the first error... */
|
|
+ if ( !ret )
|
|
+ ret = err;
|
|
+ /* .. and ignore the rest of them when removing. */
|
|
+ if ( err && add_mapping != DPCI_REMOVE_MAPPING )
|
|
+ break;
|
|
+
|
|
+ done += nr;
|
|
+ } while ( done < nr_mfns );
|
|
+
|
|
+ /*
|
|
+ * Undo what we have done unless unmapping, by unmapping the entire region.
|
|
+ * Errors here are ignored.
|
|
+ */
|
|
+ if ( ret && add_mapping != DPCI_REMOVE_MAPPING )
|
|
+ xc_domain_memory_mapping(xch, domid, first_gfn, first_mfn, nr_mfns,
|
|
+ DPCI_REMOVE_MAPPING);
|
|
+
|
|
+ /* We might get E2BIG so many times that we never advance. */
|
|
+ if ( !done && !ret )
|
|
+ ret = -1;
|
|
|
|
- return do_domctl(xch, &domctl);
|
|
+ return ret;
|
|
}
|
|
-
|
|
+#undef min
|
|
int xc_domain_ioport_mapping(
|
|
xc_interface *xch,
|
|
uint32_t domid,
|
|
|
|
--- xen/arch/x86/domctl.c.orig 2014-09-02 06:22:57.000000000 +0000
|
|
+++ xen/arch/x86/domctl.c
|
|
@@ -865,6 +865,11 @@ long arch_do_domctl(
|
|
(gfn + nr_mfns - 1) < gfn ) /* wrap? */
|
|
break;
|
|
|
|
+ ret = -E2BIG;
|
|
+ /* Must break hypercall up as this could take a while. */
|
|
+ if ( nr_mfns > 64 )
|
|
+ break;
|
|
+
|
|
ret = -EPERM;
|
|
if ( !IS_PRIV(current->domain) &&
|
|
!iomem_access_permitted(current->domain, mfn, mfn + nr_mfns - 1) )
|
|
|
|
--- xen/include/public/domctl.h.orig 2014-09-02 06:22:57.000000000 +0000
|
|
+++ xen/include/public/domctl.h
|
|
@@ -507,6 +507,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_bind_
|
|
|
|
|
|
/* Bind machine I/O address range -> HVM address range. */
|
|
+/* If this returns -E2BIG lower nr_mfns value. */
|
|
/* XEN_DOMCTL_memory_mapping */
|
|
#define DPCI_ADD_MAPPING 1
|
|
#define DPCI_REMOVE_MAPPING 0
|