render / rpms / libvirt

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