From 68c703872cf4816d6ea0f54745fa9516616a85f3 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Tue, 27 May 2025 16:55:43 +0200 Subject: [PATCH 1/3] string-table: drop unneeded initialization --- src/basic/string-table.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/basic/string-table.c b/src/basic/string-table.c index fa3cc15743..069cb40ec1 100644 --- a/src/basic/string-table.c +++ b/src/basic/string-table.c @@ -42,6 +42,7 @@ int string_table_lookup_to_string_fallback(const char * const *table, size_t len if (i < 0 || i > (ssize_t) max) return -ERANGE; + if (i < (ssize_t) len && table[i]) { s = strdup(table[i]); if (!s) @@ -54,14 +55,14 @@ int string_table_lookup_to_string_fallback(const char * const *table, size_t len } ssize_t string_table_lookup_from_string_fallback(const char * const *table, size_t len, const char *s, size_t max) { - unsigned u = 0; - if (!s) return -EINVAL; ssize_t i = string_table_lookup_from_string(table, len, s); if (i >= 0) return i; + + unsigned u; if (safe_atou(s, &u) < 0) return -EINVAL; if (u > max) From d33104eba24bd72bcdccf8dbe0a4ec837ca03903 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Tue, 27 May 2025 18:32:44 +0200 Subject: [PATCH 2/3] cgroup-util: clean up skip_{slices,session,user_manager} Let's avoid obscure memcmp()s in skip_* and instead use strndupa() to extract the bits we care and call usual string routines on it. --- src/basic/cgroup-util.c | 89 ++++++++++++++--------------------------- src/basic/cgroup-util.h | 2 +- 2 files changed, 32 insertions(+), 59 deletions(-) diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 54d845a87b..f68b2103f8 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -933,28 +933,19 @@ int cg_path_decode_unit(const char *cgroup, char **ret_unit) { } static bool valid_slice_name(const char *p, size_t n) { - - if (!p) - return false; + assert(p || n == 0); if (n < STRLEN("x.slice")) return false; - if (memcmp(p + n - 6, ".slice", 6) == 0) { - char buf[n+1], *c; + char *c = strndupa_safe(p, n); + if (!endswith(c, ".slice")) + return false; - memcpy(buf, p, n); - buf[n] = 0; - - c = cg_unescape(buf); - - return unit_name_is_valid(c, UNIT_NAME_PLAIN); - } - - return false; + return unit_name_is_valid(cg_unescape(c), UNIT_NAME_PLAIN); } -static const char *skip_slices(const char *p) { +static const char* skip_slices(const char *p) { assert(p); /* Skips over all slice assignments */ @@ -1005,7 +996,7 @@ int cg_path_get_unit_path(const char *path, char **ret) { if (!path_copy) return -ENOMEM; - unit_name = (char *)skip_slices(path_copy); + unit_name = (char*) skip_slices(path_copy); unit_name[strcspn(unit_name, "/")] = 0; if (!unit_name_is_valid(cg_unescape(unit_name), UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) @@ -1052,12 +1043,11 @@ int cg_pidref_get_unit(const PidRef *pidref, char **ret) { return 0; } -/** - * Skip session-*.scope, but require it to be there. - */ -static const char *skip_session(const char *p) { +static const char* skip_session(const char *p) { size_t n; + /* Skip session-*.scope, but require it to be there. */ + if (isempty(p)) return NULL; @@ -1067,34 +1057,29 @@ static const char *skip_session(const char *p) { if (n < STRLEN("session-x.scope")) return NULL; - if (memcmp(p, "session-", 8) == 0 && memcmp(p + n - 6, ".scope", 6) == 0) { - char buf[n - 8 - 6 + 1]; + const char *s = startswith(p, "session-"); + if (!s) + return NULL; - memcpy(buf, p + 8, n - 8 - 6); - buf[n - 8 - 6] = 0; + /* Note that session scopes never need unescaping, since they cannot conflict with the kernel's + * own names, hence we don't need to call cg_unescape() here. */ + char *f = strndupa_safe(s, p + n - s), + *e = endswith(f, ".scope"); + if (!e) + return NULL; + *e = '\0'; - /* Note that session scopes never need unescaping, - * since they cannot conflict with the kernel's own - * names, hence we don't need to call cg_unescape() - * here. */ + if (!session_id_valid(f)) + return NULL; - if (!session_id_valid(buf)) - return NULL; - - p += n; - p += strspn(p, "/"); - return p; - } - - return NULL; + return skip_leading_slash(p + n); } -/** - * Skip user@*.service or capsule@*.service, but require either of them to be there. - */ -static const char *skip_user_manager(const char *p) { +static const char* skip_user_manager(const char *p) { size_t n; + /* Skip user@*.service or capsule@*.service, but require either of them to be there. */ + if (isempty(p)) return NULL; @@ -1119,26 +1104,14 @@ static const char *skip_user_manager(const char *p) { /* Note that user manager services never need unescaping, since they cannot conflict with the * kernel's own names, hence we don't need to call cg_unescape() here. Prudently check validity of * instance names, they should be always valid as we validate them upon unit start. */ - if (startswith(unit_name, "user@")) { - if (parse_uid(i, NULL) < 0) - return NULL; + if (!(startswith(unit_name, "user@") && parse_uid(i, NULL) >= 0) && + !(startswith(unit_name, "capsule@") && capsule_name_is_valid(i) > 0)) + return NULL; - p += n; - p += strspn(p, "/"); - return p; - } else if (startswith(unit_name, "capsule@")) { - if (capsule_name_is_valid(i) <= 0) - return NULL; - - p += n; - p += strspn(p, "/"); - return p; - } - - return NULL; + return skip_leading_slash(p + n); } -static const char *skip_user_prefix(const char *path) { +static const char* skip_user_prefix(const char *path) { const char *e, *t; assert(path); diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index ac0c7d8c41..f49fc48832 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -226,7 +226,7 @@ int cg_pid_get_user_slice(pid_t pid, char **ret_slice); int cg_path_decode_unit(const char *cgroup, char **ret_unit); -bool cg_needs_escape(const char *p); +bool cg_needs_escape(const char *p) _pure_; int cg_escape(const char *p, char **ret); char* cg_unescape(const char *p) _pure_; From b6fde0875be939648a7606a607cd77ad46c54278 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Thu, 5 Jun 2025 02:14:15 +0200 Subject: [PATCH 3/3] core/cgroup: drop outdated comment --- src/core/cgroup.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index ae322eead0..ca39705972 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -1993,8 +1993,7 @@ static int unit_watch_cgroup(Unit *u) { assert(u); - /* Watches the "cgroups.events" attribute of this unit's cgroup for "empty" events, but only if - * cgroupv2 is available. */ + /* Watches the "cgroups.events" attribute of this unit's cgroup for "empty" events. */ CGroupRuntime *crt = unit_get_cgroup_runtime(u); if (!crt || !crt->cgroup_path) @@ -2038,8 +2037,7 @@ static int unit_watch_cgroup_memory(Unit *u) { assert(u); - /* Watches the "memory.events" attribute of this unit's cgroup for "oom_kill" events, but only if - * cgroupv2 is available. */ + /* Watches the "memory.events" attribute of this unit's cgroup for "oom_kill" events. */ CGroupRuntime *crt = unit_get_cgroup_runtime(u); if (!crt || !crt->cgroup_path)