[libvirt] [PATCHv2] qemu: fix a bug in numatune

Hu Tao hutao at cn.fujitsu.com
Wed Jan 4 09:41:43 UTC 2012


When setting numa nodeset for a domain which has no nodeset set
before, libvirtd crashes by dereferring the pointer to the old
nodemask which is null in the case.
---
 src/qemu/qemu_driver.c |   45 +++++++++++++++++++++++++++++++++++++--------
 1 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 82bab67..036d252 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6679,6 +6679,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
             }
         } else if (STREQ(param->field, VIR_DOMAIN_NUMA_NODESET)) {
             int rc;
+            bool savedmask;
             char oldnodemask[VIR_DOMAIN_CPUMASK_LEN];
             if (param->type != VIR_TYPED_PARAM_STRING) {
                 qemuReportError(VIR_ERR_INVALID_ARG, "%s",
@@ -6707,28 +6708,56 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
 
                 /* update vm->def here so that dumpxml can read the new
                  * values from vm->def. */
-                memcpy(oldnodemask, vm->def->numatune.memory.nodemask,
-                       VIR_DOMAIN_CPUMASK_LEN);
+                savedmask = false;
+                if (!vm->def->numatune.memory.nodemask) {
+                    if (VIR_ALLOC_N(vm->def->numatune.memory.nodemask,
+                                    VIR_DOMAIN_CPUMASK_LEN) < 0) {
+                        virReportOOMError();
+                        ret = -1;
+                        goto cleanup;
+                    }
+                } else {
+                    memcpy(oldnodemask, vm->def->numatune.memory.nodemask,
+                           VIR_DOMAIN_CPUMASK_LEN);
+                    savedmask = true;
+                }
                 if (virDomainCpuSetParse(params[i].value.s,
                                          0,
                                          vm->def->numatune.memory.nodemask,
                                          VIR_DOMAIN_CPUMASK_LEN) < 0) {
-                    memcpy(vm->def->numatune.memory.nodemask,
-                           oldnodemask, VIR_DOMAIN_CPUMASK_LEN);
+                    if (savedmask)
+                        memcpy(vm->def->numatune.memory.nodemask,
+                               oldnodemask, VIR_DOMAIN_CPUMASK_LEN);
+                    else
+                        VIR_FREE(vm->def->numatune.memory.nodemask);
                     ret = -1;
                     continue;
                 }
             }
 
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
-                memcpy(oldnodemask, persistentDef->numatune.memory.nodemask,
-                       VIR_DOMAIN_CPUMASK_LEN);
+                savedmask = false;
+                if (!persistentDef->numatune.memory.nodemask) {
+                    if (VIR_ALLOC_N(persistentDef->numatune.memory.nodemask,
+                                    VIR_DOMAIN_CPUMASK_LEN) < 0) {
+                        virReportOOMError();
+                        ret = -1;
+                        goto cleanup;
+                    }
+                } else {
+                    memcpy(oldnodemask, persistentDef->numatune.memory.nodemask,
+                           VIR_DOMAIN_CPUMASK_LEN);
+                    savedmask = true;
+                }
                 if (virDomainCpuSetParse(params[i].value.s,
                                          0,
                                          persistentDef->numatune.memory.nodemask,
                                          VIR_DOMAIN_CPUMASK_LEN) < 0) {
-                    memcpy(persistentDef->numatune.memory.nodemask,
-                           oldnodemask, VIR_DOMAIN_CPUMASK_LEN);
+                    if (savedmask)
+                        memcpy(persistentDef->numatune.memory.nodemask,
+                               oldnodemask, VIR_DOMAIN_CPUMASK_LEN);
+                    else
+                        VIR_FREE(persistentDef->numatune.memory.nodemask);
                     ret = -1;
                     continue;
                 }
-- 
1.7.4.4




More information about the libvir-list mailing list