CVE-2026-46223: cgroup: Defer css percpu_ref kill on rmdir until cgroup is depopulated
In the Linux kernel, the following vulnerability has been resolved:
cgroup: Defer css percpuref kill on rmdir until cgroup is depopulated
A chain of commits going back to v7.0 reworked rmdir to satisfy the controller invariant that a subsystem's ->cssoffline() must not run while tasks are still doing kernel-side work in the cgroup.
[1] d245698d727a ("cgroup: Defer task cgroup unlink until after the task is done switching out") [2] a72f73c4dd9b ("cgroup: Don't expose dead tasks in cgroup") [3] 1b164b876c36 ("cgroup: Wait for dying tasks to leave on rmdir") [4] 4c56a8ac6869 ("cgroup: Fix cgroupdraindying() testing the wrong condition") [5] 13e786b64bd3 ("cgroup: Increment nrdyingsubsys from rmdir context")
[1] moved task cset unlink from doexit() to finishtaskswitch() so a task's cset link drops only after the task has fully stopped scheduling. That made tasks past exitsignals() linger on cset->tasks until their final context switch, which led to a series of problems as what userspace expected to see after rmdir diverged from what the kernel needs to wait for. [2]-[5] tried to bridge that divergence: [2] filtered the exiting tasks from cgroup.procs; [3] had rmdir(2) sleep in TASKUNINTERRUPTIBLE for them; [4] fixed the wait's condition; [5] made nrdyingsubsys visible synchronously.
The cgroupdraindying() wait in [3] turned out to be a dead end. When the rmdir caller is also the reaper of a zombie that pins a pidns teardown (e.g. host PID 1 systemd reaping orphan pids that were re-parented to it during the same teardown), rmdir blocks in TASKUNINTERRUPTIBLE waiting for those pids to free, the pids can't free because PID 1 is the reaper and it's stuck in rmdir, and the system A-A deadlocks. No internal lock ordering breaks this; the wait itself is the bug.
The css killing side that drove the original reorder, however, can be made cleanly asynchronous: ->cssoffline() is already async, run from csskilledworkfn() driven by percpurefkillandconfirm(). The fix is to make that chain start only after all tasks have left the cgroup. rmdir's user-visible side then returns as soon as cgroup.procs and friends are empty, while ->cssoffline() still runs only after the cgroup is fully drained.
Verified by the original reproducer (pidns teardown + zombie reaper, runs under vng) which hangs vanilla and succeeds here, and by per-commit deterministic repros for [2], [3], [4], [5] with a boot parameter that widens the post-exitsignals() window so each state is reliably reachable. Some stress tests on top of that.
cgroupapplycontroldisable() has the same shape of pre-existing race: when a controller is disabled via subtreecontrol, killcss() ran synchronously while tasks past exitsignals() could still be linked to the cgroup's csets, and ->cssoffline() could fire before they drained. This patch preserves the existing synchronous behavior at that call site (killcsssync() + killcssfinish() back-to-back) and a follow-up patch will defer killcssfinish() there using a per-css trigger.
This seems like the right approach and I don't see problems with it. The changes are somewhat invasive but not excessively so, so backporting to -stable should be okay. If something does turn out to be wrong, the fallback is to revert the entire chain ([1]-[5]) and rework in the development branch instead.
v2: Pin cgrp across the deferred destroy work with explicit cgroupget()/cgroupput() around queuework() and the workfn. v1 wasn't actually broken (ordered cgroupofflinewq + queuework order in cgrouptaskdead() saved it) but the explicit ref removes the dependency on those non-obvious invariants. Also note the pre-existing cgroupapplycontroldisable() race in the description; a follow-up will defer killcssfinish() there.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
linux/kernelto a version that resolves this vulnerability.Patch cgroup: Defer css percpu_ref kill on rmdir until cgroup is depopulated - Operational
Backport the patch 'cgroup: Defer css percpu_ref kill on rmdir until cgroup is depopulated' to affected -stable kernel trees where appropriate.
Event History
Frequently Asked Questions
What is the severity of CVE-2026-46223?
CVE-2026-46223 has a risk rating of 46, indicating a moderate severity level.
How do I fix CVE-2026-46223?
To mitigate CVE-2026-46223, update to the latest version of the Linux kernel where the vulnerability has been patched.
What is the impact of CVE-2026-46223 on Linux kernel environments?
CVE-2026-46223 can lead to issues with cgroup management, impacting resource allocation and task management.
Is CVE-2026-46223 related to any specific Linux kernel versions?
CVE-2026-46223 affects the Linux kernel starting from version 7.0 and has been addressed in subsequent updates.
What component of the Linux kernel is affected by CVE-2026-46223?
CVE-2026-46223 addresses a vulnerability in the cgroup component of the Linux kernel.