7a3408
From cbd26cc9303bc0b00da7d63756c016c4f056ab4c Mon Sep 17 00:00:00 2001
7a3408
Message-Id: <cbd26cc9303bc0b00da7d63756c016c4f056ab4c@dist-git>
7a3408
From: Martin Kletzander <mkletzan@redhat.com>
7a3408
Date: Mon, 24 Aug 2015 13:04:51 +0200
7a3408
Subject: [PATCH] qemu: Fix access to auto-generated socket paths
7a3408
7a3408
We are automatically generating some socket paths for domains, but all
7a3408
those paths end up in a directory that's the same for multiple domains.
7a3408
The problem is that multiple domains can each run with different
7a3408
seclabels (users, selinux contexts, etc.).  The idea here is to create a
7a3408
per-domain directory labelled in a way that each domain can access its
7a3408
own unix sockets.
7a3408
7a3408
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1146886
7a3408
7a3408
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
7a3408
(cherry picked from commit f1f68ca33433825ce0deed2d96f1990200bc6618)
7a3408
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
7a3408
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
7a3408
---
7a3408
 src/qemu/qemu_command.c                            |  2 +-
7a3408
 src/qemu/qemu_domain.c                             | 16 +++---
7a3408
 src/qemu/qemu_process.c                            | 57 +++++++++++++++++++++-
7a3408
 .../qemuxml2argv-channel-virtio-unix.args          |  7 +--
7a3408
 4 files changed, 67 insertions(+), 15 deletions(-)
7a3408
7a3408
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
7a3408
index d28063c..aebaf35 100644
7a3408
--- a/src/qemu/qemu_command.c
7a3408
+++ b/src/qemu/qemu_command.c
7a3408
@@ -7807,7 +7807,7 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
7a3408
     if (graphics->data.vnc.socket || cfg->vncAutoUnixSocket) {
7a3408
         if (!graphics->data.vnc.socket &&
7a3408
             virAsprintf(&graphics->data.vnc.socket,
7a3408
-                        "%s/%s.vnc", cfg->libDir, def->name) == -1)
7a3408
+                        "%s/domain-%s/vnc.sock", cfg->libDir, def->name) == -1)
7a3408
             goto error;
7a3408
 
7a3408
         virBufferAsprintf(&opt, "unix:%s", graphics->data.vnc.socket);
7a3408
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
7a3408
index 3b542f5..943d727 100644
7a3408
--- a/src/qemu/qemu_domain.c
7a3408
+++ b/src/qemu/qemu_domain.c
7a3408
@@ -1288,16 +1288,12 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
7a3408
             goto cleanup;
7a3408
         }
7a3408
 
7a3408
-        if (dev->data.chr->target.name) {
7a3408
-            if (virAsprintf(&dev->data.chr->source.data.nix.path, "%s/%s.%s",
7a3408
-                            cfg->channelTargetDir,
7a3408
-                            def->name, dev->data.chr->target.name) < 0)
7a3408
-                goto cleanup;
7a3408
-        } else {
7a3408
-            if (virAsprintf(&dev->data.chr->source.data.nix.path, "%s/%s",
7a3408
-                            cfg->channelTargetDir, def->name) < 0)
7a3408
-                goto cleanup;
7a3408
-        }
7a3408
+        if (virAsprintf(&dev->data.chr->source.data.nix.path,
7a3408
+                        "%s/domain-%s/%s",
7a3408
+                        cfg->channelTargetDir, def->name,
7a3408
+                        dev->data.chr->target.name ? dev->data.chr->target.name
7a3408
+                        : "unknown.sock") < 0)
7a3408
+            goto cleanup;
7a3408
 
7a3408
         dev->data.chr->source.data.nix.listen = true;
7a3408
     }
7a3408
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
7a3408
index e1c7f0b..8cda456 100644
7a3408
--- a/src/qemu/qemu_process.c
7a3408
+++ b/src/qemu/qemu_process.c
7a3408
@@ -46,6 +46,7 @@
7a3408
 
7a3408
 #include "cpu/cpu.h"
7a3408
 #include "datatypes.h"
7a3408
+#include "dirname.h"
7a3408
 #include "virlog.h"
7a3408
 #include "virerror.h"
7a3408
 #include "viralloc.h"
7a3408
@@ -3269,7 +3270,7 @@ qemuProcessPrepareMonitorChr(virQEMUDriverConfigPtr cfg,
7a3408
     monConfig->type = VIR_DOMAIN_CHR_TYPE_UNIX;
7a3408
     monConfig->data.nix.listen = true;
7a3408
 
7a3408
-    if (virAsprintf(&monConfig->data.nix.path, "%s/%s.monitor",
7a3408
+    if (virAsprintf(&monConfig->data.nix.path, "%s/domain-%s/monitor.sock",
7a3408
                     cfg->libDir, vm) < 0)
7a3408
         return -1;
7a3408
     return 0;
7a3408
@@ -4393,6 +4394,7 @@ int qemuProcessStart(virConnectPtr conn,
7a3408
     unsigned int hostdev_flags = 0;
7a3408
     size_t nnicindexes = 0;
7a3408
     int *nicindexes = NULL;
7a3408
+    char *tmppath = NULL, *tmpdirpath = NULL;
7a3408
 
7a3408
     VIR_DEBUG("vm=%p name=%s id=%d pid=%llu",
7a3408
               vm, vm->def->name, vm->def->id,
7a3408
@@ -4728,6 +4730,44 @@ int qemuProcessStart(virConnectPtr conn,
7a3408
                                      &nnicindexes, &nicindexes)))
7a3408
         goto cleanup;
7a3408
 
7a3408
+
7a3408
+    /*
7a3408
+     * Create all per-domain directories in order to make sure domain
7a3408
+     * with any possible seclabels can access it.
7a3408
+     */
7a3408
+    if (virAsprintf(&tmppath, "%s/domain-%s", cfg->libDir, vm->def->name) < 0)
7a3408
+        goto cleanup;
7a3408
+
7a3408
+    if (virFileMakePath(tmppath) < 0)
7a3408
+        goto cleanup;
7a3408
+
7a3408
+    if (!(tmpdirpath = mdir_name(tmppath)))
7a3408
+        goto cleanup;
7a3408
+
7a3408
+    if (virSecurityManagerDomainSetDirLabel(driver->securityManager,
7a3408
+                                            vm->def, tmpdirpath) < 0)
7a3408
+        goto cleanup;
7a3408
+
7a3408
+    VIR_FREE(tmppath);
7a3408
+    VIR_FREE(tmpdirpath);
7a3408
+
7a3408
+    if (virAsprintf(&tmppath, "%s/domain-%s",
7a3408
+                    cfg->channelTargetDir, vm->def->name) < 0)
7a3408
+        goto cleanup;
7a3408
+
7a3408
+    if (virFileMakePath(tmppath) < 0)
7a3408
+        goto cleanup;
7a3408
+
7a3408
+    if (!(tmpdirpath = mdir_name(tmppath)))
7a3408
+        goto cleanup;
7a3408
+
7a3408
+    if (virSecurityManagerDomainSetDirLabel(driver->securityManager,
7a3408
+                                            vm->def, tmpdirpath) < 0)
7a3408
+        goto cleanup;
7a3408
+
7a3408
+    VIR_FREE(tmpdirpath);
7a3408
+    VIR_FREE(tmppath);
7a3408
+
7a3408
     /* now that we know it is about to start call the hook if present */
7a3408
     if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
7a3408
         char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
7a3408
@@ -5081,6 +5121,8 @@ int qemuProcessStart(virConnectPtr conn,
7a3408
     /* We jump here if we failed to start the VM for any reason, or
7a3408
      * if we failed to initialize the now running VM. kill it off and
7a3408
      * pretend we never started it */
7a3408
+    VIR_FREE(tmppath);
7a3408
+    VIR_FREE(tmpdirpath);
7a3408
     VIR_FREE(nodeset);
7a3408
     virCommandFree(cmd);
7a3408
     VIR_FORCE_CLOSE(logfile);
7a3408
@@ -5143,6 +5185,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
7a3408
     size_t i;
7a3408
     int logfile = -1;
7a3408
     char *timestamp;
7a3408
+    char *tmppath = NULL;
7a3408
     char ebuf[1024];
7a3408
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
7a3408
 
7a3408
@@ -5233,6 +5276,18 @@ void qemuProcessStop(virQEMUDriverPtr driver,
7a3408
         priv->monConfig = NULL;
7a3408
     }
7a3408
 
7a3408
+    ignore_value(virAsprintf(&tmppath, "%s/domain-%s",
7a3408
+                             cfg->libDir, vm->def->name));
7a3408
+    if (tmppath)
7a3408
+        virFileDeleteTree(tmppath);
7a3408
+    VIR_FREE(tmppath);
7a3408
+
7a3408
+    ignore_value(virAsprintf(&tmppath, "%s/domain-%s",
7a3408
+                             cfg->channelTargetDir, vm->def->name));
7a3408
+    if (tmppath)
7a3408
+        virFileDeleteTree(tmppath);
7a3408
+    VIR_FREE(tmppath);
7a3408
+
7a3408
     ignore_value(virDomainChrDefForeach(vm->def,
7a3408
                                         false,
7a3408
                                         qemuProcessCleanupChardevDevice,
7a3408
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args
7a3408
index 43a34ce..289b9d7 100644
7a3408
--- a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args
7a3408
+++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args
7a3408
@@ -9,11 +9,12 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
7a3408
 -usb \
7a3408
 -hda /dev/HostVG/QEMUGuest1 \
7a3408
 -chardev socket,id=charchannel0,path=\
7a3408
-/tmp/QEMUGuest1.org.qemu.guest_agent.0,server,nowait \
7a3408
+/tmp/domain-QEMUGuest1/org.qemu.guest_agent.0,server,nowait \
7a3408
 -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,\
7a3408
 name=org.qemu.guest_agent.0 \
7a3408
--chardev socket,id=charchannel1,path=/tmp/QEMUGuest1,server,nowait \
7a3408
+-chardev \
7a3408
+socket,id=charchannel1,path=/tmp/domain-QEMUGuest1/unknown.sock,server,nowait \
7a3408
 -device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1 \
7a3408
--chardev socket,id=charchannel2,path=/tmp/QEMUGuest1.ble,server,nowait \
7a3408
+-chardev socket,id=charchannel2,path=/tmp/domain-QEMUGuest1/ble,server,nowait \
7a3408
 -device virtserialport,bus=virtio-serial0.0,nr=3,chardev=charchannel2,id=channel2,\
7a3408
 name=ble
7a3408
-- 
7a3408
2.5.1
7a3408