[PATCHv2 4/5] security: add security part for shmem device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A new api to help set/restore the shmem device
label.

Signed-off-by: Luyao Huang <lhuang@xxxxxxxxxx>
---
 src/libvirt_private.syms        |   2 +
 src/security/security_dac.c     | 100 ++++++++++++++++++++++++++++++++++++++++
 src/security/security_driver.h  |   9 ++++
 src/security/security_manager.c |  35 ++++++++++++++
 src/security/security_manager.h |   6 +++
 src/security/security_nop.c     |  19 ++++++++
 src/security/security_selinux.c |  97 ++++++++++++++++++++++++++++++++++++++
 src/security/security_stack.c   |  39 ++++++++++++++++
 8 files changed, 307 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e25ef6b..620bd17 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1046,6 +1046,7 @@ virSecurityManagerRestoreDiskLabel;
 virSecurityManagerRestoreHostdevLabel;
 virSecurityManagerRestoreImageLabel;
 virSecurityManagerRestoreSavedStateLabel;
+virSecurityManagerRestoreShmemLabel;
 virSecurityManagerSetAllLabel;
 virSecurityManagerSetChildProcessLabel;
 virSecurityManagerSetDaemonSocketLabel;
@@ -1056,6 +1057,7 @@ virSecurityManagerSetImageFDLabel;
 virSecurityManagerSetImageLabel;
 virSecurityManagerSetProcessLabel;
 virSecurityManagerSetSavedStateLabel;
+virSecurityManagerSetShmemLabel;
 virSecurityManagerSetSocketLabel;
 virSecurityManagerSetTapFDLabel;
 virSecurityManagerStackAddNested;
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 864d75b..a6b4035 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -39,6 +39,7 @@
 #include "virstoragefile.h"
 #include "virstring.h"
 #include "virutil.h"
+#include "virshm.h"
 
 #define VIR_FROM_THIS VIR_FROM_SECURITY
 
@@ -930,6 +931,94 @@ virSecurityDACRestoreSecurityTPMFileLabel(virSecurityManagerPtr mgr,
 
 
 static int
+virSecurityDACSetShmemLabel(virSecurityManagerPtr mgr,
+                            virDomainDefPtr def,
+                            virDomainShmemDefPtr shmem)
+{
+    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+    virSecurityLabelDefPtr seclabel = NULL;
+    virSecurityDeviceLabelDefPtr shmem_seclabel = NULL;
+    char *tmppath = NULL;
+    uid_t user;
+    gid_t group;
+
+    if (!priv->dynamicOwnership)
+        return 0;
+
+    seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+    if (seclabel && !seclabel->relabel)
+        return 0;
+
+    shmem_seclabel = virDomainShmemDefGetSecurityLabelDef(shmem,
+                                                          SECURITY_DAC_NAME);
+    if (shmem_seclabel && !shmem_seclabel->relabel)
+        return 0;
+
+    if (shmem_seclabel && shmem_seclabel->label) {
+        if (virParseOwnershipIds(shmem_seclabel->label, &user, &group) < 0)
+            return -1;
+    } else {
+        if (virSecurityDACGetIds(seclabel, priv, &user, &group, NULL, NULL) < 0)
+            return -1;
+    }
+
+    if (shmem->server.enabled)
+        return virSecurityDACSetOwnership(shmem->server.chr.data.nix.path,
+                                          user, group);
+
+    if (virShmBuildPath(shmem->name, &tmppath) < 0)
+        return -1;
+
+    if (virSecurityDACSetOwnership(tmppath, user, group) < 0) {
+        VIR_FREE(tmppath);
+        return -1;
+    }
+    VIR_FREE(tmppath);
+    return 0;
+}
+
+
+static int
+virSecurityDACRestoreShmemLabel(virSecurityManagerPtr mgr,
+                               virDomainDefPtr def,
+                               virDomainShmemDefPtr shmem)
+{
+    virSecurityDeviceLabelDefPtr shmem_seclabel = NULL;
+    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+    virSecurityLabelDefPtr secdef = NULL;
+    char *tmppath = NULL;
+
+    if (!priv->dynamicOwnership)
+        return 0;
+
+    if (shmem->shareable)
+        return 0;
+
+    secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+    if (secdef && !secdef->relabel)
+        return 0;
+
+    shmem_seclabel = virDomainShmemDefGetSecurityLabelDef(shmem, SECURITY_DAC_NAME);
+
+    if (shmem_seclabel && !shmem_seclabel->relabel)
+        return 0;
+
+    if (shmem->server.enabled)
+        return virSecurityDACRestoreChardevLabel(mgr, def, NULL, &shmem->server.chr);
+
+    if (virShmBuildPath(shmem->name, &tmppath) < 0)
+        return -1;
+
+    if (virSecurityDACRestoreSecurityFileLabel(tmppath) < 0) {
+        VIR_FREE(tmppath);
+        return -1;
+    }
+    VIR_FREE(tmppath);
+    return 0;
+}
+
+
+static int
 virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
                                       virDomainDefPtr def,
                                       bool migrated)
@@ -961,6 +1050,10 @@ virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
                                                        migrated) < 0)
             rc = -1;
     }
+    for (i = 0; i < def->nshmems; i++) {
+        if (virSecurityDACRestoreShmemLabel(mgr, def, def->shmems[i]))
+            rc = -1;
+    }
 
     if (virDomainChrDefForeach(def,
                                false,
@@ -1038,6 +1131,10 @@ virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
                                                   NULL) < 0)
             return -1;
     }
+    for (i = 0; i < def->nshmems; i++) {
+        if (virSecurityDACSetShmemLabel(mgr, def, def->shmems[i]))
+            return -1;
+    }
 
     if (virDomainChrDefForeach(def,
                                true,
@@ -1461,4 +1558,7 @@ virSecurityDriver virSecurityDriverDAC = {
     .getBaseLabel                       = virSecurityDACGetBaseLabel,
 
     .domainSetDirLabel                  = virSecurityDACDomainSetDirLabel,
+
+    .domainSetSecurityShmemLabel        = virSecurityDACSetShmemLabel,
+    .domainRestoreSecurityShmemLabel    = virSecurityDACRestoreShmemLabel,
 };
diff --git a/src/security/security_driver.h b/src/security/security_driver.h
index 784b0de..9fab688 100644
--- a/src/security/security_driver.h
+++ b/src/security/security_driver.h
@@ -121,6 +121,12 @@ typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityManagerPtr mgr,
 typedef int (*virSecurityDomainSetDirLabel) (virSecurityManagerPtr mgr,
                                              virDomainDefPtr def,
                                              const char *path);
+typedef int (*virSecurityDomainSetShmemLabel) (virSecurityManagerPtr mgr,
+                                               virDomainDefPtr def,
+                                               virDomainShmemDefPtr shmem);
+typedef int (*virSecurityDomainRestoreShmemLabel) (virSecurityManagerPtr mgr,
+                                                   virDomainDefPtr def,
+                                                   virDomainShmemDefPtr shmem);
 
 
 struct _virSecurityDriver {
@@ -173,6 +179,9 @@ struct _virSecurityDriver {
     virSecurityDriverGetBaseLabel getBaseLabel;
 
     virSecurityDomainSetDirLabel domainSetDirLabel;
+
+    virSecurityDomainSetShmemLabel domainSetSecurityShmemLabel;
+    virSecurityDomainRestoreShmemLabel domainRestoreSecurityShmemLabel;
 };
 
 virSecurityDriverPtr virSecurityDriverLookup(const char *name,
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
index 1098558..fec73ec 100644
--- a/src/security/security_manager.c
+++ b/src/security/security_manager.c
@@ -1008,3 +1008,38 @@ virSecurityManagerDomainSetDirLabel(virSecurityManagerPtr mgr,
 
     return 0;
 }
+
+int
+virSecurityManagerRestoreShmemLabel(virSecurityManagerPtr mgr,
+                                    virDomainDefPtr vm,
+                                    virDomainShmemDefPtr shmem)
+{
+    if (mgr->drv->domainRestoreSecurityShmemLabel) {
+        int ret;
+        virObjectLock(mgr);
+        ret = mgr->drv->domainRestoreSecurityShmemLabel(mgr, vm, shmem);
+        virObjectUnlock(mgr);
+        return ret;
+    }
+
+    virReportUnsupportedError();
+    return -1;
+}
+
+
+int
+virSecurityManagerSetShmemLabel(virSecurityManagerPtr mgr,
+                                virDomainDefPtr vm,
+                                virDomainShmemDefPtr shmem)
+{
+    if (mgr->drv->domainSetSecurityShmemLabel) {
+        int ret;
+        virObjectLock(mgr);
+        ret = mgr->drv->domainSetSecurityShmemLabel(mgr, vm, shmem);
+        virObjectUnlock(mgr);
+        return ret;
+    }
+
+    virReportUnsupportedError();
+    return -1;
+}
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
index 78f34a0..c12e6e4 100644
--- a/src/security/security_manager.h
+++ b/src/security/security_manager.h
@@ -149,6 +149,12 @@ int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
 int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
                                         virDomainDefPtr vm,
                                         virStorageSourcePtr src);
+int virSecurityManagerRestoreShmemLabel(virSecurityManagerPtr mgr,
+                                        virDomainDefPtr vm,
+                                        virDomainShmemDefPtr shmem);
+int virSecurityManagerSetShmemLabel(virSecurityManagerPtr mgr,
+                                    virDomainDefPtr vm,
+                                    virDomainShmemDefPtr shmem);
 
 int virSecurityManagerDomainSetDirLabel(virSecurityManagerPtr mgr,
                                         virDomainDefPtr vm,
diff --git a/src/security/security_nop.c b/src/security/security_nop.c
index 951125d..fd786d7 100644
--- a/src/security/security_nop.c
+++ b/src/security/security_nop.c
@@ -236,6 +236,22 @@ virSecurityDomainSetImageLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
     return 0;
 }
 
+static int
+virSecuritySetShmemLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+                         virDomainDefPtr def ATTRIBUTE_UNUSED,
+                         virDomainShmemDefPtr shmem ATTRIBUTE_UNUSED)
+{
+    return 0;
+}
+
+static int
+virSecurityRestoreShmemLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+                             virDomainDefPtr def ATTRIBUTE_UNUSED,
+                             virDomainShmemDefPtr shmem ATTRIBUTE_UNUSED)
+{
+    return 0;
+}
+
 
 virSecurityDriver virSecurityDriverNop = {
     .privateDataLen                     = 0,
@@ -282,4 +298,7 @@ virSecurityDriver virSecurityDriverNop = {
     .domainGetSecurityMountOptions      = virSecurityDomainGetMountOptionsNop,
 
     .getBaseLabel                       = virSecurityGetBaseLabel,
+
+    .domainSetSecurityShmemLabel        = virSecuritySetShmemLabel,
+    .domainRestoreSecurityShmemLabel    = virSecurityRestoreShmemLabel,
 };
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index d2e5aa2..02495f8 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -46,6 +46,7 @@
 #include "virconf.h"
 #include "virtpm.h"
 #include "virstring.h"
+#include "virshm.h"
 
 #define VIR_FROM_THIS VIR_FROM_SECURITY
 
@@ -1888,6 +1889,46 @@ virSecuritySELinuxRestoreSecuritySmartcardCallback(virDomainDefPtr def,
 }
 
 
+static int
+virSecuritySELinuxRestoreShmemLabel(virSecurityManagerPtr mgr,
+                                    virDomainDefPtr def,
+                                    virDomainShmemDefPtr shmem)
+{
+    virSecurityLabelDefPtr seclabel;
+    virSecurityDeviceLabelDefPtr shmem_seclabel = NULL;
+
+    if (shmem->shareable)
+        return 0;
+
+    seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+    if (!seclabel || !seclabel->relabel)
+        return 0;
+
+    shmem_seclabel = virDomainShmemDefGetSecurityLabelDef(shmem,
+                                                          SECURITY_SELINUX_NAME);
+
+    if (shmem_seclabel && !shmem_seclabel->relabel)
+        return 0;
+
+    if (shmem->server.enabled) {
+        return virSecuritySELinuxRestoreSecurityFileLabel(mgr,
+                                              shmem->server.chr.data.nix.path);
+    } else {
+        char *tmppath = NULL;
+
+        if (virShmBuildPath(shmem->name, &tmppath) < 0)
+            return -1;
+
+        if (virSecuritySELinuxRestoreSecurityFileLabel(mgr, tmppath) < 0) {
+            VIR_FREE(tmppath);
+            return -1;
+        }
+        VIR_FREE(tmppath);
+        return 0;
+    }
+}
+
+
 static const char *
 virSecuritySELinuxGetBaseLabel(virSecurityManagerPtr mgr, int virtType)
 {
@@ -1936,6 +1977,10 @@ virSecuritySELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
                                                            migrated) < 0)
             rc = -1;
     }
+    for (i = 0; i < def->nshmems; i++) {
+        if (virSecuritySELinuxRestoreShmemLabel(mgr, def, def->shmems[i]) < 0)
+            rc = -1;
+    }
 
     if (virDomainChrDefForeach(def,
                                false,
@@ -2284,6 +2329,49 @@ virSecuritySELinuxSetSecuritySmartcardCallback(virDomainDefPtr def,
 
 
 static int
+virSecuritySELinuxSetShmemLabel(virSecurityManagerPtr mgr,
+                                virDomainDefPtr def,
+                                virDomainShmemDefPtr shmem)
+{
+    virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
+    char *imagelabel = NULL;
+    virSecurityLabelDefPtr seclabel;
+    virSecurityDeviceLabelDefPtr shmem_seclabel = NULL;
+
+    seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+    if (!seclabel || !seclabel->relabel)
+        return 0;
+
+    shmem_seclabel = virDomainShmemDefGetSecurityLabelDef(shmem, SECURITY_SELINUX_NAME);
+
+    if (shmem_seclabel && !shmem_seclabel->relabel)
+        return 0;
+
+    if (shmem_seclabel)
+        imagelabel = shmem_seclabel->label;
+    if (!imagelabel)
+        imagelabel = shmem->shareable ? data->file_context : seclabel->imagelabel;
+
+    if (shmem->server.enabled) {
+        return virSecuritySELinuxSetFilecon(shmem->server.chr.data.nix.path,
+                                            imagelabel);
+    } else {
+        char *tmppath = NULL;
+
+        if (virShmBuildPath(shmem->name, &tmppath) < 0)
+            return -1;
+
+        if (virSecuritySELinuxSetFilecon(tmppath, imagelabel) < 0) {
+            VIR_FREE(tmppath);
+            return -1;
+        }
+        VIR_FREE(tmppath);
+        return 0;
+    }
+}
+
+
+static int
 virSecuritySELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
                                       virDomainDefPtr def,
                                       const char *stdin_path)
@@ -2318,6 +2406,12 @@ virSecuritySELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
                                                       NULL) < 0)
             return -1;
     }
+
+    for (i = 0; i < def->nshmems; i++) {
+        if (virSecuritySELinuxSetShmemLabel(mgr, def, def->shmems[i]) < 0)
+            return -1;
+    }
+
     if (def->tpm) {
         if (virSecuritySELinuxSetSecurityTPMFileLabel(mgr, def,
                                                       def->tpm) < 0)
@@ -2565,4 +2659,7 @@ virSecurityDriver virSecurityDriverSELinux = {
     .getBaseLabel                       = virSecuritySELinuxGetBaseLabel,
 
     .domainSetDirLabel                  = virSecuritySELinuxDomainSetDirLabel,
+
+    .domainSetSecurityShmemLabel        = virSecuritySELinuxSetShmemLabel,
+    .domainRestoreSecurityShmemLabel    = virSecuritySELinuxRestoreShmemLabel,
 };
diff --git a/src/security/security_stack.c b/src/security/security_stack.c
index 8d9560d..cecde88 100644
--- a/src/security/security_stack.c
+++ b/src/security/security_stack.c
@@ -617,6 +617,42 @@ virSecurityStackDomainSetDirLabel(virSecurityManagerPtr mgr,
     return rc;
 }
 
+static int
+virSecurityStackSetShmemLabel(virSecurityManagerPtr mgr,
+                              virDomainDefPtr vm,
+                              virDomainShmemDefPtr shmem)
+{
+    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+    virSecurityStackItemPtr item = priv->itemsHead;
+    int rc = 0;
+
+    for (; item; item = item->next) {
+        if (virSecurityManagerSetShmemLabel(item->securityManager,
+                                            vm, shmem) < 0)
+            rc = -1;
+    }
+
+    return rc;
+}
+
+static int
+virSecurityStackRestoreShmemLabel(virSecurityManagerPtr mgr,
+                                  virDomainDefPtr vm,
+                                  virDomainShmemDefPtr shmem)
+{
+    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+    virSecurityStackItemPtr item = priv->itemsHead;
+    int rc = 0;
+
+    for (; item; item = item->next) {
+        if (virSecurityManagerRestoreShmemLabel(item->securityManager,
+                                                vm, shmem) < 0)
+            rc = -1;
+    }
+
+    return rc;
+}
+
 virSecurityDriver virSecurityDriverStack = {
     .privateDataLen                     = sizeof(virSecurityStackData),
     .name                               = "stack",
@@ -668,4 +704,7 @@ virSecurityDriver virSecurityDriverStack = {
     .getBaseLabel                       = virSecurityStackGetBaseLabel,
 
     .domainSetDirLabel                  = virSecurityStackDomainSetDirLabel,
+
+    .domainSetSecurityShmemLabel        = virSecurityStackSetShmemLabel,
+    .domainRestoreSecurityShmemLabel    = virSecurityStackRestoreShmemLabel,
 };
-- 
1.8.3.1

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]