]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/unit: refuse to spawn units under frozen cgroup
authorMike Yuan <me@yhndnzj.com>
Fri, 31 May 2024 04:41:31 +0000 (12:41 +0800)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 31 May 2024 11:25:20 +0000 (13:25 +0200)
Currently, Unit.freezer_state is always initialized to
FREEZER_RUNNING. While realizing cgroups for frozen units
was disabled in 7923e9493c48694b32d1a6de7b9a996c0194bf17,
the commit only checked for freezer_state of the unit inself,
meaning that newly-loaded units might be started and the kernel
would hang pid1 when trying to spawn sd-executor into sub-cgroup.
This can be easily reproduced by the following:

```console
# systemd-run --slice=test.slice sleep infinity
# systemctl freeze test.slice
# systemd-run --slice=test.slice sleep infinity
```

Therefore, let's correctly initialize Unit.freezer_state
based on the parent slice.

src/core/unit.c

index 1dea0db3fe2192a497e28123f1713561538c00e4..2d40618fcbb7ad201d33f65c6636e0165f58c9c5 100644 (file)
@@ -1463,6 +1463,7 @@ int unit_add_default_target_dependency(Unit *u, Unit *target) {
 
 static int unit_add_slice_dependencies(Unit *u) {
         Unit *slice;
+
         assert(u);
 
         if (!UNIT_HAS_CGROUP_CONTEXT(u))
@@ -1474,8 +1475,12 @@ static int unit_add_slice_dependencies(Unit *u) {
         UnitDependencyMask mask = u->type == UNIT_SLICE ? UNIT_DEPENDENCY_IMPLICIT : UNIT_DEPENDENCY_FILE;
 
         slice = UNIT_GET_SLICE(u);
-        if (slice)
+        if (slice) {
+                if (!IN_SET(slice->freezer_state, FREEZER_RUNNING, FREEZER_THAWING))
+                        u->freezer_state = FREEZER_FROZEN_BY_PARENT;
+
                 return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, slice, true, mask);
+        }
 
         if (unit_has_name(u, SPECIAL_ROOT_SLICE))
                 return 0;