]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Don't overwrite security labels
authorMichal Privoznik <mprivozn@redhat.com>
Mon, 11 Jun 2012 13:57:19 +0000 (15:57 +0200)
committerCole Robinson <crobinso@redhat.com>
Thu, 14 Jun 2012 22:38:27 +0000 (18:38 -0400)
Currently, if qemuProcessStart fail at some point, e.g. because
domain being started wants a PCI/USB device already assigned to
a different domain, we jump to cleanup label where qemuProcessStop
is performed. This unconditionally calls virSecurityManagerRestoreAllLabel
which is wrong because the other domain is still using those devices.

However, once we successfully label all devices/paths in
qemuProcessStart() from that point on, we have to perform a rollback
on failure - that is - we have to virSecurityManagerRestoreAllLabel.
(cherry picked from commit 86032b2276ace5a7977aad2bbae73b4c33e31914)

Conflicts:

src/qemu/qemu_process.c

src/qemu/qemu_process.c
src/qemu/qemu_process.h

index 244dcdc94889b4a6f197c93a8ef93949c35becdf..8cd7abeccaa1186747fd77e102af4981644b9200 100644 (file)
@@ -3281,8 +3281,15 @@ int qemuProcessStart(virConnectPtr conn,
     virCommandPtr cmd = NULL;
     struct qemuProcessHookData hookData;
     unsigned long cur_balloon;
+    unsigned int stop_flags;
     int i;
 
+    /* From now on until domain security labeling is done:
+     * if any operation fails and we goto cleanup, we must not
+     * restore any security label as we would overwrite labels
+     * we did not set. */
+    stop_flags = VIR_QEMU_PROCESS_STOP_NO_RELABEL;
+
     hookData.conn = conn;
     hookData.vm = vm;
     hookData.driver = driver;
@@ -3601,6 +3608,12 @@ int qemuProcessStart(virConnectPtr conn,
                                       vm->def, stdin_path) < 0)
         goto cleanup;
 
+    /* Security manager labeled all devices, therefore
+     * if any operation from now on fails and we goto cleanup,
+     * where virSecurityManagerRestoreAllLabel() is called
+     * (hidden under qemuProcessStop) we need to restore labels. */
+    stop_flags &= ~VIR_QEMU_PROCESS_STOP_NO_RELABEL;
+
     if (stdin_fd != -1) {
         /* if there's an fd to migrate from, and it's a pipe, put the
          * proper security label on it
@@ -3738,7 +3751,7 @@ cleanup:
      * pretend we never started it */
     virCommandFree(cmd);
     VIR_FORCE_CLOSE(logfile);
-    qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, 0);
+    qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, stop_flags);
 
     return -1;
 }
@@ -3951,10 +3964,11 @@ void qemuProcessStop(struct qemud_driver *driver,
         VIR_FREE(xml);
     }
 
-    /* Reset Security Labels */
-    virSecurityManagerRestoreAllLabel(driver->securityManager,
-                                      vm->def,
-                                      flags & VIR_QEMU_PROCESS_STOP_MIGRATED);
+    /* Reset Security Labels unless caller don't want us to */
+    if (!(flags & VIR_QEMU_PROCESS_STOP_NO_RELABEL))
+        virSecurityManagerRestoreAllLabel(driver->securityManager,
+                                          vm->def,
+                                          flags & VIR_QEMU_PROCESS_STOP_MIGRATED);
     virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
 
     /* Clear out dynamically assigned labels */
index 4b3a6285828418c14bf09a40538316d4a84a904f..10ba724ddc8cfbda4e930eaf2f4117a14ddeb7fa 100644 (file)
@@ -57,7 +57,8 @@ int qemuProcessStart(virConnectPtr conn,
                      enum virNetDevVPortProfileOp vmop);
 
 typedef enum {
-    VIR_QEMU_PROCESS_STOP_MIGRATED  = 1 << 0,
+    VIR_QEMU_PROCESS_STOP_MIGRATED      = 1 << 0,
+    VIR_QEMU_PROCESS_STOP_NO_RELABEL    = 1 << 1,
 } qemuProcessStopFlags;
 
 void qemuProcessStop(struct qemud_driver *driver,