]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: fix crash with shared disks
authorJán Tomko <jtomko@redhat.com>
Wed, 17 Sep 2014 10:36:21 +0000 (12:36 +0200)
committerJán Tomko <jtomko@redhat.com>
Thu, 18 Sep 2014 07:05:21 +0000 (09:05 +0200)
Commit f36a94f introduced a double free on all success paths
in qemuSharedDeviceEntryInsert.

Only call qemuSharedDeviceEntryFree on the error path and
set entry to NULL before jumping there if the entry already
is in the hash table.

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

src/qemu/qemu_conf.c
src/qemu/qemu_conf.h

index ac10b64c018596cdd0b814d30e15cfc11f908a7e..adc6cafb2762d7d9b098538b12aed3552e976e65 100644 (file)
@@ -1011,38 +1011,36 @@ qemuSharedDeviceEntryInsert(virQEMUDriverPtr driver,
                             const char *name)
 {
     qemuSharedDeviceEntry *entry = NULL;
-    int ret = -1;
 
     if ((entry = virHashLookup(driver->sharedDevices, key))) {
         /* Nothing to do if the shared scsi host device is already
          * recorded in the table.
          */
-        if (qemuSharedDeviceEntryDomainExists(entry, name, NULL)) {
-            ret = 0;
-            goto cleanup;
+        if (!qemuSharedDeviceEntryDomainExists(entry, name, NULL)) {
+            if (VIR_EXPAND_N(entry->domains, entry->ref, 1) < 0 ||
+                VIR_STRDUP(entry->domains[entry->ref - 1], name) < 0) {
+                /* entry is owned by the hash table here */
+                entry = NULL;
+                goto error;
+            }
         }
-
-        if (VIR_EXPAND_N(entry->domains, entry->ref, 1) < 0 ||
-            VIR_STRDUP(entry->domains[entry->ref - 1], name) < 0)
-            goto cleanup;
     } else {
         if (VIR_ALLOC(entry) < 0 ||
             VIR_ALLOC_N(entry->domains, 1) < 0 ||
             VIR_STRDUP(entry->domains[0], name) < 0)
-            goto cleanup;
+            goto error;
 
         entry->ref = 1;
 
         if (virHashAddEntry(driver->sharedDevices, key, entry))
-            goto cleanup;
+            goto error;
     }
 
-    ret = 0;
+    return 0;
 
cleanup:
error:
     qemuSharedDeviceEntryFree(entry, NULL);
-
-    return ret;
+    return -1;
 }
 
 
index 1f521e534a1c1aeb53944f11e481cc287c554162..cb01fb688b619149573eb0ccc20cebd41fef1a6b 100644 (file)
@@ -294,8 +294,7 @@ bool qemuSharedDeviceEntryDomainExists(qemuSharedDeviceEntryPtr entry,
 char *qemuGetSharedDeviceKey(const char *disk_path)
     ATTRIBUTE_NONNULL(1);
 
-void qemuSharedDeviceEntryFree(void *payload, const void *name)
-    ATTRIBUTE_NONNULL(1);
+void qemuSharedDeviceEntryFree(void *payload, const void *name);
 
 int qemuAddSharedDevice(virQEMUDriverPtr driver,
                         virDomainDeviceDefPtr dev,