The hash table of log file objects in libxlLogger is not protected against
concurrent access. It is possible for one thread to remove an entry while
another is updating it. Add a mutex to the libxlLogger object and lock it
when accessing the files hash table.
Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
src/libxl/libxl_logger.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/libxl/libxl_logger.c b/src/libxl/libxl_logger.c
index f7b5c8ee16..27f8f50b1c 100644
--- a/src/libxl/libxl_logger.c
+++ b/src/libxl/libxl_logger.c
@@ -28,6 +28,7 @@
#include "util/virfile.h"
#include "util/virhash.h"
#include "util/virstring.h"
+#include "util/virthread.h"
#include "util/virtime.h"
#define VIR_FROM_THIS VIR_FROM_LIBXL
@@ -43,6 +44,7 @@ struct xentoollog_logger_libvirt {
/* map storing the opened fds: "domid" -> FILE* */
GHashTable *files;
+ virMutex tableLock;
FILE *defaultLogFile;
};
@@ -85,7 +87,9 @@ libvirt_vmessage(xentoollog_logger *logger_in,
start = start + 9;
*end = '\0';
+ virMutexLock(&lg->tableLock);
domainLogFile = virHashLookup(lg->files, start);
+ virMutexUnlock(&lg->tableLock);
if (domainLogFile)
logFile = domainLogFile;
@@ -149,11 +153,14 @@ libxlLoggerNew(const char *logDir, virLogPriority minLevel)
break;
}
logger.logDir = logDir;
+ if (virMutexInit(&logger.tableLock) < 0)
+ return NULL;
logger.files = virHashNew(libxlLoggerFileFree);
path = g_strdup_printf("%s/libxl-driver.log", logDir);
if ((logger.defaultLogFile = fopen(path, "a")) == NULL) {
+ virMutexDestroy(&logger.tableLock);
virHashFree(logger.files);
return NULL;
}
@@ -168,6 +175,7 @@ libxlLoggerFree(libxlLogger *logger)
if (logger->defaultLogFile)
VIR_FORCE_FCLOSE(logger->defaultLogFile);
virHashFree(logger->files);
+ virMutexDestroy(&logger->tableLock);
xtl_logger_destroy(xtl_logger);
}
@@ -189,7 +197,9 @@ libxlLoggerOpenFile(libxlLogger *logger,
path, g_strerror(errno));
return;
}
+ virMutexLock(&logger->tableLock);
ignore_value(virHashAddEntry(logger->files, domidstr, logFile));
+ virMutexUnlock(&logger->tableLock);
/* domain_config is non NULL only when starting a new domain */
if (domain_config) {
@@ -204,5 +214,7 @@ libxlLoggerCloseFile(libxlLogger *logger, int id)
g_autofree char *domidstr = NULL;
domidstr = g_strdup_printf("%d", id);
+ virMutexLock(&logger->tableLock);
ignore_value(virHashRemoveEntry(logger->files, domidstr));
+ virMutexUnlock(&logger->tableLock);
}
--
2.33.0