From dbf1f68410e0cfd327ea0895ef1dd2bf297f4bf7 Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Mon, 27 Jan 2020 15:23:21 -0300 Subject: [PATCH] security: do not remember/recall labels for VFIO Files inside /dev/vfio/ can't be opened more than once, meaning that any subsequent open calls will fail. This behavior was introduced in kernel v3.11, commit 6d6768c61b39. When using the VFIO driver, we open a FD to /dev/vfio/N and pass it to QEMU. If any other call attempt for the same /dev/vfio/N happens while QEMU is still using the file, we are unable to open it and QEMU will report -EBUSY. This can happen if we hotplug a PCI hostdev that belongs to the same IOMMU group of an existing domain hostdev. The problem and solution is similar to what we already dealt with for TPM in commit 4e95cdcbb3. This patch changes both DAC and SELinux drivers to disable 'remember' for VFIO hostdevs in virSecurityDACSetHostdevLabelHelper() and virSecurityDACSetHostdevLabel(), and 'recall' in virSecurityDACRestoreHostdevLabel() and virSecuritySELinuxRestoreHostdevSubsysLabel(). Signed-off-by: Daniel Henrique Barboza Reviewed-by: Michal Privoznik --- src/security/security_dac.c | 7 +++++-- src/security/security_selinux.c | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/security/security_dac.c b/src/security/security_dac.c index b456c59a02..216fe93a56 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1263,7 +1263,9 @@ virSecurityDACSetHostdevLabel(virSecurityManagerPtr mgr, virPCIDeviceFree(pci); return -1; } - ret = virSecurityDACSetPCILabel(pci, vfioGroupDev, &cbdata); + ret = virSecurityDACSetHostdevLabelHelper(vfioGroupDev, + false, + &cbdata); VIR_FREE(vfioGroupDev); } else { ret = virPCIDeviceFileIterate(pci, @@ -1430,7 +1432,8 @@ virSecurityDACRestoreHostdevLabel(virSecurityManagerPtr mgr, virPCIDeviceFree(pci); return -1; } - ret = virSecurityDACRestorePCILabel(pci, vfioGroupDev, mgr); + ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL, + vfioGroupDev, false); VIR_FREE(vfioGroupDev); } else { ret = virPCIDeviceFileIterate(pci, virSecurityDACRestorePCILabel, mgr); diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 86acc0a33f..ce46df09da 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2118,7 +2118,9 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManagerPtr mgr, virPCIDeviceFree(pci); return -1; } - ret = virSecuritySELinuxSetPCILabel(pci, vfioGroupDev, &data); + ret = virSecuritySELinuxSetHostdevLabelHelper(vfioGroupDev, + false, + &data); VIR_FREE(vfioGroupDev); } else { ret = virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCILabel, &data); @@ -2356,7 +2358,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManagerPtr mgr, virPCIDeviceFree(pci); return -1; } - ret = virSecuritySELinuxRestorePCILabel(pci, vfioGroupDev, mgr); + ret = virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false); VIR_FREE(vfioGroupDev); } else { ret = virPCIDeviceFileIterate(pci, virSecuritySELinuxRestorePCILabel, mgr);