This allows us to explicitly handle the 'default' seclabel case, as
well as provide easier model validation.
Signed-off-by: Cole Robinson <crobinso(a)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