From 1a088b564aae220241ca2ef7f0d4ec732f97e29c Mon Sep 17 00:00:00 2001 From: Myrrh Periwinkle Date: Wed, 2 Jul 2025 12:53:15 +0700 Subject: [PATCH] logind: Don't match non-leader processes for utmp TTY determination This ensures we don't erroneously assign pseudoterminals created by terminal emulators that use utempter to register themselves in utmp when run under a GUI session that doesn't have a TTY assigned. --- src/login/logind-core.c | 22 ++++++++++++++++++++++ src/login/logind-utmp.c | 2 +- src/login/logind.h | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/login/logind-core.c b/src/login/logind-core.c index 3c51bc4a40a..2f8c7824d2a 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -393,6 +393,28 @@ int manager_get_session_by_pidref(Manager *m, const PidRef *pid, Session **ret) return !!s; } +int manager_get_session_by_leader(Manager *m, const PidRef *pid, Session **ret) { + Session *s; + int r; + + assert(m); + + if (!pidref_is_set(pid)) + return -EINVAL; + + s = hashmap_get(m->sessions_by_leader, pid); + if (s) { + r = pidref_verify(pid); + if (r < 0) + return r; + } + + if (ret) + *ret = s; + + return !!s; +} + int manager_get_user_by_pid(Manager *m, pid_t pid, User **ret) { _cleanup_free_ char *unit = NULL; User *u = NULL; diff --git a/src/login/logind-utmp.c b/src/login/logind-utmp.c index 8305ae743fa..2adfc082573 100644 --- a/src/login/logind-utmp.c +++ b/src/login/logind-utmp.c @@ -56,7 +56,7 @@ int manager_read_utmp(Manager *m) { if (isempty(t)) continue; - if (manager_get_session_by_pidref(m, &PIDREF_MAKE_FROM_PID(u->ut_pid), &s) <= 0) + if (manager_get_session_by_leader(m, &PIDREF_MAKE_FROM_PID(u->ut_pid), &s) <= 0) continue; if (s->tty_validity == TTY_FROM_UTMP && !streq_ptr(s->tty, t)) { diff --git a/src/login/logind.h b/src/login/logind.h index 6a46374e8ac..bc9ea97d801 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -163,6 +163,7 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t); int manager_get_user_by_pid(Manager *m, pid_t pid, User **user); int manager_get_session_by_pidref(Manager *m, const PidRef *pid, Session **ret); +int manager_get_session_by_leader(Manager *m, const PidRef *pid, Session **ret); bool manager_is_lid_closed(Manager *m); bool manager_is_docked_or_external_displays(Manager *m); -- 2.47.3