#define SECURITY_SELINUX_VOID_DOI "0"
#define SECURITY_SELINUX_NAME "selinux"
+/* Data structure to pass to *FileIterate so we have everything we need */
+struct SELinuxSCSICallbackData {
+ virSecurityManagerPtr mgr;
+ virDomainDefPtr def;
+};
+
static int
virSecuritySELinuxRestoreSecurityTPMFileLabelInt(virSecurityManagerPtr mgr,
virDomainDefPtr def,
!src->backingStore)
return 0;
- /* Don't restore labels on readoly/shared disks, because other VMs may
+ /* Don't restore labels on readonly/shared disks, because other VMs may
* still be accessing these. Alternatively we could iterate over all
* running domains and try to figure out if it is in use, but this would
* not work for clustered filesystems, since we can't see running VMs using
}
static int
-virSecuritySELinuxSetSecuritySCSILabel(virSCSIDevicePtr dev ATTRIBUTE_UNUSED,
+virSecuritySELinuxSetSecuritySCSILabel(virSCSIDevicePtr dev,
const char *file, void *opaque)
{
- return virSecuritySELinuxSetSecurityHostdevLabelHelper(file, opaque);
+ virSecurityLabelDefPtr secdef;
+ struct SELinuxSCSICallbackData *ptr = opaque;
+ virSecurityManagerPtr mgr = ptr->mgr;
+ virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
+
+ secdef = virDomainDefGetSecurityLabelDef(ptr->def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return 0;
+
+ if (virSCSIDeviceGetShareable(dev))
+ return virSecuritySELinuxSetFileconOptional(file,
+ data->file_context);
+ else if (virSCSIDeviceGetReadonly(dev))
+ return virSecuritySELinuxSetFileconOptional(file,
+ data->content_context);
+ else
+ return virSecuritySELinuxSetFileconOptional(file, secdef->imagelabel);
}
static int
-virSecuritySELinuxSetSecurityHostdevSubsysLabel(virDomainDefPtr def,
+virSecuritySELinuxSetSecurityHostdevSubsysLabel(virSecurityManagerPtr mgr,
+ virDomainDefPtr def,
virDomainHostdevDefPtr dev,
const char *vroot)
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
+ struct SELinuxSCSICallbackData data = {.mgr = mgr, .def = def};
+
virSCSIDevicePtr scsi =
virSCSIDeviceNew(NULL,
scsihostsrc->adapter, scsihostsrc->bus,
if (!scsi)
goto done;
- ret = virSCSIDeviceFileIterate(scsi, virSecuritySELinuxSetSecuritySCSILabel, def);
+ ret = virSCSIDeviceFileIterate(scsi,
+ virSecuritySELinuxSetSecuritySCSILabel,
+ &data);
virSCSIDeviceFree(scsi);
break;
static int
-virSecuritySELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+virSecuritySELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
virDomainHostdevDefPtr dev,
const char *vroot)
switch (dev->mode) {
case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS:
- return virSecuritySELinuxSetSecurityHostdevSubsysLabel(def, dev, vroot);
+ return virSecuritySELinuxSetSecurityHostdevSubsysLabel(mgr, def,
+ dev, vroot);
case VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES:
return virSecuritySELinuxSetSecurityHostdevCapsLabel(def, dev, vroot);
static int
-virSecuritySELinuxRestoreSecuritySCSILabel(virSCSIDevicePtr dev ATTRIBUTE_UNUSED,
+virSecuritySELinuxRestoreSecuritySCSILabel(virSCSIDevicePtr dev,
const char *file,
void *opaque)
{
virSecurityManagerPtr mgr = opaque;
+ /* Don't restore labels on a shareable or readonly hostdev, because
+ * other VMs may still be accessing.
+ */
+ if (virSCSIDeviceGetShareable(dev) || virSCSIDeviceGetReadonly(dev))
+ return 0;
+
return virSecuritySELinuxRestoreSecurityFileLabel(mgr, file);
}