mirror of
https://github.com/systemd/systemd.git
synced 2025-02-09 13:57:42 +03:00
core: change ownership of subcgroup we create recursively, it shall be owned by the user delegated to
If we create a subcroup (regardless if the '.control' subgroup we always created or one configured via DelegateSubgroup=) it's inside of the delegated territory of the cgroup tree, hence it should be owned fully by the unit's users. Hence do so.
This commit is contained in:
parent
18c1e481b6
commit
bcd9b98159
@ -4904,7 +4904,7 @@ static int exec_child(
|
||||
return log_unit_error_errno(unit, r, "Failed to acquire cgroup path: %m");
|
||||
}
|
||||
if (r > 0) {
|
||||
r = cg_set_access(SYSTEMD_CGROUP_CONTROLLER, p, uid, gid);
|
||||
r = cg_set_access_recursive(SYSTEMD_CGROUP_CONTROLLER, p, uid, gid);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_CGROUP;
|
||||
return log_unit_error_errno(unit, r, "Failed to adjust control subgroup access: %m");
|
||||
|
@ -483,6 +483,82 @@ int cg_set_access(
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct access_callback_data {
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int error;
|
||||
};
|
||||
|
||||
static int access_callback(
|
||||
RecurseDirEvent event,
|
||||
const char *path,
|
||||
int dir_fd,
|
||||
int inode_fd,
|
||||
const struct dirent *de,
|
||||
const struct statx *sx,
|
||||
void *userdata) {
|
||||
|
||||
struct access_callback_data *d = ASSERT_PTR(userdata);
|
||||
|
||||
if (!IN_SET(event, RECURSE_DIR_ENTER, RECURSE_DIR_ENTRY))
|
||||
return RECURSE_DIR_CONTINUE;
|
||||
|
||||
assert(inode_fd >= 0);
|
||||
|
||||
/* fchown() doesn't support O_PATH fds, hence we use the /proc/self/fd/ trick */
|
||||
if (chown(FORMAT_PROC_FD_PATH(inode_fd), d->uid, d->gid) < 0) {
|
||||
log_debug_errno(errno, "Failed to change ownership of '%s', ignoring: %m", ASSERT_PTR(path));
|
||||
|
||||
if (d->error == 0) /* Return last error to caller */
|
||||
d->error = errno;
|
||||
}
|
||||
|
||||
return RECURSE_DIR_CONTINUE;
|
||||
}
|
||||
|
||||
int cg_set_access_recursive(
|
||||
const char *controller,
|
||||
const char *path,
|
||||
uid_t uid,
|
||||
gid_t gid) {
|
||||
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
_cleanup_free_ char *fs = NULL;
|
||||
int r;
|
||||
|
||||
/* A recursive version of cg_set_access(). But note that this one changes ownership of *all* files,
|
||||
* not just the allowlist that cg_set_access() uses. Use cg_set_access() on the cgroup you want to
|
||||
* delegate, and cg_set_access_recursive() for any subcrgoups you might want to create below it. */
|
||||
|
||||
if (!uid_is_valid(uid) && !gid_is_valid(gid))
|
||||
return 0;
|
||||
|
||||
r = cg_get_path(controller, path, NULL, &fs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fd = open(fs, O_DIRECTORY|O_CLOEXEC|O_RDONLY);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
struct access_callback_data d = {
|
||||
.uid = uid,
|
||||
.gid = gid,
|
||||
};
|
||||
|
||||
r = recurse_dir(fd,
|
||||
fs,
|
||||
/* statx_mask= */ 0,
|
||||
/* n_depth_max= */ UINT_MAX,
|
||||
RECURSE_DIR_SAME_MOUNT|RECURSE_DIR_INODE_FD|RECURSE_DIR_TOPLEVEL,
|
||||
access_callback,
|
||||
&d);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return -d.error;
|
||||
}
|
||||
|
||||
int cg_migrate(
|
||||
const char *cfrom,
|
||||
const char *pfrom,
|
||||
|
@ -24,6 +24,7 @@ int cg_attach_fallback(const char *controller, const char *path, pid_t pid);
|
||||
int cg_create_and_attach(const char *controller, const char *path, pid_t pid);
|
||||
|
||||
int cg_set_access(const char *controller, const char *path, uid_t uid, gid_t gid);
|
||||
int cg_set_access_recursive(const char *controller, const char *path, uid_t uid, gid_t gid);
|
||||
|
||||
int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, CGroupFlags flags);
|
||||
int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto, const char *pto, CGroupFlags flags);
|
||||
|
Loading…
x
Reference in New Issue
Block a user