1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-01-12 13:17:58 +03:00

security: Manage SELinux labels on shared/readonly hostdev's

https://bugzilla.redhat.com/show_bug.cgi?id=1082521

Support for shared hostdev's was added in a number of commits, initially
starting with 'f2c1d9a80' and most recently commit id 'fd243fc4' to fix
issues with the initial implementation.  Missed in all those changes was
the need to mimic the virSELinux{Set|Restore}SecurityDiskLabel code to
handle the "shared" (or shareable) and readonly options when Setting
or Restoring the SELinux labels.

This patch will adjust the virSecuritySELinuxSetSecuritySCSILabel to not
use the virSecuritySELinuxSetSecurityHostdevLabelHelper in order to set
the label. Rather follow what the Disk code does by setting the label
differently based on whether shareable/readonly is set.  This patch will
also modify the virSecuritySELinuxRestoreSecuritySCSILabel to follow
the same logic as virSecuritySELinuxRestoreSecurityImageLabelInt and not
restore the label if shared/readonly
This commit is contained in:
John Ferlan 2014-11-26 12:35:46 -05:00
parent 048237e3db
commit f36d9285cd

View File

@ -71,6 +71,12 @@ struct _virSecuritySELinuxData {
#define SECURITY_SELINUX_VOID_DOI "0" #define SECURITY_SELINUX_VOID_DOI "0"
#define SECURITY_SELINUX_NAME "selinux" #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 static int
virSecuritySELinuxRestoreSecurityTPMFileLabelInt(virSecurityManagerPtr mgr, virSecuritySELinuxRestoreSecurityTPMFileLabelInt(virSecurityManagerPtr mgr,
virDomainDefPtr def, virDomainDefPtr def,
@ -1143,7 +1149,7 @@ virSecuritySELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
!src->backingStore) !src->backingStore)
return 0; 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 * 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 * 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 * not work for clustered filesystems, since we can't see running VMs using
@ -1309,14 +1315,31 @@ virSecuritySELinuxSetSecurityUSBLabel(virUSBDevicePtr dev ATTRIBUTE_UNUSED,
} }
static int static int
virSecuritySELinuxSetSecuritySCSILabel(virSCSIDevicePtr dev ATTRIBUTE_UNUSED, virSecuritySELinuxSetSecuritySCSILabel(virSCSIDevicePtr dev,
const char *file, void *opaque) 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 static int
virSecuritySELinuxSetSecurityHostdevSubsysLabel(virDomainDefPtr def, virSecuritySELinuxSetSecurityHostdevSubsysLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
virDomainHostdevDefPtr dev, virDomainHostdevDefPtr dev,
const char *vroot) const char *vroot)
@ -1377,6 +1400,8 @@ virSecuritySELinuxSetSecurityHostdevSubsysLabel(virDomainDefPtr def,
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host; virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
struct SELinuxSCSICallbackData data = {.mgr = mgr, .def = def};
virSCSIDevicePtr scsi = virSCSIDevicePtr scsi =
virSCSIDeviceNew(NULL, virSCSIDeviceNew(NULL,
scsihostsrc->adapter, scsihostsrc->bus, scsihostsrc->adapter, scsihostsrc->bus,
@ -1386,7 +1411,9 @@ virSecuritySELinuxSetSecurityHostdevSubsysLabel(virDomainDefPtr def,
if (!scsi) if (!scsi)
goto done; goto done;
ret = virSCSIDeviceFileIterate(scsi, virSecuritySELinuxSetSecuritySCSILabel, def); ret = virSCSIDeviceFileIterate(scsi,
virSecuritySELinuxSetSecuritySCSILabel,
&data);
virSCSIDeviceFree(scsi); virSCSIDeviceFree(scsi);
break; break;
@ -1454,7 +1481,7 @@ virSecuritySELinuxSetSecurityHostdevCapsLabel(virDomainDefPtr def,
static int static int
virSecuritySELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virSecuritySELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def, virDomainDefPtr def,
virDomainHostdevDefPtr dev, virDomainHostdevDefPtr dev,
const char *vroot) const char *vroot)
@ -1468,7 +1495,8 @@ virSecuritySELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UN
switch (dev->mode) { switch (dev->mode) {
case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS: case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS:
return virSecuritySELinuxSetSecurityHostdevSubsysLabel(def, dev, vroot); return virSecuritySELinuxSetSecurityHostdevSubsysLabel(mgr, def,
dev, vroot);
case VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES: case VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES:
return virSecuritySELinuxSetSecurityHostdevCapsLabel(def, dev, vroot); return virSecuritySELinuxSetSecurityHostdevCapsLabel(def, dev, vroot);
@ -1500,12 +1528,18 @@ virSecuritySELinuxRestoreSecurityUSBLabel(virUSBDevicePtr dev ATTRIBUTE_UNUSED,
static int static int
virSecuritySELinuxRestoreSecuritySCSILabel(virSCSIDevicePtr dev ATTRIBUTE_UNUSED, virSecuritySELinuxRestoreSecuritySCSILabel(virSCSIDevicePtr dev,
const char *file, const char *file,
void *opaque) void *opaque)
{ {
virSecurityManagerPtr mgr = 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); return virSecuritySELinuxRestoreSecurityFileLabel(mgr, file);
} }