From 7a1749753b4853866f90ef25d48192e4d1563543 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Thu, 26 Feb 2026 11:06:00 +0100
Subject: [PATCH 3/4] core/cgroup: avoid one unnecessary strjoina()

(cherry picked from commit 42aee39107fbdd7db1ccd402a2151822b2805e9f)
(cherry picked from commit 80acea4ef80a4bb78560ed970c34952299b890d6)
(cherry picked from commit b5fd14693057e5f2c9b4a49603be64ec3608ff6c)

Note: This backport uses u->cgroup_path directly instead of the upstream
CGroupRuntime *crt / crt->cgroup_path pattern because the CGroupRuntime
struct was introduced in systemd v256 (commit 1d9cc876). In v255, the
cgroup_path is still a direct member of the Unit struct.

CVE: CVE-2026-29111
Upstream-Status: Backport [https://github.com/systemd/systemd/commit/21167006574d6b83813c7596759b474f56562412]
Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
---
 src/core/cgroup.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index d398655b0a..e5e7f032c2 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -2568,12 +2568,13 @@ static int unit_update_cgroup(
         return 0;
 }
 
-static int unit_attach_pid_to_cgroup_via_bus(Unit *u, pid_t pid, const char *suffix_path) {
+static int unit_attach_pid_to_cgroup_via_bus(Unit *u, const char *cgroup_path, pid_t pid) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-        char *pp;
         int r;
 
         assert(u);
+        assert(cgroup_path);
+        assert(pid_is_valid(pid));
 
         if (MANAGER_IS_SYSTEM(u->manager))
                 return -EINVAL;
@@ -2581,17 +2582,13 @@ static int unit_attach_pid_to_cgroup_via_bus(Unit *u, pid_t pid, const char *suf
         if (!u->manager->system_bus)
                 return -EIO;
 
-        if (!u->cgroup_path)
-                return -EINVAL;
-
         /* Determine this unit's cgroup path relative to our cgroup root */
-        pp = path_startswith(u->cgroup_path, u->manager->cgroup_root);
+        const char *pp = path_startswith_full(cgroup_path,
+                                              u->manager->cgroup_root,
+                                              PATH_STARTSWITH_RETURN_LEADING_SLASH|PATH_STARTSWITH_REFUSE_DOT_DOT);
         if (!pp)
                 return -EINVAL;
 
-        pp = strjoina("/", pp, suffix_path);
-        path_simplify(pp);
-
         r = bus_call_method(u->manager->system_bus,
                             bus_systemd_mgr,
                             "AttachProcessesToUnit",
@@ -2630,8 +2627,10 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
                 return r;
 
         if (isempty(suffix_path))
-                p = u->cgroup_path;
+                p = empty_to_root(u->cgroup_path);
         else {
+                assert(path_is_absolute(suffix_path));
+
                 joined = path_join(u->cgroup_path, suffix_path);
                 if (!joined)
                         return -ENOMEM;
@@ -2649,7 +2648,7 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
                  * before we use it */
                 r = pidref_verify(pid);
                 if (r < 0) {
-                        log_unit_info_errno(u, r, "PID " PID_FMT " vanished before we could move it to target cgroup '%s', skipping: %m", pid->pid, empty_to_root(p));
+                        log_unit_info_errno(u, r, "PID " PID_FMT " vanished before we could move it to target cgroup '%s', skipping: %m", pid->pid, p);
                         continue;
                 }
 
@@ -2660,7 +2659,7 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
 
                         log_unit_full_errno(u, again ? LOG_DEBUG : LOG_INFO,  r,
                                             "Couldn't move process "PID_FMT" to%s requested cgroup '%s': %m",
-                                            pid->pid, again ? " directly" : "", empty_to_root(p));
+                                            pid->pid, again ? " directly" : "", p);
 
                         if (again) {
                                 int z;
@@ -2670,9 +2669,9 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
                                  * Since it's more privileged it might be able to move the process across the
                                  * leaves of a subtree whose top node is not owned by us. */
 
-                                z = unit_attach_pid_to_cgroup_via_bus(u, pid->pid, suffix_path);
+                                z = unit_attach_pid_to_cgroup_via_bus(u, p, pid->pid);
                                 if (z < 0)
-                                        log_unit_info_errno(u, z, "Couldn't move process "PID_FMT" to requested cgroup '%s' (directly or via the system bus): %m", pid->pid, empty_to_root(p));
+                                        log_unit_info_errno(u, z, "Couldn't move process "PID_FMT" to requested cgroup '%s' (directly or via the system bus): %m", pid->pid, p);
                                 else {
                                         if (ret >= 0)
                                                 ret++; /* Count successful additions */
-- 
2.43.0
