]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
virsh: Report an error when cpulist parsing fails
authorLuyao Huang <lhuang@redhat.com>
Mon, 11 May 2015 08:25:19 +0000 (16:25 +0800)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 14 May 2015 12:16:07 +0000 (14:16 +0200)
When parsing a cpulist, the virBitmapParse is used. On an invalid
bitmap an error is reported, but the error gets cleared
immediately by subsequent public APIs call, e.g. virDomainFree().
Moreover, we don't check whether bitmap fits into maximal CPU ID
on the host. Therefore the following examples failed without any
error:

 # virsh vcpupin test3 1 aaa

 # virsh vcpupin test3 1 1000

Signed-off-by: Luyao Huang <lhuang@redhat.com>
tools/virsh-domain.c

index 14e1e35924df1c152da9df37d0c597e85eb88937..20f8c75cdd69cebbfba9b63d3de1b344fc9eb5d9 100644 (file)
@@ -6348,7 +6348,7 @@ vshPrintPinInfo(unsigned char *cpumap, size_t cpumaplen)
 }
 
 static unsigned char *
-vshParseCPUList(int *cpumaplen, const char *cpulist, int maxcpu)
+vshParseCPUList(vshControl *ctl, int *cpumaplen, const char *cpulist, int maxcpu)
 {
     unsigned char *cpumap = NULL;
     virBitmapPtr map = NULL;
@@ -6358,8 +6358,17 @@ vshParseCPUList(int *cpumaplen, const char *cpulist, int maxcpu)
             return NULL;
         virBitmapSetAll(map);
     } else {
-        if (virBitmapParse(cpulist, '\0', &map, maxcpu) < 0)
-            return NULL;
+        if ((virBitmapParse(cpulist, '\0', &map, 1024) < 0) ||
+            virBitmapIsAllClear(map)) {
+            vshError(ctl, _("Invalid cpulist '%s'"), cpulist);
+            goto cleanup;
+        }
+        int lastcpu = virBitmapLastSetBit(map);
+        if (lastcpu >= maxcpu) {
+            vshError(ctl, _("CPU %d in cpulist '%s' exceed the maxcpu %d"),
+                     lastcpu, cpulist, maxcpu);
+            goto cleanup;
+        }
     }
 
     if (virBitmapToData(map, &cpumap, cpumaplen) < 0)
@@ -6458,7 +6467,7 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
         }
     } else {
         /* Pin mode: pinning specified vcpu to specified physical cpus*/
-        if (!(cpumap = vshParseCPUList(&cpumaplen, cpulist, maxcpu)))
+        if (!(cpumap = vshParseCPUList(ctl, &cpumaplen, cpulist, maxcpu)))
             goto cleanup;
 
         if (flags == -1) {
@@ -6577,7 +6586,7 @@ cmdEmulatorPin(vshControl *ctl, const vshCmd *cmd)
     }
 
     /* Pin mode: pinning emulator threads to specified physical cpus*/
-    if (!(cpumap = vshParseCPUList(&cpumaplen, cpulist, maxcpu)))
+    if (!(cpumap = vshParseCPUList(ctl, &cpumaplen, cpulist, maxcpu)))
         goto cleanup;
 
     if (flags == -1)
@@ -6862,7 +6871,7 @@ cmdIOThreadPin(vshControl *ctl, const vshCmd *cmd)
     if ((maxcpu = vshNodeGetCPUCount(ctl->conn)) < 0)
         goto cleanup;
 
-    if (!(cpumap = vshParseCPUList(&cpumaplen, cpulist, maxcpu)))
+    if (!(cpumap = vshParseCPUList(ctl, &cpumaplen, cpulist, maxcpu)))
         goto cleanup;
 
     if (virDomainPinIOThread(dom, iothread_id,