]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/execute: also check cg_is_threaded for clone3() 32263/head
authorMike Yuan <me@yhndnzj.com>
Sat, 13 Apr 2024 14:42:22 +0000 (22:42 +0800)
committerMike Yuan <me@yhndnzj.com>
Sun, 14 Apr 2024 15:22:13 +0000 (23:22 +0800)
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.

src/basic/process-util.c
src/core/exec-invoke.c
src/core/execute.c

index 351b5e4095924fd4b63505c358940f91e8e839ca..c9d968dee0a7c4fc25a9ad4ec260646b63220a02 100644 (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
index f1e1935e40ab3ea1111e01b0f3c491b1ba5e4230..90e11d0d1e9c1fc419e53940b6c807013c677648 100644 (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;
index 0cfbf79946143c79a3a49b081f885045be8a3bd0..5a4acd0775621e7c1bc91d59cc2d8280c7369675 100644 (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