[libvirt] [PATCH 12/17] security: Wire up virUdevMgr

Michal Privoznik mprivozn at redhat.com
Wed Oct 26 12:36:59 UTC 2016


Whenever a security driver wants to change label of some path, it
should let virUdevMgr module know so that it can update its
internal database too.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/libvirt_private.syms        |  2 ++
 src/security/security_dac.c     | 36 ++++++++++++++++++++++++++++---
 src/security/security_manager.c | 16 ++++++++++++++
 src/security/security_manager.h |  5 +++++
 src/security/security_selinux.c | 47 ++++++++++++++++++++++++++++++++++++++---
 5 files changed, 100 insertions(+), 6 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a0de4e9..66df1f7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1143,6 +1143,7 @@ virSecurityManagerGetModel;
 virSecurityManagerGetMountOptions;
 virSecurityManagerGetNested;
 virSecurityManagerGetProcessLabel;
+virSecurityManagerGetUdevManager;
 virSecurityManagerNew;
 virSecurityManagerNewDAC;
 virSecurityManagerNewStack;
@@ -1167,6 +1168,7 @@ virSecurityManagerSetProcessLabel;
 virSecurityManagerSetSavedStateLabel;
 virSecurityManagerSetSocketLabel;
 virSecurityManagerSetTapFDLabel;
+virSecurityManagerSetUdevManager;
 virSecurityManagerStackAddNested;
 virSecurityManagerVerify;
 
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 7f17124..54e59c7 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -356,7 +356,11 @@ virSecurityDACSetOwnership(virSecurityManagerPtr mgr,
                            gid_t gid)
 {
     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+    virUdevMgrPtr udevMgr = virSecurityManagerGetUdevManager(mgr);
+    virSecurityDeviceLabelDefPtr seclabel = NULL;
+    char *label = NULL;
     struct stat sb;
+    int ret = -1;
 
     if (!path && src && src->path &&
         virStorageSourceIsLocalStorage(src))
@@ -365,14 +369,36 @@ virSecurityDACSetOwnership(virSecurityManagerPtr mgr,
     if (path) {
         if (stat(path, &sb) < 0) {
             virReportSystemError(errno, _("unable to stat: %s"), path);
-            return -1;
+            return ret;
         }
 
         if (virSecurityDACRememberLabel(priv, path, sb.st_uid, sb.st_gid) < 0)
-            return -1;
+            return ret;
+
+        if (udevMgr) {
+            if (virAsprintf(&label, "%u %u",
+                            (unsigned int) uid,
+                            (unsigned int) gid) < 0)
+                goto cleanup;
+
+            if (!(seclabel = virSecurityDeviceLabelDefNewLabel(SECURITY_DAC_NAME, label)))
+                goto cleanup;
+            VIR_FREE(label);
+        }
     }
 
-    return virSecurityDACSetOwnershipInternal(priv, src, path, uid, gid);
+    if (virSecurityDACSetOwnershipInternal(priv, src, path, uid, gid) < 0)
+        goto cleanup;
+
+    if (udevMgr && path &&
+        virUdevMgrAddLabel(udevMgr, path, seclabel) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    VIR_FREE(label);
+    virSecurityDeviceLabelDefFree(seclabel);
+    return ret;
 }
 
 
@@ -382,6 +408,7 @@ virSecurityDACRestoreFileLabelInternal(virSecurityManagerPtr mgr,
                                        const char *path)
 {
     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+    virUdevMgrPtr udevMgr = virSecurityManagerGetUdevManager(mgr);
     int rv;
     uid_t uid = 0;  /* By default return to root:root */
     gid_t gid = 0;
@@ -399,6 +426,9 @@ virSecurityDACRestoreFileLabelInternal(virSecurityManagerPtr mgr,
             return -1;
         if (rv > 0)
             return 0;
+
+        if (udevMgr)
+            virUdevMgrRemoveAllLabels(udevMgr, path);
     }
 
     return virSecurityDACSetOwnershipInternal(priv, src, path, uid, gid);
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
index ecb4a40..2f07d6a 100644
--- a/src/security/security_manager.c
+++ b/src/security/security_manager.c
@@ -39,6 +39,7 @@ struct _virSecurityManager {
     virSecurityDriverPtr drv;
     unsigned int flags;
     const char *virtDriver;
+    virUdevMgrPtr udevMgr;
     void *privateData;
 };
 
@@ -1001,3 +1002,18 @@ virSecurityManagerDomainSetPathLabel(virSecurityManagerPtr mgr,
 
     return 0;
 }
+
+
+void
+virSecurityManagerSetUdevManager(virSecurityManagerPtr mgr,
+                                 virUdevMgrPtr udevMgr)
+{
+    mgr->udevMgr = virObjectRef(udevMgr);
+}
+
+
+virUdevMgrPtr
+virSecurityManagerGetUdevManager(virSecurityManagerPtr mgr)
+{
+    return mgr->udevMgr;
+}
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
index 4cbc2d8..8f565f7 100644
--- a/src/security/security_manager.h
+++ b/src/security/security_manager.h
@@ -26,6 +26,7 @@
 # include "domain_conf.h"
 # include "vircommand.h"
 # include "virstoragefile.h"
+# include "virudev.h"
 
 typedef struct _virSecurityManager virSecurityManager;
 typedef virSecurityManager *virSecurityManagerPtr;
@@ -164,4 +165,8 @@ int virSecurityManagerDomainSetPathLabel(virSecurityManagerPtr mgr,
                                          virDomainDefPtr vm,
                                          const char *path);
 
+void virSecurityManagerSetUdevManager(virSecurityManagerPtr mgr,
+                                      virUdevMgrPtr udevMgr);
+virUdevMgrPtr virSecurityManagerGetUdevManager(virSecurityManagerPtr mgr);
+
 #endif /* VIR_SECURITY_MANAGER_H__ */
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 5dad22c..c85f500 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -947,7 +947,24 @@ virSecuritySELinuxSetFileconOptional(virSecurityManagerPtr mgr,
                                      const char *path, char *tcon)
 {
     bool privileged = virSecurityManagerGetPrivileged(mgr);
-    return virSecuritySELinuxSetFileconHelper(path, tcon, true, privileged);
+    virUdevMgrPtr udevMgr = virSecurityManagerGetUdevManager(mgr);
+    virSecurityDeviceLabelDefPtr seclabel = NULL;
+    int rc;
+
+    if (udevMgr &&
+        !(seclabel = virSecurityDeviceLabelDefNewLabel(SECURITY_SELINUX_NAME, tcon)))
+        return -1;
+
+    rc = virSecuritySELinuxSetFileconHelper(path, tcon, true, privileged);
+
+    if (udevMgr &&
+        virUdevMgrAddLabel(udevMgr, path, seclabel) < 0) {
+        virSecurityDeviceLabelDefFree(seclabel);
+        return -1;
+    }
+
+    virSecurityDeviceLabelDefFree(seclabel);
+    return rc;
 }
 
 static int
@@ -955,7 +972,24 @@ virSecuritySELinuxSetFilecon(virSecurityManagerPtr mgr,
                              const char *path, char *tcon)
 {
     bool privileged = virSecurityManagerGetPrivileged(mgr);
-    return virSecuritySELinuxSetFileconHelper(path, tcon, false, privileged);
+    virUdevMgrPtr udevMgr = virSecurityManagerGetUdevManager(mgr);
+    virSecurityDeviceLabelDefPtr seclabel = NULL;
+    int rc;
+
+    if (udevMgr &&
+        !(seclabel = virSecurityDeviceLabelDefNewLabel(SECURITY_SELINUX_NAME, tcon)))
+        return -1;
+
+    rc = virSecuritySELinuxSetFileconHelper(path, tcon, false, privileged);
+
+    if (udevMgr &&
+        virUdevMgrAddLabel(udevMgr, path, seclabel) < 0) {
+        virSecurityDeviceLabelDefFree(seclabel);
+        return -1;
+    }
+
+    virSecurityDeviceLabelDefFree(seclabel);
+    return rc;
 }
 
 static int
@@ -1018,6 +1052,8 @@ static int
 virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr,
                                    const char *path)
 {
+    virUdevMgrPtr udevMgr = virSecurityManagerGetUdevManager(mgr);
+    bool privileged = virSecurityManagerGetPrivileged(mgr);
     struct stat buf;
     security_context_t fcon = NULL;
     int rc = -1;
@@ -1038,6 +1074,11 @@ virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr,
         goto err;
     }
 
+    if (udevMgr) {
+        virUdevMgrRemoveAllLabels(udevMgr, path);
+        virUdevMgrRemoveAllLabels(udevMgr, newpath);
+    }
+
     if (stat(newpath, &buf) != 0) {
         VIR_WARN("cannot stat %s: %s", newpath,
                  virStrerror(errno, ebuf, sizeof(ebuf)));
@@ -1051,7 +1092,7 @@ virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr,
         VIR_WARN("cannot lookup default selinux label for %s", newpath);
         rc = 0;
     } else {
-        rc = virSecuritySELinuxSetFilecon(mgr, newpath, fcon);
+        rc = virSecuritySELinuxSetFileconHelper(newpath, fcon, false, privileged);
     }
 
  err:
-- 
2.8.4




More information about the libvir-list mailing list