]> xenbits.xensource.com Git - libvirt.git/commitdiff
security_dac: Lock metadata when running transaction
authorMichal Privoznik <mprivozn@redhat.com>
Fri, 7 Sep 2018 12:04:44 +0000 (14:04 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Tue, 18 Sep 2018 15:12:53 +0000 (17:12 +0200)
Lock all the paths we want to relabel to mutually exclude other
libvirt daemons.

The only 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@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
src/security/security_dac.c

index a628d63a52bb54826d6776d87ddbc34620424b6a..2dbaf29ff5654f95fd7302f2a1c9a509db2e168b 100644 (file)
@@ -192,7 +192,8 @@ static int virSecurityDACRestoreFileLabelInternal(virSecurityManagerPtr mgr,
  *
  * This is the callback that runs in the same namespace as the domain we are
  * relabelling. For given transaction (@opaque) it relabels all the paths on
- * the list.
+ * the list. Depending on security manager configuration it might lock paths
+ * we will relabel.
  *
  * Returns: 0 on success
  *         -1 otherwise.
@@ -202,8 +203,26 @@ virSecurityDACTransactionRun(pid_t pid ATTRIBUTE_UNUSED,
                              void *opaque)
 {
     virSecurityDACChownListPtr list = opaque;
+    const char **paths = NULL;
+    size_t npaths = 0;
     size_t i;
     int rv = 0;
+    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;
 
     for (i = 0; i < list->nItems; i++) {
         virSecurityDACChownItemPtr item = list->items[i];
@@ -222,10 +241,19 @@ virSecurityDACTransactionRun(pid_t pid ATTRIBUTE_UNUSED,
         }
 
         if (rv < 0)
-            return -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;
 }