This allows us to explicitly handle the 'default' seclabel case, as well as provide easier model validation. Signed-off-by: Cole Robinson <crobinso@xxxxxxxxxx> --- 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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list