On Tue, Jul 9, 2019 at 9:24 PM Stefan Berger <stefanb(a)linux.vnet.ibm.com> wrote:
Move qemuTPMEmulatorInit to virTPMEmulatorInit in virtpm.c and introduce
a few functions to query the executables needed for virCommands.
Signed-off-by: Stefan Berger <stefanb(a)linux.ibm.com>
Couldn't there be a TOCTOU issue?
Anyway, for the move:
Reviewed-by: Marc-André Lureau <marcandre.lureau(a)redhat.com>
---
src/libvirt_private.syms | 4 ++
src/qemu/qemu_tpm.c | 83 ++++--------------------------------
src/tpm/virtpm.c | 91 ++++++++++++++++++++++++++++++++++++++++
src/tpm/virtpm.h | 5 +++
4 files changed, 108 insertions(+), 75 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e29007cab1..e33d7d9f14 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1447,6 +1447,10 @@ virSecurityManagerVerify;
# tpm/virtpm.h
virTPMCreateCancelPath;
+virTPMEmulatorInit;
+virTPMGetSwtpm;
+virTPMGetSwtpmIoctl;
+virTPMGetSwtpmSetup;
# util/viralloc.h
diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c
index cc8c69433b..61b4f72320 100644
--- a/src/qemu/qemu_tpm.c
+++ b/src/qemu/qemu_tpm.c
@@ -41,79 +41,12 @@
#include "configmake.h"
#include "dirname.h"
#include "qemu_tpm.h"
+#include "virtpm.h"
#define VIR_FROM_THIS VIR_FROM_NONE
VIR_LOG_INIT("qemu.tpm");
-/*
- * executables for the swtpm; to be found on the host
- */
-static char *swtpm_path;
-static char *swtpm_setup;
-static char *swtpm_ioctl;
-
-/*
- * qemuTPMEmulatorInit
- *
- * Initialize the Emulator functions by searching for necessary
- * executables that we will use to start and setup the swtpm
- */
-static int
-qemuTPMEmulatorInit(void)
-{
- if (!swtpm_path) {
- swtpm_path = virFindFileInPath("swtpm");
- if (!swtpm_path) {
- virReportSystemError(ENOENT, "%s",
- _("Unable to find 'swtpm' binary in
$PATH"));
- return -1;
- }
- if (!virFileIsExecutable(swtpm_path)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("TPM emulator %s is not an executable"),
- swtpm_path);
- VIR_FREE(swtpm_path);
- return -1;
- }
- }
-
- if (!swtpm_setup) {
- swtpm_setup = virFindFileInPath("swtpm_setup");
- if (!swtpm_setup) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Could not find 'swtpm_setup' in
PATH"));
- return -1;
- }
- if (!virFileIsExecutable(swtpm_setup)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("'%s' is not an executable"),
- swtpm_setup);
- VIR_FREE(swtpm_setup);
- return -1;
- }
- }
-
- if (!swtpm_ioctl) {
- swtpm_ioctl = virFindFileInPath("swtpm_ioctl");
- if (!swtpm_ioctl) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Could not find swtpm_ioctl in PATH"));
- return -1;
- }
- if (!virFileIsExecutable(swtpm_ioctl)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("swtpm_ioctl program %s is not an executable"),
- swtpm_ioctl);
- VIR_FREE(swtpm_ioctl);
- return -1;
- }
- }
-
- return 0;
-}
-
-
/*
* qemuTPMCreateEmulatorStoragePath
*
@@ -350,7 +283,7 @@ qemuTPMEmulatorGetPid(const char *swtpmStateDir,
if (!pidfile)
return -ENOMEM;
- ret = virPidFileReadPathIfAlive(pidfile, pid, swtpm_path);
+ ret = virPidFileReadPathIfAlive(pidfile, pid, virTPMGetSwtpm());
VIR_FREE(pidfile);
@@ -386,7 +319,7 @@ qemuTPMEmulatorPrepareHost(virDomainTPMDefPtr tpm,
{
int ret = -1;
- if (qemuTPMEmulatorInit() < 0)
+ if (virTPMEmulatorInit() < 0)
return -1;
/* create log dir ... allow 'tss' user to cd into it */
@@ -478,7 +411,7 @@ qemuTPMEmulatorRunSetup(const char *storagepath,
"this requires privileged mode for a "
"TPM 1.2\n"), 0600);
- cmd = virCommandNew(swtpm_setup);
+ cmd = virCommandNew(virTPMGetSwtpmSetup());
if (!cmd)
goto cleanup;
@@ -518,7 +451,7 @@ qemuTPMEmulatorRunSetup(const char *storagepath,
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Could not run '%s'. exitstatus: %d; "
"Check error log '%s' for details."),
- swtpm_setup, exitstatus, logfile);
+ virTPMGetSwtpmSetup(), exitstatus, logfile);
goto cleanup;
}
@@ -575,7 +508,7 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDefPtr tpm,
unlink(tpm->data.emulator.source.data.nix.path);
- cmd = virCommandNew(swtpm_path);
+ cmd = virCommandNew(virTPMGetSwtpm());
if (!cmd)
goto error;
@@ -640,7 +573,7 @@ qemuTPMEmulatorStop(const char *swtpmStateDir,
char *pathname;
char *errbuf = NULL;
- if (qemuTPMEmulatorInit() < 0)
+ if (virTPMEmulatorInit() < 0)
return;
if (!(pathname = qemuTPMCreateEmulatorSocket(swtpmStateDir, shortName)))
@@ -649,7 +582,7 @@ qemuTPMEmulatorStop(const char *swtpmStateDir,
if (!virFileExists(pathname))
goto cleanup;
- cmd = virCommandNew(swtpm_ioctl);
+ cmd = virCommandNew(virTPMGetSwtpmIoctl());
if (!cmd)
goto cleanup;
diff --git a/src/tpm/virtpm.c b/src/tpm/virtpm.c
index 583b9a64a4..4635d8add0 100644
--- a/src/tpm/virtpm.c
+++ b/src/tpm/virtpm.c
@@ -72,3 +72,94 @@ virTPMCreateCancelPath(const char *devpath)
cleanup:
return path;
}
+
+/*
+ * executables for the swtpm; to be found on the host
+ */
+static char *swtpm_path;
+static char *swtpm_setup;
+static char *swtpm_ioctl;
+
+const char *
+virTPMGetSwtpm(void)
+{
+ if (!swtpm_path)
+ virTPMEmulatorInit();
+ return swtpm_path;
+}
+
+const char *
+virTPMGetSwtpmSetup(void)
+{
+ if (!swtpm_setup)
+ virTPMEmulatorInit();
+ return swtpm_setup;
+}
+
+const char *
+virTPMGetSwtpmIoctl(void)
+{
+ if (!swtpm_ioctl)
+ virTPMEmulatorInit();
+ return swtpm_ioctl;
+}
+
+/*
+ * virTPMEmulatorInit
+ *
+ * Initialize the Emulator functions by searching for necessary
+ * executables that we will use to start and setup the swtpm
+ */
+int
+virTPMEmulatorInit(void)
+{
+ if (!swtpm_path) {
+ swtpm_path = virFindFileInPath("swtpm");
+ if (!swtpm_path) {
+ virReportSystemError(ENOENT, "%s",
+ _("Unable to find 'swtpm' binary in
$PATH"));
+ return -1;
+ }
+ if (!virFileIsExecutable(swtpm_path)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("TPM emulator %s is not an executable"),
+ swtpm_path);
+ VIR_FREE(swtpm_path);
+ return -1;
+ }
+ }
+
+ if (!swtpm_setup) {
+ swtpm_setup = virFindFileInPath("swtpm_setup");
+ if (!swtpm_setup) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not find 'swtpm_setup' in
PATH"));
+ return -1;
+ }
+ if (!virFileIsExecutable(swtpm_setup)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("'%s' is not an executable"),
+ swtpm_setup);
+ VIR_FREE(swtpm_setup);
+ return -1;
+ }
+ }
+
+ if (!swtpm_ioctl) {
+ swtpm_ioctl = virFindFileInPath("swtpm_ioctl");
+ if (!swtpm_ioctl) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not find swtpm_ioctl in PATH"));
+ return -1;
+ }
+ if (!virFileIsExecutable(swtpm_ioctl)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("swtpm_ioctl program %s is not an executable"),
+ swtpm_ioctl);
+ VIR_FREE(swtpm_ioctl);
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/tpm/virtpm.h b/src/tpm/virtpm.h
index 4408bdb217..66d55fb231 100644
--- a/src/tpm/virtpm.h
+++ b/src/tpm/virtpm.h
@@ -21,3 +21,8 @@
#pragma once
char *virTPMCreateCancelPath(const char *devpath) ATTRIBUTE_NOINLINE;
+
+const char *virTPMGetSwtpm(void);
+const char *virTPMGetSwtpmSetup(void);
+const char *virTPMGetSwtpmIoctl(void);
+int virTPMEmulatorInit(void);
--
2.20.1