qemuSecurityCommandRun() causes an explicit domain transition of the
new process, but passt ships with its own SELinux policy, with
external interfaces for libvirtd, so we simply need to transition
from virtd_t to passt_t as passt is executed. The qemu type
enforcement rules have little to do with it.
That is, if we switch to svirt_t, passt will run in the security
context that's intended for QEMU, which allows a number of
operations not needed by passt. On the other hand, with a switch
to svirt_t, passt won't be able to create its own PID file.
Usage of those new interfaces is implemented by this change in
selinux-policy:
https://github.com/fedora-selinux/selinux-policy/pull/1613
Replace qemuSecurityCommandRun() with virCommandRun(), and explicitly
set the label, preserving the correct MCS range for the given VM
instance. This is a temporary measure: eventually, we'll need a more
generic and elegant mechanism for helper binaries.
Fixes: a56f0168d576 ("qemu: hook up passt config to qemu domains")
Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com>
---
src/qemu/qemu_passt.c | 33 +++++++++++++++++++++++++++------
1 file changed, 27 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_passt.c b/src/qemu/qemu_passt.c
index 1217a6a087..81f48dd630 100644
--- a/src/qemu/qemu_passt.c
+++ b/src/qemu/qemu_passt.c
@@ -30,6 +30,11 @@
#include "virlog.h"
#include "virpidfile.h"
+#ifdef WITH_SELINUX
+# include <selinux/selinux.h>
+# include <selinux/context.h>
+#endif
+
#define VIR_FROM_THIS VIR_FROM_NONE
VIR_LOG_INIT("qemu.passt");
@@ -158,8 +163,11 @@ qemuPasstStart(virDomainObj *vm,
g_autofree char *errbuf = NULL;
char macaddr[VIR_MAC_STRING_BUFLEN];
size_t i;
- int exitstatus = 0;
- int cmdret = 0;
+#ifdef WITH_SELINUX
+ virSecurityLabelDef *seclabel;
+ context_t s;
+ const char *newLabel;
+#endif
cmd = virCommandNew(PASST);
@@ -271,18 +279,31 @@ qemuPasstStart(virDomainObj *vm,
if (qemuExtDeviceLogCommand(driver, vm, cmd, "passt") < 0)
return -1;
- if (qemuSecurityCommandRun(driver, vm, cmd, -1, -1, &exitstatus, &cmdret)
< 0)
- goto error;
+#ifdef WITH_SELINUX
+ /* TODO: Implement a new security manager function for helper binaries,
+ * possibly deriving domain names from security attributes of the helper
+ * binary itself.
+ */
+ seclabel = virDomainDefGetSecurityLabelDef(vm->def, "selinux");
+ s = context_new(seclabel->label);
+ context_type_set(s, "passt_t");
+ newLabel = context_str(s);
+
+ virCommandSetSELinuxLabel(cmd, newLabel);
+#endif
- if (cmdret < 0 || exitstatus != 0) {
+ if (virCommandRun(cmd, NULL)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Could not start 'passt': %s"),
NULLSTR(errbuf));
goto error;
}
+ context_free(s);
+
return 0;
error:
- qemuPasstKill(pidfile);
+ context_free(s);
+ qemuPasstKill(pidfile, passtSocketName);
return -1;
}
--
2.39.1