51 lines
2.0 KiB
Diff
51 lines
2.0 KiB
Diff
|
References: CVE-2012-5515 XSA-31 bnc#789950
|
||
|
|
||
|
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>
|
||
|
|
||
|
--- a/xen/common/memory.c
|
||
|
+++ b/xen/common/memory.c
|
||
|
@@ -115,7 +115,8 @@ static void populate_physmap(struct memo
|
||
|
|
||
|
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
|
||
|
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_HA
|
||
|
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) ||
|