mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
Allow a base label to be specified in dynamic labelling mode
Normally the dynamic labelling mode will always use a base label of 'svirt_t' for VMs. Introduce a <baselabel> field in the <seclabel> XML to allow this base label to be changed eg <seclabel type='dynamic' model='selinux'> <baselabel>system_u:object_r:virt_t:s0</baselabel> </seclabel> * docs/schemas/domain.rng: Add <baselabel> * src/conf/domain_conf.c, src/conf/domain_conf.h: Parsing of base label * src/qemu/qemu_process.c: Don't reset 'model' attribute if a base label is specified * src/security/security_apparmor.c: Refuse to support base label * src/security/security_selinux.c: Use 'baselabel' when generating label, if available
This commit is contained in:
parent
49826eda7a
commit
4ebfc42716
@ -67,6 +67,9 @@
|
||||
<element name="imagelabel">
|
||||
<text/>
|
||||
</element>
|
||||
<element name="baselabel">
|
||||
<text/>
|
||||
</element>
|
||||
</element>
|
||||
</define>
|
||||
<define name="hvs">
|
||||
|
@ -966,6 +966,7 @@ void virSecurityLabelDefFree(virDomainDefPtr def)
|
||||
VIR_FREE(def->seclabel.model);
|
||||
VIR_FREE(def->seclabel.label);
|
||||
VIR_FREE(def->seclabel.imagelabel);
|
||||
VIR_FREE(def->seclabel.baselabel);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -5072,20 +5073,11 @@ virSecurityLabelDefParseXML(const virDomainDefPtr def,
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Only parse details, if using static labels, or
|
||||
/* Only parse label, if using static labels, or
|
||||
* if the 'live' VM XML is requested
|
||||
*/
|
||||
if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC ||
|
||||
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
|
||||
p = virXPathStringLimit("string(./seclabel/@model)",
|
||||
VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
|
||||
if (p == NULL) {
|
||||
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||
"%s", _("missing security model"));
|
||||
goto error;
|
||||
}
|
||||
def->seclabel.model = p;
|
||||
|
||||
p = virXPathStringLimit("string(./seclabel/label[1])",
|
||||
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
||||
if (p == NULL) {
|
||||
@ -5110,6 +5102,30 @@ virSecurityLabelDefParseXML(const virDomainDefPtr def,
|
||||
def->seclabel.imagelabel = p;
|
||||
}
|
||||
|
||||
/* Only parse baselabel, for dynamic label */
|
||||
if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
|
||||
p = virXPathStringLimit("string(./seclabel/baselabel[1])",
|
||||
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
|
||||
if (p != NULL)
|
||||
def->seclabel.baselabel = p;
|
||||
}
|
||||
|
||||
/* Only parse model, if static labelling, or a base
|
||||
* label is set, or doing active XML
|
||||
*/
|
||||
if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC ||
|
||||
def->seclabel.baselabel ||
|
||||
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
|
||||
p = virXPathStringLimit("string(./seclabel/@model)",
|
||||
VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
|
||||
if (p == NULL) {
|
||||
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||
"%s", _("missing security model"));
|
||||
goto error;
|
||||
}
|
||||
def->seclabel.model = p;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
@ -9844,20 +9860,26 @@ char *virDomainDefFormat(virDomainDefPtr def,
|
||||
const char *sectype = virDomainSeclabelTypeToString(def->seclabel.type);
|
||||
if (!sectype)
|
||||
goto cleanup;
|
||||
if (!def->seclabel.label ||
|
||||
(def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
|
||||
(flags & VIR_DOMAIN_XML_INACTIVE))) {
|
||||
|
||||
if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
|
||||
!def->seclabel.baselabel &&
|
||||
(flags & VIR_DOMAIN_XML_INACTIVE)) {
|
||||
virBufferAsprintf(&buf, " <seclabel type='%s' model='%s'/>\n",
|
||||
sectype, def->seclabel.model);
|
||||
} else {
|
||||
virBufferAsprintf(&buf, " <seclabel type='%s' model='%s'>\n",
|
||||
sectype, def->seclabel.model);
|
||||
virBufferEscapeString(&buf, " <label>%s</label>\n",
|
||||
def->seclabel.label);
|
||||
sectype, def->seclabel.model);
|
||||
if (def->seclabel.label)
|
||||
virBufferEscapeString(&buf, " <label>%s</label>\n",
|
||||
def->seclabel.label);
|
||||
if (def->seclabel.imagelabel &&
|
||||
def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC)
|
||||
(def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC))
|
||||
virBufferEscapeString(&buf, " <imagelabel>%s</imagelabel>\n",
|
||||
def->seclabel.imagelabel);
|
||||
if (def->seclabel.baselabel &&
|
||||
(def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC))
|
||||
virBufferEscapeString(&buf, " <baselabel>%s</baselabel>\n",
|
||||
def->seclabel.baselabel);
|
||||
virBufferAddLit(&buf, " </seclabel>\n");
|
||||
}
|
||||
}
|
||||
|
@ -958,6 +958,7 @@ struct _virSecurityLabelDef {
|
||||
char *model; /* name of security model */
|
||||
char *label; /* security label string */
|
||||
char *imagelabel; /* security image label string */
|
||||
char *baselabel; /* base name of label string */
|
||||
int type;
|
||||
};
|
||||
|
||||
|
@ -2883,7 +2883,8 @@ void qemuProcessStop(struct qemud_driver *driver,
|
||||
|
||||
/* Clear out dynamically assigned labels */
|
||||
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
|
||||
VIR_FREE(vm->def->seclabel.model);
|
||||
if (!vm->def->seclabel.baselabel)
|
||||
VIR_FREE(vm->def->seclabel.model);
|
||||
VIR_FREE(vm->def->seclabel.label);
|
||||
VIR_FREE(vm->def->seclabel.imagelabel);
|
||||
}
|
||||
|
@ -398,6 +398,12 @@ AppArmorGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
|
||||
return 0;
|
||||
|
||||
if (vm->def->seclabel.baselabel) {
|
||||
virSecurityReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
"%s", _("Cannot set a base label with AppArmour"));
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ((vm->def->seclabel.label) ||
|
||||
(vm->def->seclabel.model) || (vm->def->seclabel.imagelabel)) {
|
||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
|
@ -173,14 +173,29 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
|
||||
return 0;
|
||||
|
||||
if ((vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) &&
|
||||
!vm->def->seclabel.baselabel &&
|
||||
vm->def->seclabel.model) {
|
||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("security model already defined for VM"));
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (vm->def->seclabel.label ||
|
||||
vm->def->seclabel.model ||
|
||||
vm->def->seclabel.imagelabel) {
|
||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("security label already defined for VM"));
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (vm->def->seclabel.model &&
|
||||
STRNEQ(vm->def->seclabel.model, SECURITY_SELINUX_NAME)) {
|
||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("security label model %s is not supported with selinux"),
|
||||
vm->def->seclabel.model);
|
||||
return rc;
|
||||
}
|
||||
|
||||
do {
|
||||
c1 = virRandom(1024);
|
||||
c2 = virRandom(1024);
|
||||
@ -195,7 +210,10 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||
}
|
||||
} while(mcsAdd(mcs) == -1);
|
||||
|
||||
vm->def->seclabel.label = SELinuxGenNewContext(default_domain_context, mcs);
|
||||
vm->def->seclabel.label =
|
||||
SELinuxGenNewContext(vm->def->seclabel.baselabel ?
|
||||
vm->def->seclabel.baselabel :
|
||||
default_domain_context, mcs);
|
||||
if (! vm->def->seclabel.label) {
|
||||
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot generate selinux context for %s"), mcs);
|
||||
@ -207,8 +225,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) {
|
||||
if (!vm->def->seclabel.model &&
|
||||
!(vm->def->seclabel.model = strdup(SECURITY_SELINUX_NAME))) {
|
||||
virReportOOMError();
|
||||
goto err;
|
||||
}
|
||||
@ -219,7 +237,8 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||
err:
|
||||
VIR_FREE(vm->def->seclabel.label);
|
||||
VIR_FREE(vm->def->seclabel.imagelabel);
|
||||
VIR_FREE(vm->def->seclabel.model);
|
||||
if (!vm->def->seclabel.baselabel)
|
||||
VIR_FREE(vm->def->seclabel.model);
|
||||
done:
|
||||
VIR_FREE(scontext);
|
||||
return rc;
|
||||
|
Loading…
x
Reference in New Issue
Block a user