[libvirt] [PATCH 1/2] conf: Sanitize cpu topology numbers

Peter Krempa pkrempa at redhat.com
Mon Oct 10 14:01:43 UTC 2016


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   | 39 +++++++++++++++++++++++++++++++++++++++
 src/conf/domain_conf.h   |  2 ++
 src/libvirt_private.syms |  1 +
 3 files changed, 42 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f562323..44752b9 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -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;
 }

diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a70bc21..54c9502 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -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);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 923afd1..233cf6b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -247,6 +247,7 @@ virDomainDefGetVcpu;
 virDomainDefGetVcpuPinInfoHelper;
 virDomainDefGetVcpus;
 virDomainDefGetVcpusMax;
+virDomainDefGetVcpusTopology;
 virDomainDefHasDeviceAddress;
 virDomainDefHasMemballoon;
 virDomainDefHasMemoryHotplug;
-- 
2.10.0




More information about the libvir-list mailing list