]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
security: Try harder to run transactions
authorMichal Privoznik <mprivozn@redhat.com>
Wed, 18 Mar 2020 09:18:46 +0000 (10:18 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 20 Mar 2020 15:43:13 +0000 (16:43 +0100)
When a QEMU process dies in the middle of a hotplug, then we fail
to restore the seclabels on the device. The problem is that if
the thread doing hotplug locks the domain object first and thus
blocks the thread that wants to do qemuProcessStop(), the
seclabel cleanup code will see vm->pid still set and mount
namespace used and therefore try to enter the namespace
represented by the PID. But the PID is gone really and thus
entering will fail and no restore is done. What we can do is to
try enter the namespace (if requested to do so) but if entering
fails, fall back to no NS mode.

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

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Mores <pmores@redhat.com>
src/security/security_dac.c
src/security/security_selinux.c

index 9046b510049af76359ebeb82d15fe77fd165f556..11fff63bc7349dc23507b4f31de32bb429a03615 100644 (file)
@@ -640,15 +640,23 @@ virSecurityDACTransactionCommit(virSecurityManagerPtr mgr G_GNUC_UNUSED,
 
     list->lock = lock;
 
+    if (pid != -1) {
+        rc = virProcessRunInMountNamespace(pid,
+                                           virSecurityDACTransactionRun,
+                                           list);
+        if (rc < 0) {
+            if (virGetLastErrorCode() == VIR_ERR_SYSTEM_ERROR)
+                pid = -1;
+            else
+                goto cleanup;
+        }
+    }
+
     if (pid == -1) {
         if (lock)
             rc = virProcessRunInFork(virSecurityDACTransactionRun, list);
         else
             rc = virSecurityDACTransactionRun(pid, list);
-    } else {
-        rc = virProcessRunInMountNamespace(pid,
-                                           virSecurityDACTransactionRun,
-                                           list);
     }
 
     if (rc < 0)
index c94f31727c994a27ba0267725741e1aebae81ab6..8aeb6e45a5e95efd6e3e0bd99504bd297e20bc15 100644 (file)
@@ -1163,15 +1163,23 @@ virSecuritySELinuxTransactionCommit(virSecurityManagerPtr mgr G_GNUC_UNUSED,
 
     list->lock = lock;
 
+    if (pid != -1) {
+        rc = virProcessRunInMountNamespace(pid,
+                                           virSecuritySELinuxTransactionRun,
+                                           list);
+        if (rc < 0) {
+            if (virGetLastErrorCode() == VIR_ERR_SYSTEM_ERROR)
+                pid = -1;
+            else
+                goto cleanup;
+        }
+    }
+
     if (pid == -1) {
         if (lock)
             rc = virProcessRunInFork(virSecuritySELinuxTransactionRun, list);
         else
             rc = virSecuritySELinuxTransactionRun(pid, list);
-    } else {
-        rc = virProcessRunInMountNamespace(pid,
-                                           virSecuritySELinuxTransactionRun,
-                                           list);
     }
 
     if (rc < 0)