|
|
b4ba5df |
From 25abc02995b91351fc48bd41c1824944d9225fe6 Mon Sep 17 00:00:00 2001
|
|
|
b4ba5df |
From: Ray Strode <rstrode@redhat.com>
|
|
|
b4ba5df |
Date: Tue, 7 Apr 2020 14:37:41 -0400
|
|
|
b4ba5df |
Subject: [PATCH] session-worker: ensure initial vt is never picked for
|
|
|
b4ba5df |
!is_initial displays
|
|
|
b4ba5df |
|
|
|
b4ba5df |
Normally, a !is_initial display would never "get" tty1, since the system
|
|
|
b4ba5df |
boots to tty1. But if, for some reason, the user booted to runlevel 3,
|
|
|
b4ba5df |
then switched to runlevel 5, the login screen could get started when
|
|
|
b4ba5df |
tty1 is free.
|
|
|
b4ba5df |
|
|
|
b4ba5df |
That means, e.g., an autologin user can end up getting allocated tty1,
|
|
|
b4ba5df |
which is bad, since we assume tty1 is used for the login screen.
|
|
|
b4ba5df |
|
|
|
b4ba5df |
This commit opens up /dev/tty1 when querying for available VTs, so that
|
|
|
b4ba5df |
it never gets returned by the kernel as available.
|
|
|
b4ba5df |
---
|
|
|
b4ba5df |
daemon/gdm-session-worker.c | 39 ++++++++++++++------
|
|
|
b4ba5df |
data/applications/mime-dummy-handler.desktop | 7 +---
|
|
|
b4ba5df |
2 files changed, 28 insertions(+), 18 deletions(-)
|
|
|
b4ba5df |
|
|
|
b4ba5df |
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
|
|
|
b4ba5df |
index 5acf55868..cb983302e 100644
|
|
|
b4ba5df |
--- a/daemon/gdm-session-worker.c
|
|
|
b4ba5df |
+++ b/daemon/gdm-session-worker.c
|
|
|
b4ba5df |
@@ -2163,105 +2163,120 @@ gdm_session_worker_start_session (GdmSessionWorker *worker,
|
|
|
b4ba5df |
|
|
|
b4ba5df |
/* If we end up execing again, make sure we don't use the executable context set up
|
|
|
b4ba5df |
* by pam_selinux durin pam_open_session
|
|
|
b4ba5df |
*/
|
|
|
b4ba5df |
#ifdef HAVE_SELINUX
|
|
|
b4ba5df |
setexeccon (NULL);
|
|
|
b4ba5df |
#endif
|
|
|
b4ba5df |
|
|
|
b4ba5df |
worker->priv->child_pid = session_pid;
|
|
|
b4ba5df |
|
|
|
b4ba5df |
g_debug ("GdmSessionWorker: session opened creating reply...");
|
|
|
b4ba5df |
g_assert (sizeof (GPid) <= sizeof (int));
|
|
|
b4ba5df |
|
|
|
b4ba5df |
g_debug ("GdmSessionWorker: state SESSION_STARTED");
|
|
|
b4ba5df |
gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SESSION_STARTED);
|
|
|
b4ba5df |
|
|
|
b4ba5df |
gdm_session_worker_watch_child (worker);
|
|
|
b4ba5df |
|
|
|
b4ba5df |
out:
|
|
|
b4ba5df |
if (error_code != PAM_SUCCESS) {
|
|
|
b4ba5df |
gdm_session_worker_uninitialize_pam (worker, error_code);
|
|
|
b4ba5df |
return FALSE;
|
|
|
b4ba5df |
}
|
|
|
b4ba5df |
|
|
|
b4ba5df |
return TRUE;
|
|
|
b4ba5df |
}
|
|
|
b4ba5df |
|
|
|
b4ba5df |
static gboolean
|
|
|
b4ba5df |
set_up_for_new_vt (GdmSessionWorker *worker)
|
|
|
b4ba5df |
{
|
|
|
b4ba5df |
- int fd;
|
|
|
b4ba5df |
+ int initial_vt_fd;
|
|
|
b4ba5df |
char vt_string[256], tty_string[256];
|
|
|
b4ba5df |
int session_vt = 0;
|
|
|
b4ba5df |
|
|
|
b4ba5df |
- fd = open ("/dev/tty0", O_RDWR | O_NOCTTY);
|
|
|
b4ba5df |
-
|
|
|
b4ba5df |
- if (fd < 0) {
|
|
|
b4ba5df |
- g_debug ("GdmSessionWorker: couldn't open VT master: %m");
|
|
|
b4ba5df |
+ /* open the initial vt. We need it for two scenarios:
|
|
|
b4ba5df |
+ *
|
|
|
b4ba5df |
+ * 1) display_is_initial is TRUE. We need it directly.
|
|
|
b4ba5df |
+ * 2) display_is_initial is FALSE. We need it to mark
|
|
|
b4ba5df |
+ * the initial VT as "in use" so it doesn't get returned
|
|
|
b4ba5df |
+ * by VT_OPENQRY
|
|
|
b4ba5df |
+ * */
|
|
|
b4ba5df |
+ g_snprintf (tty_string, sizeof (tty_string), "/dev/tty%d", GDM_INITIAL_VT);
|
|
|
b4ba5df |
+ initial_vt_fd = open (tty_string, O_RDWR | O_NOCTTY);
|
|
|
b4ba5df |
+
|
|
|
b4ba5df |
+ if (initial_vt_fd < 0) {
|
|
|
b4ba5df |
+ g_debug ("GdmSessionWorker: couldn't open console of initial fd: %m");
|
|
|
b4ba5df |
return FALSE;
|
|
|
b4ba5df |
}
|
|
|
b4ba5df |
|
|
|
b4ba5df |
if (worker->priv->display_is_initial) {
|
|
|
b4ba5df |
session_vt = GDM_INITIAL_VT;
|
|
|
b4ba5df |
} else {
|
|
|
b4ba5df |
- if (ioctl(fd, VT_OPENQRY, &session_vt) < 0) {
|
|
|
b4ba5df |
+
|
|
|
b4ba5df |
+ /* Typically VT_OPENQRY is called on /dev/tty0, but we already
|
|
|
b4ba5df |
+ * have /dev/tty1 open above, so might as well use it.
|
|
|
b4ba5df |
+ */
|
|
|
b4ba5df |
+ if (ioctl (initial_vt_fd, VT_OPENQRY, &session_vt) < 0) {
|
|
|
b4ba5df |
g_debug ("GdmSessionWorker: couldn't open new VT: %m");
|
|
|
b4ba5df |
goto fail;
|
|
|
b4ba5df |
}
|
|
|
b4ba5df |
}
|
|
|
b4ba5df |
|
|
|
b4ba5df |
worker->priv->session_vt = session_vt;
|
|
|
b4ba5df |
|
|
|
b4ba5df |
- close (fd);
|
|
|
b4ba5df |
- fd = -1;
|
|
|
b4ba5df |
-
|
|
|
b4ba5df |
g_assert (session_vt > 0);
|
|
|
b4ba5df |
|
|
|
b4ba5df |
g_snprintf (vt_string, sizeof (vt_string), "%d", session_vt);
|
|
|
b4ba5df |
|
|
|
b4ba5df |
/* Set the VTNR. This is used by logind to configure a session in
|
|
|
b4ba5df |
* the logind-managed case, but it doesn't hurt to set it always.
|
|
|
b4ba5df |
* When logind gains support for XDG_VTNR=auto, we can make the
|
|
|
b4ba5df |
* OPENQRY and this whole path only used by the new VT code. */
|
|
|
b4ba5df |
gdm_session_worker_set_environment_variable (worker,
|
|
|
b4ba5df |
"XDG_VTNR",
|
|
|
b4ba5df |
vt_string);
|
|
|
b4ba5df |
|
|
|
b4ba5df |
- g_snprintf (tty_string, 256, "/dev/tty%d", session_vt);
|
|
|
b4ba5df |
- worker->priv->session_tty_fd = open (tty_string, O_RDWR | O_NOCTTY);
|
|
|
b4ba5df |
+ if (worker->priv->display_is_initial) {
|
|
|
b4ba5df |
+ worker->priv->session_tty_fd = initial_vt_fd;
|
|
|
b4ba5df |
+ } else {
|
|
|
b4ba5df |
+ g_snprintf (tty_string, sizeof (tty_string), "/dev/tty%d", session_vt);
|
|
|
b4ba5df |
+ worker->priv->session_tty_fd = open (tty_string, O_RDWR | O_NOCTTY);
|
|
|
b4ba5df |
+ close (initial_vt_fd);
|
|
|
b4ba5df |
+ }
|
|
|
b4ba5df |
+
|
|
|
b4ba5df |
pam_set_item (worker->priv->pam_handle, PAM_TTY, tty_string);
|
|
|
b4ba5df |
|
|
|
b4ba5df |
return TRUE;
|
|
|
b4ba5df |
|
|
|
b4ba5df |
fail:
|
|
|
b4ba5df |
- close (fd);
|
|
|
b4ba5df |
+ close (initial_vt_fd);
|
|
|
b4ba5df |
return FALSE;
|
|
|
b4ba5df |
}
|
|
|
b4ba5df |
|
|
|
b4ba5df |
static gboolean
|
|
|
b4ba5df |
set_xdg_vtnr_to_current_vt (GdmSessionWorker *worker)
|
|
|
b4ba5df |
{
|
|
|
b4ba5df |
int fd;
|
|
|
b4ba5df |
char vt_string[256];
|
|
|
b4ba5df |
struct vt_stat vt_state = { 0 };
|
|
|
b4ba5df |
|
|
|
b4ba5df |
fd = open ("/dev/tty0", O_RDWR | O_NOCTTY);
|
|
|
b4ba5df |
|
|
|
b4ba5df |
if (fd < 0) {
|
|
|
b4ba5df |
g_debug ("GdmSessionWorker: couldn't open VT master: %m");
|
|
|
b4ba5df |
return FALSE;
|
|
|
b4ba5df |
}
|
|
|
b4ba5df |
|
|
|
b4ba5df |
if (ioctl (fd, VT_GETSTATE, &vt_state) < 0) {
|
|
|
b4ba5df |
g_debug ("GdmSessionWorker: couldn't get current VT: %m");
|
|
|
b4ba5df |
goto fail;
|
|
|
b4ba5df |
}
|
|
|
b4ba5df |
|
|
|
b4ba5df |
close (fd);
|
|
|
b4ba5df |
fd = -1;
|
|
|
b4ba5df |
|
|
|
b4ba5df |
g_snprintf (vt_string, sizeof (vt_string), "%d", vt_state.v_active);
|
|
|
b4ba5df |
|
|
|
b4ba5df |
gdm_session_worker_set_environment_variable (worker,
|
|
|
b4ba5df |
"XDG_VTNR",
|
|
|
b4ba5df |
vt_string);
|
|
|
b4ba5df |
diff --git a/data/applications/mime-dummy-handler.desktop b/data/applications/mime-dummy-handler.desktop
|
|
|
b4ba5df |
index 8f6623ebc..ca405e5c1 100644
|
|
|
b4ba5df |
--- a/data/applications/mime-dummy-handler.desktop
|
|
|
b4ba5df |
+++ b/data/applications/mime-dummy-handler.desktop
|
|
|
b4ba5df |
@@ -1,6 +1 @@
|
|
|
b4ba5df |
-[Desktop Entry]
|
|
|
b4ba5df |
-Type=Application
|
|
|
b4ba5df |
-Name=Dummy URI Handler
|
|
|
b4ba5df |
-Exec=true %U
|
|
|
b4ba5df |
-Terminal=false
|
|
|
b4ba5df |
-StartupNotify=false
|
|
|
b4ba5df |
+[Default Applications]
|
|
|
b4ba5df |
--
|
|
|
b4ba5df |
2.21.1
|
|
|
b4ba5df |
|