diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng index 65c7c72edd87731d6324c310b0e37039eb9f3bf5..aee03d7fcd5870d24fcfdbfb0a7d0bcdbcc24ca9 100644 --- a/docs/schemas/capability.rng +++ b/docs/schemas/capability.rng @@ -60,6 +60,14 @@ + + + + + + + + diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c index 1acc9366f7b604f84e4caacc5144842e04956129..1eb5e3aa0b8b16a38c94b029b108eda82fb0d607 100644 --- a/src/conf/capabilities.c +++ b/src/conf/capabilities.c @@ -183,6 +183,20 @@ virCapabilitiesFreeNUMAInfo(virCapsPtr caps) caps->host.nnumaCell = 0; } +static void +virCapabilitiesClearSecModel(virCapsHostSecModelPtr secmodel) +{ + size_t i; + for (i = 0; i < secmodel->nlabels; i++) { + VIR_FREE(secmodel->labels[i].type); + VIR_FREE(secmodel->labels[i].label); + } + + VIR_FREE(secmodel->labels); + VIR_FREE(secmodel->model); + VIR_FREE(secmodel->doi); +} + static void virCapabilitiesDispose(void *object) { @@ -204,8 +218,7 @@ virCapabilitiesDispose(void *object) VIR_FREE(caps->host.migrateTrans); for (i = 0; i < caps->host.nsecModels; i++) { - VIR_FREE(caps->host.secModels[i].model); - VIR_FREE(caps->host.secModels[i].doi); + virCapabilitiesClearSecModel(&caps->host.secModels[i]); } VIR_FREE(caps->host.secModels); @@ -506,6 +519,44 @@ virCapabilitiesAddGuestFeature(virCapsGuestPtr guest, return NULL; } +/** + * virCapabilitiesHostSecModelAddBaseLabel + * @secmodel: Security model to add a base label for + * @type: virtualization type + * @label: base label + * + * Returns non-zero on error. + */ +extern int +virCapabilitiesHostSecModelAddBaseLabel(virCapsHostSecModelPtr secmodel, + const char *type, + const char *label) +{ + char *t = NULL, *l = NULL; + + if (type == NULL || label == NULL) + return -1; + + if (VIR_STRDUP(t, type) < 0) + goto no_memory; + + if (VIR_STRDUP(l, label) < 0) + goto no_memory; + + if (VIR_EXPAND_N(secmodel->labels, secmodel->nlabels, 1) < 0) + goto no_memory; + + secmodel->labels[secmodel->nlabels - 1].type = t; + secmodel->labels[secmodel->nlabels - 1].label = l; + + return 0; + +no_memory: + VIR_FREE(l); + VIR_FREE(t); + return -1; +} + /** * virCapabilitiesSupportsGuestArch: * @caps: capabilities to query @@ -826,6 +877,11 @@ virCapabilitiesFormatXML(virCapsPtr caps) caps->host.secModels[i].model); virBufferAsprintf(&xml, " %s\n", caps->host.secModels[i].doi); + for (j = 0; j < caps->host.secModels[i].nlabels; j++) { + virBufferAsprintf(&xml, " %s\n", + caps->host.secModels[i].labels[j].type, + caps->host.secModels[i].labels[j].label); + } virBufferAddLit(&xml, " \n"); } diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index 88ec4547f7ff9ebbf2c369cd49d3c79f47ef6e11..5bc7bb502343a973eb2fe42a4a4edfa600059973 100644 --- a/src/conf/capabilities.h +++ b/src/conf/capabilities.h @@ -104,11 +104,20 @@ struct _virCapsHostNUMACell { virCapsHostNUMACellCPUPtr cpus; }; +typedef struct _virCapsHostSecModelLabel virCapsHostSecModelLabel; +typedef virCapsHostSecModelLabel *virCapsHostSecModelLabelPtr; +struct _virCapsHostSecModelLabel { + char *type; + char *label; +}; + typedef struct _virCapsHostSecModel virCapsHostSecModel; typedef virCapsHostSecModel *virCapsHostSecModelPtr; struct _virCapsHostSecModel { char *model; char *doi; + size_t nlabels; + virCapsHostSecModelLabelPtr labels; }; typedef struct _virCapsHost virCapsHost; @@ -224,6 +233,11 @@ virCapabilitiesAddGuestFeature(virCapsGuestPtr guest, int defaultOn, int toggle); +extern int +virCapabilitiesHostSecModelAddBaseLabel(virCapsHostSecModelPtr secmodel, + const char *type, + const char *label); + extern int virCapabilitiesSupportsGuestArch(virCapsPtr caps, virArch arch); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 092f79749c468028a39a0e1c5437ad834c5298df..675835f040a5ac72b100e4f52cb3148d236680fb 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -58,6 +58,7 @@ virCapabilitiesFormatXML; virCapabilitiesFreeMachines; virCapabilitiesFreeNUMAInfo; virCapabilitiesGetCpusForNodemask; +virCapabilitiesHostSecModelAddBaseLabel; virCapabilitiesNew; virCapabilitiesSetHostCPU; diff --git a/src/lxc/lxc_conf.c b/src/lxc/lxc_conf.c index c1cee3f841810e245515635933290cddcdbea651..557191aec0cbe4f0cd438176d44207d1c36ec858 100644 --- a/src/lxc/lxc_conf.c +++ b/src/lxc/lxc_conf.c @@ -126,10 +126,13 @@ virCapsPtr virLXCDriverCapsInit(virLXCDriverPtr driver) if (driver) { /* Security driver data */ - const char *doi, *model; + const char *doi, *model, *label, *type; doi = virSecurityManagerGetDOI(driver->securityManager); model = virSecurityManagerGetModel(driver->securityManager); + label = virSecurityManagerGetBaseLabel(driver->securityManager, + VIR_DOMAIN_VIRT_LXC); + type = virDomainVirtTypeToString(VIR_DOMAIN_VIRT_LXC); /* Allocate the primary security driver for LXC. */ if (VIR_ALLOC(caps->host.secModels) < 0) goto error; @@ -138,6 +141,11 @@ virCapsPtr virLXCDriverCapsInit(virLXCDriverPtr driver) goto error; if (VIR_STRDUP(caps->host.secModels[0].doi, doi) < 0) goto error; + if (label && + virCapabilitiesHostSecModelAddBaseLabel(&caps->host.secModels[0], + type, + label) < 0) + goto error; VIR_DEBUG("Initialized caps for security driver \"%s\" with " "DOI \"%s\"", model, doi); diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 4ef9c758884519a5cc7ea16dcf8809a5015f4f47..03c9c7d486d27c0ad0614d683b67ad66a468d2d0 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -605,12 +605,14 @@ virQEMUDriverCreateXMLConf(virQEMUDriverPtr driver) virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver) { - size_t i; + size_t i, j; virCapsPtr caps; virSecurityManagerPtr *sec_managers = NULL; /* Security driver data */ - const char *doi, *model; + const char *doi, *model, *lbl, *type; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + const int virtTypes[] = {VIR_DOMAIN_VIRT_KVM, + VIR_DOMAIN_VIRT_QEMU,}; /* Basic host arch / guest machine capabilities */ if (!(caps = virQEMUCapsInit(driver->qemuCapsCache))) @@ -635,11 +637,21 @@ virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver) goto error; for (i = 0; sec_managers[i]; i++) { + virCapsHostSecModelPtr sm = &caps->host.secModels[i]; doi = virSecurityManagerGetDOI(sec_managers[i]); model = virSecurityManagerGetModel(sec_managers[i]); - if (VIR_STRDUP(caps->host.secModels[i].model, model) < 0 || - VIR_STRDUP(caps->host.secModels[i].doi, doi) < 0) + if (VIR_STRDUP(sm->model, model) < 0 || + VIR_STRDUP(sm->doi, doi) < 0) goto error; + + for (j = 0; j < ARRAY_CARDINALITY(virtTypes); j++) { + lbl = virSecurityManagerGetBaseLabel(sec_managers[i], virtTypes[j]); + type = virDomainVirtTypeToString(virtTypes[j]); + if (lbl && + virCapabilitiesHostSecModelAddBaseLabel(sm, type, lbl) < 0) + goto error; + } + VIR_DEBUG("Initialized caps for security driver \"%s\" with " "DOI \"%s\"", model, doi); } diff --git a/tests/capabilityschemadata/caps-qemu-kvm.xml b/tests/capabilityschemadata/caps-qemu-kvm.xml index de0c57feb408c7d6b2eb9f922d6b549fcf212647..55faa16b2d3a1efdc5ce8e9ef12c062e921501c2 100644 --- a/tests/capabilityschemadata/caps-qemu-kvm.xml +++ b/tests/capabilityschemadata/caps-qemu-kvm.xml @@ -25,6 +25,8 @@ selinux 0 + system_u:system_r:svirt_t:s0 + system_u:system_r:svirt_tcg_t:s0 diff --git a/tests/capabilityschemadata/caps-test3.xml b/tests/capabilityschemadata/caps-test3.xml index e6c56c55f98f3364e036f705a2ce9930d6347ade..7e21f850488a531a2e385a12f7532db04868cf2a 100644 --- a/tests/capabilityschemadata/caps-test3.xml +++ b/tests/capabilityschemadata/caps-test3.xml @@ -82,6 +82,8 @@ dac 0 + 107:107 + 107:107