[libvirt] [PATCH for 5.7.0 v2 3/3] qemu_blockjob: Remove secdriver metadata more frequently

Michal Privoznik mprivozn at redhat.com
Fri Aug 30 14:56:10 UTC 2019


If a block job reaches failed/cancelled state, or is completed
without pivot then we must remove security driver metadata
associated to the backing chain so that we don't leave any
metadata behind.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1741456

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/qemu/qemu_blockjob.c | 59 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 54 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
index 1b22689e0c..a991309ee7 100644
--- a/src/qemu/qemu_blockjob.c
+++ b/src/qemu/qemu_blockjob.c
@@ -659,7 +659,23 @@ qemuBlockJobEventProcessLegacyCompleted(virQEMUDriverPtr driver,
         disk->src = disk->mirror;
     } else {
         if (disk->mirror) {
+            virStorageSourcePtr n;
+
             virDomainLockImageDetach(driver->lockManager, vm, disk->mirror);
+
+            /* Ideally, we would restore seclabels on the backing chain here
+             * but we don't know if somebody else is not using parts of it.
+             * Remove security driver metadata so that they are not leaked. */
+            for (n = disk->mirror; virStorageSourceIsBacking(n); n = n->backingStore) {
+                if (qemuSecurityMoveImageMetadata(driver, vm, n, NULL) < 0) {
+                    VIR_WARN("Unable to remove disk metadata on "
+                             "vm %s from %s (disk target %s)",
+                             vm->def->name,
+                             NULLSTR(disk->src->path),
+                             disk->dst);
+                }
+            }
+
             virObjectUnref(disk->mirror);
         }
     }
@@ -728,7 +744,23 @@ qemuBlockJobEventProcessLegacy(virQEMUDriverPtr driver,
     case VIR_DOMAIN_BLOCK_JOB_FAILED:
     case VIR_DOMAIN_BLOCK_JOB_CANCELED:
         if (disk->mirror) {
+            virStorageSourcePtr n;
+
             virDomainLockImageDetach(driver->lockManager, vm, disk->mirror);
+
+            /* Ideally, we would restore seclabels on the backing chain here
+             * but we don't know if somebody else is not using parts of it.
+             * Remove security driver metadata so that they are not leaked. */
+            for (n = disk->mirror; virStorageSourceIsBacking(n); n = n->backingStore) {
+                if (qemuSecurityMoveImageMetadata(driver, vm, n, NULL) < 0) {
+                    VIR_WARN("Unable to remove disk metadata on "
+                             "vm %s from %s (disk target %s)",
+                             vm->def->name,
+                             NULLSTR(disk->src->path),
+                             disk->dst);
+                }
+            }
+
             virObjectUnref(disk->mirror);
             disk->mirror = NULL;
         }
@@ -1128,16 +1160,33 @@ qemuBlockJobProcessEventConcludedCopyAbort(virQEMUDriverPtr driver,
 
 
 static void
-qemuBlockJobProcessEventFailedActiveCommit(virDomainObjPtr vm,
+qemuBlockJobProcessEventFailedActiveCommit(virQEMUDriverPtr driver,
+                                           virDomainObjPtr vm,
                                            qemuBlockJobDataPtr job)
 {
+    virDomainDiskDefPtr disk = job->disk;
+    virStorageSourcePtr n;
+
     VIR_DEBUG("active commit job '%s' on VM '%s' failed", job->name, vm->def->name);
 
-    if (!job->disk)
+    if (!disk)
         return;
 
-    virObjectUnref(job->disk->mirror);
-    job->disk->mirror = NULL;
+    /* Ideally, we would make the backing chain read only again (yes, SELinux
+     * can do that using different labels). But that is not implemented yet and
+     * not leaking security driver metadata is more important. */
+    for (n = disk->mirror; virStorageSourceIsBacking(n); n = n->backingStore) {
+        if (qemuSecurityMoveImageMetadata(driver, vm, n, NULL) < 0) {
+            VIR_WARN("Unable to remove disk metadata on "
+                     "vm %s from %s (disk target %s)",
+                     vm->def->name,
+                     NULLSTR(disk->src->path),
+                     disk->dst);
+        }
+    }
+
+    virObjectUnref(disk->mirror);
+    disk->mirror = NULL;
 }
 
 
@@ -1231,7 +1280,7 @@ qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job,
             break;
 
         case QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT:
-            qemuBlockJobProcessEventFailedActiveCommit(vm, job);
+            qemuBlockJobProcessEventFailedActiveCommit(driver, vm, job);
             break;
 
         case QEMU_BLOCKJOB_TYPE_CREATE:
-- 
2.21.0




More information about the libvir-list mailing list