]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
util: ensure all TPM global vars access is protected by lock
authorDaniel P. Berrangé <berrange@redhat.com>
Wed, 24 Nov 2021 10:30:25 +0000 (10:30 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Wed, 1 Dec 2021 12:14:03 +0000 (12:14 +0000)
The virTPMEmulatorInit method updates various global variables
and holds a lock while doing so. Other methods which access
these variables, however, don't reliably hold locks over all
of their accesses.

Since virTPMEmulatorInit is no longer exported, we can push
the locking up into all the callers and achieve proper safety
for concurrent usage.

Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/util/virtpm.c

index 3ea3b668e2eccf472a01a9208f183ab61845dc83..7e75c74d67811a21d473550ff3e36ac2f9434e20 100644 (file)
@@ -137,15 +137,17 @@ static int virTPMEmulatorInit(void);
 static char *
 virTPMBinaryGetPath(virTPMBinary binary)
 {
-    char *s;
-
-    if (!swtpmBinaries[binary].path && virTPMEmulatorInit() < 0)
-        return NULL;
+    char *s = NULL;
 
     virMutexLock(&swtpm_tools_lock);
+
+    if (virTPMEmulatorInit() < 0)
+        goto cleanup;
+
     s = g_strdup(swtpmBinaries[binary].path);
-    virMutexUnlock(&swtpm_tools_lock);
 
+ cleanup:
+    virMutexUnlock(&swtpm_tools_lock);
     return s;
 }
 
@@ -269,11 +271,8 @@ virTPMGetCaps(virTPMBinaryCapsParse capsParse,
 static int
 virTPMEmulatorInit(void)
 {
-    int ret = -1;
     size_t i;
 
-    virMutexLock(&swtpm_tools_lock);
-
     for (i = 0; i < VIR_TPM_BINARY_LAST; i++) {
         g_autofree char *path = NULL;
         bool findit = swtpmBinaries[i].path == NULL;
@@ -297,18 +296,18 @@ virTPMEmulatorInit(void)
                 virReportSystemError(ENOENT,
                                      _("Unable to find '%s' binary in $PATH"),
                                      virTPMBinaryTypeToString(i));
-                goto cleanup;
+                return -1;
             }
             if (!virFileIsExecutable(path)) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("%s is not an executable"),
                                path);
-                goto cleanup;
+                return -1;
             }
             if (stat(path, &swtpmBinaries[i].stat) < 0) {
                 virReportSystemError(errno,
                                      _("Could not stat %s"), path);
-                goto cleanup;
+                return -1;
             }
             swtpmBinaries[i].path = g_steal_pointer(&path);
 
@@ -317,26 +316,29 @@ virTPMEmulatorInit(void)
                                                       swtpmBinaries[i].path,
                                                       swtpmBinaries[i].parm);
                 if (!swtpmBinaries[i].caps)
-                    goto cleanup;
+                    return -1;
             }
         }
     }
 
-    ret = 0;
-
- cleanup:
-    virMutexUnlock(&swtpm_tools_lock);
-
-    return ret;
+    return 0;
 }
 
 static bool
 virTPMBinaryGetCaps(virTPMBinary binary,
                     unsigned int cap)
 {
+    bool ret = false;
+
+    virMutexLock(&swtpm_tools_lock);
+
     if (virTPMEmulatorInit() < 0)
-        return false;
-    return virBitmapIsBitSet(swtpmBinaries[binary].caps, cap);
+        goto cleanup;
+    ret = virBitmapIsBitSet(swtpmBinaries[binary].caps, cap);
+
+ cleanup:
+    virMutexUnlock(&swtpm_tools_lock);
+    return ret;
 }
 
 bool