void virDomainChrDefFree(virDomainChrDefPtr def)
{
+ size_t i;
+
if (!def)
return;
virDomainChrSourceDefClear(&def->source);
virDomainDeviceInfoClear(&def->info);
+ if (def->seclabels) {
+ for (i = 0; i < def->nseclabels; i++)
+ virSecurityDeviceLabelDefFree(def->seclabels[i]);
+ VIR_FREE(def->seclabels);
+ }
+
VIR_FREE(def);
}
* <target>, which is used by <serial> but not <smartcard>). */
static int
virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
- xmlNodePtr cur, unsigned int flags)
+ xmlNodePtr cur, unsigned int flags,
+ virDomainChrDefPtr chr_def,
+ xmlXPathContextPtr ctxt,
+ virSecurityLabelDefPtr* vmSeclabels,
+ int nvmSeclabels)
{
char *bindHost = NULL;
char *bindService = NULL;
if (def->type == VIR_DOMAIN_CHR_TYPE_UDP)
VIR_FREE(mode);
}
+
+ /* Check for an optional seclabel override in <source/>. */
+ if (chr_def) {
+ xmlNodePtr saved_node = ctxt->node;
+ ctxt->node = cur;
+ if (virSecurityDeviceLabelDefParseXML(&chr_def->seclabels,
+ &chr_def->nseclabels,
+ vmSeclabels,
+ nvmSeclabels,
+ ctxt) < 0) {
+ ctxt->node = saved_node;
+ goto error;
+ }
+ ctxt->node = saved_node;
+ }
} else if (xmlStrEqual(cur->name, BAD_CAST "protocol")) {
if (protocol == NULL)
protocol = virXMLPropString(cur, "type");
static virDomainChrDefPtr
virDomainChrDefParseXML(virCapsPtr caps,
virDomainDefPtr vmdef,
+ xmlXPathContextPtr ctxt,
xmlNodePtr node,
+ virSecurityLabelDefPtr* vmSeclabels,
+ int nvmSeclabels,
unsigned int flags)
{
xmlNodePtr cur;
}
cur = node->children;
- remaining = virDomainChrSourceDefParseXML(&def->source, cur, flags);
+ remaining = virDomainChrSourceDefParseXML(&def->source, cur, flags,
+ def, ctxt,
+ vmSeclabels, nvmSeclabels);
if (remaining < 0)
goto error;
if (remaining) {
}
cur = node->children;
- if (virDomainChrSourceDefParseXML(&def->data.passthru, cur, flags) < 0)
+ if (virDomainChrSourceDefParseXML(&def->data.passthru, cur, flags,
+ NULL, NULL, NULL, 0) < 0)
goto error;
if (def->data.passthru.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) {
if (xmlStrEqual(cur->name, BAD_CAST "source")) {
int remaining;
- remaining = virDomainChrSourceDefParseXML(&def->source.chr, cur, flags);
+ remaining = virDomainChrSourceDefParseXML(&def->source.chr, cur, flags,
+ NULL, NULL, NULL, 0);
if (remaining != 0)
goto error;
}
for (i = 0 ; i < n ; i++) {
virDomainChrDefPtr chr = virDomainChrDefParseXML(caps,
def,
+ ctxt,
nodes[i],
+ def->seclabels,
+ def->nseclabels,
flags);
if (!chr)
goto error;
for (i = 0 ; i < n ; i++) {
virDomainChrDefPtr chr = virDomainChrDefParseXML(caps,
def,
+ ctxt,
nodes[i],
+ def->seclabels,
+ def->nseclabels,
flags);
if (!chr)
goto error;
bool create_stub = true;
virDomainChrDefPtr chr = virDomainChrDefParseXML(caps,
def,
+ ctxt,
nodes[i],
+ def->seclabels,
+ def->nseclabels,
flags);
if (!chr)
goto error;
for (i = 0 ; i < n ; i++) {
virDomainChrDefPtr chr = virDomainChrDefParseXML(caps,
def,
+ ctxt,
nodes[i],
+ def->seclabels,
+ def->nseclabels,
flags);
if (!chr)
goto error;
const char *targetType = virDomainChrTargetTypeToString(def->deviceType,
def->targetType);
bool tty_compat;
+ size_t n;
int ret = 0;
return -1;
}
+ /* Security label overrides, if any. */
+ if (def->seclabels && def->nseclabels > 0) {
+ virBufferAdjustIndent(buf, 2);
+ for (n = 0; n < def->nseclabels; n++)
+ virSecurityDeviceLabelDefFormat(buf, def->seclabels[n]);
+ virBufferAdjustIndent(buf, -2);
+ }
+
virBufferAsprintf(buf, " </%s>\n", elementName);
return ret;
return NULL;
}
+virSecurityDeviceLabelDefPtr
+virDomainChrDefGetSecurityLabelDef(virDomainChrDefPtr def, const char *model)
+{
+ int i;
+
+ if (def == NULL)
+ return NULL;
+
+ for (i = 0; i < def->nseclabels; i++) {
+ if (STREQ_NULLABLE(def->seclabels[i]->model, model))
+ return def->seclabels[i];
+ }
+ return NULL;
+}
+
virSecurityLabelDefPtr
virDomainDefAddSecurityLabelDef(virDomainDefPtr def, const char *model)
{
static int
virSecuritySELinuxSetSecurityChardevLabel(virDomainDefPtr def,
- virDomainChrSourceDefPtr dev)
+ virDomainChrDefPtr dev,
+ virDomainChrSourceDefPtr dev_source)
{
- virSecurityLabelDefPtr secdef;
+ virSecurityLabelDefPtr seclabel;
+ virSecurityDeviceLabelDefPtr chr_seclabel = NULL;
+ char *imagelabel = NULL;
char *in = NULL, *out = NULL;
int ret = -1;
- secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
- if (secdef == NULL)
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (seclabel == NULL)
return -1;
- if (secdef->norelabel)
+ if (dev)
+ chr_seclabel = virDomainChrDefGetSecurityLabelDef(dev,
+ SECURITY_SELINUX_NAME);
+
+ if (seclabel->norelabel || (chr_seclabel && chr_seclabel->norelabel))
return 0;
- switch (dev->type) {
+ if (chr_seclabel)
+ imagelabel = chr_seclabel->label;
+ if (!imagelabel)
+ imagelabel = seclabel->imagelabel;
+
+ switch (dev_source->type) {
case VIR_DOMAIN_CHR_TYPE_DEV:
case VIR_DOMAIN_CHR_TYPE_FILE:
- ret = virSecuritySELinuxSetFilecon(dev->data.file.path, secdef->imagelabel);
+ ret = virSecuritySELinuxSetFilecon(dev_source->data.file.path,
+ imagelabel);
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_UNIX:
+ if (!dev_source->data.nix.listen) {
+ if (virSecuritySELinuxSetFilecon(dev_source->data.file.path,
+ imagelabel) < 0)
+ goto done;
+ }
+ ret = 0;
break;
case VIR_DOMAIN_CHR_TYPE_PIPE:
- if ((virAsprintf(&in, "%s.in", dev->data.file.path) < 0) ||
- (virAsprintf(&out, "%s.out", dev->data.file.path) < 0)) {
+ if ((virAsprintf(&in, "%s.in", dev_source->data.file.path) < 0) ||
+ (virAsprintf(&out, "%s.out", dev_source->data.file.path) < 0)) {
virReportOOMError();
goto done;
}
if (virFileExists(in) && virFileExists(out)) {
- if ((virSecuritySELinuxSetFilecon(in, secdef->imagelabel) < 0) ||
- (virSecuritySELinuxSetFilecon(out, secdef->imagelabel) < 0)) {
+ if ((virSecuritySELinuxSetFilecon(in, imagelabel) < 0) ||
+ (virSecuritySELinuxSetFilecon(out, imagelabel) < 0)) {
goto done;
}
- } else if (virSecuritySELinuxSetFilecon(dev->data.file.path, secdef->imagelabel) < 0) {
+ } else if (virSecuritySELinuxSetFilecon(dev_source->data.file.path,
+ imagelabel) < 0) {
goto done;
}
ret = 0;
static int
virSecuritySELinuxRestoreSecurityChardevLabel(virDomainDefPtr def,
- virDomainChrSourceDefPtr dev)
+ virDomainChrDefPtr dev,
+ virDomainChrSourceDefPtr dev_source)
{
- virSecurityLabelDefPtr secdef;
+ virSecurityLabelDefPtr seclabel;
+ virSecurityDeviceLabelDefPtr chr_seclabel = NULL;
char *in = NULL, *out = NULL;
int ret = -1;
- secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
- if (secdef == NULL)
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (seclabel == NULL)
return -1;
- if (secdef->norelabel)
+ if (dev)
+ chr_seclabel = virDomainChrDefGetSecurityLabelDef(dev,
+ SECURITY_SELINUX_NAME);
+ if (seclabel->norelabel || (chr_seclabel && chr_seclabel->norelabel))
return 0;
- switch (dev->type) {
+ switch (dev_source->type) {
case VIR_DOMAIN_CHR_TYPE_DEV:
case VIR_DOMAIN_CHR_TYPE_FILE:
- if (virSecuritySELinuxRestoreSecurityFileLabel(dev->data.file.path) < 0)
+ if (virSecuritySELinuxRestoreSecurityFileLabel(dev_source->data.file.path) < 0)
goto done;
ret = 0;
break;
+
+ case VIR_DOMAIN_CHR_TYPE_UNIX:
+ if (!dev_source->data.nix.listen) {
+ if (virSecuritySELinuxRestoreSecurityFileLabel(dev_source->data.file.path) < 0)
+ goto done;
+ }
+ ret = 0;
+ break;
+
case VIR_DOMAIN_CHR_TYPE_PIPE:
- if ((virAsprintf(&out, "%s.out", dev->data.file.path) < 0) ||
- (virAsprintf(&in, "%s.in", dev->data.file.path) < 0)) {
+ if ((virAsprintf(&out, "%s.out", dev_source->data.file.path) < 0) ||
+ (virAsprintf(&in, "%s.in", dev_source->data.file.path) < 0)) {
virReportOOMError();
goto done;
}
(virSecuritySELinuxRestoreSecurityFileLabel(in) < 0)) {
goto done;
}
- } else if (virSecuritySELinuxRestoreSecurityFileLabel(dev->data.file.path) < 0) {
+ } else if (virSecuritySELinuxRestoreSecurityFileLabel(dev_source->data.file.path) < 0) {
goto done;
}
ret = 0;
dev->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL)
return 0;
- return virSecuritySELinuxRestoreSecurityChardevLabel(def, &dev->source);
+ return virSecuritySELinuxRestoreSecurityChardevLabel(def, dev,
+ &dev->source);
}
return virSecuritySELinuxRestoreSecurityFileLabel(database);
case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
- return virSecuritySELinuxRestoreSecurityChardevLabel(def, &dev->data.passthru);
+ return virSecuritySELinuxRestoreSecurityChardevLabel(def, NULL, &dev->data.passthru);
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
dev->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL)
return 0;
- return virSecuritySELinuxSetSecurityChardevLabel(def, &dev->source);
+ return virSecuritySELinuxSetSecurityChardevLabel(def, dev, &dev->source);
}
return virSecuritySELinuxSetFilecon(database, data->content_context);
case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
- return virSecuritySELinuxSetSecurityChardevLabel(def, &dev->data.passthru);
+ return virSecuritySELinuxSetSecurityChardevLabel(def, NULL, &dev->data.passthru);
default:
virReportError(VIR_ERR_INTERNAL_ERROR,