render / rpms / libvirt

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