This patch updates the structures that store information about each domain and each hypervisor to support multiple security labels and drivers. It also updates all the remaining code to use the new fields. --- src/conf/capabilities.c | 17 ++++-- src/conf/capabilities.h | 6 ++- src/conf/domain_audit.c | 14 +++-- src/conf/domain_conf.c | 86 +++++++++++++++++--------- src/conf/domain_conf.h | 9 ++- src/lxc/lxc_conf.c | 8 ++- src/lxc/lxc_controller.c | 8 +- src/lxc/lxc_driver.c | 35 ++++++----- src/qemu/qemu_driver.c | 15 +++-- src/qemu/qemu_process.c | 18 +++--- src/security/security_manager.c | 10 ++-- src/security/security_selinux.c | 132 +++++++++++++++++++------------------- src/test/test_driver.c | 11 ++- 13 files changed, 217 insertions(+), 152 deletions(-) diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c index cc7d018..e58e0e8 100644 --- a/src/conf/capabilities.c +++ b/src/conf/capabilities.c @@ -181,8 +181,13 @@ virCapabilitiesFree(virCapsPtr caps) { VIR_FREE(caps->host.migrateTrans); VIR_FREE(caps->host.arch); - VIR_FREE(caps->host.secModel.model); - VIR_FREE(caps->host.secModel.doi); + + for (i = 0; i < caps->host.nsecModels; i++) { + VIR_FREE(caps->host.secModels[i].model); + VIR_FREE(caps->host.secModels[i].doi); + } + VIR_FREE(caps->host.secModels); + virCPUDefFree(caps->host.cpu); VIR_FREE(caps); @@ -767,10 +772,12 @@ virCapabilitiesFormatXML(virCapsPtr caps) virBufferAddLit(&xml, " </topology>\n"); } - if (caps->host.secModel.model) { + for (i = 0; i < caps->host.nsecModels; i++) { virBufferAddLit(&xml, " <secmodel>\n"); - virBufferAsprintf(&xml, " <model>%s</model>\n", caps->host.secModel.model); - virBufferAsprintf(&xml, " <doi>%s</doi>\n", caps->host.secModel.doi); + virBufferAsprintf(&xml, " <model>%s</model>\n", + caps->host.secModels[i].model); + virBufferAsprintf(&xml, " <doi>%s</doi>\n", + caps->host.secModels[i].doi); virBufferAddLit(&xml, " </secmodel>\n"); } diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index 9568b4c..34bd8cd 100644 --- a/src/conf/capabilities.h +++ b/src/conf/capabilities.h @@ -93,6 +93,7 @@ struct _virCapsHostNUMACell { }; typedef struct _virCapsHostSecModel virCapsHostSecModel; +typedef virCapsHostSecModel *virCapsHostSecModelPtr; struct _virCapsHostSecModel { char *model; char *doi; @@ -116,7 +117,10 @@ struct _virCapsHost { size_t nnumaCell; size_t nnumaCell_max; virCapsHostNUMACellPtr *numaCell; - virCapsHostSecModel secModel; + + size_t nsecModels; + virCapsHostSecModelPtr secModels; + virCPUDefPtr cpu; unsigned char host_uuid[VIR_UUID_BUFLEN]; }; diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c index cb81fa0..d224682 100644 --- a/src/conf/domain_audit.c +++ b/src/conf/domain_audit.c @@ -618,6 +618,7 @@ virDomainAuditSecurityLabel(virDomainObjPtr vm, bool success) char uuidstr[VIR_UUID_STRING_BUFLEN]; char *vmname; const char *virt; + int i; virUUIDFormat(vm->def->uuid, uuidstr); if (!(vmname = virAuditEncode("vm", vm->def->name))) { @@ -630,11 +631,14 @@ virDomainAuditSecurityLabel(virDomainObjPtr vm, bool success) virt = "?"; } - VIR_AUDIT(VIR_AUDIT_RECORD_MACHINE_ID, success, - "virt=%s %s uuid=%s vm-ctx=%s img-ctx=%s", - virt, vmname, uuidstr, - VIR_AUDIT_STR(vm->def->seclabel.label), - VIR_AUDIT_STR(vm->def->seclabel.imagelabel)); + for (i = 0; i < vm->def->nseclabels; i++) { + VIR_AUDIT(VIR_AUDIT_RECORD_MACHINE_ID, success, + "virt=%s %s uuid=%s vm-ctx=%s img-ctx=%s model=%s", + virt, vmname, uuidstr, + VIR_AUDIT_STR(vm->def->seclabels[i]->label), + VIR_AUDIT_STR(vm->def->seclabels[i]->imagelabel), + VIR_AUDIT_STR(vm->def->seclabels[i]->model)); + } VIR_FREE(vmname); } diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 398f630..b468174 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -857,12 +857,15 @@ virDomainGraphicsListenDefClear(virDomainGraphicsListenDefPtr def) } static void -virSecurityLabelDefClear(virSecurityLabelDefPtr def) +virSecurityLabelDefFree(virSecurityLabelDefPtr def) { - VIR_FREE(def->model); - VIR_FREE(def->label); - VIR_FREE(def->imagelabel); - VIR_FREE(def->baselabel); + if (def) { + VIR_FREE(def->model); + VIR_FREE(def->label); + VIR_FREE(def->imagelabel); + VIR_FREE(def->baselabel); + VIR_FREE(def); + } } @@ -871,6 +874,7 @@ virSecurityDeviceLabelDefFree(virSecurityDeviceLabelDefPtr def) { if (!def) return; + VIR_FREE(def->model); VIR_FREE(def->label); VIR_FREE(def); } @@ -956,7 +960,11 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def) virStorageEncryptionFree(def->encryption); virDomainDeviceInfoClear(&def->info); - virSecurityDeviceLabelDefFree(def->seclabel); + if (def->seclabels) { + for (i = 0; i < def->nseclabels; i++) + virSecurityDeviceLabelDefFree(def->seclabels[i]); + VIR_FREE(def->seclabels); + } for (i = 0 ; i < def->nhosts ; i++) virDomainDiskHostDefFree(&def->hosts[i]); @@ -1622,7 +1630,9 @@ void virDomainDefFree(virDomainDefPtr def) virDomainMemballoonDefFree(def->memballoon); - virSecurityLabelDefClear(&def->seclabel); + for (i = 0; i < def->nseclabels; i++) + virSecurityLabelDefFree(def->seclabels[i]); + VIR_FREE(def->seclabels); virCPUDefFree(def->cpu); @@ -3077,10 +3087,10 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def, { char *p; - if (virXPathNode("./seclabel", ctxt) == NULL) + if (virXPathNode("./seclabel[1]", ctxt) == NULL) return 0; - p = virXPathStringLimit("string(./seclabel/@type)", + p = virXPathStringLimit("string(./seclabel[1]/@type)", VIR_SECURITY_LABEL_BUFLEN-1, ctxt); if (p == NULL) { def->type = VIR_DOMAIN_SECLABEL_DYNAMIC; @@ -3094,7 +3104,7 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def, } } - p = virXPathStringLimit("string(./seclabel/@relabel)", + p = virXPathStringLimit("string(./seclabel[1]/@relabel)", VIR_SECURITY_LABEL_BUFLEN-1, ctxt); if (p != NULL) { if (STREQ(p, "yes")) { @@ -3134,7 +3144,7 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def, if (def->type == VIR_DOMAIN_SECLABEL_STATIC || (!(flags & VIR_DOMAIN_XML_INACTIVE) && def->type != VIR_DOMAIN_SECLABEL_NONE)) { - p = virXPathStringLimit("string(./seclabel/label[1])", + p = virXPathStringLimit("string(./seclabel[1]/label[1])", VIR_SECURITY_LABEL_BUFLEN-1, ctxt); if (p == NULL) { virDomainReportError(VIR_ERR_XML_ERROR, @@ -3149,7 +3159,7 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def, if (!def->norelabel && (!(flags & VIR_DOMAIN_XML_INACTIVE) && def->type != VIR_DOMAIN_SECLABEL_NONE)) { - p = virXPathStringLimit("string(./seclabel/imagelabel[1])", + p = virXPathStringLimit("string(./seclabel[1]/imagelabel[1])", VIR_SECURITY_LABEL_BUFLEN-1, ctxt); if (p == NULL) { virDomainReportError(VIR_ERR_XML_ERROR, @@ -3161,7 +3171,7 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def, /* Only parse baselabel for dynamic label type */ if (def->type == VIR_DOMAIN_SECLABEL_DYNAMIC) { - p = virXPathStringLimit("string(./seclabel/baselabel[1])", + p = virXPathStringLimit("string(./seclabel[1]/baselabel[1])", VIR_SECURITY_LABEL_BUFLEN-1, ctxt); def->baselabel = p; } @@ -3173,7 +3183,7 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def, def->baselabel || (!(flags & VIR_DOMAIN_XML_INACTIVE) && def->type != VIR_DOMAIN_SECLABEL_NONE)) { - p = virXPathStringLimit("string(./seclabel/@model)", + p = virXPathStringLimit("string(./seclabel[1]/@model)", VIR_SECURITY_MODEL_BUFLEN-1, ctxt); if (p == NULL) { virDomainReportError(VIR_ERR_XML_ERROR, @@ -3186,7 +3196,7 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def, return 0; error: - virSecurityLabelDefClear(def); + virSecurityLabelDefFree(def); return -1; } @@ -3200,7 +3210,7 @@ virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr *def, *def = NULL; - if (virXPathNode("./seclabel", ctxt) == NULL) + if (virXPathNode("./seclabel[1]", ctxt) == NULL) return 0; /* Can't use overrides if top-level doesn't allow relabeling. */ @@ -3216,7 +3226,7 @@ virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr *def, return -1; } - p = virXPathStringLimit("string(./seclabel/@relabel)", + p = virXPathStringLimit("string(./seclabel[1]/@relabel)", VIR_SECURITY_LABEL_BUFLEN-1, ctxt); if (p != NULL) { if (STREQ(p, "yes")) { @@ -3235,7 +3245,7 @@ virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr *def, (*def)->norelabel = false; } - p = virXPathStringLimit("string(./seclabel/label[1])", + p = virXPathStringLimit("string(./seclabel[1]/label[1])", VIR_SECURITY_LABEL_BUFLEN-1, ctxt); (*def)->label = p; @@ -3669,10 +3679,15 @@ virDomainDiskDefParseXML(virCapsPtr caps, if (sourceNode) { xmlNodePtr saved_node = ctxt->node; ctxt->node = sourceNode; - if (virSecurityDeviceLabelDefParseXML(&def->seclabel, + if ((VIR_ALLOC(def->seclabels) < 0) || (VIR_ALLOC(def->seclabels[0]) < 0)) { + virReportOOMError(); + goto error; + } + if (virSecurityDeviceLabelDefParseXML(&def->seclabels[0], vmSeclabel, ctxt) < 0) goto error; + def->nseclabels = 1; ctxt->node = saved_node; } @@ -7115,10 +7130,16 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps, goto error; } + if ((VIR_ALLOC(def->seclabels) < 0) || + (VIR_ALLOC(def->seclabels[0])) < 0 ) { + virReportOOMError(); + goto error; + } + if (xmlStrEqual(node->name, BAD_CAST "disk")) { dev->type = VIR_DOMAIN_DEVICE_DISK; if (!(dev->data.disk = virDomainDiskDefParseXML(caps, node, ctxt, - NULL, &def->seclabel, flags))) + NULL, def->seclabels[0], flags))) goto error; } else if (xmlStrEqual(node->name, BAD_CAST "lease")) { dev->type = VIR_DOMAIN_DEVICE_LEASE; @@ -8017,7 +8038,12 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, /* analysis of security label, done early even though we format it * late, so devices can refer to this for defaults */ - if (virSecurityLabelDefParseXML(&def->seclabel, ctxt, flags) == -1) + if ((VIR_ALLOC(def->seclabels) < 0) || (VIR_ALLOC(def->seclabels[0]) < 0)) { + virReportOOMError(); + goto error; + } + def->nseclabels = 1; + if (virSecurityLabelDefParseXML(def->seclabels[0], ctxt, flags) == -1) goto error; /* Extract domain memory */ @@ -8616,7 +8642,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, nodes[i], ctxt, bootMap, - &def->seclabel, + def->seclabels[0], flags); if (!disk) goto error; @@ -11085,10 +11111,10 @@ virDomainDiskDefFormat(virBufferPtr buf, if (def->startupPolicy) virBufferEscapeString(buf, " startupPolicy='%s'", startupPolicy); - if (def->seclabel) { + if (def->seclabels && def->seclabels[0]) { virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 8); - virSecurityDeviceLabelDefFormat(buf, def->seclabel); + virSecurityDeviceLabelDefFormat(buf, def->seclabels[0]); virBufferAdjustIndent(buf, -8); virBufferAddLit(buf, " </source>\n"); } else { @@ -11098,10 +11124,10 @@ virDomainDiskDefFormat(virBufferPtr buf, case VIR_DOMAIN_DISK_TYPE_BLOCK: virBufferEscapeString(buf, " <source dev='%s'", def->src); - if (def->seclabel) { + if (def->seclabels && def->seclabels[0]) { virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 8); - virSecurityDeviceLabelDefFormat(buf, def->seclabel); + virSecurityDeviceLabelDefFormat(buf, def->seclabels[0]); virBufferAdjustIndent(buf, -8); virBufferAddLit(buf, " </source>\n"); } else { @@ -13127,9 +13153,11 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAddLit(buf, " </devices>\n"); - virBufferAdjustIndent(buf, 2); - virSecurityLabelDefFormat(buf, &def->seclabel); - virBufferAdjustIndent(buf, -2); + if (def->nseclabels && def->seclabels) { + virBufferAdjustIndent(buf, 2); + virSecurityLabelDefFormat(buf, def->seclabels[0]); + virBufferAdjustIndent(buf, -2); + } if (def->namespaceData && def->ns.format) { if ((def->ns.format)(buf, def->namespaceData) < 0) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 6c777e7..9a2189a 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -310,6 +310,7 @@ struct _virSecurityLabelDef { typedef struct _virSecurityDeviceLabelDef virSecurityDeviceLabelDef; typedef virSecurityDeviceLabelDef *virSecurityDeviceLabelDefPtr; struct _virSecurityDeviceLabelDef { + char *model; char *label; /* image label string */ bool norelabel; }; @@ -554,7 +555,6 @@ struct _virDomainDiskDef { int device; int bus; char *src; - virSecurityDeviceLabelDefPtr seclabel; char *dst; int tray_status; int protocol; @@ -594,6 +594,9 @@ struct _virDomainDiskDef { virStorageEncryptionPtr encryption; bool rawio_specified; int rawio; /* no = 0, yes = 1 */ + + size_t nseclabels; + virSecurityDeviceLabelDefPtr *seclabels; }; @@ -1673,8 +1676,10 @@ struct _virDomainDef { int nhubs; virDomainHubDefPtr *hubs; + size_t nseclabels; + virSecurityLabelDefPtr *seclabels; + /* Only 1 */ - virSecurityLabelDef seclabel; virDomainWatchdogDefPtr watchdog; virDomainMemballoonDefPtr memballoon; virCPUDefPtr cpu; diff --git a/src/lxc/lxc_conf.c b/src/lxc/lxc_conf.c index 72547c4..807c704 100644 --- a/src/lxc/lxc_conf.c +++ b/src/lxc/lxc_conf.c @@ -134,9 +134,13 @@ virCapsPtr lxcCapsInit(lxc_driver_t *driver) doi = virSecurityManagerGetDOI(driver->securityManager); model = virSecurityManagerGetModel(driver->securityManager); if (STRNEQ(model, "none")) { - if (!(caps->host.secModel.model = strdup(model))) + /* Allocate just the primary security driver for LXC. */ + if (VIR_ALLOC(caps->host.secModels) < 0) goto no_memory; - if (!(caps->host.secModel.doi = strdup(doi))) + caps->host.nsecModels = 1; + if (!(caps->host.secModels[0].model = strdup(model))) + goto no_memory; + if (!(caps->host.secModels[0].doi = strdup(doi))) goto no_memory; } diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 7a1ce14..fc41c74 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -1689,10 +1689,10 @@ int main(int argc, char *argv[]) goto cleanup; VIR_DEBUG("Security model %s type %s label %s imagelabel %s", - NULLSTR(ctrl->def->seclabel.model), - virDomainSeclabelTypeToString(ctrl->def->seclabel.type), - NULLSTR(ctrl->def->seclabel.label), - NULLSTR(ctrl->def->seclabel.imagelabel)); + NULLSTR(ctrl->def->seclabels[0]->model), + virDomainSeclabelTypeToString(ctrl->def->seclabels[0]->type), + NULLSTR(ctrl->def->seclabels[0]->label), + NULLSTR(ctrl->def->seclabels[0]->imagelabel)); ctrl->veths = veths; ctrl->nveths = nveths; diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 2d931db..af63cd0 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1489,10 +1489,12 @@ static int lxcVmTerminate(lxc_driver_t *driver, vm->def, false); virSecurityManagerReleaseLabel(driver->securityManager, vm->def); /* Clear out dynamically assigned labels */ - if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) { - VIR_FREE(vm->def->seclabel.model); - VIR_FREE(vm->def->seclabel.label); - VIR_FREE(vm->def->seclabel.imagelabel); + /* Manages just the primary sec driver for lxc */ + if (vm->def->nseclabels + && vm->def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) { + VIR_FREE(vm->def->seclabels[0]->model); + VIR_FREE(vm->def->seclabels[0]->label); + VIR_FREE(vm->def->seclabels[0]->imagelabel); } if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) == 0) { @@ -1828,8 +1830,10 @@ static int lxcVmStart(virConnectPtr conn, /* If you are using a SecurityDriver with dynamic labelling, then generate a security label for isolation */ VIR_DEBUG("Generating domain security label (if required)"); - if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DEFAULT) - vm->def->seclabel.type = VIR_DOMAIN_SECLABEL_NONE; + if (vm->def->nseclabels + && vm->def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DEFAULT) { + vm->def->seclabels[0]->type = VIR_DOMAIN_SECLABEL_NONE; + } if (virSecurityManagerGenLabel(driver->securityManager, vm->def) < 0) { virDomainAuditSecurityLabel(vm, false); @@ -2034,10 +2038,11 @@ cleanup: vm->def, false); virSecurityManagerReleaseLabel(driver->securityManager, vm->def); /* Clear out dynamically assigned labels */ - if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) { - VIR_FREE(vm->def->seclabel.model); - VIR_FREE(vm->def->seclabel.label); - VIR_FREE(vm->def->seclabel.imagelabel); + if (vm->def->nseclabels + && vm->def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) { + VIR_FREE(vm->def->seclabels[0]->model); + VIR_FREE(vm->def->seclabels[0]->label); + VIR_FREE(vm->def->seclabels[0]->imagelabel); } } for (i = 0 ; i < nttyFDs ; i++) @@ -2277,12 +2282,12 @@ static int lxcNodeGetSecurityModel(virConnectPtr conn, lxcDriverLock(driver); memset(secmodel, 0, sizeof(*secmodel)); - /* NULL indicates no driver, which we treat as - * success, but simply return no data in *secmodel */ - if (driver->caps->host.secModel.model == NULL) + /* we treat no driver as success, but simply return no data in *secmodel */ + if (driver->caps->host.nsecModels == 0 + || driver->caps->host.secModels[0].model == NULL) goto cleanup; - if (!virStrcpy(secmodel->model, driver->caps->host.secModel.model, + if (!virStrcpy(secmodel->model, driver->caps->host.secModels[0].model, VIR_SECURITY_MODEL_BUFLEN)) { lxcError(VIR_ERR_INTERNAL_ERROR, _("security model string exceeds max %d bytes"), @@ -2291,7 +2296,7 @@ static int lxcNodeGetSecurityModel(virConnectPtr conn, goto cleanup; } - if (!virStrcpy(secmodel->doi, driver->caps->host.secModel.doi, + if (!virStrcpy(secmodel->doi, driver->caps->host.secModels[0].doi, VIR_SECURITY_DOI_BUFLEN)) { lxcError(VIR_ERR_INTERNAL_ERROR, _("security DOI string exceeds max %d bytes"), diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d3988b8..a512a45 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -293,10 +293,15 @@ qemuCreateCapabilities(virCapsPtr oldcaps, doi = virSecurityManagerGetDOI(driver->securityManager); model = virSecurityManagerGetModel(driver->securityManager); + + if (VIR_ALLOC(caps->host.secModels) < 0) { + goto no_memory; + } + if (STRNEQ(model, "none")) { - if (!(caps->host.secModel.model = strdup(model))) + if (!(caps->host.secModels[0].model = strdup(model))) goto no_memory; - if (!(caps->host.secModel.doi = strdup(doi))) + if (!(caps->host.secModels[0].doi = strdup(doi))) goto no_memory; } @@ -4032,10 +4037,10 @@ static int qemudNodeGetSecurityModel(virConnectPtr conn, /* NULL indicates no driver, which we treat as * success, but simply return no data in *secmodel */ - if (driver->caps->host.secModel.model == NULL) + if (driver->caps->host.secModels[0].model == NULL) goto cleanup; - p = driver->caps->host.secModel.model; + p = driver->caps->host.secModels[0].model; if (strlen(p) >= VIR_SECURITY_MODEL_BUFLEN-1) { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("security model string exceeds max %d bytes"), @@ -4045,7 +4050,7 @@ static int qemudNodeGetSecurityModel(virConnectPtr conn, } strcpy(secmodel->model, p); - p = driver->caps->host.secModel.doi; + p = driver->caps->host.secModels[0].doi; if (strlen(p) >= VIR_SECURITY_DOI_BUFLEN-1) { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("security DOI string exceeds max %d bytes"), diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index d8169e8..e9a41df 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4079,12 +4079,12 @@ void qemuProcessStop(struct qemud_driver *driver, virSecurityManagerReleaseLabel(driver->securityManager, vm->def); /* Clear out dynamically assigned labels */ - if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) { - if (!vm->def->seclabel.baselabel) - VIR_FREE(vm->def->seclabel.model); - VIR_FREE(vm->def->seclabel.label); + if (vm->def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) { + if (!vm->def->seclabels[0]->baselabel) + VIR_FREE(vm->def->seclabels[0]->model); + VIR_FREE(vm->def->seclabels[0]->label); } - VIR_FREE(vm->def->seclabel.imagelabel); + VIR_FREE(vm->def->seclabels[0]->imagelabel); virDomainDefClearDeviceAliases(vm->def); if (!priv->persistentAddrs) { @@ -4227,16 +4227,16 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, goto no_memory; VIR_DEBUG("Detect security driver config"); - vm->def->seclabel.type = VIR_DOMAIN_SECLABEL_STATIC; + vm->def->seclabels[0]->type = VIR_DOMAIN_SECLABEL_STATIC; if (VIR_ALLOC(seclabel) < 0) goto no_memory; if (virSecurityManagerGetProcessLabel(driver->securityManager, vm->def, vm->pid, seclabel) < 0) goto cleanup; - if (driver->caps->host.secModel.model && - !(vm->def->seclabel.model = strdup(driver->caps->host.secModel.model))) + if (driver->caps->host.secModels[0].model && + !(vm->def->seclabels[0]->model = strdup(driver->caps->host.secModels[0].model))) goto no_memory; - if (!(vm->def->seclabel.label = strdup(seclabel->label))) + if (!(vm->def->seclabels[0]->label = strdup(seclabel->label))) goto no_memory; VIR_DEBUG("Creating domain log file"); diff --git a/src/security/security_manager.c b/src/security/security_manager.c index 8ec4d3e..5ca3201 100644 --- a/src/security/security_manager.c +++ b/src/security/security_manager.c @@ -308,14 +308,14 @@ int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr, int virSecurityManagerGenLabel(virSecurityManagerPtr mgr, virDomainDefPtr vm) { - if (vm->seclabel.type == VIR_DOMAIN_SECLABEL_DEFAULT) { + if (vm->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DEFAULT) { if (mgr->defaultConfined) - vm->seclabel.type = VIR_DOMAIN_SECLABEL_DYNAMIC; + vm->seclabels[0]->type = VIR_DOMAIN_SECLABEL_DYNAMIC; else - vm->seclabel.type = VIR_DOMAIN_SECLABEL_NONE; + vm->seclabels[0]->type = VIR_DOMAIN_SECLABEL_NONE; } - if ((vm->seclabel.type == VIR_DOMAIN_SECLABEL_NONE) && + if ((vm->seclabels[0]->type == VIR_DOMAIN_SECLABEL_NONE) && mgr->requireConfined) { virSecurityReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Unconfined guests are not allowed on this host")); @@ -397,7 +397,7 @@ int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr, int virSecurityManagerVerify(virSecurityManagerPtr mgr, virDomainDefPtr def) { - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; /* NULL model == dynamic labelling, with whatever driver * is active, so we can short circuit verify check to * avoid drivers de-referencing NULLs by accident diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index ffa65fb..9a708b1 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -274,43 +274,43 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr, virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr); VIR_DEBUG("SELinuxGenSecurityLabel %s", virSecurityManagerGetDriver(mgr)); - if ((def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) && - !def->seclabel.baselabel && - def->seclabel.model) { + if ((def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) && + !def->seclabels[0]->baselabel && + def->seclabels[0]->model) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("security model already defined for VM")); return rc; } - if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC && - def->seclabel.label) { + if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC && + def->seclabels[0]->label) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("security label already defined for VM")); return rc; } - if (def->seclabel.imagelabel) { + if (def->seclabels[0]->imagelabel) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("security image label already defined for VM")); return rc; } - if (def->seclabel.model && - STRNEQ(def->seclabel.model, SECURITY_SELINUX_NAME)) { + if (def->seclabels[0]->model && + STRNEQ(def->seclabels[0]->model, SECURITY_SELINUX_NAME)) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, _("security label model %s is not supported with selinux"), - def->seclabel.model); + def->seclabels[0]->model); return rc; } - VIR_DEBUG("SELinuxGenSecurityLabel %d", def->seclabel.type); + VIR_DEBUG("SELinuxGenSecurityLabel %d", def->seclabels[0]->type); - switch (def->seclabel.type) { + switch (def->seclabels[0]->type) { case VIR_DOMAIN_SECLABEL_STATIC: - if (!(ctx = context_new(def->seclabel.label)) ) { + if (!(ctx = context_new(def->seclabels[0]->label)) ) { virReportSystemError(errno, _("unable to allocate socket security context '%s'"), - def->seclabel.label); + def->seclabels[0]->label); return rc; } @@ -345,11 +345,11 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr, } } while (mcsAdd(mcs) == -1); - def->seclabel.label = - SELinuxGenNewContext(def->seclabel.baselabel ? - def->seclabel.baselabel : + def->seclabels[0]->label = + SELinuxGenNewContext(def->seclabels[0]->baselabel ? + def->seclabels[0]->baselabel : data->domain_context, mcs); - if (! def->seclabel.label) { + if (! def->seclabels[0]->label) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, _("cannot generate selinux context for %s"), mcs); goto cleanup; @@ -363,21 +363,21 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr, default: virSecurityReportError(VIR_ERR_INTERNAL_ERROR, _("unexpected security label type '%s'"), - virDomainSeclabelTypeToString(def->seclabel.type)); + virDomainSeclabelTypeToString(def->seclabels[0]->type)); goto cleanup; } - if (!def->seclabel.norelabel) { - def->seclabel.imagelabel = SELinuxGenNewContext(data->file_context, mcs); - if (!def->seclabel.imagelabel) { + if (!def->seclabels[0]->norelabel) { + def->seclabels[0]->imagelabel = SELinuxGenNewContext(data->file_context, mcs); + if (!def->seclabels[0]->imagelabel) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, _("cannot generate selinux context for %s"), mcs); goto cleanup; } } - if (!def->seclabel.model && - !(def->seclabel.model = strdup(SECURITY_SELINUX_NAME))) { + if (!def->seclabels[0]->model && + !(def->seclabels[0]->model = strdup(SECURITY_SELINUX_NAME))) { virReportOOMError(); goto cleanup; } @@ -386,12 +386,12 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr, cleanup: if (rc != 0) { - if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) - VIR_FREE(def->seclabel.label); - VIR_FREE(def->seclabel.imagelabel); - if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC && - !def->seclabel.baselabel) - VIR_FREE(def->seclabel.model); + if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) + VIR_FREE(def->seclabels[0]->label); + VIR_FREE(def->seclabels[0]->imagelabel); + if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC && + !def->seclabels[0]->baselabel) + VIR_FREE(def->seclabels[0]->model); } if (ctx) @@ -400,10 +400,10 @@ cleanup: VIR_FREE(mcs); VIR_DEBUG("model=%s label=%s imagelabel=%s baselabel=%s", - NULLSTR(def->seclabel.model), - NULLSTR(def->seclabel.label), - NULLSTR(def->seclabel.imagelabel), - NULLSTR(def->seclabel.baselabel)); + NULLSTR(def->seclabels[0]->model), + NULLSTR(def->seclabels[0]->label), + NULLSTR(def->seclabels[0]->imagelabel), + NULLSTR(def->seclabels[0]->baselabel)); return rc; } @@ -417,7 +417,7 @@ SELinuxReserveSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, context_t ctx = NULL; const char *mcs; - if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC) + if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_STATIC) return 0; if (getpidcon(pid, &pctx) == -1) { @@ -709,9 +709,9 @@ SELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virDomainDiskDefPtr disk, int migrated) { - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; - if (secdef->norelabel || (disk->seclabel && disk->seclabel->norelabel)) + if (secdef->norelabel || (disk->seclabels[0] && disk->seclabels[0]->norelabel)) return 0; /* Don't restore labels on readoly/shared disks, because @@ -768,12 +768,12 @@ SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk, int ret; virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(cbdata->manager); - if (disk->seclabel && disk->seclabel->norelabel) + if (disk->seclabels[0] && disk->seclabels[0]->norelabel) return 0; - if (disk->seclabel && !disk->seclabel->norelabel && - disk->seclabel->label) { - ret = SELinuxSetFilecon(path, disk->seclabel->label); + if (disk->seclabels[0] && !disk->seclabels[0]->norelabel && + disk->seclabels[0]->label) { + ret = SELinuxSetFilecon(path, disk->seclabels[0]->label); } else if (depth == 0) { if (disk->shared) { @@ -788,14 +788,14 @@ SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk, } else { ret = SELinuxSetFileconOptional(path, data->content_context); } - if (ret == 1 && !disk->seclabel) { + if (ret == 1 && !disk->seclabels[0]) { /* If we failed to set a label, but virt_use_nfs let us * proceed anyway, then we don't need to relabel later. */ - if (VIR_ALLOC(disk->seclabel) < 0) { + if (VIR_ALLOC(disk->seclabels[0]) < 0) { virReportOOMError(); return -1; } - disk->seclabel->norelabel = true; + disk->seclabels[0]->norelabel = true; ret = 0; } return ret; @@ -808,7 +808,7 @@ SELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr, { virSecuritySELinuxCallbackData cbdata; - cbdata.secdef = &def->seclabel; + cbdata.secdef = def->seclabels[0]; cbdata.manager = mgr; bool allowDiskFormatProbing = virSecurityManagerGetAllowDiskFormatProbing(mgr); @@ -839,7 +839,7 @@ SELinuxSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED, const char *file, void *opaque) { virDomainDefPtr def = opaque; - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; return SELinuxSetFilecon(file, secdef->imagelabel); } @@ -849,7 +849,7 @@ SELinuxSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED, const char *file, void *opaque) { virDomainDefPtr def = opaque; - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; return SELinuxSetFilecon(file, secdef->imagelabel); } @@ -860,7 +860,7 @@ SELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virDomainHostdevDefPtr dev) { - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; int ret = -1; if (secdef->norelabel) @@ -929,7 +929,7 @@ SELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virDomainHostdevDefPtr dev) { - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; int ret = -1; if (secdef->norelabel) @@ -982,7 +982,7 @@ SELinuxSetSecurityChardevLabel(virDomainDefPtr def, virDomainChrSourceDefPtr dev) { - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; char *in = NULL, *out = NULL; int ret = -1; @@ -1028,7 +1028,7 @@ SELinuxRestoreSecurityChardevLabel(virDomainDefPtr def, virDomainChrSourceDefPtr dev) { - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; char *in = NULL, *out = NULL; int ret = -1; @@ -1121,7 +1121,7 @@ SELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virDomainDefPtr def, int migrated ATTRIBUTE_UNUSED) { - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; int i; int rc = 0; @@ -1171,7 +1171,7 @@ static int SELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virDomainDefPtr def) { - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; if (secdef->type == VIR_DOMAIN_SECLABEL_DYNAMIC) { if (secdef->label != NULL) { @@ -1196,7 +1196,7 @@ SELinuxSetSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virDomainDefPtr def, const char *savefile) { - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; if (secdef->norelabel) return 0; @@ -1210,7 +1210,7 @@ SELinuxRestoreSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virDomainDefPtr def, const char *savefile) { - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; if (secdef->norelabel) return 0; @@ -1223,7 +1223,7 @@ static int SELinuxSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virDomainDefPtr def) { - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, _("security label driver mismatch: " @@ -1248,10 +1248,10 @@ SELinuxSetSecurityProcessLabel(virSecurityManagerPtr mgr, virDomainDefPtr def) { /* TODO: verify DOI */ - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; VIR_DEBUG("SELinuxSetSecurityProcessLabel %s", secdef->label); - if (def->seclabel.label == NULL) + if (def->seclabels[0]->label == NULL) return 0; if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) { @@ -1280,13 +1280,13 @@ SELinuxSetSecurityDaemonSocketLabel(virSecurityManagerPtr mgr, virDomainDefPtr def) { /* TODO: verify DOI */ - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; context_t execcon = NULL; context_t proccon = NULL; security_context_t scon = NULL; int rc = -1; - if (def->seclabel.label == NULL) + if (def->seclabels[0]->label == NULL) return 0; if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) { @@ -1350,7 +1350,7 @@ static int SELinuxSetSecuritySocketLabel(virSecurityManagerPtr mgr, virDomainDefPtr vm) { - const virSecurityLabelDefPtr secdef = &vm->seclabel; + const virSecurityLabelDefPtr secdef = vm->seclabels[0]; int rc = -1; if (secdef->label == NULL) @@ -1388,9 +1388,9 @@ SELinuxClearSecuritySocketLabel(virSecurityManagerPtr mgr, virDomainDefPtr def) { /* TODO: verify DOI */ - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; - if (def->seclabel.label == NULL) + if (def->seclabels[0]->label == NULL) return 0; if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) { @@ -1467,7 +1467,7 @@ SELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr, const char *stdin_path) { virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr); - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; int i; if (secdef->norelabel) @@ -1528,7 +1528,7 @@ SELinuxSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virDomainDefPtr def, int fd) { - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; if (secdef->imagelabel == NULL) return 0; @@ -1538,7 +1538,7 @@ SELinuxSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, static char *genImageLabel(virSecurityManagerPtr mgr, virDomainDefPtr def) { - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr); const char *range; context_t ctx = NULL; @@ -1575,7 +1575,7 @@ cleanup: static char *SELinuxGetSecurityMountOptions(virSecurityManagerPtr mgr, virDomainDefPtr def) { char *opts = NULL; - const virSecurityLabelDefPtr secdef = &def->seclabel; + const virSecurityLabelDefPtr secdef = def->seclabels[0]; if (! secdef->imagelabel) secdef->imagelabel = genImageLabel(mgr,def); diff --git a/src/test/test_driver.c b/src/test/test_driver.c index b3b774d..023fd3f 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -211,12 +211,15 @@ testBuildCapabilities(virConnectPtr conn) { caps->privateDataAllocFunc = testDomainObjPrivateAlloc; caps->privateDataFreeFunc = testDomainObjPrivateFree; - caps->host.secModel.model = strdup("testSecurity"); - if (!caps->host.secModel.model) + caps->host.nsecModels = 1; + if (VIR_ALLOC_N(caps->host.secModels, caps->host.nsecModels) < 0) + goto no_memory; + caps->host.secModels[0].model = strdup("testSecurity"); + if (!caps->host.secModels[0].model) goto no_memory; - caps->host.secModel.doi = strdup(""); - if (!caps->host.secModel.doi) + caps->host.secModels[0].doi = strdup(""); + if (!caps->host.secModels[0].doi) goto no_memory; return caps; -- 1.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list