cgroup-util: Handle capsule@ paths like user@ paths (#36664)
The capsule instances are related to user instances, so treat them equally to user@.service when handling cgroup paths. This also saves us from polluting public libsystemd API with variant for capsules too. Fix: https://github.com/systemd/systemd/issues/36098
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "capsule-util.h"
|
||||
#include "path-util.h"
|
||||
#include "user-util.h"
|
||||
|
||||
int capsule_name_is_valid(const char *name) {
|
||||
|
||||
if (!filename_is_valid(name))
|
||||
return false;
|
||||
|
||||
_cleanup_free_ char *prefixed = strjoin("c-", name);
|
||||
if (!prefixed)
|
||||
return -ENOMEM;
|
||||
|
||||
return valid_user_group_name(prefixed, /* flags= */ 0);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
int capsule_name_is_valid(const char *name);
|
||||
+23
-11
@@ -12,6 +12,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "capsule-util.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "constants.h"
|
||||
#include "dirent-util.h"
|
||||
@@ -1284,7 +1285,7 @@ static const char *skip_session(const char *p) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip user@*.service, but require it to be there.
|
||||
* Skip user@*.service or capsule@*.service, but require either of them to be there.
|
||||
*/
|
||||
static const char *skip_user_manager(const char *p) {
|
||||
size_t n;
|
||||
@@ -1295,26 +1296,37 @@ static const char *skip_user_manager(const char *p) {
|
||||
p += strspn(p, "/");
|
||||
|
||||
n = strcspn(p, "/");
|
||||
if (n < STRLEN("user@x.service"))
|
||||
if (n < CONST_MIN(STRLEN("user@x.service"), STRLEN("capsule@x.service")))
|
||||
return NULL;
|
||||
|
||||
if (memcmp(p, "user@", 5) == 0 && memcmp(p + n - 8, ".service", 8) == 0) {
|
||||
char buf[n - 5 - 8 + 1];
|
||||
/* Any possible errors from functions called below are converted to NULL return, so our callers won't
|
||||
* resolve user/capsule name. */
|
||||
_cleanup_free_ char *unit_name = strndup(p, n);
|
||||
if (!unit_name)
|
||||
return NULL;
|
||||
|
||||
memcpy(buf, p + 5, n - 5 - 8);
|
||||
buf[n - 5 - 8] = 0;
|
||||
_cleanup_free_ char *i = NULL;
|
||||
UnitNameFlags type = unit_name_to_instance(unit_name, &i);
|
||||
|
||||
/* 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. */
|
||||
if (type != UNIT_NAME_INSTANCE)
|
||||
return NULL;
|
||||
|
||||
if (parse_uid(buf, NULL) < 0)
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ basic_sources = files(
|
||||
'bus-label.c',
|
||||
'cap-list.c',
|
||||
'capability-util.c',
|
||||
'capsule-util.c',
|
||||
'cgroup-util.c',
|
||||
'chase.c',
|
||||
'chattr-util.c',
|
||||
|
||||
Reference in New Issue
Block a user