This allows us to explicitly handle the 'default' seclabel case, as
well as provide easier model validation.

Signed-off-by: Cole Robinson <crobi...@redhat.com>
---
 src/conf/domain_conf.c           |   38 ++++++++++++++++++++++++++++++--------
 src/conf/domain_conf.h           |   14 ++++++++++++--
 src/security/security_apparmor.c |    9 +++------
 src/security/security_driver.c   |   15 ++++++++++-----
 src/security/security_selinux.c  |    8 ++------
 5 files changed, 57 insertions(+), 27 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8f6ef55..077a396 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -313,6 +313,12 @@ VIR_ENUM_IMPL(virDomainSeclabel, VIR_DOMAIN_SECLABEL_LAST,
               "dynamic",
               "static")
 
+VIR_ENUM_IMPL(virDomainSeclabelModel, VIR_DOMAIN_SECLABEL_MODEL_LAST,
+              "default",
+              "selinux",
+              "apparmor",
+              "none")
+
 VIR_ENUM_IMPL(virDomainNetdevMacvtap, VIR_DOMAIN_NETDEV_MACVTAP_MODE_LAST,
               "vepa",
               "private",
@@ -759,7 +765,7 @@ void virDomainSeclabelDefClear(virSecurityLabelDefPtr 
seclabel)
     if (!seclabel)
         return;
 
-    VIR_FREE(seclabel->model);
+    seclabel->model = VIR_DOMAIN_SECLABEL_MODEL_DEFAULT;
     VIR_FREE(seclabel->label);
     VIR_FREE(seclabel->imagelabel);
 }
@@ -4244,7 +4250,15 @@ virSecurityLabelDefParseXML(const virDomainDefPtr def,
                                  "%s", _("missing security model"));
             goto error;
         }
-        def->seclabel.model = p;
+
+        def->seclabel.model = virDomainSeclabelModelTypeFromString(p);
+        if (def->seclabel.model < 0) {
+            virDomainReportError(VIR_ERR_XML_ERROR,
+                                 _("unknown security model '%s'"), p);
+            VIR_FREE(p);
+            goto error;
+        }
+        VIR_FREE(p);
 
         p = virXPathStringLimit("string(./seclabel/label[1])",
                                 VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
@@ -7336,18 +7350,26 @@ char *virDomainDefFormat(virDomainDefPtr def,
 
     virBufferAddLit(&buf, "  </devices>\n");
 
-    if (def->seclabel.model) {
-        const char *sectype = 
virDomainSeclabelTypeToString(def->seclabel.type);
+    if (def->seclabel.model != VIR_DOMAIN_SECLABEL_MODEL_DEFAULT) {
+        const char *sectype, *secmodel;
+
+        sectype = virDomainSeclabelTypeToString(def->seclabel.type);
         if (!sectype)
             goto cleanup;
+
+        secmodel = virDomainSeclabelModelTypeToString(def->seclabel.model);
+        if (!secmodel)
+            goto cleanup;
+
+        virBufferVSprintf(&buf, "  <seclabel type='%s' model='%s'",
+                          sectype, secmodel);
+
         if (!def->seclabel.label ||
             (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
              (flags & VIR_DOMAIN_XML_INACTIVE))) {
-            virBufferVSprintf(&buf, "  <seclabel type='%s' model='%s'/>\n",
-                              sectype, def->seclabel.model);
+            virBufferAddLit(&buf, "/>\n");
         } else {
-            virBufferVSprintf(&buf, "  <seclabel type='%s' model='%s'>\n",
-                                  sectype, def->seclabel.model);
+            virBufferAddLit(&buf, ">\n");
             virBufferEscapeString(&buf, "    <label>%s</label>\n",
                                   def->seclabel.label);
             if (def->seclabel.imagelabel &&
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index b5cf433..81409f8 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -782,14 +782,23 @@ enum virDomainSeclabelType {
     VIR_DOMAIN_SECLABEL_LAST,
 };
 
+enum virDomainSeclabelModel {
+    VIR_DOMAIN_SECLABEL_MODEL_DEFAULT,
+    VIR_DOMAIN_SECLABEL_MODEL_SELINUX,
+    VIR_DOMAIN_SECLABEL_MODEL_APPARMOR,
+    VIR_DOMAIN_SECLABEL_MODEL_NONE,
+
+    VIR_DOMAIN_SECLABEL_MODEL_LAST,
+};
+
 /* Security configuration for domain */
 typedef struct _virSecurityLabelDef virSecurityLabelDef;
 typedef virSecurityLabelDef *virSecurityLabelDefPtr;
 struct _virSecurityLabelDef {
-    char *model;        /* name of security model */
     char *label;        /* security label string */
     char *imagelabel;   /* security image label string */
-    int type;
+    int type;           /* dynamic vs. static */
+    int model;          /* name of security model */
 };
 
 enum virDomainTimerNameType {
@@ -1287,6 +1296,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceChannelMode)
 /* from libvirt.h */
 VIR_ENUM_DECL(virDomainState)
 VIR_ENUM_DECL(virDomainSeclabel)
+VIR_ENUM_DECL(virDomainSeclabelModel)
 VIR_ENUM_DECL(virDomainClockOffset)
 
 VIR_ENUM_DECL(virDomainNetdevMacvtap)
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 00e5a01..7a6fe5c 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -441,7 +441,8 @@ AppArmorGenSecurityLabel(virSecurityManagerPtr mgr 
ATTRIBUTE_UNUSED,
         return 0;
 
     if ((vm->def->seclabel.label) ||
-        (vm->def->seclabel.model) || (vm->def->seclabel.imagelabel)) {
+        (vm->def->seclabel.model != VIR_DOMAIN_SECLABEL_MODEL_DEFAULT) ||
+        (vm->def->seclabel.imagelabel)) {
         virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
                                "%s",
                                _("security label already defined for VM"));
@@ -465,11 +466,7 @@ AppArmorGenSecurityLabel(virSecurityManagerPtr mgr 
ATTRIBUTE_UNUSED,
         goto err;
     }
 
-    vm->def->seclabel.model = strdup(SECURITY_APPARMOR_NAME);
-    if (!vm->def->seclabel.model) {
-        virReportOOMError();
-        goto err;
-    }
+    vm->def->seclabel.model = VIR_DOMAIN_SECLABEL_MODEL_APPARMOR;
 
     rc = 0;
     goto clean;
diff --git a/src/security/security_driver.c b/src/security/security_driver.c
index 7d2e0de..2cd4c0e 100644
--- a/src/security/security_driver.c
+++ b/src/security/security_driver.c
@@ -80,18 +80,23 @@ bool
 virSecurityIsSpecifiedDriver(virSecurityManagerPtr mgr,
                              virDomainDefPtr def)
 {
-    bool ret = true;
+    bool ret = false;
+    const char *model = 
virDomainSeclabelModelTypeToString(def->seclabel.model);
+    if (!model)
+        goto err;
 
-    if (def->seclabel.model &&
-        !STREQ(virSecurityManagerGetModel(mgr), def->seclabel.model)) {
+    if (def->seclabel.model != VIR_DOMAIN_SECLABEL_MODEL_DEFAULT &&
+        !STREQ(virSecurityManagerGetModel(mgr), model)) {
         virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
                                _("security label driver mismatch: "
                                  "'%s' model configured for domain, but "
                                  "hypervisor driver is '%s'."),
-                               def->seclabel.model,
+                               model,
                                virSecurityManagerGetModel(mgr));
-        ret = false;
+        goto err;
     }
 
+    ret = true;
+err:
     return ret;
 }
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index f3b76f9..2266c21 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -173,7 +173,7 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr 
ATTRIBUTE_UNUSED,
         return 0;
 
     if (vm->def->seclabel.label ||
-        vm->def->seclabel.model ||
+        vm->def->seclabel.model != VIR_DOMAIN_SECLABEL_MODEL_DEFAULT ||
         vm->def->seclabel.imagelabel) {
         virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
                                "%s", _("security label already defined for 
VM"));
@@ -206,12 +206,8 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr 
ATTRIBUTE_UNUSED,
                                _("cannot generate selinux context for %s"), 
mcs);
         goto err;
     }
-    vm->def->seclabel.model = strdup(SECURITY_SELINUX_NAME);
-    if (!vm->def->seclabel.model) {
-        virReportOOMError();
-        goto err;
-    }
 
+    vm->def->seclabel.model = VIR_DOMAIN_SECLABEL_MODEL_SELINUX;
 
     rc = 0;
     goto done;
-- 
1.7.3.2

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to