core/unit: refuse to spawn units under frozen cgroup

Currently, Unit.freezer_state is always initialized to
FREEZER_RUNNING. While realizing cgroups for frozen units
was disabled in 7923e9493c,
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.
This commit is contained in:
Mike Yuan
2024-05-31 13:25:20 +02:00
committed by Zbigniew Jędrzejewski-Szmek
parent 87d6cedfdb
commit 3b23501a0d
+6 -1
View 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;