core/execute: also check cg_is_threaded for clone3()

Prompted by #32259

We already have this check in exec_invoke(), i.e. child.
But if CLONE_INTO_CGROUP is used, the failure would
occur on parent's side, so do the check there too.
This commit is contained in:
Mike Yuan
2024-04-14 23:22:13 +08:00
parent ad68a4e58a
commit 58ff2f1e38
3 changed files with 16 additions and 3 deletions
+8 -1
View File
@@ -25,6 +25,7 @@
#include "alloc-util.h"
#include "architecture.h"
#include "argv-util.h"
#include "cgroup-util.h"
#include "dirent-util.h"
#include "env-file.h"
#include "env-util.h"
@@ -2108,7 +2109,13 @@ int posix_spawn_wrapper(
return FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP);
}
if (!(ERRNO_IS_NOT_SUPPORTED(r) || ERRNO_IS_PRIVILEGE(r)))
if (ERRNO_IS_NOT_SUPPORTED(r)) {
/* clone3() could also return EOPNOTSUPP if the target cgroup is in threaded mode. */
if (cgroup && cg_is_threaded(cgroup) > 0)
return -EUCLEAN;
/* clone3() not available? */
} else if (!ERRNO_IS_PRIVILEGE(r))
return -r;
/* Compiled on a newer host, or seccomp&friends blocking clone3()? Fallback, but need to change the
+3 -2
View File
@@ -4264,9 +4264,10 @@ int exec_invoke(
r = cg_attach_everywhere(params->cgroup_supported, p, 0, NULL, NULL);
if (r == -EUCLEAN) {
*exit_status = EXIT_CGROUP;
return log_exec_error_errno(context, params, r, "Failed to attach process to cgroup %s "
return log_exec_error_errno(context, params, r,
"Failed to attach process to cgroup '%s', "
"because the cgroup or one of its parents or "
"siblings is in the threaded mode: %m", p);
"siblings is in the threaded mode.", p);
}
if (r < 0) {
*exit_status = EXIT_CGROUP;
+5
View File
@@ -456,6 +456,11 @@ int exec_spawn(Unit *unit,
environ,
cg_unified() > 0 ? subcgroup_path : NULL,
&pidref);
if (r == -EUCLEAN && subcgroup_path)
return log_unit_error_errno(unit, r,
"Failed to spawn process into cgroup '%s', because the cgroup "
"or one of its parents or siblings is in the threaded mode.",
subcgroup_path);
if (r < 0)
return log_unit_error_errno(unit, r, "Failed to spawn executor: %m");
/* We add the new process to the cgroup both in the child (so that we can be sure that no user code is ever