aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2012-12-04 18:50:03 +0000
committerJan Beulich <jbeulich@suse.com>2012-12-04 18:50:03 +0000
commit44dbb797f043cd5ab084726641aeb1d178d18cd0 (patch)
treef36c580d7ee2a551271ead8916d82aaa120b3077
parentb535076955fbe0a54b794959eafc9b918adb3629 (diff)
downloadxen-44dbb797f043cd5ab084726641aeb1d178d18cd0.tar.gz
xen-44dbb797f043cd5ab084726641aeb1d178d18cd0.tar.bz2
xen-44dbb797f043cd5ab084726641aeb1d178d18cd0.zip
memop: limit guest specified extent order
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>
-rw-r--r--xen/common/memory.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/xen/common/memory.c b/xen/common/memory.c
index 59379d3607..51c3cc6f91 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -117,7 +117,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;
}
@@ -216,7 +217,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++ )
@@ -278,6 +280,9 @@ static long memory_exchange(XEN_GUEST_HANDLE(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) ||