CVE-2026-89985 Overview
CVE-2026-89985 is a race condition vulnerability in the Linux kernel's memory cgroup (memcg) subsystem. The flaw resides in memcg_reparent_objcgs(), which assumes a folio's object cgroup (objcg) always matches the objcg of the folio's NUMA node. Folio migration across nodes breaks this assumption, causing non-atomic reparenting of the folio's objcg and its LRU list. Subsequent LRU operations resolve the wrong lruvec through the objcg and acquire the incorrect memcg lru_lock, corrupting kernel memory accounting structures.
Critical Impact
A local, low-privileged attacker can trigger memory cgroup state corruption leading to loss of confidentiality, integrity, and availability on affected Linux systems.
Affected Products
- Linux kernel (mainline branch prior to the fix commit)
- Linux kernel stable branches containing the memcg_reparent_objcgs() regression
- Distributions shipping vulnerable kernels with NUMA and memory cgroup support enabled
Discovery Timeline
- 2026-09-16 - CVE-2026-89985 published to NVD
- 2026-09-16 - Last updated in NVD database
Technical Details for CVE-2026-89985
Vulnerability Analysis
The Linux kernel tracks memory accounting through memory cgroups, associating each folio with an object cgroup (objcg). The function memcg_reparent_objcgs() reparents objcgs when a memcg is removed, processing one NUMA node per iteration and releasing locks between iterations.
The subsystem assumes a folio's objcg is always the objcg belonging to the folio's node. Folio migration across NUMA nodes violates this assumption. The migrated folio inherits the old folio's objcg while physically residing on a different node.
When reparenting runs, the objcg gets reparented during the iteration for the objcg's original node. The LRU list splice occurs in the iteration for the folio's actual node. Any LRU operation between these iterations resolves lruvec through the objcg and acquires the lru_lock of the wrong memcg. This causes concurrent modification of LRU lists under mismatched locks.
Root Cause
The root cause is a broken invariant between a folio's objcg and its NUMA node placement after cross-node migration. memcg_reparent_objcgs() drops locks between per-node iterations, splitting objcg reparenting and LRU splicing into non-atomic steps. This creates a race window where LRU operations use a stale objcg-derived lock that does not protect the list the folio actually resides on.
Attack Vector
Exploitation requires local access with the ability to allocate memory, trigger folio migration across NUMA nodes, and remove memory cgroups. An unprivileged process operating within a memcg can influence migration and reparenting timing. Successful exploitation corrupts kernel LRU list state, enabling denial of service through kernel panic or potential privilege escalation via memory corruption primitives.
No verified public exploit code is available. The vulnerability is described in prose based on the upstream commit message. See the Kernel Git Commit - Fix for technical details of the patch.
Detection Methods for CVE-2026-89985
Indicators of Compromise
- Kernel warnings or BUG_ON traces referencing lru_lock, lruvec, or memcg_reparent_objcgs in dmesg output.
- Unexpected kernel panics on NUMA-enabled hosts running container workloads with frequent cgroup creation and teardown.
- Corrupted memory accounting counters visible under /sys/fs/cgroup/memory for terminated cgroups.
Detection Strategies
- Monitor kernel logs for soft lockups, RCU stalls, or list corruption warnings originating in mm/memcontrol.c and mm/vmscan.c.
- Audit running kernel versions across the fleet and correlate against the fixed commit 6165478e in the stable tree.
- Track container orchestration events that create and destroy memory cgroups on NUMA nodes at high rates.
Monitoring Recommendations
- Enable kdump and crash-dump collection to capture kernel state when memcg-related faults occur.
- Instrument endpoint telemetry to forward dmesg and journalctl -k output to a central data lake for correlation.
- Alert on repeated cgroup teardown failures or orphaned memcg entries reported by memory.stat.
How to Mitigate CVE-2026-89985
Immediate Actions Required
- Inventory Linux hosts running kernels that predate the upstream fix, focusing on NUMA systems and container workloads.
- Apply the vendor-supplied kernel update as soon as your distribution publishes patched packages.
- Restrict unprivileged access to cgroup management interfaces on multi-tenant systems until patches are deployed.
Patch Information
The upstream fix selects the objcg by folio_nid() at charge time and re-derives it for the destination node in mem_cgroup_migrate() and mem_cgroup_replace_folio(). This keeps a folio's objcg consistent with its node, restoring the atomicity assumption in memcg_reparent_objcgs(). Refer to the Kernel Git Commit - Fix and the follow-up Kernel Git Commit - Update.
Workarounds
- Disable automatic NUMA balancing via sysctl kernel.numa_balancing=0 to reduce cross-node folio migration on affected hosts.
- Constrain workloads to a single NUMA node using numactl or cgroup cpuset.mems until patches are applied.
- Limit creation and destruction of memory cgroups by untrusted workloads through user namespace restrictions and Kubernetes admission policies.
# Configuration example: reduce cross-node migration exposure
sysctl -w kernel.numa_balancing=0
echo 0 > /proc/sys/kernel/numa_balancing
# Pin a workload to a single NUMA node
numactl --cpunodebind=0 --membind=0 /path/to/workload
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.