[libvirt] [PATCH v2 32/39] virSecuritySELinuxRestoreImageLabelInt: Don't skip non-local storage

Michal Privoznik mprivozn at redhat.com
Thu Sep 26 16:12:28 UTC 2019


This function is currently not called for any type of storage
source that is not considered 'local' (as defined by
virStorageSourceIsLocalStorage()). Well, NVMe disks are not
'local' from that point of view and therefore we will need to
call this function more frequently.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/security/security_apparmor.c | 33 +++++++++++++++-------
 src/security/security_dac.c      | 30 ++++++++++++++++++++
 src/security/security_selinux.c  | 48 +++++++++++++++++++++++++++-----
 3 files changed, 94 insertions(+), 17 deletions(-)

diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 77eee9410c..580cd72223 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -803,22 +803,35 @@ AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr,
 {
     int rc = -1;
     char *profile_name = NULL;
+    VIR_AUTOFREE(char *) vfioGroupDev = NULL;
+    const char *path = NULL;
     virSecurityLabelDefPtr secdef;
 
-    if (!src->path || !virStorageSourceIsLocalStorage(src))
-        return 0;
-
     secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
     if (!secdef || !secdef->relabel)
         return 0;
 
     if (secdef->imagelabel) {
-        /* if the device doesn't exist, error out */
-        if (!virFileExists(src->path)) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("\'%s\' does not exist"),
-                           src->path);
-            return -1;
+        if (src->type == VIR_STORAGE_TYPE_NVME) {
+            const virStorageSourceNVMeDef *nvme = src->nvme;
+
+            if (!(vfioGroupDev = virPCIDeviceAddressGetIOMMUGroupDev(&nvme->pciAddr)))
+                return -1;
+
+            path = vfioGroupDev;
+        } else {
+            if (!src->path || !virStorageSourceIsLocalStorage(src))
+                return 0;
+
+            /* if the device doesn't exist, error out */
+            if (!virFileExists(src->path)) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("\'%s\' does not exist"),
+                               src->path);
+                return -1;
+            }
+
+            path = src->path;
         }
 
         if ((profile_name = get_profile_name(def)) == NULL)
@@ -827,7 +840,7 @@ AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr,
         /* update the profile only if it is loaded */
         if (profile_loaded(secdef->imagelabel) >= 0) {
             if (load_profile(mgr, secdef->imagelabel, def,
-                             src->path, false) < 0) {
+                             path, false) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("cannot update AppArmor profile "
                                  "\'%s\'"),
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 4b4afef18a..42d585500d 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -915,6 +915,19 @@ virSecurityDACSetImageLabelInternal(virSecurityManagerPtr mgr,
             return -1;
     }
 
+    /* This is not very clean. But so far we don't have NVMe
+     * storage pool backend so that its chownCallback would be
+     * called. And this place looks least offensive. */
+    if (src->type == VIR_STORAGE_TYPE_NVME) {
+        const virStorageSourceNVMeDef *nvme = src->nvme;
+        VIR_AUTOFREE(char *) vfioGroupDev = NULL;
+
+        if (!(vfioGroupDev = virPCIDeviceAddressGetIOMMUGroupDev(&nvme->pciAddr)))
+            return -1;
+
+        return virSecurityDACSetOwnership(mgr, NULL, vfioGroupDev, user, group, false);
+    }
+
     /* We can't do restore on shared resources safely. Not even
      * with refcounting implemented in XATTRs because if there
      * was a domain running with the feature turned off the
@@ -1004,6 +1017,23 @@ virSecurityDACRestoreImageLabelInt(virSecurityManagerPtr mgr,
         }
     }
 
+    /* This is not very clean. But so far we don't have NVMe
+     * storage pool backend so that its chownCallback would be
+     * called. And this place looks least offensive. */
+    if (src->type == VIR_STORAGE_TYPE_NVME) {
+        const virStorageSourceNVMeDef *nvme = src->nvme;
+        VIR_AUTOFREE(char *) vfioGroupDev = NULL;
+
+        if (!(vfioGroupDev = virPCIDeviceAddressGetIOMMUGroupDev(&nvme->pciAddr)))
+            return -1;
+
+        /* Ideally, we would check if there is not another PCI
+         * device within domain def that is in the same IOMMU
+         * group. But we're not doing that for hostdevs yet. */
+
+        return virSecurityDACRestoreFileLabelInternal(mgr, NULL, vfioGroupDev, false);
+    }
+
     return virSecurityDACRestoreFileLabelInternal(mgr, src, NULL, true);
 }
 
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 3a00666d26..f439ecec46 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1754,9 +1754,8 @@ virSecuritySELinuxRestoreImageLabelInt(virSecurityManagerPtr mgr,
 {
     virSecurityLabelDefPtr seclabel;
     virSecurityDeviceLabelDefPtr disk_seclabel;
-
-    if (!src->path || !virStorageSourceIsLocalStorage(src))
-        return 0;
+    VIR_AUTOFREE(char *) vfioGroupDev = NULL;
+    const char *path = src->path;
 
     seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
     if (seclabel == NULL)
@@ -1788,9 +1787,16 @@ virSecuritySELinuxRestoreImageLabelInt(virSecurityManagerPtr mgr,
      * ownership, because that kills access on the destination host which is
      * sub-optimal for the guest VM's I/O attempts :-) */
     if (migrated) {
-        int rc = virFileIsSharedFS(src->path);
-        if (rc < 0)
-            return -1;
+        int rc = 1;
+
+        if (virStorageSourceIsLocalStorage(src)) {
+            if (!src->path)
+                return 0;
+
+            if ((rc = virFileIsSharedFS(src->path)) < 0)
+                return -1;
+        }
+
         if (rc == 1) {
             VIR_DEBUG("Skipping image label restore on %s because FS is shared",
                       src->path);
@@ -1798,7 +1804,22 @@ virSecuritySELinuxRestoreImageLabelInt(virSecurityManagerPtr mgr,
         }
     }
 
-    return virSecuritySELinuxRestoreFileLabel(mgr, src->path, true);
+    /* This is not very clean. But so far we don't have NVMe
+     * storage pool backend so that its chownCallback would be
+     * called. And this place looks least offensive. */
+    if (src->type == VIR_STORAGE_TYPE_NVME) {
+        const virStorageSourceNVMeDef *nvme = src->nvme;
+
+        if (!(vfioGroupDev = virPCIDeviceAddressGetIOMMUGroupDev(&nvme->pciAddr)))
+            return -1;
+
+        /* Ideally, we would check if there is not another PCI
+         * device within domain def that is in the same IOMMU
+         * group. But we're not doing that for hostdevs yet. */
+        path = vfioGroupDev;
+    }
+
+    return virSecuritySELinuxRestoreFileLabel(mgr, path, true);
 }
 
 
@@ -1823,6 +1844,7 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
     virSecurityDeviceLabelDefPtr disk_seclabel;
     virSecurityDeviceLabelDefPtr parent_seclabel = NULL;
     bool remember;
+    VIR_AUTOFREE(char *) vfioGroupDev = NULL;
     const char *path = src->path;
     const char *tcon = NULL;
     int ret = -1;
@@ -1878,6 +1900,18 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
         tcon = data->content_context;
     }
 
+    /* This is not very clean. But so far we don't have NVMe
+     * storage pool backend so that its chownCallback would be
+     * called. And this place looks least offensive. */
+    if (src->type == VIR_STORAGE_TYPE_NVME) {
+        const virStorageSourceNVMeDef *nvme = src->nvme;
+
+        if (!(vfioGroupDev = virPCIDeviceAddressGetIOMMUGroupDev(&nvme->pciAddr)))
+            return -1;
+
+        path = vfioGroupDev;
+    }
+
     ret = virSecuritySELinuxSetFilecon(mgr, path, tcon, remember);
 
     if (ret == 1 && !disk_seclabel) {
-- 
2.21.0




More information about the libvir-list mailing list