render / rpms / libvirt

Forked from rpms/libvirt 5 months ago
Clone
d76c62
From 157a222a2001e3d5df4851ea3f43a00873f82be1 Mon Sep 17 00:00:00 2001
d76c62
Message-Id: <157a222a2001e3d5df4851ea3f43a00873f82be1@dist-git>
d76c62
From: Michal Privoznik <mprivozn@redhat.com>
d76c62
Date: Tue, 25 Feb 2020 11:24:50 +0100
d76c62
Subject: [PATCH] virSecurityManagerMetadataLock: Store locked paths
d76c62
d76c62
So far, in the lock state we are storing only the file
d76c62
descriptors of the files we've locked. Therefore, when unlocking
d76c62
them and something does wrong the only thing we can report is FD
d76c62
number, which is not user friendly at all. But if we store paths
d76c62
among with FDs we can do better error reporting.
d76c62
d76c62
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
d76c62
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
d76c62
(cherry picked from commit 256e01e59e922ff70dce56284e53e3463d4dc072)
d76c62
d76c62
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1804672
d76c62
d76c62
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
d76c62
Message-Id: <8b12c9adde3c8553b4a2b588ac1a657d0638336b.1582626185.git.mprivozn@redhat.com>
d76c62
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
d76c62
---
d76c62
 src/security/security_manager.c | 21 +++++++++++++++------
d76c62
 1 file changed, 15 insertions(+), 6 deletions(-)
d76c62
d76c62
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
d76c62
index f229d94570..05d20e36af 100644
d76c62
--- a/src/security/security_manager.c
d76c62
+++ b/src/security/security_manager.c
d76c62
@@ -1246,8 +1246,9 @@ virSecurityManagerRestoreTPMLabels(virSecurityManagerPtr mgr,
d76c62
 
d76c62
 
d76c62
 struct _virSecurityManagerMetadataLockState {
d76c62
-    size_t nfds;
d76c62
+    size_t nfds; /* Captures size of both @fds and @paths */
d76c62
     int *fds;
d76c62
+    const char **paths;
d76c62
 };
d76c62
 
d76c62
 
d76c62
@@ -1278,6 +1279,7 @@ cmpstringp(const void *p1, const void *p2)
d76c62
  *
d76c62
  * Lock passed @paths for metadata change. The returned state
d76c62
  * should be passed to virSecurityManagerMetadataUnlock.
d76c62
+ * Passed @paths must not be freed until the corresponding unlock call.
d76c62
  *
d76c62
  * NOTE: this function is not thread safe (because of usage of
d76c62
  * POSIX locks).
d76c62
@@ -1293,9 +1295,11 @@ virSecurityManagerMetadataLock(virSecurityManagerPtr mgr G_GNUC_UNUSED,
d76c62
     size_t i = 0;
d76c62
     size_t nfds = 0;
d76c62
     int *fds = NULL;
d76c62
+    const char **locked_paths = NULL;
d76c62
     virSecurityManagerMetadataLockStatePtr ret = NULL;
d76c62
 
d76c62
-    if (VIR_ALLOC_N(fds, npaths) < 0)
d76c62
+    if (VIR_ALLOC_N(fds, npaths) < 0 ||
d76c62
+        VIR_ALLOC_N(locked_paths, npaths) < 0)
d76c62
         return NULL;
d76c62
 
d76c62
     /* Sort paths to lock in order to avoid deadlocks with other
d76c62
@@ -1372,12 +1376,14 @@ virSecurityManagerMetadataLock(virSecurityManagerPtr mgr G_GNUC_UNUSED,
d76c62
             break;
d76c62
         } while (1);
d76c62
 
d76c62
+        locked_paths[nfds] = p;
d76c62
         VIR_APPEND_ELEMENT_COPY_INPLACE(fds, nfds, fd);
d76c62
     }
d76c62
 
d76c62
     if (VIR_ALLOC(ret) < 0)
d76c62
         goto cleanup;
d76c62
 
d76c62
+    ret->paths = g_steal_pointer(&locked_paths);
d76c62
     ret->fds = g_steal_pointer(&fds);
d76c62
     ret->nfds = nfds;
d76c62
     nfds = 0;
d76c62
@@ -1386,6 +1392,7 @@ virSecurityManagerMetadataLock(virSecurityManagerPtr mgr G_GNUC_UNUSED,
d76c62
     for (i = nfds; i > 0; i--)
d76c62
         VIR_FORCE_CLOSE(fds[i - 1]);
d76c62
     VIR_FREE(fds);
d76c62
+    VIR_FREE(locked_paths);
d76c62
     return ret;
d76c62
 }
d76c62
 
d76c62
@@ -1401,21 +1408,23 @@ virSecurityManagerMetadataUnlock(virSecurityManagerPtr mgr G_GNUC_UNUSED,
d76c62
 
d76c62
     for (i = 0; i < (*state)->nfds; i++) {
d76c62
         char ebuf[1024];
d76c62
+        const char *path = (*state)->paths[i];
d76c62
         int fd = (*state)->fds[i];
d76c62
 
d76c62
         /* Technically, unlock is not needed because it will
d76c62
          * happen on VIR_CLOSE() anyway. But let's play it nice. */
d76c62
         if (virFileUnlock(fd, METADATA_OFFSET, METADATA_LEN) < 0) {
d76c62
-            VIR_WARN("Unable to unlock fd %d: %s",
d76c62
-                     fd, virStrerror(errno, ebuf, sizeof(ebuf)));
d76c62
+            VIR_WARN("Unable to unlock fd %d path %s: %s",
d76c62
+                     fd, path, virStrerror(errno, ebuf, sizeof(ebuf)));
d76c62
         }
d76c62
 
d76c62
         if (VIR_CLOSE(fd) < 0) {
d76c62
-            VIR_WARN("Unable to close fd %d: %s",
d76c62
-                     fd, virStrerror(errno, ebuf, sizeof(ebuf)));
d76c62
+            VIR_WARN("Unable to close fd %d path %s: %s",
d76c62
+                     fd, path, virStrerror(errno, ebuf, sizeof(ebuf)));
d76c62
         }
d76c62
     }
d76c62
 
d76c62
     VIR_FREE((*state)->fds);
d76c62
+    VIR_FREE((*state)->paths);
d76c62
     VIR_FREE(*state);
d76c62
 }
d76c62
-- 
d76c62
2.25.1
d76c62