]> xenbits.xensource.com Git - people/gdunlap/xen.git/commitdiff
vNUMA: validate XEN_DOMCTL_setvnumainfo input
authorJan Beulich <jbeulich@suse.com>
Wed, 4 Mar 2015 09:01:41 +0000 (10:01 +0100)
committerJan Beulich <jbeulich@suse.com>
Wed, 4 Mar 2015 09:01:41 +0000 (10:01 +0100)
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 <jbeulich@suse.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@cigtrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/common/domctl.c
xen/include/xen/domain.h

index 4a42c6656f12544c8e2f00c3271e9d8485dd8d82..df68734a12d0c80c25c720ee5cb10dda9736818e 100644 (file)
@@ -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;
 
index 72667dac70c1471a63827b9b5ffac2756c25d74d..920f524c450868cccfc29b0227abf0763fe90453 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <public/xen.h>
 #include <asm/domain.h>
+#include <asm/numa.h>
 
 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;
 };