[libvirt] [PATCH v4 19/23] security_dac: Lock metadata when running transaction

Michal Privoznik mprivozn at redhat.com
Mon Sep 10 09:36:20 UTC 2018


Lock all the paths we want to relabel to mutually exclude other
libvirt daemons.

The only culprit here hitch here is that directories can't be
locked. Therefore, when relabeling a directory do not lock it
(this happens only when setting up some domain private paths
anyway, e.g. huge pages directory).

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/security/security_dac.c | 37 ++++++++++++++++++++++++++++++++++---
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 414e226f0f..e8fd4a9132 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -202,8 +202,28 @@ virSecurityDACTransactionRun(pid_t pid ATTRIBUTE_UNUSED,
                              void *opaque)
 {
     virSecurityDACChownListPtr list = opaque;
+    const char **paths = NULL;
+    size_t npaths = 0;
     size_t i;
+    int rv;
+    int ret = -1;
 
+    if (VIR_ALLOC_N(paths, list->nItems) < 0)
+        return -1;
+
+    for (i = 0; i < list->nItems; i++) {
+        const char *p = list->items[i]->path;
+
+        if (virFileIsDir(p))
+            continue;
+
+        VIR_APPEND_ELEMENT_COPY_INPLACE(paths, npaths, p);
+    }
+
+    if (virSecurityManagerMetadataLock(list->manager, paths, npaths) < 0)
+        goto cleanup;
+
+    rv = 0;
     for (i = 0; i < list->nItems; i++) {
         virSecurityDACChownItemPtr item = list->items[i];
 
@@ -217,11 +237,22 @@ virSecurityDACTransactionRun(pid_t pid ATTRIBUTE_UNUSED,
             (item->restore &&
              virSecurityDACRestoreFileLabelInternal(list->manager,
                                                     item->src,
-                                                    item->path) < 0))
-            return -1;
+                                                    item->path) < 0)) {
+            rv = -1;
+            break;
+        }
     }
 
-    return 0;
+    if (virSecurityManagerMetadataUnlock(list->manager, paths, npaths) < 0)
+        goto cleanup;
+
+    if (rv < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    VIR_FREE(paths);
+    return ret;
 }
 
 
-- 
2.16.4




More information about the libvir-list mailing list