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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list