Vulnerability · Published May 28, 2026 · Assigned by Linux

CVE-2026-46223cgroup: Defer css percpu_ref kill on rmdir until cgroup is depopulated

Medium 5.5

In plain English

A medium-severity security flaw in Linux from Linux. There are no confirmed reports of exploitation so far. The chance it is exploited in the next 30 days is estimated at 0.1% (higher than 0% of all known vulnerabilities). Fixed versions are available - upgrade the affected package.

Severity (CVSS NVD)5.5Medium
Exploit odds (30 days)<0.1%top 99.8% of all CVEs
Exploited in the wildNo reportsnot in CISA KEV
Attack toolingNoneno public tooling known

Official description

In the Linux kernel, the following vulnerability has been resolved: cgroup: Defer css percpu_ref 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 ->css_offline() 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 cgroup_drain_dying() testing the wrong condition") [5] 13e786b64bd3 ("cgroup: Increment nr_dying_subsys_* from rmdir context") [1] moved task cset unlink from do_exit() to finish_task_switch() so a task's cset link drops only after the task has fully stopped scheduling. That made tasks past exit_signals() 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 TASK_UNINTERRUPTIBLE for them; [4] fixed the wait's condition; [5] made nr_dying_subsys_* visible synchronously. The cgroup_drain_dying() 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 TASK_UNINTERRUPTIBLE 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: ->css_offline() is already async, run from css_killed_work_fn() driven by percpu_ref_kill_and_confirm(). 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 ->css_offline() 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-exit_signals() window so each state is reliably reachable. Some stress tests on top of that. cgroup_apply_control_disable() has the same shape of pre-existing race: when a controller is disabled via subtree_control, kill_css() ran synchronously while tasks past exit_signals() could still be linked to the cgroup's csets, and ->css_offline() could fire before they drained. This patch preserves the existing synchronous behavior at that call site (kill_css_sync() + kill_css_finish() back-to-back) and a follow-up patch will defer kill_css_finish() 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 cgroup_get()/cgroup_put() around queue_work() and the work_fn. v1 wasn't actually broken (ordered cgroup_offline_wq + queue_work order in cgroup_task_dead() saved it) but the explicit ref removes the dependency on those non-obvious invariants. Also note the pre-existing cgroup_apply_control_disable() race in the description; a follow-up will defer kill_css_finish() there.

Affected packages & fixed versions

EcosystemPackageFixed inAdvisory
Debian:14linux7.0.9-1DEBIAN-CVE-2026-46223
Ubuntu:26.04:LTSlinux7.0.0-28.28UBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-allwinner-5.19no fix listedUBUNTU-CVE-2026-46223
Ubuntu:26.04:LTSlinux-aws7.0.0-1009.9UBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-aws-5.19no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-aws-6.14no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-aws-6.2no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-aws-6.5no fix listedUBUNTU-CVE-2026-46223
Ubuntu:26.04:LTSlinux-azure7.0.0-1010.10UBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-azure-5.19no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-azure-6.11no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-azure-6.2no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-azure-6.5no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-azure-7.07.0.0-1014.14~24.04.1UBUNTU-CVE-2026-46223
Ubuntu:26.04:LTSlinux-azure-fde7.0.0-1009.9UBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-azure-fde-5.19no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-azure-fde-6.2no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-azure-fde-7.07.0.0-1013.13~24.04.1UBUNTU-CVE-2026-46223
Ubuntu:26.04:LTSlinux-gcp7.0.0-1008.8UBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-gcp-5.19no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-gcp-6.11no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-gcp-6.14no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-gcp-6.2no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-gcp-6.5no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-gcp-7.07.0.0-1011.11~24.04.1UBUNTU-CVE-2026-46223
Ubuntu:26.04:LTSlinux-gke7.0.0-1003.4UBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-hwe-5.19no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-hwe-6.11no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-hwe-6.14no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-hwe-6.2no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-hwe-6.5no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-hwe-7.07.0.0-28.28~24.04.1UBUNTU-CVE-2026-46223
Ubuntu:26.04:LTSlinux-ibm7.0.0-1010.10UBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-intel-iot-realtimeno fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-lowlatency-hwe-5.19no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-lowlatency-hwe-6.11no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-lowlatency-hwe-6.2no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-lowlatency-hwe-6.5no fix listedUBUNTU-CVE-2026-46223
Ubuntu:26.04:LTSlinux-nvidia7.0.0-1016.16UBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-nvidia-6.11no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-nvidia-6.2no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-nvidia-6.5no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-nvidia-7.07.0.0-1016.16~24.04.1UBUNTU-CVE-2026-46223
Ubuntu:26.04:LTSlinux-nvidia-bos7.0.0-2016.16UBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-oem-5.17no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-oem-6.0no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-oem-6.1no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-oem-6.11no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-oem-6.14no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-oem-6.5no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-oem-6.8no fix listedUBUNTU-CVE-2026-46223
Ubuntu:26.04:LTSlinux-oem-7.07.0.0-1009.9UBUNTU-CVE-2026-46223
Ubuntu:26.04:LTSlinux-oracle7.0.0-1008.8UBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-oracle-6.14no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-oracle-6.5no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-oracle-7.07.0.0-1011.11~24.04.1UBUNTU-CVE-2026-46223
Ubuntu:26.04:LTSlinux-raspi7.0.0-1015.15UBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-raspi-realtimeno fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-realtimeno fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-realtimeno fix listedUBUNTU-CVE-2026-46223
Ubuntu:26.04:LTSlinux-realtime7.0.0-28.28.1UBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-riscvno fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-riscvno fix listedUBUNTU-CVE-2026-46223
Ubuntu:26.04:LTSlinux-riscv7.0.0-28.28.1UBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-riscv-5.19no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-riscv-6.14no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-riscv-6.5no fix listedUBUNTU-CVE-2026-46223
Ubuntu:24.04:LTSlinux-riscv-7.07.0.0-28.28.1~24.04.3UBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-starfive-5.19no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-starfive-6.2no fix listedUBUNTU-CVE-2026-46223
Ubuntu:22.04:LTSlinux-starfive-6.5no fix listedUBUNTU-CVE-2026-46223

Affected products (as reported)

VendorProductVersions
Linux Linux 1b164b876c36c3eb5561dd9b37702b04401b0166 – before 33fa2e6b1507a0a377a151a8826438bedad1d0b01b164b876c36c3eb5561dd9b37702b04401b0166 – before 93618edf753838a727dbff63c7c291dee22d656b78c72bce4a87819126211c0d24e18350010604fb6.19.12 – before 6.20
Linux Linux 7.0

References