diff --git a/ChangeLog b/ChangeLog index c295a61a62..da7f5b6f95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Tue Mar 3 16:43:13 GMT 2009 Daniel P. Berrange + + Explicitly track static declared vs dynamically generated + security labels for VMs + * src/domain_conf.c, src/domain_conf.h: Add type='static|dynamic' + for to determine whether to auto-generate labels + * src/qemu_driver.c: Only generate security labels for type=dynamic + Tue Mar 3 14:58:13 GMT 2009 Daniel P. Berrange Misc sVirt bug fixes diff --git a/src/domain_conf.c b/src/domain_conf.c index 43c51eb25e..5bf34837f4 100644 --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -168,6 +168,10 @@ VIR_ENUM_IMPL(virDomainState, VIR_DOMAIN_CRASHED+1, "shutoff", "crashed") +VIR_ENUM_IMPL(virDomainSeclabel, VIR_DOMAIN_SECLABEL_LAST, + "dynamic", + "static") + #define virDomainReportError(conn, code, fmt...) \ virReportErrorHelper(conn, VIR_FROM_DOMAIN, code, __FILE__, \ __FUNCTION__, __LINE__, fmt) @@ -1847,24 +1851,49 @@ static int virDomainLifecycleParseXML(virConnectPtr conn, static int virSecurityLabelDefParseXML(virConnectPtr conn, const virDomainDefPtr def, - xmlXPathContextPtr ctxt) + xmlXPathContextPtr ctxt, + int flags) { char *p; if (virXPathNode(conn, "./seclabel", ctxt) == NULL) return 0; - p = virXPathStringLimit(conn, "string(./seclabel/label[1])", + p = virXPathStringLimit(conn, "string(./seclabel/@type)", VIR_SECURITY_LABEL_BUFLEN-1, ctxt); if (p == NULL) goto error; - def->seclabel.label = p; - - p = virXPathStringLimit(conn, "string(./seclabel/@model)", - VIR_SECURITY_MODEL_BUFLEN-1, ctxt); - if (p == NULL) + if ((def->seclabel.type = virDomainSeclabelTypeFromString(p)) < 0) goto error; - def->seclabel.model = p; + VIR_FREE(p); + + /* Only parse details, 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(conn, "string(./seclabel/@model)", + VIR_SECURITY_MODEL_BUFLEN-1, ctxt); + if (p == NULL) + goto error; + def->seclabel.model = p; + + p = virXPathStringLimit(conn, "string(./seclabel/label[1])", + VIR_SECURITY_LABEL_BUFLEN-1, ctxt); + if (p == NULL) + goto error; + def->seclabel.label = p; + } + + /* Only parse imagelabel, if requested live XML for dynamic label */ + if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC && + !(flags & VIR_DOMAIN_XML_INACTIVE)) { + p = virXPathStringLimit(conn, "string(./seclabel/imagelabel[1])", + VIR_SECURITY_LABEL_BUFLEN-1, ctxt); + if (p == NULL) + goto error; + def->seclabel.imagelabel = p; + } return 0; @@ -2458,7 +2487,7 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn, VIR_FREE(nodes); /* analysis of security label */ - if (virSecurityLabelDefParseXML(conn, def, ctxt) == -1) + if (virSecurityLabelDefParseXML(conn, def, ctxt, flags) == -1) goto error; return def; @@ -3480,9 +3509,25 @@ char *virDomainDefFormat(virConnectPtr conn, virBufferAddLit(&buf, " \n"); if (def->seclabel.model) { - virBufferEscapeString(&buf, " \n", def->seclabel.model); - virBufferEscapeString(&buf, " \n", def->seclabel.label); - virBufferAddLit(&buf, " \n"); + 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))) { + virBufferVSprintf(&buf, " \n", + sectype, def->seclabel.model); + } else { + virBufferVSprintf(&buf, " \n", + sectype, def->seclabel.model); + virBufferEscapeString(&buf, " \n", + def->seclabel.label); + if (def->seclabel.imagelabel && + def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) + virBufferEscapeString(&buf, " %s\n", + def->seclabel.imagelabel); + virBufferAddLit(&buf, " \n"); + } } virBufferAddLit(&buf, "\n"); diff --git a/src/domain_conf.h b/src/domain_conf.h index fe83e0b19a..dd614678c6 100644 --- a/src/domain_conf.h +++ b/src/domain_conf.h @@ -410,6 +410,13 @@ struct _virDomainOSDef { char *bootloaderArgs; }; +enum virDomainSeclabelType { + VIR_DOMAIN_SECLABEL_DYNAMIC, + VIR_DOMAIN_SECLABEL_STATIC, + + VIR_DOMAIN_SECLABEL_LAST, +}; + /* Security configuration for domain */ typedef struct _virSecurityLabelDef virSecurityLabelDef; typedef virSecurityLabelDef *virSecurityLabelDefPtr; @@ -417,6 +424,7 @@ struct _virSecurityLabelDef { char *model; /* name of security model */ char *label; /* security label string */ char *imagelabel; /* security image label string */ + int type; }; #define VIR_DOMAIN_CPUMASK_LEN 1024 @@ -650,5 +658,6 @@ VIR_ENUM_DECL(virDomainInputBus) VIR_ENUM_DECL(virDomainGraphics) /* from libvirt.h */ VIR_ENUM_DECL(virDomainState) +VIR_ENUM_DECL(virDomainSeclabel) #endif /* __DOMAIN_CONF_H */ diff --git a/src/qemu_driver.c b/src/qemu_driver.c index bb52db48b5..e73bd3aacc 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -1314,9 +1314,9 @@ static int qemudStartVMDaemon(virConnectPtr conn, hookData.vm = vm; hookData.driver = driver; - /* If you are using a SecurityDriver and there was no security label in - database, then generate a security label for isolation */ - if (vm->def->seclabel.label == NULL && + /* If you are using a SecurityDriver with dynamic labelling, + then generate a security label for isolation */ + if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC && driver->securityDriver && driver->securityDriver->domainGenSecurityLabel && driver->securityDriver->domainGenSecurityLabel(conn, vm) < 0) @@ -1525,6 +1525,13 @@ static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED, if (driver->securityDriver) driver->securityDriver->domainRestoreSecurityLabel(conn, vm); + /* 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 (qemudRemoveDomainStatus(conn, driver, vm) < 0) { VIR_WARN(_("Failed to remove domain status for %s"), vm->def->name);