]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: Sanitize cpu topology numbers
authorPeter Krempa <pkrempa@redhat.com>
Mon, 10 Oct 2016 13:46:25 +0000 (15:46 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 11 Oct 2016 11:52:09 +0000 (13:52 +0200)
Make sure that the topology results into a sane number of cpus (up to
UINT_MAX) so that it can be sanely compared to the vcpu count of the VM.

Additionally the helper added in this patch allows to fetch the total
number the topology results to so that it does not have to be
reimplemented later.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1378290

src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms

index f562323657fdfbd572eb4de1d6ed4db722bae98a..44752b948dea492272a6470613cb6d118ba2f65b 100644 (file)
@@ -1570,6 +1570,42 @@ virDomainDefGetVcpuPinInfoHelper(virDomainDefPtr def,
 }
 
 
+/**
+ * virDomainDeGetVcpusTopology:
+ * @def: domain definition
+ * @maxvcpus: optionally filled with number of vcpus the domain topology describes
+ *
+ * Calculates and validates that the vcpu topology is in sane bounds and
+ * optionally returns the total number of vcpus described by given topology.
+ *
+ * Returns 0 on success, 1 if topology is not configured and -1 on error.
+ */
+int
+virDomainDefGetVcpusTopology(const virDomainDef *def,
+                             unsigned int *maxvcpus)
+{
+    unsigned long long tmp;
+
+    if (!def->cpu || def->cpu->sockets == 0)
+        return 1;
+
+    tmp = def->cpu->sockets;
+
+    /* multiplication of 32bit numbers fits into a 64bit variable */
+    if ((tmp *= def->cpu->cores) > UINT_MAX ||
+        (tmp *= def->cpu->threads) > UINT_MAX) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("cpu topology results in more than %u cpus"), UINT_MAX);
+        return -1;
+    }
+
+    if (maxvcpus)
+        *maxvcpus = tmp;
+
+    return 0;
+}
+
+
 virDomainDiskDefPtr
 virDomainDiskDefNew(virDomainXMLOptionPtr xmlopt)
 {
@@ -4786,6 +4822,9 @@ virDomainDefValidateInternal(const virDomainDef *def)
     if (virDomainDefCheckDuplicateDiskInfo(def) < 0)
         return -1;
 
+    if (virDomainDefGetVcpusTopology(def, NULL) < 0)
+        return -1;
+
     return 0;
 }
 
index a70bc2182a48a65a2ff6dd99f72f51ea9adde740..54c9502ce4a0881533321a5b1e57021619b28e6d 100644 (file)
@@ -2488,6 +2488,8 @@ virBitmapPtr virDomainDefGetOnlineVcpumap(const virDomainDef *def);
 virDomainVcpuDefPtr virDomainDefGetVcpu(virDomainDefPtr def, unsigned int vcpu)
     ATTRIBUTE_RETURN_CHECK;
 void virDomainDefVcpuOrderClear(virDomainDefPtr def);
+int  virDomainDefGetVcpusTopology(const virDomainDef *def,
+                                  unsigned int *maxvcpus);
 
 virDomainObjPtr virDomainObjNew(virDomainXMLOptionPtr caps)
     ATTRIBUTE_NONNULL(1);
index b88e903744ec8ae0f404a32a64025d31032feb40..11a90b18740577f16040e9ae7f8e60513996fe83 100644 (file)
@@ -247,6 +247,7 @@ virDomainDefGetVcpu;
 virDomainDefGetVcpuPinInfoHelper;
 virDomainDefGetVcpus;
 virDomainDefGetVcpusMax;
+virDomainDefGetVcpusTopology;
 virDomainDefHasDeviceAddress;
 virDomainDefHasMemballoon;
 virDomainDefHasMemoryHotplug;