]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Enter the namespace on relabelling
authorMichal Privoznik <mprivozn@redhat.com>
Wed, 23 Nov 2016 10:52:57 +0000 (11:52 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 15 Dec 2016 08:25:16 +0000 (09:25 +0100)
Instead of trying to fix our security drivers, we can use a
simple trick to relabel paths in both namespace and the host.
I mean, if we enter the namespace some paths are still shared
with the host so any change done to them is visible from the host
too.
Therefore, we can just enter the namespace and call
SetAllLabel()/RestoreAllLabel() from there. Yes, it has slight
overhead because we have to fork in order to enter the namespace.
But on the other hand, no complexity is added to our code.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/Makefile.am
src/qemu/qemu_process.c
src/qemu/qemu_security.c [new file with mode: 0644]
src/qemu/qemu_security.h [new file with mode: 0644]

index 92006eef19d2882efbd020e67fd8831908a21e3a..b7137872885ab92be130f8204e081bd0a9fa2d16 100644 (file)
@@ -838,7 +838,8 @@ QEMU_DRIVER_SOURCES =                                                       \
                qemu/qemu_monitor_json.h                                \
                qemu/qemu_driver.c qemu/qemu_driver.h   \
                qemu/qemu_interface.c qemu/qemu_interface.h             \
-               qemu/qemu_capspriv.h
+               qemu/qemu_capspriv.h                                    \
+               qemu/qemu_security.c qemu/qemu_security.h
 
 XENAPI_DRIVER_SOURCES =                                                \
                xenapi/xenapi_driver.c xenapi/xenapi_driver.h   \
index 08859b8880fb24c9e785b82a9c46d1b5ef05c45b..721ad6370f04177b9bde8a6353c872ea46d42616 100644 (file)
@@ -45,6 +45,7 @@
 #include "qemu_hotplug.h"
 #include "qemu_migration.h"
 #include "qemu_interface.h"
+#include "qemu_security.h"
 
 #include "cpu/cpu.h"
 #include "datatypes.h"
@@ -5591,10 +5592,10 @@ qemuProcessLaunch(virConnectPtr conn,
         goto cleanup;
 
     VIR_DEBUG("Setting domain security labels");
-    if (virSecurityManagerSetAllLabel(driver->securityManager,
-                                      vm->def,
-                                      incoming ? incoming->path : NULL) < 0)
-        goto cleanup;
+        if (qemuSecuritySetAllLabel(driver,
+                                    vm,
+                                    incoming ? incoming->path : NULL) < 0)
+            goto cleanup;
 
     /* Security manager labeled all devices, therefore
      * if any operation from now on fails, we need to ask the caller to
@@ -6131,9 +6132,9 @@ void qemuProcessStop(virQEMUDriverPtr driver,
 
     /* 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));
+        qemuSecurityRestoreAllLabel(driver, vm,
+                                    !!(flags & VIR_QEMU_PROCESS_STOP_MIGRATED));
+
     virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
 
     for (i = 0; i < vm->def->ndisks; i++) {
diff --git a/src/qemu/qemu_security.c b/src/qemu/qemu_security.c
new file mode 100644 (file)
index 0000000..bfebfe4
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * qemu_security.c: QEMU security management
+ *
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *     Michal Privoznik <mprivozn@redhat.com>
+ */
+
+#include <config.h>
+
+#include "qemu_domain.h"
+#include "qemu_security.h"
+#include "virlog.h"
+
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
+VIR_LOG_INIT("qemu.qemu_process");
+
+struct qemuSecuritySetRestoreAllLabelData {
+    bool set;
+    virQEMUDriverPtr driver;
+    virDomainObjPtr vm;
+    const char *stdin_path;
+    bool migrated;
+};
+
+
+static int
+qemuSecuritySetRestoreAllLabelHelper(pid_t pid,
+                                     void *opaque)
+{
+    struct qemuSecuritySetRestoreAllLabelData *data = opaque;
+
+    virSecurityManagerPostFork(data->driver->securityManager);
+
+    if (data->set) {
+        VIR_DEBUG("Setting up security labels inside namespace pid=%lld",
+                  (long long) pid);
+        if (virSecurityManagerSetAllLabel(data->driver->securityManager,
+                                          data->vm->def,
+                                          data->stdin_path) < 0)
+            return -1;
+    } else {
+        VIR_DEBUG("Restoring security labels inside namespace pid=%lld",
+                  (long long) pid);
+        if (virSecurityManagerRestoreAllLabel(data->driver->securityManager,
+                                              data->vm->def,
+                                              data->migrated) < 0)
+            return -1;
+    }
+
+    return 0;
+}
+
+
+int
+qemuSecuritySetAllLabel(virQEMUDriverPtr driver,
+                        virDomainObjPtr vm,
+                        const char *stdin_path)
+{
+    struct qemuSecuritySetRestoreAllLabelData data;
+
+    memset(&data, 0, sizeof(data));
+
+    data.set = true;
+    data.driver = driver;
+    data.vm = vm;
+    data.stdin_path = stdin_path;
+
+    if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) {
+        if (virSecurityManagerPreFork(driver->securityManager) < 0)
+            return -1;
+        if (virProcessRunInMountNamespace(vm->pid,
+                                          qemuSecuritySetRestoreAllLabelHelper,
+                                          &data) < 0) {
+            virSecurityManagerPostFork(driver->securityManager);
+            return -1;
+        }
+        virSecurityManagerPostFork(driver->securityManager);
+
+    } else {
+        if (virSecurityManagerSetAllLabel(driver->securityManager,
+                                          vm->def,
+                                          stdin_path) < 0)
+            return -1;
+    }
+    return 0;
+}
+
+
+void
+qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver,
+                            virDomainObjPtr vm,
+                            bool migrated)
+{
+    struct qemuSecuritySetRestoreAllLabelData data;
+
+    memset(&data, 0, sizeof(data));
+
+    data.driver = driver;
+    data.vm = vm;
+    data.migrated = migrated;
+
+    if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) {
+        if (virSecurityManagerPreFork(driver->securityManager) < 0)
+            return;
+
+        virProcessRunInMountNamespace(vm->pid,
+                                      qemuSecuritySetRestoreAllLabelHelper,
+                                      &data);
+        virSecurityManagerPostFork(driver->securityManager);
+    } else {
+        virSecurityManagerRestoreAllLabel(driver->securityManager,
+                                          vm->def,
+                                          migrated);
+    }
+}
diff --git a/src/qemu/qemu_security.h b/src/qemu/qemu_security.h
new file mode 100644 (file)
index 0000000..88c53e7
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * qemu_security.h: QEMU security management
+ *
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *     Michal Privoznik <mprivozn@redhat.com>
+ */
+
+#ifndef __QEMU_SECURITY_H__
+# define __QEMU_SECURITY_H__
+
+# include <stdbool.h>
+
+# include "qemu_conf.h"
+# include "domain_conf.h"
+
+int qemuSecuritySetAllLabel(virQEMUDriverPtr driver,
+                            virDomainObjPtr vm,
+                            const char *stdin_path);
+
+void qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver,
+                                 virDomainObjPtr vm,
+                                 bool migrated);
+#endif /* __QEMU_SECURITY_H__ */