]> xenbits.xensource.com Git - people/aperard/xen-arm.git/commitdiff
memop: limit guest specified extent order
authorJan Beulich <jbeulich@suse.com>
Tue, 4 Dec 2012 18:38:26 +0000 (18:38 +0000)
committerJan Beulich <jbeulich@suse.com>
Tue, 4 Dec 2012 18:38:26 +0000 (18:38 +0000)
Allowing unbounded order values here causes almost unbounded loops
and/or partially incomplete requests, particularly in PoD code.

The added range checks in populate_physmap(), decrease_reservation(),
and the "in" one in memory_exchange() architecturally all could use
PADDR_BITS - PAGE_SHIFT, and are being artificially constrained to
MAX_ORDER.

This is XSA-31 / CVE-2012-5515.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Tim Deegan <tim@xen.org>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
xen/common/memory.c

index bdb6ed8f352643ce04845c4e1391fd15132092ea..a076f81afeb34657c4b043e13474659169bbad2c 100644 (file)
@@ -115,7 +115,8 @@ static void populate_physmap(struct memop_args *a)
 
         if ( a->memflags & MEMF_populate_on_demand )
         {
-            if ( guest_physmap_mark_populate_on_demand(d, gpfn,
+            if ( a->extent_order > MAX_ORDER ||
+                 guest_physmap_mark_populate_on_demand(d, gpfn,
                                                        a->extent_order) < 0 )
                 goto out;
         }
@@ -235,7 +236,8 @@ static void decrease_reservation(struct memop_args *a)
     xen_pfn_t gmfn;
 
     if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done,
-                                     a->nr_extents-1) )
+                                     a->nr_extents-1) ||
+         a->extent_order > MAX_ORDER )
         return;
 
     for ( i = a->nr_done; i < a->nr_extents; i++ )
@@ -297,6 +299,9 @@ static long memory_exchange(XEN_GUEST_HANDLE_PARAM(xen_memory_exchange_t) arg)
     if ( (exch.nr_exchanged > exch.in.nr_extents) ||
          /* Input and output domain identifiers match? */
          (exch.in.domid != exch.out.domid) ||
+         /* Extent orders are sensible? */
+         (exch.in.extent_order > MAX_ORDER) ||
+         (exch.out.extent_order > MAX_ORDER) ||
          /* Sizes of input and output lists do not overflow a long? */
          ((~0UL >> exch.in.extent_order) < exch.in.nr_extents) ||
          ((~0UL >> exch.out.extent_order) < exch.out.nr_extents) ||