With recent fixes for the permission checking when moving a task into a cgroup using a file descriptor to a cgroup's cgroup.procs file and calling write() it seems a good idea to clarify CLONE_INTO_CGROUP permission checking with a comment.
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -6161,6 +6161,20 @@ static int cgroup_css_set_fork(struct kernel_clone_args *kargs) · 6160 unmodified lines | ||
| 6161 | 6161 | if (ret) |
| 6162 | 6162 | goto err; |
| 6163 | 6163 | |
| 6164 | + /* | |
| 6165 | + * Spawning a task directly into a cgroup works by passing a file | |
| 6166 | + * descriptor to the target cgroup directory. This can even be an O_PATH | |
| 6167 | + * file descriptor. But it can never be a cgroup.procs file descriptor. | |
| 6168 | + * This was done on purpose so spawning into a cgroup could be | |
| 6169 | + * conceptualized as an atomic | |
| 6170 | + * | |
| 6171 | + * fd = openat(dfd_cgroup, "cgroup.procs", ...); | |
| 6172 | + * write(fd, <child-pid>, ...); | |
| 6173 | + * | |
| 6174 | + * sequence, i.e. it's a shorthand for the caller opening and writing | |
| 6175 | + * cgroup.procs of the cgroup indicated by @dfd_cgroup. This allows us | |
| 6176 | + * to always use the caller's credentials. | |
| 6177 | + */ | |
| 6164 | 6178 | ret = cgroup_attach_permissions(cset->dfl_cgrp, dst_cgrp, sb, |
| 6165 | 6179 | !(kargs->flags & CLONE_THREAD), |
| 6166 | 6180 | current->nsproxy->cgroup_ns); |