[PATCH] qemuProcessReconnect: fix possible use after free for xmlopt

Chuan Zheng posted 1 patch 3 years, 8 months ago
Test syntax-check failed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/1595926286-63323-1-git-send-email-zhengchuan@huawei.com
src/qemu/qemu_process.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
[PATCH] qemuProcessReconnect: fix possible use after free for xmlopt
Posted by Chuan Zheng 3 years, 8 months ago
From: Zheng Chuan <zhengchuan@huawei.com>

In a case that libvirtd is killed when it has just started,
the qemu_driver->xmlopt is freed in the main thread while qemuProcessReconnect
still visits it, which resulting in null pointer accesses.
Fix that by adding refcount of qemu_driver->xmlopt at the begining of
qemuProcessReconnect.

Signed-off-by: Zheng Chuan <zhengchuan@huawei.com>
---
 src/qemu/qemu_process.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index ec6ca14..ef3fe12 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8009,6 +8009,7 @@ qemuProcessReconnect(void *opaque)
     virQEMUDriverPtr driver = data->driver;
     virDomainObjPtr obj = data->obj;
     qemuDomainObjPrivatePtr priv;
+    virDomainXMLOptionPtr xmlopt;
     qemuDomainJobObj oldjob;
     int state;
     int reason;
@@ -8030,6 +8031,9 @@ qemuProcessReconnect(void *opaque)
     cfg = virQEMUDriverGetConfig(driver);
     priv = obj->privateData;
 
+    /* need xmlopt later to save status, do not free */
+    xmlopt = virObjectRef(driver->xmlopt);
+
     if (qemuDomainObjBeginJob(driver, obj, QEMU_JOB_MODIFY) < 0)
         goto error;
     jobStarted = true;
@@ -8229,7 +8233,7 @@ qemuProcessReconnect(void *opaque)
     }
 
     /* update domain state XML with possibly updated state in virDomainObj */
-    if (virDomainObjSave(obj, driver->xmlopt, cfg->stateDir) < 0)
+    if (virDomainObjSave(obj, xmlopt, cfg->stateDir) < 0)
         goto error;
 
     /* Run an hook to allow admins to do some magic */
@@ -8262,6 +8266,7 @@ qemuProcessReconnect(void *opaque)
         if (!virDomainObjIsActive(obj))
             qemuDomainRemoveInactiveJob(driver, obj);
     }
+    virObjectUnref(xmlopt);
     virDomainObjEndAPI(&obj);
     virNWFilterUnlockFilterUpdates();
     virIdentitySetCurrent(NULL);
-- 
1.8.3.1