[libvirt] [PATCH v2 4/5] Support for multiple default security drivers in QEMU config

Marcelo Cerri mhcerri at linux.vnet.ibm.com
Wed Jul 18 01:28:37 UTC 2012


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




More information about the libvir-list mailing list