Commit e263b362 authored by Giovanni Campagna's avatar Giovanni Campagna
Browse files

mutter-launch: use systemd to obtain the TTY

Using the command line or an environment variable is dangerous,
as those can be spoofed to gain access to other sessions.

https://bugzilla.gnome.org/show_bug.cgi?id=705861
parent 1c34f0b3
......@@ -141,6 +141,11 @@ AM_GLIB_GNU_GETTEXT
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
PKG_CHECK_MODULES(MUTTER_LAUNCH, libdrm libsystemd-login)
saved_LIBS="$LIBS"
LIBS="$LIBS $MUTTER_LAUNCH"
AC_CHECK_FUNCS([sd_session_get_vt])
LIBS="$saved_LIBS"
# Unconditionally use this dir to avoid a circular dep with gnomecc
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
AC_SUBST(GNOME_KEYBINDINGS_KEYSDIR)
......
......@@ -374,33 +374,52 @@ handle_signal(struct weston_launch *wl)
}
static int
setup_tty(struct weston_launch *wl, const char *tty)
setup_tty(struct weston_launch *wl)
{
struct stat buf;
char *t;
if (tty) {
t = ttyname(STDIN_FILENO);
if (t && strcmp(t, tty) == 0)
wl->tty = STDIN_FILENO;
else
wl->tty = open(tty, O_RDWR | O_NOCTTY);
} else {
wl->tty = STDIN_FILENO;
}
char *session, *tty;
char path[PATH_MAX];
int ok;
ok = sd_pid_get_session(getpid(), &session);
if (ok < 0)
error(1, -ok, "could not determine current session");
ok = sd_session_get_tty(session, &tty);
if (ok == 0) {
snprintf(path, PATH_MAX, "/dev/%s", tty);
wl->tty = open(path, O_RDWR | O_NOCTTY);
free(tty);
#ifdef HAVE_SD_SESSION_GET_VT
} else if (ok == -ENOENT) {
/* Negative errnos are cool, right?
So cool that we can't distinguish "session not found"
from "key does not exist in the session file"!
Let's assume the latter, as we got the value
from sd_pid_get_session()...
*/
ok = sd_session_get_vt(session, &tty);
if (ok < 0)
error(1, -ok, "could not determine current TTY");
snprintf(path, PATH_MAX, "/dev/tty%s", tty);
wl->tty = open(path, O_RDWR | O_NOCTTY);
free(tty);
#endif
} else
error(1, -ok, "could not determine current TTY");
if (wl->tty < 0)
error(1, errno, "failed to open tty");
if (tty) {
if (fstat(wl->tty, &buf) < 0)
error(1, errno, "stat %s failed", tty);
if (fstat(wl->tty, &buf) < 0)
error(1, errno, "stat %s failed", path);
if (major(buf.st_rdev) != TTY_MAJOR)
error(1, 0, "invalid tty device: %s", tty);
if (major(buf.st_rdev) != TTY_MAJOR)
error(1, 0, "invalid tty device: %s", path);
wl->ttynr = minor(buf.st_rdev);
}
wl->ttynr = minor(buf.st_rdev);
return 0;
}
......@@ -429,9 +448,7 @@ launch_compositor(struct weston_launch *wl, int argc, char *argv[])
drop_privileges(wl);
if (wl->tty != STDIN_FILENO)
setenv_fd("WESTON_TTY_FD", wl->tty);
setenv_fd("WESTON_TTY_FD", wl->tty);
setenv_fd("WESTON_LAUNCHER_SOCK", wl->sock[1]);
setenv("LD_LIBRARY_PATH", LIBDIR, 1);
unsetenv("DISPLAY");
......@@ -462,7 +479,6 @@ help(const char *name)
{
fprintf(stderr, "Usage: %s [args...] [-- [weston args..]]\n", name);
fprintf(stderr, " -u, --user Start session as specified username\n");
fprintf(stderr, " -t, --tty Start session on alternative tty\n");
fprintf(stderr, " -v, --verbose Be verbose\n");
fprintf(stderr, " -h, --help Display this help message\n");
}
......@@ -472,9 +488,7 @@ main(int argc, char *argv[])
{
struct weston_launch wl;
int i, c;
char *tty = NULL;
struct option opts[] = {
{ "tty", required_argument, NULL, 't' },
{ "verbose", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ 0, 0, NULL, 0 }
......@@ -484,9 +498,6 @@ main(int argc, char *argv[])
while ((c = getopt_long(argc, argv, "u:t::vh", opts, &i)) != -1) {
switch (c) {
case 't':
tty = optarg;
break;
case 'v':
wl.verbose = 1;
break;
......@@ -510,7 +521,7 @@ main(int argc, char *argv[])
if (!weston_launch_allowed(&wl))
error(1, 0, "Permission denied. You must run from an active and local (systemd) session.");
if (setup_tty(&wl, tty) < 0)
if (setup_tty(&wl) < 0)
exit(EXIT_FAILURE);
if (setup_launcher_socket(&wl) < 0)
......@@ -529,8 +540,7 @@ main(int argc, char *argv[])
launch_compositor(&wl, argc - optind, argv + optind);
close(wl.sock[1]);
if (wl.tty != STDIN_FILENO)
close(wl.tty);
close(wl.tty);
while (1) {
struct pollfd fds[2];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment