char *tcon;
bool remember; /* Whether owner remembering should be done for @path/@src */
bool restore; /* Whether current operation is 'set' or 'restore' */
+ bool is_shared; /* @path is shared, so don't use fallback restore path */
};
typedef struct _virSecuritySELinuxContextList virSecuritySELinuxContextList;
const char *path,
const char *tcon,
bool remember,
- bool restore)
+ bool restore,
+ bool is_shared)
{
virSecuritySELinuxContextItem *item = NULL;
item->remember = remember;
item->restore = restore;
+ item->is_shared = is_shared;
VIR_APPEND_ELEMENT(list->items, list->nItems, item);
virSecuritySELinuxTransactionAppend(const char *path,
const char *tcon,
bool remember,
- bool restore)
+ bool restore,
+ bool is_shared)
{
virSecuritySELinuxContextList *list;
return 0;
if (virSecuritySELinuxContextListAppend(list, path, tcon,
- remember, restore) < 0)
+ remember, restore, is_shared) < 0)
return -1;
return 1;
static int virSecuritySELinuxRestoreFileLabel(virSecurityManager *mgr,
const char *path,
- bool recall);
+ bool recall,
+ bool is_shared);
/**
} else {
rv = virSecuritySELinuxRestoreFileLabel(list->manager,
item->path,
- remember);
+ remember,
+ item->is_shared);
}
if (rv < 0)
if (!item->restore) {
virSecuritySELinuxRestoreFileLabel(list->manager,
item->path,
- remember);
+ remember,
+ item->is_shared);
} else {
VIR_WARN("Ignoring failed restore attempt on %s", item->path);
}
int ret = -1;
if ((rc = virSecuritySELinuxTransactionAppend(path, tcon,
- remember, false)) < 0)
+ remember, false, false)) < 0)
return -1;
else if (rc > 0)
return 0;
* this function. However, if our attempt fails, there's
* not much we can do. XATTRs refcounting is fubar'ed and
* the only option we have is warn users. */
- if (virSecuritySELinuxRestoreFileLabel(mgr, path, remember) < 0)
+ if (virSecuritySELinuxRestoreFileLabel(mgr, path, remember, false) < 0)
VIR_WARN("Unable to restore label on '%s'. "
"XATTRs might have been left in inconsistent state.",
path);
static int
virSecuritySELinuxRestoreFileLabel(virSecurityManager *mgr,
const char *path,
- bool recall)
+ bool recall,
+ bool is_shared)
{
bool privileged = virSecurityManagerGetPrivileged(mgr);
struct stat buf;
}
if ((rc = virSecuritySELinuxTransactionAppend(path, NULL,
- recall, true)) < 0) {
+ recall, true,
+ is_shared)) < 0) {
return -1;
} else if (rc > 0) {
return 0;
}
if (!recall || rc == -2) {
+ /* if path is marked as shared (eg. using label virt_content_t),
+ * skip fallback labelling, which has race conditions with multiple
+ * VM startup: https://issues.redhat.com/browse/RHEL-126945
+ */
+ if (is_shared)
+ return 0;
+
if (stat(newpath, &buf) != 0) {
VIR_WARN("cannot stat %s: %s", newpath,
g_strerror(errno));
switch ((virDomainInputType)input->type) {
case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH:
case VIR_DOMAIN_INPUT_TYPE_EVDEV:
- return virSecuritySELinuxRestoreFileLabel(mgr, input->source.evdev, true);
+ return virSecuritySELinuxRestoreFileLabel(mgr, input->source.evdev, true, false);
case VIR_DOMAIN_INPUT_TYPE_MOUSE:
case VIR_DOMAIN_INPUT_TYPE_TABLET:
path = mem->source.virtio_pmem.path;
break;
case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
- ret = virSecuritySELinuxRestoreFileLabel(mgr, DEV_SGX_VEPC, true);
- if (virSecuritySELinuxRestoreFileLabel(mgr, DEV_SGX_PROVISION, true) < 0)
+ ret = virSecuritySELinuxRestoreFileLabel(mgr, DEV_SGX_VEPC, true, false);
+ if (virSecuritySELinuxRestoreFileLabel(mgr, DEV_SGX_PROVISION, true, false) < 0)
ret = -1;
return ret;
if (!path)
return 0;
- return virSecuritySELinuxRestoreFileLabel(mgr, path, true);
+ return virSecuritySELinuxRestoreFileLabel(mgr, path, true, false);
}
switch (tpm->type) {
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
tpmdev = tpm->data.passthrough.source->data.file.path;
- rc = virSecuritySELinuxRestoreFileLabel(mgr, tpmdev, false);
+ rc = virSecuritySELinuxRestoreFileLabel(mgr, tpmdev, false, false);
if ((cancel_path = virTPMCreateCancelPath(tpmdev)) != NULL) {
- if (virSecuritySELinuxRestoreFileLabel(mgr, cancel_path, false) < 0)
+ if (virSecuritySELinuxRestoreFileLabel(mgr, cancel_path, false, false) < 0)
rc = -1;
}
break;
path = vfioGroupDev;
}
- return virSecuritySELinuxRestoreFileLabel(mgr, path, true);
+ return virSecuritySELinuxRestoreFileLabel(mgr, path, true, false);
}
{
virSecurityManager *mgr = opaque;
- return virSecuritySELinuxRestoreFileLabel(mgr, file, true);
+ return virSecuritySELinuxRestoreFileLabel(mgr, file, true, false);
}
static int
{
virSecurityManager *mgr = opaque;
- return virSecuritySELinuxRestoreFileLabel(mgr, file, true);
+ return virSecuritySELinuxRestoreFileLabel(mgr, file, true, false);
}
if (virSCSIDeviceGetShareable(dev) || virSCSIDeviceGetReadonly(dev))
return 0;
- return virSecuritySELinuxRestoreFileLabel(mgr, file, true);
+ return virSecuritySELinuxRestoreFileLabel(mgr, file, true, false);
}
static int
{
virSecurityManager *mgr = opaque;
- return virSecuritySELinuxRestoreFileLabel(mgr, file, true);
+ return virSecuritySELinuxRestoreFileLabel(mgr, file, true, false);
}
if (!vfioGroupDev)
return -1;
- ret = virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false);
+ ret = virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false);
} else {
ret = virPCIDeviceFileIterate(pci, virSecuritySELinuxRestorePCILabel, mgr);
}
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
return -1;
- ret = virSecuritySELinuxRestoreFileLabel(mgr, vfiodev, false);
+ ret = virSecuritySELinuxRestoreFileLabel(mgr, vfiodev, false, false);
break;
}
} else {
path = g_strdup(dev->source.caps.u.storage.block);
}
- ret = virSecuritySELinuxRestoreFileLabel(mgr, path, true);
+ ret = virSecuritySELinuxRestoreFileLabel(mgr, path, true, false);
break;
}
} else {
path = g_strdup(dev->source.caps.u.misc.chardev);
}
- ret = virSecuritySELinuxRestoreFileLabel(mgr, path, true);
+ ret = virSecuritySELinuxRestoreFileLabel(mgr, path, true, false);
break;
}
if (!secdef || !secdef->relabel)
return 0;
- return virSecuritySELinuxRestoreFileLabel(mgr, savefile, false);
+ return virSecuritySELinuxRestoreFileLabel(mgr, savefile, false, false);
}
case VIR_DOMAIN_CHR_TYPE_FILE:
if (virSecuritySELinuxRestoreFileLabel(mgr,
dev_source->data.file.path,
- true) < 0)
+ true,
+ false) < 0)
return -1;
break;
if (!dev_source->data.nix.listen) {
if (virSecuritySELinuxRestoreFileLabel(mgr,
dev_source->data.nix.path,
- true) < 0)
+ true,
+ false) < 0)
return -1;
}
g_autofree char *out = g_strdup_printf("%s.out", dev_source->data.file.path);
g_autofree char *in = g_strdup_printf("%s.in", dev_source->data.file.path);
if (virFileExists(in) && virFileExists(out)) {
- if ((virSecuritySELinuxRestoreFileLabel(mgr, out, true) < 0) ||
- (virSecuritySELinuxRestoreFileLabel(mgr, in, true) < 0))
+ if ((virSecuritySELinuxRestoreFileLabel(mgr, out, true, false) < 0) ||
+ (virSecuritySELinuxRestoreFileLabel(mgr, in, true, false) < 0))
return -1;
} else {
if (virSecuritySELinuxRestoreFileLabel(mgr,
dev_source->data.file.path,
- true) < 0)
+ true,
+ false) < 0)
return -1;
}
}
database = dev->data.cert.database;
if (!database)
database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
- return virSecuritySELinuxRestoreFileLabel(mgr, database, true);
+ return virSecuritySELinuxRestoreFileLabel(mgr, database, true, false);
case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
return virSecuritySELinuxRestoreChardevLabel(mgr, def,
virSysinfoFWCfgDef *f = &def->fw_cfgs[i];
if (f->file &&
- virSecuritySELinuxRestoreFileLabel(mgr, f->file, true) < 0)
+ virSecuritySELinuxRestoreFileLabel(mgr, f->file, true, false) < 0)
return -1;
}
}
if (def->os.kernel &&
- virSecuritySELinuxRestoreFileLabel(mgr, def->os.kernel, true) < 0)
+ virSecuritySELinuxRestoreFileLabel(mgr, def->os.kernel, true, false) < 0)
rc = -1;
if (def->os.initrd &&
- virSecuritySELinuxRestoreFileLabel(mgr, def->os.initrd, true) < 0)
+ virSecuritySELinuxRestoreFileLabel(mgr, def->os.initrd, true, false) < 0)
rc = -1;
if (def->os.shim &&
- virSecuritySELinuxRestoreFileLabel(mgr, def->os.shim, true) < 0)
+ virSecuritySELinuxRestoreFileLabel(mgr, def->os.shim, true, false) < 0)
rc = -1;
if (def->os.dtb &&
- virSecuritySELinuxRestoreFileLabel(mgr, def->os.dtb, true) < 0)
+ virSecuritySELinuxRestoreFileLabel(mgr, def->os.dtb, true, false) < 0)
rc = -1;
for (i = 0; i < def->os.nacpiTables; i++) {
- if (virSecuritySELinuxRestoreFileLabel(mgr, def->os.acpiTables[i]->path, true) < 0)
+ if (virSecuritySELinuxRestoreFileLabel(mgr, def->os.acpiTables[i]->path, true, false) < 0)
rc = -1;
}
if (def->pstore &&
- virSecuritySELinuxRestoreFileLabel(mgr, def->pstore->path, true) < 0)
+ virSecuritySELinuxRestoreFileLabel(mgr, def->pstore->path, true, false) < 0)
rc = -1;
return rc;
if (!secdef || !secdef->relabel)
return 0;
- return virSecuritySELinuxRestoreFileLabel(mgr, path, true);
+ return virSecuritySELinuxRestoreFileLabel(mgr, path, true, false);
}
struct dirent *ent;
g_autoptr(DIR) dir = NULL;
- if ((ret = virSecuritySELinuxRestoreFileLabel(mgr, path, true)))
+ if ((ret = virSecuritySELinuxRestoreFileLabel(mgr, path, true, false)))
return ret;
if (!virFileIsDir(path))
while ((ret = virDirRead(dir, &ent, path)) > 0) {
g_autofree char *filename = g_strdup_printf("%s/%s", path, ent->d_name);
- ret = virSecuritySELinuxRestoreFileLabel(mgr, filename, true);
+ ret = virSecuritySELinuxRestoreFileLabel(mgr, filename, true, false);
if (ret < 0)
break;
}