diff options
author | Ray Strode <rstrode@redhat.com> | 2020-04-07 14:37:41 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2020-04-07 16:26:14 -0400 |
commit | f843233ad49fc1f4e8c85ca4753686ccbbbcf38e (patch) | |
tree | dfe854a1c67afd72711af0445fe892aa86dec230 /daemon | |
parent | 419cc94d3060c4cbaaa06239a7742004b6d8a8f0 (diff) | |
download | gdm-f843233ad49fc1f4e8c85ca4753686ccbbbcf38e.tar.gz |
session-worker: ensure initial vt is never picked for !is_initial displays
Normally, a !is_initial display would never "get" tty1, since the system
boots to tty1. But if, for some reason, the user booted to runlevel 3,
then switched to runlevel 5, the login screen could get started when
tty1 is free.
That means, e.g., an autologin user can end up getting allocated tty1,
which is bad, since we assume tty1 is used for the login screen.
This commit opens up /dev/tty1 when querying for available VTs, so that
it never gets returned by the kernel as available.
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/gdm-session-worker.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c index 1319907e..d2cfde51 100644 --- a/daemon/gdm-session-worker.c +++ b/daemon/gdm-session-worker.c @@ -2190,21 +2190,33 @@ gdm_session_worker_start_session (GdmSessionWorker *worker, static gboolean set_up_for_new_vt (GdmSessionWorker *worker) { - int fd; + int initial_vt_fd; char vt_string[256], tty_string[256]; int session_vt = 0; - fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); - - if (fd < 0) { - g_debug ("GdmSessionWorker: couldn't open VT master: %m"); + /* open the initial vt. We need it for two scenarios: + * + * 1) display_is_initial is TRUE. We need it directly. + * 2) display_is_initial is FALSE. We need it to mark + * the initial VT as "in use" so it doesn't get returned + * by VT_OPENQRY + * */ + g_snprintf (tty_string, sizeof (tty_string), "/dev/tty%d", GDM_INITIAL_VT); + initial_vt_fd = open (tty_string, O_RDWR | O_NOCTTY); + + if (initial_vt_fd < 0) { + g_debug ("GdmSessionWorker: couldn't open console of initial fd: %m"); return FALSE; } if (worker->priv->display_is_initial) { session_vt = GDM_INITIAL_VT; } else { - if (ioctl(fd, VT_OPENQRY, &session_vt) < 0) { + + /* Typically VT_OPENQRY is called on /dev/tty0, but we already + * have /dev/tty1 open above, so might as well use it. + */ + if (ioctl (initial_vt_fd, VT_OPENQRY, &session_vt) < 0) { g_debug ("GdmSessionWorker: couldn't open new VT: %m"); goto fail; } @@ -2212,9 +2224,6 @@ set_up_for_new_vt (GdmSessionWorker *worker) worker->priv->session_vt = session_vt; - close (fd); - fd = -1; - g_assert (session_vt > 0); g_snprintf (vt_string, sizeof (vt_string), "%d", session_vt); @@ -2227,14 +2236,20 @@ set_up_for_new_vt (GdmSessionWorker *worker) "XDG_VTNR", vt_string); - g_snprintf (tty_string, 256, "/dev/tty%d", session_vt); - worker->priv->session_tty_fd = open (tty_string, O_RDWR | O_NOCTTY); + if (worker->priv->display_is_initial) { + worker->priv->session_tty_fd = initial_vt_fd; + } else { + g_snprintf (tty_string, sizeof (tty_string), "/dev/tty%d", session_vt); + worker->priv->session_tty_fd = open (tty_string, O_RDWR | O_NOCTTY); + close (initial_vt_fd); + } + pam_set_item (worker->priv->pam_handle, PAM_TTY, tty_string); return TRUE; fail: - close (fd); + close (initial_vt_fd); return FALSE; } |