From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> This re-introduces parsing & formatting for per device seclabels. There is a new virDomainDeviceSeclabelPtr struct and corresponding APIs for parsing/formatting. --- src/conf/domain_conf.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++-- src/conf/domain_conf.h | 12 +++++- 2 files changed, 122 insertions(+), 5 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 8db674b..4ae417e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -798,6 +798,17 @@ virSecurityLabelDefClear(virSecurityLabelDefPtr def) VIR_FREE(def->baselabel); } + +static void +virSecurityDeviceLabelDefFree(virSecurityDeviceLabelDefPtr def) +{ + if (!def) + return; + VIR_FREE(def->label); + VIR_FREE(def); +} + + void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def) { int ii; @@ -876,6 +887,8 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def) virStorageEncryptionFree(def->encryption); virDomainDeviceInfoClear(&def->info); + virSecurityDeviceLabelDefFree(def->seclabel); + for (i = 0 ; i < def->nhosts ; i++) virDomainDiskHostDefFree(&def->hosts[i]); VIR_FREE(def->hosts); @@ -2628,6 +2641,54 @@ error: return -1; } + +static int +virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr *def, + virSecurityLabelDefPtr vmDef, + xmlXPathContextPtr ctxt) +{ + char *p; + + *def = NULL; + + if (virXPathNode("./seclabel", ctxt) == NULL) + return 0; + + if (VIR_ALLOC(*def) < 0) { + virReportOOMError(); + return -1; + } + + p = virXPathStringLimit("string(./seclabel/@relabel)", + VIR_SECURITY_LABEL_BUFLEN-1, ctxt); + if (p != NULL) { + if (STREQ(p, "yes")) { + (*def)->norelabel = false; + } else if (STREQ(p, "no")) { + (*def)->norelabel = true; + } else { + virDomainReportError(VIR_ERR_XML_ERROR, + _("invalid security relabel value %s"), p); + VIR_FREE(p); + VIR_FREE(*def); + return -1; + } + VIR_FREE(p); + } else { + if (vmDef->type == VIR_DOMAIN_SECLABEL_STATIC) + (*def)->norelabel = true; + else + (*def)->norelabel = false; + } + + p = virXPathStringLimit("string(./seclabel/label[1])", + VIR_SECURITY_LABEL_BUFLEN-1, ctxt); + (*def)->label = p; + + return 0; +} + + /* Parse the XML definition for a lease */ static virDomainLeaseDefPtr @@ -2709,9 +2770,11 @@ virDomainDiskDefParseXML(virCapsPtr caps, xmlNodePtr node, xmlXPathContextPtr ctxt, virBitmapPtr bootMap, + virSecurityLabelDefPtr vmSeclabel, unsigned int flags) { virDomainDiskDefPtr def; + xmlNodePtr sourceNode = NULL; xmlNodePtr cur, child; xmlNodePtr save_ctxt = ctxt->node; char *type = NULL; @@ -2766,6 +2829,8 @@ virDomainDiskDefParseXML(virCapsPtr caps, if ((source == NULL && hosts == NULL) && (xmlStrEqual(cur->name, BAD_CAST "source"))) { + sourceNode = cur; + switch (def->type) { case VIR_DOMAIN_DISK_TYPE_FILE: source = virXMLPropString(cur, "file"); @@ -3016,6 +3081,17 @@ virDomainDiskDefParseXML(virCapsPtr caps, goto error; } + /* If source is present, check for an optional seclabel override. */ + if (sourceNode) { + xmlNodePtr saved_node = ctxt->node; + ctxt->node = sourceNode; + if (virSecurityDeviceLabelDefParseXML(&def->seclabel, + vmSeclabel, + ctxt) < 0) + goto error; + ctxt->node = saved_node; + } + if (target == NULL) { virDomainReportError(VIR_ERR_NO_TARGET, source ? "%s" : NULL, source); @@ -6338,7 +6414,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps, if (xmlStrEqual(node->name, BAD_CAST "disk")) { dev->type = VIR_DOMAIN_DEVICE_DISK; if (!(dev->data.disk = virDomainDiskDefParseXML(caps, node, ctxt, - NULL, flags))) + NULL, &def->seclabel, flags))) goto error; } else if (xmlStrEqual(node->name, BAD_CAST "lease")) { dev->type = VIR_DOMAIN_DEVICE_LEASE; @@ -7440,6 +7516,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, nodes[i], ctxt, bootMap, + &def->seclabel, flags); if (!disk) goto error; @@ -9767,6 +9844,19 @@ cleanup: } +static void +virSecurityDeviceLabelDefFormat(virBufferPtr buf, + virSecurityDeviceLabelDefPtr def) +{ + virBufferAsprintf(buf, "<seclabel relabel='%s'>\n", + def->norelabel ? "no" : "yes"); + if (def->label) + virBufferEscapeString(buf, " <label>%s</label>\n", + def->label); + virBufferAddLit(buf, "</seclabel>\n"); +} + + static int virDomainLeaseDefFormat(virBufferPtr buf, virDomainLeaseDefPtr def) @@ -9879,17 +9969,34 @@ virDomainDiskDefFormat(virBufferPtr buf, def->startupPolicy) { switch (def->type) { case VIR_DOMAIN_DISK_TYPE_FILE: - virBufferAsprintf(buf," <source"); + virBufferAddLit(buf," <source"); if (def->src) virBufferEscapeString(buf, " file='%s'", def->src); if (def->startupPolicy) virBufferEscapeString(buf, " startupPolicy='%s'", startupPolicy); - virBufferAsprintf(buf, "/>\n"); + if (def->seclabel) { + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 8); + virSecurityDeviceLabelDefFormat(buf, def->seclabel); + virBufferAdjustIndent(buf, -8); + virBufferAddLit(buf, " </source>\n"); + } else { + virBufferAddLit(buf, "/>\n"); + } break; case VIR_DOMAIN_DISK_TYPE_BLOCK: - virBufferEscapeString(buf, " <source dev='%s'/>\n", + virBufferEscapeString(buf, " <source dev='%s'", def->src); + if (def->seclabel) { + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 8); + virSecurityDeviceLabelDefFormat(buf, def->seclabel); + virBufferAdjustIndent(buf, -8); + virBufferAddLit(buf, " </source>\n"); + } else { + virBufferAddLit(buf, "/>\n"); + } break; case VIR_DOMAIN_DISK_TYPE_DIR: virBufferEscapeString(buf, " <source dir='%s'/>\n", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3d5d4f8..25aae62 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -180,6 +180,16 @@ struct _virSecurityLabelDef { bool norelabel; }; + +/* Security configuration for domain */ +typedef struct _virSecurityDeviceLabelDef virSecurityDeviceLabelDef; +typedef virSecurityDeviceLabelDef *virSecurityDeviceLabelDefPtr; +struct _virSecurityDeviceLabelDef { + char *label; /* image label string */ + bool norelabel; +}; + + typedef struct _virDomainHostdevOrigStates virDomainHostdevOrigStates; typedef virDomainHostdevOrigStates *virDomainHostdevOrigStatesPtr; struct _virDomainHostdevOrigStates { @@ -358,7 +368,7 @@ struct _virDomainDiskDef { int device; int bus; char *src; - virSecurityLabelDefPtr seclabel; + virSecurityDeviceLabelDefPtr seclabel; char *dst; int protocol; int nhosts; -- 1.7.7.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list