[PATCH 2/3] qemu: get the stackManager lock before getting nested lock

Jiang Jiacheng jiangjiacheng at huawei.com
Wed Sep 28 13:53:29 UTC 2022


When creating a VM by forking, there is a logic that get the lock of
StacksecurityManager before get other nested lock to avoid deadlock
between child process and thread of the parent. While in
`virQEMUDriverCreateCapabilities` and `qemuDomainGetSecurityLabelList`,
we get nested lock without getting the StacksecurityManager lock, which
will result in deadlock in some concurrent scenarios. It is better to keep
the logical in these funcitons same as others.

Signed-off-by: Jiang Jiacheng <jiangjiacheng at huawei.com>
---
 src/qemu/qemu_conf.c   | 6 +++++-
 src/qemu/qemu_driver.c | 3 +++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 3b75cdeb95..745d3e6a5e 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1331,6 +1331,7 @@ virCaps *virQEMUDriverCreateCapabilities(virQEMUDriver *driver)
 
     caps->host.secModels = g_new0(virCapsHostSecModel, caps->host.nsecModels);
 
+    virObjectLock(driver->securityManager);
     for (i = 0; sec_managers[i]; i++) {
         virCapsHostSecModel *sm = &caps->host.secModels[i];
         doi = qemuSecurityGetDOI(sec_managers[i]);
@@ -1342,14 +1343,17 @@ virCaps *virQEMUDriverCreateCapabilities(virQEMUDriver *driver)
             lbl = qemuSecurityGetBaseLabel(sec_managers[i], virtTypes[j]);
             type = virDomainVirtTypeToString(virtTypes[j]);
             if (lbl &&
-                virCapabilitiesHostSecModelAddBaseLabel(sm, type, lbl) < 0)
+                virCapabilitiesHostSecModelAddBaseLabel(sm, type, lbl) < 0) {
+                virObjectUnlock(driver->securityManager);
                 return NULL;
+            }
         }
 
         VIR_DEBUG("Initialized caps for security driver \"%s\" with "
                   "DOI \"%s\"", model, doi);
     }
 
+    virObjectUnlock(driver->securityManager);
     caps->host.numa = virCapabilitiesHostNUMANewHost();
     caps->host.cpu = virQEMUDriverGetHostCPU(driver);
     return g_steal_pointer(&caps);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 707f4cc1bb..9fb5f1d653 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5848,15 +5848,18 @@ static int qemuDomainGetSecurityLabelList(virDomainPtr dom,
         (*seclabels) = g_new0(virSecurityLabel, len);
         memset(*seclabels, 0, sizeof(**seclabels) * len);
 
+        virObjectLock(driver->securityManager);
         /* Fill the array */
         for (i = 0; i < len; i++) {
             if (qemuSecurityGetProcessLabel(mgrs[i], vm->def, vm->pid,
                                             &(*seclabels)[i]) < 0) {
                 VIR_FREE(mgrs);
                 VIR_FREE(*seclabels);
+                virObjectUnlock(driver->securityManager);
                 goto cleanup;
             }
         }
+        virObjectUnlock(driver->securityManager);
         ret = len;
         VIR_FREE(mgrs);
     }
-- 
2.33.0



More information about the libvir-list mailing list