Skip to content

Commit 2a1d00c

Browse files
authored
systemd: add patches to correct ipc dbus communication issue (#16121)
1 parent 78c507b commit 2a1d00c

5 files changed

Lines changed: 407 additions & 1 deletion
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
From 69fd960a8d5a5aad6874cc11be6dc258ae7eef23 Mon Sep 17 00:00:00 2001
2+
From: Lennart Poettering <lennart@poettering.net>
3+
Date: Mon, 19 May 2025 12:58:52 +0200
4+
Subject: [PATCH 1/4] path-util: add flavour of path_startswith() that leaves a
5+
leading slash in place
6+
7+
(cherry picked from commit ee19edbb9f3455db3f750089082f3e5a925e3a0c)
8+
(cherry picked from commit 20021e7686426052e3a7505425d7e12085feb2a6)
9+
---
10+
src/basic/fs-util.c | 2 +-
11+
src/basic/mkdir.c | 4 ++--
12+
src/basic/path-util.c | 39 ++++++++++++++++++++++++++++-----------
13+
src/basic/path-util.h | 10 ++++++++--
14+
src/test/test-path-util.c | 16 ++++++++++++++++
15+
5 files changed, 55 insertions(+), 16 deletions(-)
16+
17+
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
18+
index 552986f546..8b2f6cc087 100644
19+
--- a/src/basic/fs-util.c
20+
+++ b/src/basic/fs-util.c
21+
@@ -67,7 +67,7 @@ int rmdir_parents(const char *path, const char *stop) {
22+
assert(*slash == '/');
23+
*slash = '\0';
24+
25+
- if (path_startswith_full(stop, p, /* accept_dot_dot= */ false))
26+
+ if (path_startswith_full(stop, p, /* flags= */ 0))
27+
return 0;
28+
29+
if (rmdir(p) < 0 && errno != ENOENT)
30+
diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c
31+
index 6e2b94d024..454739679c 100644
32+
--- a/src/basic/mkdir.c
33+
+++ b/src/basic/mkdir.c
34+
@@ -92,7 +92,7 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, ui
35+
assert(_mkdirat != mkdirat);
36+
37+
if (prefix) {
38+
- p = path_startswith_full(path, prefix, /* accept_dot_dot= */ false);
39+
+ p = path_startswith_full(path, prefix, /* flags= */ 0);
40+
if (!p)
41+
return -ENOTDIR;
42+
} else
43+
@@ -137,7 +137,7 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, ui
44+
45+
s[n] = '\0';
46+
47+
- if (!prefix || !path_startswith_full(prefix, path, /* accept_dot_dot= */ false)) {
48+
+ if (!prefix || !path_startswith_full(prefix, path, /* flags= */ 0)) {
49+
r = mkdir_safe_internal(path, mode, uid, gid, flags, _mkdirat);
50+
if (r < 0 && r != -EEXIST)
51+
return r;
52+
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
53+
index 4c952d863c..9b44d5735c 100644
54+
--- a/src/basic/path-util.c
55+
+++ b/src/basic/path-util.c
56+
@@ -424,8 +424,8 @@ int path_simplify_and_warn(
57+
return 0;
58+
}
59+
60+
-char *path_startswith_full(const char *path, const char *prefix, bool accept_dot_dot) {
61+
- assert(path);
62+
+char* path_startswith_full(const char *original_path, const char *prefix, PathStartWithFlags flags) {
63+
+ assert(original_path);
64+
assert(prefix);
65+
66+
/* Returns a pointer to the start of the first component after the parts matched by
67+
@@ -438,28 +438,45 @@ char *path_startswith_full(const char *path, const char *prefix, bool accept_dot
68+
* Returns NULL otherwise.
69+
*/
70+
71+
+ const char *path = original_path;
72+
+
73+
if ((path[0] == '/') != (prefix[0] == '/'))
74+
return NULL;
75+
76+
for (;;) {
77+
const char *p, *q;
78+
- int r, k;
79+
+ int m, n;
80+
81+
- r = path_find_first_component(&path, accept_dot_dot, &p);
82+
- if (r < 0)
83+
+ m = path_find_first_component(&path, FLAGS_SET(flags, PATH_STARTSWITH_ACCEPT_DOT_DOT), &p);
84+
+ if (m < 0)
85+
return NULL;
86+
87+
- k = path_find_first_component(&prefix, accept_dot_dot, &q);
88+
- if (k < 0)
89+
+ n = path_find_first_component(&prefix, FLAGS_SET(flags, PATH_STARTSWITH_ACCEPT_DOT_DOT), &q);
90+
+ if (n < 0)
91+
return NULL;
92+
93+
- if (k == 0)
94+
- return (char*) (p ?: path);
95+
+ if (n == 0) {
96+
+ if (!p)
97+
+ p = path;
98+
+
99+
+ if (FLAGS_SET(flags, PATH_STARTSWITH_RETURN_LEADING_SLASH)) {
100+
+
101+
+ if (p <= original_path)
102+
+ return NULL;
103+
+
104+
+ p--;
105+
+
106+
+ if (*p != '/')
107+
+ return NULL;
108+
+ }
109+
+
110+
+ return (char*) p;
111+
+ }
112+
113+
- if (r != k)
114+
+ if (m != n)
115+
return NULL;
116+
117+
- if (!strneq(p, q, r))
118+
+ if (!strneq(p, q, m))
119+
return NULL;
120+
}
121+
}
122+
diff --git a/src/basic/path-util.h b/src/basic/path-util.h
123+
index 518f3340bf..763d1fe1a1 100644
124+
--- a/src/basic/path-util.h
125+
+++ b/src/basic/path-util.h
126+
@@ -57,9 +57,15 @@ char* path_make_absolute(const char *p, const char *prefix);
127+
int safe_getcwd(char **ret);
128+
int path_make_absolute_cwd(const char *p, char **ret);
129+
int path_make_relative(const char *from, const char *to, char **ret);
130+
-char *path_startswith_full(const char *path, const char *prefix, bool accept_dot_dot) _pure_;
131+
+
132+
+typedef enum PathStartWithFlags {
133+
+ PATH_STARTSWITH_ACCEPT_DOT_DOT = 1U << 0,
134+
+ PATH_STARTSWITH_RETURN_LEADING_SLASH = 1U << 1,
135+
+} PathStartWithFlags;
136+
+
137+
+char* path_startswith_full(const char *path, const char *prefix, PathStartWithFlags flags) _pure_;
138+
static inline char* path_startswith(const char *path, const char *prefix) {
139+
- return path_startswith_full(path, prefix, true);
140+
+ return path_startswith_full(path, prefix, PATH_STARTSWITH_ACCEPT_DOT_DOT);
141+
}
142+
int path_compare(const char *a, const char *b) _pure_;
143+
144+
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
145+
index b9c4ef4126..c9794244d7 100644
146+
--- a/src/test/test-path-util.c
147+
+++ b/src/test/test-path-util.c
148+
@@ -541,6 +541,22 @@ TEST(path_startswith) {
149+
test_path_startswith_one("/foo/bar/barfoo/", "/fo", NULL, NULL);
150+
}
151+
152+
+static void test_path_startswith_return_leading_slash_one(const char *path, const char *prefix, const char *expected) {
153+
+ const char *p;
154+
+
155+
+ log_debug("/* %s(%s, %s) */", __func__, path, prefix);
156+
+
157+
+ p = path_startswith_full(path, prefix, PATH_STARTSWITH_RETURN_LEADING_SLASH);
158+
+ assert_se(streq(p, expected));
159+
+}
160+
+
161+
+TEST(path_startswith_return_leading_slash) {
162+
+ test_path_startswith_return_leading_slash_one("/foo/bar", "/", "/foo/bar");
163+
+ test_path_startswith_return_leading_slash_one("/foo/bar", "/foo", "/bar");
164+
+ test_path_startswith_return_leading_slash_one("/foo/bar", "/foo/bar", NULL);
165+
+ test_path_startswith_return_leading_slash_one("/foo/bar/", "/foo/bar", "/");
166+
+}
167+
+
168+
static void test_prefix_root_one(const char *r, const char *p, const char *expected) {
169+
_cleanup_free_ char *s = NULL;
170+
const char *t;
171+
--
172+
2.51.0
173+
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
From 0b9afe68a36c751113e5abbc41964adb42009b16 Mon Sep 17 00:00:00 2001
2+
From: Lennart Poettering <lennart@poettering.net>
3+
Date: Fri, 23 May 2025 06:45:40 +0200
4+
Subject: [PATCH 2/4] path-util: invert PATH_STARTSWITH_ACCEPT_DOT_DOT flag
5+
6+
As requested: https://github.com/systemd/systemd/pull/37572#pullrequestreview-2861928094
7+
8+
(cherry picked from commit ceed11e465f1c8efff1931412a85924d9de7c08d)
9+
(cherry picked from commit 7ac3220213690e8a8d6d2a6e81e43bd1dce01d69)
10+
---
11+
src/basic/fs-util.c | 2 +-
12+
src/basic/mkdir.c | 4 ++--
13+
src/basic/path-util.c | 4 ++--
14+
src/basic/path-util.h | 4 ++--
15+
4 files changed, 7 insertions(+), 7 deletions(-)
16+
17+
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
18+
index 8b2f6cc087..5e853a863a 100644
19+
--- a/src/basic/fs-util.c
20+
+++ b/src/basic/fs-util.c
21+
@@ -67,7 +67,7 @@ int rmdir_parents(const char *path, const char *stop) {
22+
assert(*slash == '/');
23+
*slash = '\0';
24+
25+
- if (path_startswith_full(stop, p, /* flags= */ 0))
26+
+ if (path_startswith_full(stop, p, PATH_STARTSWITH_REFUSE_DOT_DOT))
27+
return 0;
28+
29+
if (rmdir(p) < 0 && errno != ENOENT)
30+
diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c
31+
index 454739679c..361c142ebe 100644
32+
--- a/src/basic/mkdir.c
33+
+++ b/src/basic/mkdir.c
34+
@@ -92,7 +92,7 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, ui
35+
assert(_mkdirat != mkdirat);
36+
37+
if (prefix) {
38+
- p = path_startswith_full(path, prefix, /* flags= */ 0);
39+
+ p = path_startswith_full(path, prefix, PATH_STARTSWITH_REFUSE_DOT_DOT);
40+
if (!p)
41+
return -ENOTDIR;
42+
} else
43+
@@ -137,7 +137,7 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, ui
44+
45+
s[n] = '\0';
46+
47+
- if (!prefix || !path_startswith_full(prefix, path, /* flags= */ 0)) {
48+
+ if (!prefix || !path_startswith_full(prefix, path, PATH_STARTSWITH_REFUSE_DOT_DOT)) {
49+
r = mkdir_safe_internal(path, mode, uid, gid, flags, _mkdirat);
50+
if (r < 0 && r != -EEXIST)
51+
return r;
52+
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
53+
index 9b44d5735c..47266b8206 100644
54+
--- a/src/basic/path-util.c
55+
+++ b/src/basic/path-util.c
56+
@@ -447,11 +447,11 @@ char* path_startswith_full(const char *original_path, const char *prefix, PathSt
57+
const char *p, *q;
58+
int m, n;
59+
60+
- m = path_find_first_component(&path, FLAGS_SET(flags, PATH_STARTSWITH_ACCEPT_DOT_DOT), &p);
61+
+ m = path_find_first_component(&path, !FLAGS_SET(flags, PATH_STARTSWITH_REFUSE_DOT_DOT), &p);
62+
if (m < 0)
63+
return NULL;
64+
65+
- n = path_find_first_component(&prefix, FLAGS_SET(flags, PATH_STARTSWITH_ACCEPT_DOT_DOT), &q);
66+
+ n = path_find_first_component(&prefix, !FLAGS_SET(flags, PATH_STARTSWITH_REFUSE_DOT_DOT), &q);
67+
if (n < 0)
68+
return NULL;
69+
70+
diff --git a/src/basic/path-util.h b/src/basic/path-util.h
71+
index 763d1fe1a1..c16c525464 100644
72+
--- a/src/basic/path-util.h
73+
+++ b/src/basic/path-util.h
74+
@@ -59,13 +59,13 @@ int path_make_absolute_cwd(const char *p, char **ret);
75+
int path_make_relative(const char *from, const char *to, char **ret);
76+
77+
typedef enum PathStartWithFlags {
78+
- PATH_STARTSWITH_ACCEPT_DOT_DOT = 1U << 0,
79+
+ PATH_STARTSWITH_REFUSE_DOT_DOT = 1U << 0,
80+
PATH_STARTSWITH_RETURN_LEADING_SLASH = 1U << 1,
81+
} PathStartWithFlags;
82+
83+
char* path_startswith_full(const char *path, const char *prefix, PathStartWithFlags flags) _pure_;
84+
static inline char* path_startswith(const char *path, const char *prefix) {
85+
- return path_startswith_full(path, prefix, PATH_STARTSWITH_ACCEPT_DOT_DOT);
86+
+ return path_startswith_full(path, prefix, 0);
87+
}
88+
int path_compare(const char *a, const char *b) _pure_;
89+
90+
--
91+
2.51.0
92+
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
From 9f9c7d231d80e68f4d2117a02bb53f8c2949f048 Mon Sep 17 00:00:00 2001
2+
From: Mike Yuan <me@yhndnzj.com>
3+
Date: Thu, 26 Feb 2026 11:06:00 +0100
4+
Subject: [PATCH 3/4] core/cgroup: avoid one unnecessary strjoina()
5+
6+
(cherry picked from commit 42aee39107fbdd7db1ccd402a2151822b2805e9f)
7+
(cherry picked from commit 80acea4ef80a4bb78560ed970c34952299b890d6)
8+
(cherry picked from commit b5fd14693057e5f2c9b4a49603be64ec3608ff6c)
9+
(cherry picked from commit 21167006574d6b83813c7596759b474f56562412)
10+
---
11+
src/core/cgroup.c | 29 ++++++++++++++---------------
12+
1 file changed, 14 insertions(+), 15 deletions(-)
13+
14+
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
15+
index f58de95a49..5b8591ca97 100644
16+
--- a/src/core/cgroup.c
17+
+++ b/src/core/cgroup.c
18+
@@ -2221,12 +2221,13 @@ static int unit_update_cgroup(
19+
return 0;
20+
}
21+
22+
-static int unit_attach_pid_to_cgroup_via_bus(Unit *u, pid_t pid, const char *suffix_path) {
23+
+static int unit_attach_pid_to_cgroup_via_bus(Unit *u, const char *cgroup_path, pid_t pid) {
24+
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
25+
- char *pp;
26+
int r;
27+
28+
assert(u);
29+
+ assert(cgroup_path);
30+
+ assert(pid_is_valid(pid));
31+
32+
if (MANAGER_IS_SYSTEM(u->manager))
33+
return -EINVAL;
34+
@@ -2234,17 +2235,13 @@ static int unit_attach_pid_to_cgroup_via_bus(Unit *u, pid_t pid, const char *suf
35+
if (!u->manager->system_bus)
36+
return -EIO;
37+
38+
- if (!u->cgroup_path)
39+
- return -EINVAL;
40+
-
41+
/* Determine this unit's cgroup path relative to our cgroup root */
42+
- pp = path_startswith(u->cgroup_path, u->manager->cgroup_root);
43+
+ const char *pp = path_startswith_full(cgroup_path,
44+
+ u->manager->cgroup_root,
45+
+ PATH_STARTSWITH_RETURN_LEADING_SLASH|PATH_STARTSWITH_REFUSE_DOT_DOT);
46+
if (!pp)
47+
return -EINVAL;
48+
49+
- pp = strjoina("/", pp, suffix_path);
50+
- path_simplify(pp);
51+
-
52+
r = sd_bus_call_method(u->manager->system_bus,
53+
"org.freedesktop.systemd1",
54+
"/org/freedesktop/systemd1",
55+
@@ -2284,9 +2281,11 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
56+
return r;
57+
58+
if (isempty(suffix_path))
59+
- p = u->cgroup_path;
60+
- else
61+
+ p = empty_to_root(u->cgroup_path);
62+
+ else {
63+
+ assert(path_is_absolute(suffix_path));
64+
p = prefix_roota(u->cgroup_path, suffix_path);
65+
+ }
66+
67+
delegated_mask = unit_get_delegate_mask(u);
68+
69+
@@ -2301,7 +2300,7 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
70+
71+
log_unit_full_errno(u, again ? LOG_DEBUG : LOG_INFO, r,
72+
"Couldn't move process "PID_FMT" to%s requested cgroup '%s': %m",
73+
- pid, again ? " directly" : "", empty_to_root(p));
74+
+ pid, again ? " directly" : "", p);
75+
76+
if (again) {
77+
int z;
78+
@@ -2311,9 +2310,9 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
79+
* Since it's more privileged it might be able to move the process across the
80+
* leaves of a subtree whose top node is not owned by us. */
81+
82+
- z = unit_attach_pid_to_cgroup_via_bus(u, pid, suffix_path);
83+
+ z = unit_attach_pid_to_cgroup_via_bus(u, p, pid);
84+
if (z < 0)
85+
- log_unit_info_errno(u, z, "Couldn't move process "PID_FMT" to requested cgroup '%s' (directly or via the system bus): %m", pid, empty_to_root(p));
86+
+ log_unit_info_errno(u, z, "Couldn't move process "PID_FMT" to requested cgroup '%s' (directly or via the system bus): %m", pid, p);
87+
else {
88+
if (ret >= 0)
89+
ret++; /* Count successful additions */
90+
@@ -2351,7 +2350,7 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
91+
continue; /* Success! */
92+
93+
log_unit_debug_errno(u, r, "Failed to attach PID " PID_FMT " to requested cgroup %s in controller %s, falling back to unit's cgroup: %m",
94+
- pid, empty_to_root(p), cgroup_controller_to_string(c));
95+
+ pid, p, cgroup_controller_to_string(c));
96+
}
97+
98+
/* So this controller is either not delegate or realized, or something else weird happened. In
99+
--
100+
2.51.0
101+

0 commit comments

Comments
 (0)