9119d9
From dc201f5982fafc2727a2206536c4afe1b1a9017d Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <dc201f5982fafc2727a2206536c4afe1b1a9017d@dist-git>
9119d9
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
9119d9
Date: Thu, 18 Sep 2014 09:18:43 +0200
9119d9
Subject: [PATCH] qemu: fix crash with shared disks
9119d9
9119d9
Commit f36a94f introduced a double free on all success paths
9119d9
in qemuSharedDeviceEntryInsert.
9119d9
9119d9
Only call qemuSharedDeviceEntryFree on the error path and
9119d9
set entry to NULL before jumping there if the entry already
9119d9
is in the hash table.
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=1142722
9119d9
(cherry picked from commit 540ee872494316ef5bfc17ef3dd4338080c3e513)
9119d9
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 src/qemu/qemu_conf.c | 26 ++++++++++++--------------
9119d9
 src/qemu/qemu_conf.h |  3 +--
9119d9
 2 files changed, 13 insertions(+), 16 deletions(-)
9119d9
9119d9
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
9119d9
index ac10b64..adc6caf 100644
9119d9
--- a/src/qemu/qemu_conf.c
9119d9
+++ b/src/qemu/qemu_conf.c
9119d9
@@ -1011,38 +1011,36 @@ qemuSharedDeviceEntryInsert(virQEMUDriverPtr driver,
9119d9
                             const char *name)
9119d9
 {
9119d9
     qemuSharedDeviceEntry *entry = NULL;
9119d9
-    int ret = -1;
9119d9
 
9119d9
     if ((entry = virHashLookup(driver->sharedDevices, key))) {
9119d9
         /* Nothing to do if the shared scsi host device is already
9119d9
          * recorded in the table.
9119d9
          */
9119d9
-        if (qemuSharedDeviceEntryDomainExists(entry, name, NULL)) {
9119d9
-            ret = 0;
9119d9
-            goto cleanup;
9119d9
+        if (!qemuSharedDeviceEntryDomainExists(entry, name, NULL)) {
9119d9
+            if (VIR_EXPAND_N(entry->domains, entry->ref, 1) < 0 ||
9119d9
+                VIR_STRDUP(entry->domains[entry->ref - 1], name) < 0) {
9119d9
+                /* entry is owned by the hash table here */
9119d9
+                entry = NULL;
9119d9
+                goto error;
9119d9
+            }
9119d9
         }
9119d9
-
9119d9
-        if (VIR_EXPAND_N(entry->domains, entry->ref, 1) < 0 ||
9119d9
-            VIR_STRDUP(entry->domains[entry->ref - 1], name) < 0)
9119d9
-            goto cleanup;
9119d9
     } else {
9119d9
         if (VIR_ALLOC(entry) < 0 ||
9119d9
             VIR_ALLOC_N(entry->domains, 1) < 0 ||
9119d9
             VIR_STRDUP(entry->domains[0], name) < 0)
9119d9
-            goto cleanup;
9119d9
+            goto error;
9119d9
 
9119d9
         entry->ref = 1;
9119d9
 
9119d9
         if (virHashAddEntry(driver->sharedDevices, key, entry))
9119d9
-            goto cleanup;
9119d9
+            goto error;
9119d9
     }
9119d9
 
9119d9
-    ret = 0;
9119d9
+    return 0;
9119d9
 
9119d9
- cleanup:
9119d9
+ error:
9119d9
     qemuSharedDeviceEntryFree(entry, NULL);
9119d9
-
9119d9
-    return ret;
9119d9
+    return -1;
9119d9
 }
9119d9
 
9119d9
 
9119d9
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
9119d9
index 1f521e5..cb01fb6 100644
9119d9
--- a/src/qemu/qemu_conf.h
9119d9
+++ b/src/qemu/qemu_conf.h
9119d9
@@ -294,8 +294,7 @@ bool qemuSharedDeviceEntryDomainExists(qemuSharedDeviceEntryPtr entry,
9119d9
 char *qemuGetSharedDeviceKey(const char *disk_path)
9119d9
     ATTRIBUTE_NONNULL(1);
9119d9
 
9119d9
-void qemuSharedDeviceEntryFree(void *payload, const void *name)
9119d9
-    ATTRIBUTE_NONNULL(1);
9119d9
+void qemuSharedDeviceEntryFree(void *payload, const void *name);
9119d9
 
9119d9
 int qemuAddSharedDevice(virQEMUDriverPtr driver,
9119d9
                         virDomainDeviceDefPtr dev,
9119d9
-- 
9119d9
2.1.0
9119d9