]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
homed: Ensure closed FD is handled before bus req
authorAdrian Vovk <adrianvovk@gmail.com>
Thu, 21 Mar 2024 17:51:16 +0000 (13:51 -0400)
committerLuca Boccassi <luca.boccassi@gmail.com>
Sat, 23 Mar 2024 01:04:51 +0000 (01:04 +0000)
Before this fix, the following sequence of events was possible:
1. A client holding a Ref() FD closes their FD
2. kernel sends notification that all clients closed their FDs
3. Another client obtains its own Ref() FD from homed
4. homed handles the notification that all clients have closed their
   Ref() FDs. Thus it loses track of the fact that the session is
   actually still being held open by the client from step 3

This change makes sure that homed won't respond to bus messages (and
thus won't open more Ref() FDs) until it has handled all notifications
about the existing FDs being closed.

logind has had a very similar fix applied to it in
e11544a8305ab9dea097c74bb16e296150c9cc10

Fixes https://github.com/systemd/systemd/issues/31518

src/home/homed-home.c
src/home/homed-manager.c

index e1379f51f5840e8bd3ac7d71f3889258d27e2786..09e86f37f36b03f943e18308b6336ba8c9fc8675 100644 (file)
@@ -2756,7 +2756,9 @@ int home_create_fifo(Home *h, bool please_suspend) {
 
                 (void) sd_event_source_set_description(*ss, "acquire-ref");
 
-                r = sd_event_source_set_priority(*ss, SD_EVENT_PRIORITY_IDLE-1);
+                /* We need to notice dropped refs before we process new bus requests (which
+                 * might try to obtain new refs) */
+                r = sd_event_source_set_priority(*ss, SD_EVENT_PRIORITY_NORMAL-10);
                 if (r < 0)
                         return r;
 
index 0653eeef784cfda56668cf5ae6d09f2054e76d72..d4eaf1821b4e49988d92b7bfe4a85d832f5fae75 100644 (file)
@@ -991,7 +991,7 @@ static int manager_connect_bus(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to request name: %m");
 
-        r = sd_bus_attach_event(m->bus, m->event, 0);
+        r = sd_bus_attach_event(m->bus, m->event, SD_EVENT_PRIORITY_NORMAL);
         if (r < 0)
                 return log_error_errno(r, "Failed to attach bus to event loop: %m");