[Libguestfs] [PATCH] lib: libvirt: If root, run qemu as root.root.

Richard W.M. Jones rjones at redhat.com
Tue Mar 14 13:50:58 UTC 2017


Previously we had assumed that when running as root, libvirt would
always run qemu as a non-root user (eg. qemu.qemu), unless you modify
a global configuration file (/etc/libvirt/qemu.conf).

It turns out there is a little-known feature to make libvirt run qemu
as root without modifying any configuration files.  We have to add a
<seclabel/> element to the appliance XML:

  <seclabel type='static' model='dac' relabel='no'>
    <label>root:root</label>
  </seclabel>

For further information see:

  https://libvirt.org/formatdomain.html#seclabel

This change adds the required <seclabel/> element when running as
root, and also removes the code which changed the owner of the console
and daemon sockets, as that is no longer required.

Thanks: Peter Krempa, Pino Toscano, Dan Berrange.
---
 lib/launch-libvirt.c | 60 +++++++++++-----------------------------------------
 1 file changed, 12 insertions(+), 48 deletions(-)

diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
index 168bba6..81cdead 100644
--- a/lib/launch-libvirt.c
+++ b/lib/launch-libvirt.c
@@ -523,53 +523,6 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri)
 
   clear_socket_create_context (g);
 
-  /* libvirt, if running as root, will run the qemu process as
-   * qemu.qemu, which means it won't be able to access the socket.
-   * There are roughly three things that get in the way:
-   *
-   * (1) Permissions of the socket.
-   *
-   * (2) Permissions of the parent directory(-ies).  Remember this if
-   *     $TMPDIR is located in your home directory.
-   *
-   * (3) SELinux/sVirt will prevent access.  libvirt ought to label
-   *     the socket.
-   *
-   * Note that the 'current_proc_is_root' flag here just means that we
-   * are root.  It's also possible for non-root user to try to use the
-   * system libvirtd by specifying a qemu:///system URI (RHBZ#913774)
-   * but there's no sane way to test for that.
-   */
-  if (params.current_proc_is_root) {
-    /* Current process is root, so try to create sockets that are
-     * owned by root.qemu with mode 0660 and hence accessible to qemu.
-     */
-    struct group *grp;
-
-    if (chmod (data->guestfsd_path, 0660) == -1) {
-      perrorf (g, "chmod: %s", data->guestfsd_path);
-      goto cleanup;
-    }
-
-    if (chmod (data->console_path, 0660) == -1) {
-      perrorf (g, "chmod: %s", data->console_path);
-      goto cleanup;
-    }
-
-    grp = getgrnam ("qemu");
-    if (grp != NULL) {
-      if (chown (data->guestfsd_path, 0, grp->gr_gid) == -1) {
-        perrorf (g, "chown: %s", data->guestfsd_path);
-        goto cleanup;
-      }
-      if (chown (data->console_path, 0, grp->gr_gid) == -1) {
-        perrorf (g, "chown: %s", data->console_path);
-        goto cleanup;
-      }
-    } else
-      debug (g, "cannot find group 'qemu'");
-  }
-
   /* Store any secrets in libvirtd, keeping a mapping from the secret
    * to its UUID.
    */
@@ -1256,7 +1209,18 @@ construct_libvirt_xml_seclabel (guestfs_h *g,
                                 const struct libvirt_xml_params *params,
                                 xmlTextWriterPtr xo)
 {
-  if (!params->enable_svirt) {
+  if (params->current_proc_is_root) {
+    /* Force libvirt to run qemu as root.root. */
+    start_element ("seclabel") {
+      attribute ("type", "static");
+      attribute ("model", "dac");
+      attribute ("relabel", "no");
+      start_element ("label") {
+        string ("root:root");
+      } end_element ();
+    } end_element ();
+  }
+  else if (!params->enable_svirt) {
     /* This disables SELinux/sVirt confinement. */
     start_element ("seclabel") {
       attribute ("type", "none");
-- 
2.10.2




More information about the Libguestfs mailing list