From: Jan Beulich Date: Wed, 4 Mar 2015 09:01:41 +0000 (+0100) Subject: vNUMA: validate XEN_DOMCTL_setvnumainfo input X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=519205d2ade90f8402512521fab564a0a015d03c;p=people%2Fgdunlap%2Fxen.git vNUMA: validate XEN_DOMCTL_setvnumainfo input As we get ready to use the information set for a domain here we should make sure it is actually valid: Both vNode and pNode numbers should be in range. Do a little bit of other cleanup so the code ends up looking reasonably consistent in style. Along with this goes that we don't need an array of unsigned int to store the pNode number - a nodeid_t one (a quarter the size) suffices. Signed-off-by: Jan Beulich Reviewed-by: Wei Liu Acked-by: Ian Campbell Reviewed-by: Andrew Cooper --- diff --git a/xen/common/domctl.c b/xen/common/domctl.c index 4a42c6656f..df68734a12 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -344,7 +344,7 @@ static struct vnuma_info *vnuma_alloc(unsigned int nr_vnodes, vnuma->vdistance = xmalloc_array(unsigned int, nr_vnodes * nr_vnodes); vnuma->vcpu_to_vnode = xmalloc_array(unsigned int, nr_vcpus); - vnuma->vnode_to_pnode = xmalloc_array(unsigned int, nr_vnodes); + vnuma->vnode_to_pnode = xmalloc_array(nodeid_t, nr_vnodes); vnuma->vmemrange = xmalloc_array(xen_vmemrange_t, nr_ranges); if ( vnuma->vdistance == NULL || vnuma->vmemrange == NULL || @@ -382,30 +382,40 @@ static struct vnuma_info *vnuma_init(const struct xen_domctl_vnuma *uinfo, nr_vnodes * nr_vnodes) ) goto vnuma_fail; + if ( copy_from_guest(info->vmemrange, uinfo->vmemrange, + uinfo->nr_vmemranges) ) + goto vnuma_fail; + if ( copy_from_guest(info->vcpu_to_vnode, uinfo->vcpu_to_vnode, d->max_vcpus) ) goto vnuma_fail; - if ( copy_from_guest(info->vnode_to_pnode, uinfo->vnode_to_pnode, - nr_vnodes) ) - goto vnuma_fail; + ret = -E2BIG; + for ( i = 0; i < d->max_vcpus; ++i ) + if ( info->vcpu_to_vnode[i] >= nr_vnodes ) + goto vnuma_fail; - if (copy_from_guest(info->vmemrange, uinfo->vmemrange, - uinfo->nr_vmemranges)) - goto vnuma_fail; + for ( i = 0; i < nr_vnodes; ++i ) + { + unsigned int pnode; + + ret = -EFAULT; + if ( copy_from_guest_offset(&pnode, uinfo->vnode_to_pnode, i, 1) ) + goto vnuma_fail; + ret = -E2BIG; + if ( pnode >= MAX_NUMNODES ) + goto vnuma_fail; + info->vnode_to_pnode[i] = pnode; + } info->nr_vnodes = nr_vnodes; info->nr_vmemranges = uinfo->nr_vmemranges; /* Check that vmemranges flags are zero. */ + ret = -EINVAL; for ( i = 0; i < info->nr_vmemranges; i++ ) - { if ( info->vmemrange[i].flags != 0 ) - { - ret = -EINVAL; goto vnuma_fail; - } - } return info; diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h index 72667dac70..920f524c45 100644 --- a/xen/include/xen/domain.h +++ b/xen/include/xen/domain.h @@ -4,6 +4,7 @@ #include #include +#include typedef union { struct vcpu_guest_context *nat; @@ -99,7 +100,7 @@ struct vnuma_info { unsigned int nr_vmemranges; unsigned int *vdistance; unsigned int *vcpu_to_vnode; - unsigned int *vnode_to_pnode; + nodeid_t *vnode_to_pnode; struct xen_vmemrange *vmemrange; };