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. Signed-off-by: Daniel P. Berrangé <berrange@xxxxxxxxxx> --- src/util/virtpm.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/util/virtpm.c b/src/util/virtpm.c index 3ea3b668e2..7e75c74d67 100644 --- a/src/util/virtpm.c +++ b/src/util/virtpm.c @@ -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 -- 2.33.1