43fe83
From 5f78e7c3588d19b63acd717a53a62fca1971fc9a Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <5f78e7c3588d19b63acd717a53a62fca1971fc9a.1383922565.git.jdenemar@redhat.com>
43fe83
From: Michal Privoznik <mprivozn@redhat.com>
43fe83
Date: Fri, 8 Nov 2013 08:01:41 +0100
43fe83
Subject: [PATCH] qemu: Avoid double free of VM
43fe83
43fe83
https://bugzilla.redhat.com/show_bug.cgi?id=1018267
43fe83
43fe83
One of my previous patches (c7ac2519b7f) did try to fix the issue when
43fe83
domain dies too soon during migration. However, this clumsy approach was
43fe83
missing removal of qemuProcessHandleMonitorDestroy resulting in double
43fe83
unrefing of mon->vm and hence producing the daemon crash:
43fe83
43fe83
==11843== Invalid read of size 4
43fe83
==11843==    at 0x50C28C5: virObjectUnref (virobject.c:255)
43fe83
==11843==    by 0x1148F7DB: qemuMonitorDispose (qemu_monitor.c:258)
43fe83
==11843==    by 0x50C2991: virObjectUnref (virobject.c:262)
43fe83
==11843==    by 0x50C2D13: virObjectFreeCallback (virobject.c:388)
43fe83
==11843==    by 0x509C37B: virEventPollCleanupHandles (vireventpoll.c:583)
43fe83
==11843==    by 0x509C711: virEventPollRunOnce (vireventpoll.c:652)
43fe83
==11843==    by 0x509A620: virEventRunDefaultImpl (virevent.c:274)
43fe83
==11843==    by 0x520D21C: virNetServerRun (virnetserver.c:1112)
43fe83
==11843==    by 0x11F368: main (libvirtd.c:1513)
43fe83
==11843==  Address 0x13b88864 is 4 bytes inside a block of size 136 free'd
43fe83
==11843==    at 0x4A07F5C: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
43fe83
==11843==    by 0x5079A2F: virFree (viralloc.c:580)
43fe83
==11843==    by 0x50C29E3: virObjectUnref (virobject.c:270)
43fe83
==11843==    by 0x114770E4: qemuProcessHandleMonitorDestroy (qemu_process.c:1103)
43fe83
==11843==    by 0x1148F7CB: qemuMonitorDispose (qemu_monitor.c:257)
43fe83
==11843==    by 0x50C2991: virObjectUnref (virobject.c:262)
43fe83
==11843==    by 0x50C2D13: virObjectFreeCallback (virobject.c:388)
43fe83
==11843==    by 0x509C37B: virEventPollCleanupHandles (vireventpoll.c:583)
43fe83
==11843==    by 0x509C711: virEventPollRunOnce (vireventpoll.c:652)
43fe83
==11843==    by 0x509A620: virEventRunDefaultImpl (virevent.c:274)
43fe83
==11843==    by 0x520D21C: virNetServerRun (virnetserver.c:1112)
43fe83
==11843==    by 0x11F368: main (libvirtd.c:1513)
43fe83
43fe83
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
43fe83
(cherry picked from commit 5a4c2374a2ca5d9d5c5d495f507abcef0f5aabe7)
43fe83
43fe83
Conflicts:
43fe83
	src/qemu/qemu_process.c: Context, as 809ee6bad is not backported yet.
43fe83
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
43fe83
---
43fe83
 src/qemu/qemu_process.c | 15 +++------------
43fe83
 1 file changed, 3 insertions(+), 12 deletions(-)
43fe83
43fe83
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
43fe83
index b9f291d..e0097df 100644
43fe83
--- a/src/qemu/qemu_process.c
43fe83
+++ b/src/qemu/qemu_process.c
43fe83
@@ -1082,13 +1082,6 @@ error:
43fe83
     return -1;
43fe83
 }
43fe83
 
43fe83
-
43fe83
-static void qemuProcessHandleMonitorDestroy(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
43fe83
-                                            virDomainObjPtr vm)
43fe83
-{
43fe83
-    virObjectUnref(vm);
43fe83
-}
43fe83
-
43fe83
 static int
43fe83
 qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
43fe83
                             virDomainObjPtr vm,
43fe83
@@ -1345,7 +1338,6 @@ cleanup:
43fe83
 
43fe83
 
43fe83
 static qemuMonitorCallbacks monitorCallbacks = {
43fe83
-    .destroy = qemuProcessHandleMonitorDestroy,
43fe83
     .eofNotify = qemuProcessHandleMonitorEOF,
43fe83
     .errorNotify = qemuProcessHandleMonitorError,
43fe83
     .diskSecretLookup = qemuProcessFindVolumeQcowPassphrase,
43fe83
@@ -1382,7 +1374,7 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int logfd)
43fe83
     }
43fe83
 
43fe83
     /* Hold an extra reference because we can't allow 'vm' to be
43fe83
-     * deleted while the monitor is active */
43fe83
+     * deleted unitl the monitor gets its own reference. */
43fe83
     virObjectRef(vm);
43fe83
 
43fe83
     ignore_value(virTimeMillisNow(&priv->monStart));
43fe83
@@ -1397,11 +1389,10 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int logfd)
43fe83
         ignore_value(qemuMonitorSetDomainLog(mon, logfd));
43fe83
 
43fe83
     virObjectLock(vm);
43fe83
+    virObjectUnref(vm);
43fe83
     priv->monStart = 0;
43fe83
 
43fe83
-    if (mon == NULL) {
43fe83
-        virObjectUnref(vm);
43fe83
-    } else if (!virDomainObjIsActive(vm)) {
43fe83
+    if (!virDomainObjIsActive(vm)) {
43fe83
         qemuMonitorClose(mon);
43fe83
         mon = NULL;
43fe83
     }
43fe83
-- 
43fe83
1.8.4.2
43fe83