From d34cf29b3831637cd3c79045b68440d34c19eeec Mon Sep 17 00:00:00 2001 From: Daniel De Graaf <code@danieldg.net> Date: Tue, 25 Mar 2025 22:32:19 -0400 Subject: [PATCH] Move cgroup dbus requests to the child This avoids a race where a spawned child that quickly forks will have only the parent process moved to the newly created cgroup, leaving the early children in tmux's own cgroup. It also avoids problems if the spawned process inspects or changes its own cgroup. --- compat.h | 2 +- compat/systemd.c | 7 ++++--- spawn.c | 21 ++++++++++----------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/compat.h b/compat.h index 93928603..bdc77513 100644 --- a/compat.h +++ b/compat.h @@ -450,7 +450,7 @@ void *recallocarray(void *, size_t, size_t, size_t); /* systemd.c */ int systemd_activated(void); int systemd_create_socket(int, char **); -int systemd_move_pid_to_new_cgroup(pid_t, char **); +int systemd_move_to_new_cgroup(char **); #endif #ifdef HAVE_UTF8PROC diff --git a/compat/systemd.c b/compat/systemd.c index 22773c42..b3d51b81 100644 --- a/compat/systemd.c +++ b/compat/systemd.c @@ -76,7 +76,7 @@ fail: } int -systemd_move_pid_to_new_cgroup(pid_t pid, char **cause) +systemd_move_to_new_cgroup(char **cause) { sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus_message *m = NULL, *reply = NULL; @@ -84,7 +84,7 @@ systemd_move_pid_to_new_cgroup(pid_t pid, char **cause) char *name, *desc, *slice; sd_id128_t uuid; int r; - pid_t parent_pid; + pid_t pid, parent_pid; /* Connect to the session bus. */ r = sd_bus_default_user(&bus); @@ -138,7 +138,8 @@ systemd_move_pid_to_new_cgroup(pid_t pid, char **cause) goto finish; } - parent_pid = getpid(); + pid = getpid(); + parent_pid = getppid(); xasprintf(&desc, "tmux child pane %ld launched by process %ld", (long)pid, (long)parent_pid); r = sd_bus_message_append(m, "(sv)", "Description", "s", desc); diff --git a/spawn.c b/spawn.c index d321dba4..0342ea03 100644 --- a/spawn.c +++ b/spawn.c @@ -382,20 +382,19 @@ spawn_pane(struct spawn_context *sc, char **cause) /* In the parent process, everything is done now. */ if (new_wp->pid != 0) { -#if defined(HAVE_SYSTEMD) && defined(ENABLE_CGROUPS) - /* - * Move the child process into a new cgroup for systemd-oomd - * isolation. - */ - if (systemd_move_pid_to_new_cgroup(new_wp->pid, cause) < 0) { - log_debug("%s: moving pane to new cgroup failed: %s", - __func__, *cause); - free (*cause); - } -#endif goto complete; } +#if defined(HAVE_SYSTEMD) && defined(ENABLE_CGROUPS) + /* + * Move the child process into a new cgroup for systemd-oomd isolation. + */ + if (systemd_move_to_new_cgroup(cause) < 0) { + log_debug("%s: moving pane to new cgroup failed: %s", + __func__, *cause); + free (*cause); + } +#endif /* * Child process. Change to the working directory or home if that * fails.