]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: set session->started before seat_read_active_vt() call
authorcountgitmick <263313427+countgitmick@users.noreply.github.com>
Thu, 9 Apr 2026 07:53:03 +0000 (00:53 -0700)
committerLennart Poettering <lennart@poettering.net>
Thu, 9 Jul 2026 08:17:46 +0000 (10:17 +0200)
session_start() calls seat_read_active_vt() before setting
s->started = true. seat_read_active_vt() can reach
seat_triggered_uevents_done() synchronously via:

  seat_active_vt_changed -> seat_set_active -> seat_trigger_devices
  -> seat_triggered_uevents_done

When seat_trigger_devices() produces no pending uevents,
seat_triggered_uevents_done() runs in the same call stack as
session_start() and tests session->started before the assignment
further down. The check fails, session_device_resume_all() is
skipped, and the compositor never receives DRM master.

Set started before seat_read_active_vt() so the gate sees the
correct value, and document the ordering constraint at the call
site to prevent regression.

Reproducible with greetd plus a Wayland compositor on the same VT
on kernel 6.19+.

Fixes: #41562
Signed-off-by: countgitmick <263313427+countgitmick@users.noreply.github.com>
src/login/logind-session.c

index e62a5768da69325668b52969da48566bf8805c2e..f5fb47920749c2e3aa64669c4a0516626f898f16 100644 (file)
@@ -923,11 +923,14 @@ int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error) {
         if (!dual_timestamp_is_set(&s->timestamp))
                 dual_timestamp_now(&s->timestamp);
 
+        /* Must be set before seat_read_active_vt(); the activation it
+         * triggers reaches seat_triggered_uevents_done() synchronously
+         * and gates session_device_resume_all() on s->started. */
+        s->started = true;
+
         if (s->seat)
                 seat_read_active_vt(s->seat);
 
-        s->started = true;
-
         user_elect_display(s->user);
 
         /* Save data */