From: Keir Fraser Date: Fri, 13 Jun 2008 12:49:56 +0000 (+0100) Subject: Introduce guest_handle_subrange_okay() for checking sub-sections of an X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14192^2~71 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=faef567a6b88dac76e1b56be0fff33c52211330c;p=xen.git Introduce guest_handle_subrange_okay() for checking sub-sections of an argument array. Needed where a compat shim is splitting up a 32-bit guest's larger argument array, and only the currently-active part of the translated array is contained within the compat_arg_xlat_area. Signed-off-by: Keir Fraser --- diff --git a/xen/common/memory.c b/xen/common/memory.c index 58f138939f..eba18fdc3e 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -47,7 +47,8 @@ static void increase_reservation(struct memop_args *a) unsigned int node = domain_to_node(d); if ( !guest_handle_is_null(a->extent_list) && - !guest_handle_okay(a->extent_list, a->nr_extents) ) + !guest_handle_subrange_okay(a->extent_list, a->nr_done, + a->nr_extents-1) ) return; if ( (a->extent_order != 0) && @@ -94,7 +95,8 @@ static void populate_physmap(struct memop_args *a) struct domain *d = a->domain; unsigned int node = domain_to_node(d); - if ( !guest_handle_okay(a->extent_list, a->nr_extents) ) + if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done, + a->nr_extents-1) ) return; if ( (a->extent_order != 0) && @@ -179,7 +181,8 @@ static void decrease_reservation(struct memop_args *a) unsigned long i, j; xen_pfn_t gmfn; - if ( !guest_handle_okay(a->extent_list, a->nr_extents) ) + if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done, + a->nr_extents-1) ) return; for ( i = a->nr_done; i < a->nr_extents; i++ ) @@ -219,8 +222,8 @@ static long translate_gpfn_list( if ( op.nr_gpfns > (ULONG_MAX >> MEMOP_EXTENT_SHIFT) ) return -EINVAL; - if ( !guest_handle_okay(op.gpfn_list, op.nr_gpfns) || - !guest_handle_okay(op.mfn_list, op.nr_gpfns) ) + if ( !guest_handle_subrange_okay(op.gpfn_list, *progress, op.nr_gpfns-1) || + !guest_handle_subrange_okay(op.mfn_list, *progress, op.nr_gpfns-1) ) return -EFAULT; if ( op.domid == DOMID_SELF ) diff --git a/xen/include/asm-x86/guest_access.h b/xen/include/asm-x86/guest_access.h index 75f1f3097d..a8f111ae9b 100644 --- a/xen/include/asm-x86/guest_access.h +++ b/xen/include/asm-x86/guest_access.h @@ -79,6 +79,11 @@ #define guest_handle_okay(hnd, nr) \ (shadow_mode_external(current->domain) || \ array_access_ok((hnd).p, (nr), sizeof(*(hnd).p))) +#define guest_handle_subrange_okay(hnd, first, last) \ + (shadow_mode_external(current->domain) || \ + array_access_ok((hnd).p + (first), \ + (last)-(first)+1, \ + sizeof(*(hnd).p))) #define __copy_to_guest_offset(hnd, off, ptr, nr) ({ \ const typeof(*(ptr)) *_s = (ptr); \ diff --git a/xen/include/xen/xencomm.h b/xen/include/xen/xencomm.h index f044c74f99..bce2ca720d 100644 --- a/xen/include/xen/xencomm.h +++ b/xen/include/xen/xencomm.h @@ -62,6 +62,7 @@ static inline unsigned long xencomm_inline_addr(const void *handle) /* Since we run in real mode, we can safely access all addresses. That also * means our __routines are identical to our "normal" routines. */ #define guest_handle_okay(hnd, nr) 1 +#define guest_handle_subrange_okay(hnd, first, last) 1 /* * Copy an array of objects to guest context via a guest handle.