lib: fix sockdir for root

When running as root libvirt will launch qemu as qemu.qemu, which will
not be able to read inside the socket directory in case it is set as
XDG_RUNTIME_DIR under /run/user/0.

Since normal users don't need particular extra access permissions for
their sockdirs, restrict /tmp as only possible sockdir for root,
changing the permissions only for this user (and making this operation
fatal).

Fixes commit 55202a4d49 and
commit 7453952d24.
This commit is contained in:
Pino Toscano
2016-02-09 11:36:23 +01:00
parent d5c0f85c6e
commit 772f649e59
2 changed files with 31 additions and 10 deletions

View File

@@ -428,12 +428,6 @@ guestfs_int_create_socketname (guestfs_h *g, const char *filename,
if (guestfs_int_lazy_make_sockdir (g) == -1)
return -1;
/* Allow qemu (which may be running as qemu.qemu) to read the socket
* temporary directory. (RHBZ#610880).
*/
if (chmod (g->sockdir, 0755) == -1)
warning (g, "chmod: %s: %m (ignored)", g->sockdir);
if (strlen (g->sockdir) + 1 + strlen (filename) > UNIX_PATH_MAX-1) {
error (g, _("socket path too long: %s/%s"), g->sockdir, filename);
return -1;

View File

@@ -23,6 +23,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <libintl.h>
#include <unistd.h>
#include "ignore-value.h"
@@ -130,11 +131,20 @@ char *
guestfs_impl_get_sockdir (guestfs_h *g)
{
const char *str;
uid_t euid = geteuid ();
if (g->env_runtimedir)
str = g->env_runtimedir;
else
if (euid == 0) {
/* Use /tmp exclusively for root, as otherwise qemu (running as
* qemu.qemu when launched by libvirt) will not be able to access
* the directory.
*/
str = "/tmp";
} else {
if (g->env_runtimedir)
str = g->env_runtimedir;
else
str = "/tmp";
}
return safe_strdup (g, str);
}
@@ -168,7 +178,24 @@ guestfs_int_lazy_make_tmpdir (guestfs_h *g)
int
guestfs_int_lazy_make_sockdir (guestfs_h *g)
{
return lazy_make_tmpdir (g, guestfs_get_sockdir, &g->sockdir);
int ret;
uid_t euid = geteuid ();
ret = lazy_make_tmpdir (g, guestfs_get_sockdir, &g->sockdir);
if (ret == -1)
return ret;
if (euid == 0) {
/* Allow qemu (which may be running as qemu.qemu) to read the socket
* temporary directory. (RHBZ#610880).
*/
if (chmod (g->sockdir, 0755) == -1) {
perrorf (g, "chmod: %s", g->sockdir);
return -1;
}
}
return ret;
}
/* Recursively remove a temporary directory. If removal fails, just