As libvirt gives guest minimal cgroup, we need to add sg into guest cgroup whitelist for scsi hostdev. And we should set and restore selinux label correctly for scsi hostdev. Signed-off-by: Han Cheng <hanc.fnst@xxxxxxxxxxxxxx> --- src/qemu/qemu_cgroup.c | 71 ++++++++++++++++++++++++++++++-------- src/qemu/qemu_cgroup.h | 3 ++ src/security/security_selinux.c | 56 ++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 15 deletions(-) diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 5aa9416..4f75cee 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -180,6 +180,30 @@ int qemuSetupHostUsbDeviceCgroup(virUSBDevicePtr dev ATTRIBUTE_UNUSED, return 0; } +int qemuSetupHostScsiDeviceCgroup(virSCSIDevicePtr dev, + const char *path, + void *opaque) +{ + qemuCgroupData *data = opaque; + int rc; + + VIR_DEBUG("Process path '%s' for SCSI device", path); + rc = virCgroupAllowDevicePath(data->cgroup, path, + virSCSIDeviceGetReadonly(dev) ? VIR_CGROUP_DEVICE_READ + : VIR_CGROUP_DEVICE_RW); + virDomainAuditCgroupPath(data->vm, data->cgroup, "allow", path, + virSCSIDeviceGetReadonly(dev) ? "r" : "rw", rc); + if (rc < 0) { + virReportSystemError(-rc, + _("Unable to allow device %s"), + path); + return -1; + } + + return 0; + +} + int qemuSetupCgroup(virQEMUDriverPtr driver, virDomainObjPtr vm, virBitmapPtr nodemask) @@ -277,26 +301,43 @@ int qemuSetupCgroup(virQEMUDriverPtr driver, for (i = 0; i < vm->def->nhostdevs; i++) { virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i]; - virUSBDevicePtr usb; + virUSBDevicePtr usb = NULL; + virSCSIDevicePtr scsi = NULL; if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) continue; - if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) - continue; - if (hostdev->missing) - continue; + switch (hostdev->source.subsys.type) { + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: + if (hostdev->missing) + continue; - if ((usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus, - hostdev->source.subsys.u.usb.device, - NULL)) == NULL) - goto cleanup; + if ((usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus, + hostdev->source.subsys.u.usb.device, + NULL)) == NULL) + goto cleanup; - if (virUSBDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup, - &data) < 0) { + if (virUSBDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup, + &data) < 0) { + goto cleanup; + } virUSBDeviceFree(usb); - goto cleanup; + break; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: + if ((scsi = virSCSIDeviceNew(hostdev->source.subsys.u.scsi.adapter, + hostdev->source.subsys.u.scsi.bus, + hostdev->source.subsys.u.scsi.target, + hostdev->source.subsys.u.scsi.unit, + hostdev->readonly))== NULL) + goto cleanup; + + if (virSCSIDeviceFileIterate(scsi, qemuSetupHostScsiDeviceCgroup, + &data) < 0) { + virSCSIDeviceFree(scsi); + goto cleanup; + } + virSCSIDeviceFree(scsi); + break; } - virUSBDeviceFree(usb); } } diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h index a677d07..72ed66a 100644 --- a/src/qemu/qemu_cgroup.h +++ b/src/qemu/qemu_cgroup.h @@ -45,6 +45,9 @@ int qemuTeardownDiskCgroup(virDomainObjPtr vm, int qemuSetupHostUsbDeviceCgroup(virUSBDevicePtr dev, const char *path, void *opaque); +int qemuSetupHostScsiDeviceCgroup(virSCSIDevicePtr dev, + const char *path, + void *opaque); int qemuSetupCgroup(virQEMUDriverPtr driver, virDomainObjPtr vm, virBitmapPtr nodemask); diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 60596ad..8b5ddc9 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -39,6 +39,7 @@ #include "virlog.h" #include "virpci.h" #include "virusb.h" +#include "virscsi.h" #include "virstoragefile.h" #include "virfile.h" #include "virhash.h" @@ -1200,6 +1201,18 @@ virSecuritySELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr, &cbdata); } +static int +virSecuritySELinuxSetSecuritySCSILabel(virSCSIDevicePtr dev ATTRIBUTE_UNUSED, + const char *file, void *opaque) +{ + virSecurityLabelDefPtr secdef; + virDomainDefPtr def = opaque; + + secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME); + if (secdef == NULL) + return -1; + return virSecuritySELinuxSetFilecon(file, secdef->imagelabel); +} static int virSecuritySELinuxSetSecurityPCILabel(virPCIDevicePtr dev ATTRIBUTE_UNUSED, @@ -1271,6 +1284,23 @@ virSecuritySELinuxSetSecurityHostdevSubsysLabel(virDomainDefPtr def, break; } + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: { + virSCSIDevicePtr scsi = + virSCSIDeviceNew(dev->source.subsys.u.scsi.adapter, + dev->source.subsys.u.scsi.bus, + dev->source.subsys.u.scsi.target, + dev->source.subsys.u.scsi.unit, + dev->readonly); + + if (!scsi) + goto done; + + ret = virSCSIDeviceFileIterate(scsi, virSecuritySELinuxSetSecuritySCSILabel, def); + virSCSIDeviceFree(scsi); + + break; + } + default: ret = 0; break; @@ -1368,6 +1398,15 @@ virSecuritySELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UN } } +static int +virSecuritySELinuxRestoreSecuritySCSILabel(virSCSIDevicePtr dev ATTRIBUTE_UNUSED, + const char *file, + void *opaque) +{ + virSecurityManagerPtr mgr = opaque; + + return virSecuritySELinuxRestoreSecurityFileLabel(mgr, file); +} static int virSecuritySELinuxRestoreSecurityPCILabel(virPCIDevicePtr dev ATTRIBUTE_UNUSED, @@ -1433,6 +1472,23 @@ virSecuritySELinuxRestoreSecurityHostdevSubsysLabel(virSecurityManagerPtr mgr, break; } + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: { + virSCSIDevicePtr scsi = + virSCSIDeviceNew(dev->source.subsys.u.scsi.adapter, + dev->source.subsys.u.scsi.bus, + dev->source.subsys.u.scsi.target, + dev->source.subsys.u.scsi.unit, + dev->readonly); + + if (!scsi) + goto done; + + ret = virSCSIDeviceFileIterate(scsi, virSecuritySELinuxRestoreSecuritySCSILabel, mgr); + virSCSIDeviceFree(scsi); + + break; + } + default: ret = 0; break; -- 1.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list