mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 03:20:46 -05:00
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
This commit is contained in:
parent
1c34f0b342
commit
e263b3624c
@ -141,6 +141,11 @@ AM_GLIB_GNU_GETTEXT
|
|||||||
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
|
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
|
||||||
PKG_CHECK_MODULES(MUTTER_LAUNCH, libdrm libsystemd-login)
|
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
|
# Unconditionally use this dir to avoid a circular dep with gnomecc
|
||||||
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
|
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
|
||||||
AC_SUBST(GNOME_KEYBINDINGS_KEYSDIR)
|
AC_SUBST(GNOME_KEYBINDINGS_KEYSDIR)
|
||||||
|
@ -374,33 +374,52 @@ handle_signal(struct weston_launch *wl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
setup_tty(struct weston_launch *wl, const char *tty)
|
setup_tty(struct weston_launch *wl)
|
||||||
{
|
{
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
char *t;
|
char *session, *tty;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
int ok;
|
||||||
|
|
||||||
if (tty) {
|
ok = sd_pid_get_session(getpid(), &session);
|
||||||
t = ttyname(STDIN_FILENO);
|
if (ok < 0)
|
||||||
if (t && strcmp(t, tty) == 0)
|
error(1, -ok, "could not determine current session");
|
||||||
wl->tty = STDIN_FILENO;
|
|
||||||
else
|
ok = sd_session_get_tty(session, &tty);
|
||||||
wl->tty = open(tty, O_RDWR | O_NOCTTY);
|
if (ok == 0) {
|
||||||
} else {
|
snprintf(path, PATH_MAX, "/dev/%s", tty);
|
||||||
wl->tty = STDIN_FILENO;
|
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)
|
if (wl->tty < 0)
|
||||||
error(1, errno, "failed to open tty");
|
error(1, errno, "failed to open tty");
|
||||||
|
|
||||||
if (tty) {
|
if (fstat(wl->tty, &buf) < 0)
|
||||||
if (fstat(wl->tty, &buf) < 0)
|
error(1, errno, "stat %s failed", path);
|
||||||
error(1, errno, "stat %s failed", tty);
|
|
||||||
|
|
||||||
if (major(buf.st_rdev) != TTY_MAJOR)
|
if (major(buf.st_rdev) != TTY_MAJOR)
|
||||||
error(1, 0, "invalid tty device: %s", tty);
|
error(1, 0, "invalid tty device: %s", path);
|
||||||
|
|
||||||
wl->ttynr = minor(buf.st_rdev);
|
wl->ttynr = minor(buf.st_rdev);
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -429,9 +448,7 @@ launch_compositor(struct weston_launch *wl, int argc, char *argv[])
|
|||||||
|
|
||||||
drop_privileges(wl);
|
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_fd("WESTON_LAUNCHER_SOCK", wl->sock[1]);
|
||||||
setenv("LD_LIBRARY_PATH", LIBDIR, 1);
|
setenv("LD_LIBRARY_PATH", LIBDIR, 1);
|
||||||
unsetenv("DISPLAY");
|
unsetenv("DISPLAY");
|
||||||
@ -462,7 +479,6 @@ help(const char *name)
|
|||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s [args...] [-- [weston args..]]\n", name);
|
fprintf(stderr, "Usage: %s [args...] [-- [weston args..]]\n", name);
|
||||||
fprintf(stderr, " -u, --user Start session as specified username\n");
|
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, " -v, --verbose Be verbose\n");
|
||||||
fprintf(stderr, " -h, --help Display this help message\n");
|
fprintf(stderr, " -h, --help Display this help message\n");
|
||||||
}
|
}
|
||||||
@ -472,9 +488,7 @@ main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
struct weston_launch wl;
|
struct weston_launch wl;
|
||||||
int i, c;
|
int i, c;
|
||||||
char *tty = NULL;
|
|
||||||
struct option opts[] = {
|
struct option opts[] = {
|
||||||
{ "tty", required_argument, NULL, 't' },
|
|
||||||
{ "verbose", no_argument, NULL, 'v' },
|
{ "verbose", no_argument, NULL, 'v' },
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ 0, 0, NULL, 0 }
|
{ 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) {
|
while ((c = getopt_long(argc, argv, "u:t::vh", opts, &i)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 't':
|
|
||||||
tty = optarg;
|
|
||||||
break;
|
|
||||||
case 'v':
|
case 'v':
|
||||||
wl.verbose = 1;
|
wl.verbose = 1;
|
||||||
break;
|
break;
|
||||||
@ -510,7 +521,7 @@ main(int argc, char *argv[])
|
|||||||
if (!weston_launch_allowed(&wl))
|
if (!weston_launch_allowed(&wl))
|
||||||
error(1, 0, "Permission denied. You must run from an active and local (systemd) session.");
|
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);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
if (setup_launcher_socket(&wl) < 0)
|
if (setup_launcher_socket(&wl) < 0)
|
||||||
@ -529,8 +540,7 @@ main(int argc, char *argv[])
|
|||||||
launch_compositor(&wl, argc - optind, argv + optind);
|
launch_compositor(&wl, argc - optind, argv + optind);
|
||||||
|
|
||||||
close(wl.sock[1]);
|
close(wl.sock[1]);
|
||||||
if (wl.tty != STDIN_FILENO)
|
close(wl.tty);
|
||||||
close(wl.tty);
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
struct pollfd fds[2];
|
struct pollfd fds[2];
|
||||||
|
Loading…
Reference in New Issue
Block a user