[libvirt] [PATCHv3 17/26] security: selinux: Implement per-image seclabel set

Peter Krempa pkrempa at redhat.com
Wed Jun 25 16:55:01 UTC 2014


Refactor the code and reuse it to implement the functionality.
---
 src/security/security_selinux.c | 92 ++++++++++++++++++++++++-----------------
 1 file changed, 54 insertions(+), 38 deletions(-)

diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 7b534b2..97f91f7 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -56,9 +56,6 @@ VIR_LOG_INIT("security.security_selinux");
 typedef struct _virSecuritySELinuxData virSecuritySELinuxData;
 typedef virSecuritySELinuxData *virSecuritySELinuxDataPtr;

-typedef struct _virSecuritySELinuxCallbackData virSecuritySELinuxCallbackData;
-typedef virSecuritySELinuxCallbackData *virSecuritySELinuxCallbackDataPtr;
-
 struct _virSecuritySELinuxData {
     char *domain_context;
     char *alt_domain_context;
@@ -71,11 +68,6 @@ struct _virSecuritySELinuxData {
 #endif
 };

-struct _virSecuritySELinuxCallbackData {
-    virSecurityManagerPtr manager;
-    virSecurityLabelDefPtr secdef;
-};
-
 #define SECURITY_SELINUX_VOID_DOI       "0"
 #define SECURITY_SELINUX_NAME "selinux"

@@ -1199,40 +1191,50 @@ virSecuritySELinuxRestoreSecurityImageLabel(virSecurityManagerPtr mgr,


 static int
-virSecuritySELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
-                                       const char *path,
-                                       size_t depth,
-                                       void *opaque)
+virSecuritySELinuxSetSecurityImageLabelInternal(virSecurityManagerPtr mgr,
+                                                virDomainDefPtr def,
+                                                virStorageSourcePtr src,
+                                                bool first)
 {
-    int ret;
+    virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
+    virSecurityLabelDefPtr secdef;
     virSecurityDeviceLabelDefPtr disk_seclabel;
-    virSecuritySELinuxCallbackDataPtr cbdata = opaque;
-    virSecurityLabelDefPtr secdef = cbdata->secdef;
-    virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(cbdata->manager);
+    int ret;
+
+    if (!src->path ||
+        virStorageSourceGetActualType(src) == VIR_STORAGE_TYPE_NETWORK)
+        return 0;
+
+    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+    if (!secdef || secdef->norelabel)
+        return 0;

-    disk_seclabel = virStorageSourceGetSecurityLabelDef(disk->src,
+    disk_seclabel = virStorageSourceGetSecurityLabelDef(src,
                                                         SECURITY_SELINUX_NAME);

     if (disk_seclabel && disk_seclabel->norelabel)
         return 0;

-    if (disk_seclabel && !disk_seclabel->norelabel &&
-        disk_seclabel->label) {
-        ret = virSecuritySELinuxSetFilecon(path, disk_seclabel->label);
-    } else if (depth == 0) {
-
-        if (disk->src->shared) {
-            ret = virSecuritySELinuxSetFileconOptional(path, data->file_context);
-        } else if (disk->src->readonly) {
-            ret = virSecuritySELinuxSetFileconOptional(path, data->content_context);
+    if (disk_seclabel && !disk_seclabel->norelabel && disk_seclabel->label) {
+        ret = virSecuritySELinuxSetFilecon(src->path, disk_seclabel->label);
+    } else if (first) {
+        if (src->shared) {
+            ret = virSecuritySELinuxSetFileconOptional(src->path,
+                                                       data->file_context);
+        } else if (src->readonly) {
+            ret = virSecuritySELinuxSetFileconOptional(src->path,
+                                                       data->content_context);
         } else if (secdef->imagelabel) {
-            ret = virSecuritySELinuxSetFileconOptional(path, secdef->imagelabel);
+            ret = virSecuritySELinuxSetFileconOptional(src->path,
+                                                       secdef->imagelabel);
         } else {
             ret = 0;
         }
     } else {
-        ret = virSecuritySELinuxSetFileconOptional(path, data->content_context);
+        ret = virSecuritySELinuxSetFileconOptional(src->path,
+                                                   data->content_context);
     }
+
     if (ret == 1 && !disk_seclabel) {
         /* If we failed to set a label, but virt_use_nfs let us
          * proceed anyway, then we don't need to relabel later.  */
@@ -1240,35 +1242,48 @@ virSecuritySELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
         if (!disk_seclabel)
             return -1;
         disk_seclabel->labelskip = true;
-        if (VIR_APPEND_ELEMENT(disk->src->seclabels, disk->src->nseclabels,
+        if (VIR_APPEND_ELEMENT(src->seclabels, src->nseclabels,
                                disk_seclabel) < 0) {
             virSecurityDeviceLabelDefFree(disk_seclabel);
             return -1;
         }
         ret = 0;
     }
+
     return ret;
 }

+
+static int
+virSecuritySELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr,
+                                        virDomainDefPtr def,
+                                        virStorageSourcePtr src)
+{
+    return virSecuritySELinuxSetSecurityImageLabelInternal(mgr, def, src, true);
+}
+
+
 static int
 virSecuritySELinuxSetSecurityDiskLabel(virSecurityManagerPtr mgr,
                                        virDomainDefPtr def,
                                        virDomainDiskDefPtr disk)

 {
-    virSecuritySELinuxCallbackData cbdata;
-    cbdata.manager = mgr;
-    cbdata.secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+    bool first = true;
+    virStorageSourcePtr next;

-    if (!cbdata.secdef || cbdata.secdef->norelabel)
-        return 0;
+    for (next = disk->src; next; next = next->backingStore) {
+        if (virSecuritySELinuxSetSecurityImageLabelInternal(mgr, def, next,
+                                                            first) < 0)
+            return -1;

-    return virDomainDiskDefForeachPath(disk,
-                                       true,
-                                       virSecuritySELinuxSetSecurityFileLabel,
-                                       &cbdata);
+        first = false;
+    }
+
+    return 0;
 }

+
 static int
 virSecuritySELinuxSetSecurityHostdevLabelHelper(const char *file, void *opaque)
 {
@@ -2437,6 +2452,7 @@ virSecurityDriver virSecurityDriverSELinux = {
     .domainSetSecurityDiskLabel         = virSecuritySELinuxSetSecurityDiskLabel,
     .domainRestoreSecurityDiskLabel     = virSecuritySELinuxRestoreSecurityDiskLabel,

+    .domainSetSecurityImageLabel        = virSecuritySELinuxSetSecurityImageLabel,
     .domainRestoreSecurityImageLabel    = virSecuritySELinuxRestoreSecurityImageLabel,

     .domainSetSecurityDaemonSocketLabel = virSecuritySELinuxSetSecurityDaemonSocketLabel,
-- 
1.9.3




More information about the libvir-list mailing list