This patch replaces the key "security_driver" in QEMU config by
"security_drivers", which accepts a list of default drivers. If
"security_drivers" can't be found, libvirt will use
"security_driver" to
ensure that it will remain compatible with older version of the config
file.
---
src/qemu/libvirtd_qemu.aug | 2 +-
src/qemu/qemu.conf | 2 +-
src/qemu/qemu_conf.c | 42 ++++++++++++++-
src/qemu/qemu_conf.h | 2 +-
src/qemu/qemu_driver.c | 97 ++++++++++++++++++++++++++++--------
src/qemu/test_libvirtd_qemu.aug.in | 2 +-
6 files changed, 119 insertions(+), 28 deletions(-)
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
index 683aadb..fab97d7 100644
--- a/src/qemu/libvirtd_qemu.aug
+++ b/src/qemu/libvirtd_qemu.aug
@@ -39,7 +39,7 @@ module Libvirtd_qemu =
| str_entry "spice_tls_x509_cert_dir"
| str_entry "spice_password"
- let security_entry = str_entry "security_driver"
+ let security_entry = str_entry "security_drivers"
| bool_entry "security_default_confined"
| bool_entry "security_require_confined"
| str_entry "user"
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index ed4683c..ffb03f8 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -146,7 +146,7 @@
# leaving SELinux enabled for the host in general, then set this
# to 'none' instead.
#
-#security_driver = "selinux"
+#security_drivers = "selinux"
# If set to non-zero, then the default security labeling
# will make guests confined. If set to zero, then guests
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 88a04bc..6e1c608 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -192,14 +192,50 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
}
}
- p = virConfGetValue (conf, "security_driver");
- CHECK_TYPE ("security_driver", VIR_CONF_STRING);
+ p = virConfGetValue (conf, "security_drivers");
+ CHECK_TYPE ("security_drivers", VIR_CONF_STRING);
if (p && p->str) {
- if (!(driver->securityDriverName = strdup(p->str))) {
+ char *it, *tok;
+ size_t len;
+
+ for (len = 1, it = p->str; *it; it++)
+ len++;
+ if (VIR_ALLOC_N(driver->securityDriverNames, len + 1) < 0) {
virReportOOMError();
virConfFree(conf);
return -1;
}
+
+ i = 0;
+ tok = it = p->str;
+ while (1) {
+ if (*it == ',' || *it == '\0') {
+ driver->securityDriverNames[i] = strndup(tok, it - tok);
+ if (driver->securityDriverNames == NULL) {
+ virReportOOMError();
+ virConfFree(conf);
+ return -1;
+ }
+ tok = it + 1;
+ i++;
+ }
+ if (*it == '\0')
+ break;
+ it++;
+ }
+ } else {
+ VIR_WARN("'security_drivers' config not found. Trying
'security_driver'");
+ p = virConfGetValue (conf, "security_driver");
+ CHECK_TYPE ("security_driver", VIR_CONF_STRING);
+ if (p && p->str) {
+ if (VIR_ALLOC_N(driver->securityDriverNames, 2) < 0 ||
+ !(driver->securityDriverNames[0] = strdup(p->str))) {
+ virReportOOMError();
+ virConfFree(conf);
+ return -1;
+ }
+ driver->securityDriverNames[1] = NULL;
+ }
}
p = virConfGetValue (conf, "security_default_confined");
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 482e6d3..e808f4f 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -116,7 +116,7 @@ struct qemud_driver {
virDomainEventStatePtr domainEventState;
- char *securityDriverName;
+ char **securityDriverNames;
bool securityDefaultConfined;
bool securityRequireConfined;
virSecurityManagerPtr securityManager;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1b02f28..f01566b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -220,36 +220,91 @@ qemuAutostartDomains(struct qemud_driver *driver)
static int
qemuSecurityInit(struct qemud_driver *driver)
{
- virSecurityManagerPtr mgr = virSecurityManagerNew(driver->securityDriverName,
- QEMU_DRIVER_NAME,
- driver->allowDiskFormatProbing,
-
driver->securityDefaultConfined,
-
driver->securityRequireConfined);
+ char **names;
+ char *primary;
+ virSecurityManagerPtr mgr, nested, stack;
+ if (driver->securityDriverNames == NULL)
+ primary = NULL;
+ else
+ primary = driver->securityDriverNames[0];
+
+ /* Create primary driver */
+ mgr = virSecurityManagerNew(primary,
+ QEMU_DRIVER_NAME,
+ driver->allowDiskFormatProbing,
+ driver->securityDefaultConfined,
+ driver->securityRequireConfined);
if (!mgr)
goto error;
- if (driver->privileged) {
- virSecurityManagerPtr dac = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
- driver->user,
- driver->group,
-
driver->allowDiskFormatProbing,
-
driver->securityDefaultConfined,
-
driver->securityRequireConfined,
-
driver->dynamicOwnership);
- if (!dac)
+ /* If a DAC driver is required or additional drivers are provived, a stack
+ * driver should be create to group them all */
+ if (driver->privileged ||
+ (driver->securityDriverNames && driver->securityDriverNames[1])) {
+ stack = virSecurityManagerNewStack(mgr);
+ if (!stack)
goto error;
+ mgr = stack;
+ }
+
+ /* Loop through additional driver names and add a secudary driver to each
+ * one */
+ if (driver->securityDriverNames) {
+ names = driver->securityDriverNames + 1;
+ while (names && *names) {
+ if (STREQ("dac", *names)) {
+ /* A DAC driver has specific parameters */
+ nested = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
+ driver->user,
+ driver->group,
+ driver->allowDiskFormatProbing,
+ driver->securityDefaultConfined,
+ driver->securityRequireConfined,
+ driver->dynamicOwnership);
+ } else {
+ nested = virSecurityManagerNew(*names,
+ QEMU_DRIVER_NAME,
+ driver->allowDiskFormatProbing,
+ driver->securityDefaultConfined,
+ driver->securityRequireConfined);
+ }
+ if (nested == NULL)
+ goto error;
+ if (virSecurityManagerStackAddNested(stack, nested))
+ goto error;
+ names++;
+ }
+ }
- if (!(driver->securityManager = virSecurityManagerNewStack(mgr)) ||
- !(virSecurityManagerStackAddNested(mgr, dac))) {
-
- virSecurityManagerFree(dac);
- goto error;
+ if (driver->privileged) {
+ /* When a DAC driver is required, check if there is already one in the
+ * additional drivers */
+ names = driver->securityDriverNames;
+ while (names && *names) {
+ if (STREQ("dac", *names)) {
+ break;
+ }
+ names++;
+ }
+ /* If there is no DAC driver, create a new one and add it to the stack
+ * manager */
+ if (names == NULL || *names == NULL) {
+ nested = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
+ driver->user,
+ driver->group,
+ driver->allowDiskFormatProbing,
+ driver->securityDefaultConfined,
+ driver->securityRequireConfined,
+ driver->dynamicOwnership);
+ if (nested == NULL)
+ goto error;
+ if (virSecurityManagerStackAddNested(stack, nested))
+ goto error;
}
- } else {
- driver->securityManager = mgr;
}
+ driver->securityManager = mgr;
return 0;
error:
diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in
index 959f250..ff24a38 100644
--- a/src/qemu/test_libvirtd_qemu.aug.in
+++ b/src/qemu/test_libvirtd_qemu.aug.in
@@ -15,7 +15,7 @@ module Test_libvirtd_qemu =
{ "spice_tls" = "1" }
{ "spice_tls_x509_cert_dir" = "/etc/pki/libvirt-spice" }
{ "spice_password" = "XYZ12345" }
-{ "security_driver" = "selinux" }
+{ "security_drivers" = "selinux" }
{ "security_default_confined" = "1" }
{ "security_require_confined" = "1" }
{ "user" = "root" }
--
1.7.1