6ae9ed
From e3f4b7809a6f2738801f7f9610fcbfa2166c1bb3 Mon Sep 17 00:00:00 2001
6ae9ed
Message-Id: <e3f4b7809a6f2738801f7f9610fcbfa2166c1bb3@dist-git>
6ae9ed
From: Peter Krempa <pkrempa@redhat.com>
6ae9ed
Date: Wed, 24 Aug 2016 16:11:01 -0400
6ae9ed
Subject: [PATCH] qemu: caps: Sanitize storage of machine type related data
6ae9ed
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1097930
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1224341
6ae9ed
6ae9ed
Add a structure to store the data and use a single array of the
6ae9ed
structures rather than having 3 separate arrays with shared indexes.
6ae9ed
6ae9ed
(cherry picked from commit ceec23d97f1d32f2047750c7329574a17b7290f9)
6ae9ed
---
6ae9ed
 src/qemu/qemu_capabilities.c | 117 +++++++++++++++++--------------------------
6ae9ed
 1 file changed, 46 insertions(+), 71 deletions(-)
6ae9ed
6ae9ed
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
6ae9ed
index 56fefbb..f6a42e7 100644
6ae9ed
--- a/src/qemu/qemu_capabilities.c
6ae9ed
+++ b/src/qemu/qemu_capabilities.c
6ae9ed
@@ -342,6 +342,11 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
6ae9ed
     );
6ae9ed
 
6ae9ed
 
6ae9ed
+struct virQEMUCapsMachineType {
6ae9ed
+    char *name;
6ae9ed
+    char *alias;
6ae9ed
+    unsigned int maxCpus;
6ae9ed
+};
6ae9ed
 /*
6ae9ed
  * Update the XML parser/formatter when adding more
6ae9ed
  * information to this struct so that it gets cached
6ae9ed
@@ -369,9 +374,7 @@ struct _virQEMUCaps {
6ae9ed
     char **cpuDefinitions;
6ae9ed
 
6ae9ed
     size_t nmachineTypes;
6ae9ed
-    char **machineTypes;
6ae9ed
-    char **machineAliases;
6ae9ed
-    unsigned int *machineMaxCpus;
6ae9ed
+    struct virQEMUCapsMachineType *machineTypes;
6ae9ed
 
6ae9ed
     size_t ngicCapabilities;
6ae9ed
     virGICCapability *gicCapabilities;
6ae9ed
@@ -473,22 +476,13 @@ static void
6ae9ed
 virQEMUCapsSetDefaultMachine(virQEMUCapsPtr qemuCaps,
6ae9ed
                              size_t defIdx)
6ae9ed
 {
6ae9ed
-    char *name = qemuCaps->machineTypes[defIdx];
6ae9ed
-    char *alias = qemuCaps->machineAliases[defIdx];
6ae9ed
-    unsigned int maxCpus = qemuCaps->machineMaxCpus[defIdx];
6ae9ed
+    struct virQEMUCapsMachineType tmp = qemuCaps->machineTypes[defIdx];
6ae9ed
 
6ae9ed
     memmove(qemuCaps->machineTypes + 1,
6ae9ed
             qemuCaps->machineTypes,
6ae9ed
             sizeof(qemuCaps->machineTypes[0]) * defIdx);
6ae9ed
-    memmove(qemuCaps->machineAliases + 1,
6ae9ed
-            qemuCaps->machineAliases,
6ae9ed
-            sizeof(qemuCaps->machineAliases[0]) * defIdx);
6ae9ed
-    memmove(qemuCaps->machineMaxCpus + 1,
6ae9ed
-            qemuCaps->machineMaxCpus,
6ae9ed
-            sizeof(qemuCaps->machineMaxCpus[0]) * defIdx);
6ae9ed
-    qemuCaps->machineTypes[0] = name;
6ae9ed
-    qemuCaps->machineAliases[0] = alias;
6ae9ed
-    qemuCaps->machineMaxCpus[0] = maxCpus;
6ae9ed
+
6ae9ed
+    qemuCaps->machineTypes[0] = tmp;
6ae9ed
 }
6ae9ed
 
6ae9ed
 /* Format is:
6ae9ed
@@ -536,23 +530,21 @@ virQEMUCapsParseMachineTypesStr(const char *output,
6ae9ed
             }
6ae9ed
         }
6ae9ed
 
6ae9ed
-        if (VIR_REALLOC_N(qemuCaps->machineTypes, qemuCaps->nmachineTypes + 1) < 0 ||
6ae9ed
-            VIR_REALLOC_N(qemuCaps->machineAliases, qemuCaps->nmachineTypes + 1) < 0 ||
6ae9ed
-            VIR_REALLOC_N(qemuCaps->machineMaxCpus, qemuCaps->nmachineTypes + 1) < 0) {
6ae9ed
+        if (VIR_REALLOC_N(qemuCaps->machineTypes, qemuCaps->nmachineTypes + 1) < 0) {
6ae9ed
             VIR_FREE(name);
6ae9ed
             VIR_FREE(canonical);
6ae9ed
             return -1;
6ae9ed
         }
6ae9ed
         qemuCaps->nmachineTypes++;
6ae9ed
         if (canonical) {
6ae9ed
-            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1] = canonical;
6ae9ed
-            qemuCaps->machineAliases[qemuCaps->nmachineTypes-1] = name;
6ae9ed
+            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].name = canonical;
6ae9ed
+            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].alias = name;
6ae9ed
         } else {
6ae9ed
-            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1] = name;
6ae9ed
-            qemuCaps->machineAliases[qemuCaps->nmachineTypes-1] = NULL;
6ae9ed
+            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].name = name;
6ae9ed
+            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].alias = NULL;
6ae9ed
         }
6ae9ed
         /* When parsing from command line we don't have information about maxCpus */
6ae9ed
-        qemuCaps->machineMaxCpus[qemuCaps->nmachineTypes-1] = 0;
6ae9ed
+        qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].maxCpus = 0;
6ae9ed
     } while ((p = next));
6ae9ed
 
6ae9ed
 
6ae9ed
@@ -2041,16 +2033,12 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
6ae9ed
 
6ae9ed
     if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
6ae9ed
         goto error;
6ae9ed
-    if (VIR_ALLOC_N(ret->machineAliases, qemuCaps->nmachineTypes) < 0)
6ae9ed
-        goto error;
6ae9ed
-    if (VIR_ALLOC_N(ret->machineMaxCpus, qemuCaps->nmachineTypes) < 0)
6ae9ed
-        goto error;
6ae9ed
     ret->nmachineTypes = qemuCaps->nmachineTypes;
6ae9ed
     for (i = 0; i < qemuCaps->nmachineTypes; i++) {
6ae9ed
-        if (VIR_STRDUP(ret->machineTypes[i], qemuCaps->machineTypes[i]) < 0 ||
6ae9ed
-            VIR_STRDUP(ret->machineAliases[i], qemuCaps->machineAliases[i]) < 0)
6ae9ed
+        if (VIR_STRDUP(ret->machineTypes[i].name, qemuCaps->machineTypes[i].name) < 0 ||
6ae9ed
+            VIR_STRDUP(ret->machineTypes[i].alias, qemuCaps->machineTypes[i].alias) < 0)
6ae9ed
             goto error;
6ae9ed
-        ret->machineMaxCpus[i] = qemuCaps->machineMaxCpus[i];
6ae9ed
+        ret->machineTypes[i].maxCpus = qemuCaps->machineTypes[i].maxCpus;
6ae9ed
     }
6ae9ed
 
6ae9ed
     return ret;
6ae9ed
@@ -2067,12 +2055,10 @@ void virQEMUCapsDispose(void *obj)
6ae9ed
     size_t i;
6ae9ed
 
6ae9ed
     for (i = 0; i < qemuCaps->nmachineTypes; i++) {
6ae9ed
-        VIR_FREE(qemuCaps->machineTypes[i]);
6ae9ed
-        VIR_FREE(qemuCaps->machineAliases[i]);
6ae9ed
+        VIR_FREE(qemuCaps->machineTypes[i].name);
6ae9ed
+        VIR_FREE(qemuCaps->machineTypes[i].alias);
6ae9ed
     }
6ae9ed
     VIR_FREE(qemuCaps->machineTypes);
6ae9ed
-    VIR_FREE(qemuCaps->machineAliases);
6ae9ed
-    VIR_FREE(qemuCaps->machineMaxCpus);
6ae9ed
 
6ae9ed
     for (i = 0; i < qemuCaps->ncpuDefinitions; i++)
6ae9ed
         VIR_FREE(qemuCaps->cpuDefinitions[i]);
6ae9ed
@@ -2257,15 +2243,15 @@ int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps,
6ae9ed
         if (VIR_ALLOC(mach) < 0)
6ae9ed
             goto error;
6ae9ed
         (*machines)[i] = mach;
6ae9ed
-        if (qemuCaps->machineAliases[i]) {
6ae9ed
-            if (VIR_STRDUP(mach->name, qemuCaps->machineAliases[i]) < 0 ||
6ae9ed
-                VIR_STRDUP(mach->canonical, qemuCaps->machineTypes[i]) < 0)
6ae9ed
+        if (qemuCaps->machineTypes[i].alias) {
6ae9ed
+            if (VIR_STRDUP(mach->name, qemuCaps->machineTypes[i].alias) < 0 ||
6ae9ed
+                VIR_STRDUP(mach->canonical, qemuCaps->machineTypes[i].name) < 0)
6ae9ed
                 goto error;
6ae9ed
         } else {
6ae9ed
-            if (VIR_STRDUP(mach->name, qemuCaps->machineTypes[i]) < 0)
6ae9ed
+            if (VIR_STRDUP(mach->name, qemuCaps->machineTypes[i].name) < 0)
6ae9ed
                 goto error;
6ae9ed
         }
6ae9ed
-        mach->maxCpus = qemuCaps->machineMaxCpus[i];
6ae9ed
+        mach->maxCpus = qemuCaps->machineTypes[i].maxCpus;
6ae9ed
     }
6ae9ed
 
6ae9ed
     /* Make sure all canonical machine types also have their own entry so that
6ae9ed
@@ -2327,10 +2313,10 @@ const char *virQEMUCapsGetCanonicalMachine(virQEMUCapsPtr qemuCaps,
6ae9ed
         return NULL;
6ae9ed
 
6ae9ed
     for (i = 0; i < qemuCaps->nmachineTypes; i++) {
6ae9ed
-        if (!qemuCaps->machineAliases[i])
6ae9ed
+        if (!qemuCaps->machineTypes[i].alias)
6ae9ed
             continue;
6ae9ed
-        if (STREQ(qemuCaps->machineAliases[i], name))
6ae9ed
-            return qemuCaps->machineTypes[i];
6ae9ed
+        if (STREQ(qemuCaps->machineTypes[i].alias, name))
6ae9ed
+            return qemuCaps->machineTypes[i].name;
6ae9ed
     }
6ae9ed
 
6ae9ed
     return name;
6ae9ed
@@ -2346,10 +2332,10 @@ int virQEMUCapsGetMachineMaxCpus(virQEMUCapsPtr qemuCaps,
6ae9ed
         return 0;
6ae9ed
 
6ae9ed
     for (i = 0; i < qemuCaps->nmachineTypes; i++) {
6ae9ed
-        if (!qemuCaps->machineMaxCpus[i])
6ae9ed
+        if (!qemuCaps->machineTypes[i].maxCpus)
6ae9ed
             continue;
6ae9ed
-        if (STREQ(qemuCaps->machineTypes[i], name))
6ae9ed
-            return qemuCaps->machineMaxCpus[i];
6ae9ed
+        if (STREQ(qemuCaps->machineTypes[i].name, name))
6ae9ed
+            return qemuCaps->machineTypes[i].maxCpus;
6ae9ed
     }
6ae9ed
 
6ae9ed
     return 0;
6ae9ed
@@ -2497,23 +2483,19 @@ virQEMUCapsProbeQMPMachineTypes(virQEMUCapsPtr qemuCaps,
6ae9ed
 
6ae9ed
     if (VIR_ALLOC_N(qemuCaps->machineTypes, nmachines) < 0)
6ae9ed
         goto cleanup;
6ae9ed
-    if (VIR_ALLOC_N(qemuCaps->machineAliases, nmachines) < 0)
6ae9ed
-        goto cleanup;
6ae9ed
-    if (VIR_ALLOC_N(qemuCaps->machineMaxCpus, nmachines) < 0)
6ae9ed
-        goto cleanup;
6ae9ed
 
6ae9ed
     for (i = 0; i < nmachines; i++) {
6ae9ed
         if (STREQ(machines[i]->name, "none"))
6ae9ed
             continue;
6ae9ed
         qemuCaps->nmachineTypes++;
6ae9ed
-        if (VIR_STRDUP(qemuCaps->machineAliases[qemuCaps->nmachineTypes -1],
6ae9ed
+        if (VIR_STRDUP(qemuCaps->machineTypes[qemuCaps->nmachineTypes -1].alias,
6ae9ed
                        machines[i]->alias) < 0 ||
6ae9ed
-            VIR_STRDUP(qemuCaps->machineTypes[qemuCaps->nmachineTypes - 1],
6ae9ed
+            VIR_STRDUP(qemuCaps->machineTypes[qemuCaps->nmachineTypes - 1].name,
6ae9ed
                        machines[i]->name) < 0)
6ae9ed
             goto cleanup;
6ae9ed
         if (machines[i]->isDefault)
6ae9ed
             defIdx = qemuCaps->nmachineTypes - 1;
6ae9ed
-        qemuCaps->machineMaxCpus[qemuCaps->nmachineTypes - 1] =
6ae9ed
+        qemuCaps->machineTypes[qemuCaps->nmachineTypes - 1].maxCpus =
6ae9ed
             machines[i]->maxCpus;
6ae9ed
     }
6ae9ed
 
6ae9ed
@@ -2908,25 +2890,20 @@ virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps, const char *filename,
6ae9ed
     }
6ae9ed
     if (n > 0) {
6ae9ed
         qemuCaps->nmachineTypes = n;
6ae9ed
-        if (VIR_ALLOC_N(qemuCaps->machineTypes,
6ae9ed
-                        qemuCaps->nmachineTypes) < 0 ||
6ae9ed
-            VIR_ALLOC_N(qemuCaps->machineAliases,
6ae9ed
-                        qemuCaps->nmachineTypes) < 0 ||
6ae9ed
-            VIR_ALLOC_N(qemuCaps->machineMaxCpus,
6ae9ed
-                        qemuCaps->nmachineTypes) < 0)
6ae9ed
+        if (VIR_ALLOC_N(qemuCaps->machineTypes, qemuCaps->nmachineTypes) < 0)
6ae9ed
             goto cleanup;
6ae9ed
 
6ae9ed
         for (i = 0; i < n; i++) {
6ae9ed
-            if (!(qemuCaps->machineTypes[i] = virXMLPropString(nodes[i], "name"))) {
6ae9ed
+            if (!(qemuCaps->machineTypes[i].name = virXMLPropString(nodes[i], "name"))) {
6ae9ed
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6ae9ed
                                _("missing machine name in QEMU capabilities cache"));
6ae9ed
                 goto cleanup;
6ae9ed
             }
6ae9ed
-            qemuCaps->machineAliases[i] = virXMLPropString(nodes[i], "alias");
6ae9ed
+            qemuCaps->machineTypes[i].alias = virXMLPropString(nodes[i], "alias");
6ae9ed
 
6ae9ed
             str = virXMLPropString(nodes[i], "maxCpus");
6ae9ed
             if (str &&
6ae9ed
-                virStrToLong_ui(str, NULL, 10, &(qemuCaps->machineMaxCpus[i])) < 0) {
6ae9ed
+                virStrToLong_ui(str, NULL, 10, &(qemuCaps->machineTypes[i].maxCpus)) < 0) {
6ae9ed
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6ae9ed
                                _("malformed machine cpu count in QEMU capabilities cache"));
6ae9ed
                 goto cleanup;
6ae9ed
@@ -3061,12 +3038,12 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps,
6ae9ed
 
6ae9ed
     for (i = 0; i < qemuCaps->nmachineTypes; i++) {
6ae9ed
         virBufferEscapeString(&buf, "
6ae9ed
-                              qemuCaps->machineTypes[i]);
6ae9ed
-        if (qemuCaps->machineAliases[i])
6ae9ed
+                              qemuCaps->machineTypes[i].name);
6ae9ed
+        if (qemuCaps->machineTypes[i].alias)
6ae9ed
             virBufferEscapeString(&buf, " alias='%s'",
6ae9ed
-                              qemuCaps->machineAliases[i]);
6ae9ed
+                              qemuCaps->machineTypes[i].alias);
6ae9ed
         virBufferAsprintf(&buf, " maxCpus='%u'/>\n",
6ae9ed
-                          qemuCaps->machineMaxCpus[i]);
6ae9ed
+                          qemuCaps->machineTypes[i].maxCpus);
6ae9ed
     }
6ae9ed
 
6ae9ed
     for (i = 0; i < qemuCaps->ngicCapabilities; i++) {
6ae9ed
@@ -3178,12 +3155,10 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
6ae9ed
     qemuCaps->ncpuDefinitions = 0;
6ae9ed
 
6ae9ed
     for (i = 0; i < qemuCaps->nmachineTypes; i++) {
6ae9ed
-        VIR_FREE(qemuCaps->machineTypes[i]);
6ae9ed
-        VIR_FREE(qemuCaps->machineAliases[i]);
6ae9ed
+        VIR_FREE(qemuCaps->machineTypes[i].name);
6ae9ed
+        VIR_FREE(qemuCaps->machineTypes[i].alias);
6ae9ed
     }
6ae9ed
     VIR_FREE(qemuCaps->machineTypes);
6ae9ed
-    VIR_FREE(qemuCaps->machineAliases);
6ae9ed
-    VIR_FREE(qemuCaps->machineMaxCpus);
6ae9ed
     qemuCaps->nmachineTypes = 0;
6ae9ed
 
6ae9ed
     VIR_FREE(qemuCaps->gicCapabilities);
6ae9ed
@@ -4066,7 +4041,7 @@ virQEMUCapsIsMachineSupported(virQEMUCapsPtr qemuCaps,
6ae9ed
     size_t i;
6ae9ed
 
6ae9ed
     for (i = 0; i < qemuCaps->nmachineTypes; i++) {
6ae9ed
-        if (STREQ(canonical_machine, qemuCaps->machineTypes[i]))
6ae9ed
+        if (STREQ(canonical_machine, qemuCaps->machineTypes[i].name))
6ae9ed
             return true;
6ae9ed
     }
6ae9ed
     return false;
6ae9ed
@@ -4078,7 +4053,7 @@ virQEMUCapsGetDefaultMachine(virQEMUCapsPtr qemuCaps)
6ae9ed
 {
6ae9ed
     if (!qemuCaps->nmachineTypes)
6ae9ed
         return NULL;
6ae9ed
-    return qemuCaps->machineTypes[0];
6ae9ed
+    return qemuCaps->machineTypes[0].name;
6ae9ed
 }
6ae9ed
 
6ae9ed
 
6ae9ed
-- 
6ae9ed
2.10.0
6ae9ed