summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2020-04-07 14:37:41 -0400
committerRay Strode <rstrode@redhat.com>2020-04-07 16:26:14 -0400
commitf843233ad49fc1f4e8c85ca4753686ccbbbcf38e (patch)
treedfe854a1c67afd72711af0445fe892aa86dec230
parent419cc94d3060c4cbaaa06239a7742004b6d8a8f0 (diff)
downloadgdm-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.
-rw-r--r--daemon/gdm-session-worker.c39
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;
}