Look up another CVE · open CVE-2026-89985 in the interactive tracker
CVE-2026-89985
memcg: keep folio's objcg same as its node
Published 2026-09-16 (33 days ago) by the Linux kernel CNA. Subsystem mm. Debian urgency: unimportant.
What to do, per Debian release
Debian's own status for CVE-2026-89985 in every release this site tracks, and what each one means in practice. Every status below is the one the Debian Security Team publishes for this CVE. source
| Release | Status | Version | What this means |
|---|---|---|---|
| Debian 12bookworm | not affected | 6.1.190-1 | Nothing to do. bookworm never shipped the vulnerable code. |
| Debian 13trixie | not affected | 6.12.113-1 | Nothing to do. trixie never shipped the vulnerable code. |
| Debian 14forky | fixed | 7.2.6-1 | Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts. |
| Debian unstablesid | fixed | 7.2.6-1 | Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts. |
The vulnerability
What the bug is
memcg_reparent_objcgs() has an inherent assumption that a folio's objcg is the objcg of the folio's node. Folio migration across nodes breaks that assumption: the new folio simply inherits the old folio's objcg while living on a different node. Once the assumption is broken, the reparenting of the folio's objcg and the reparenting of the folio's LRU list are no longer atomic. memcg_reparent_objcgs() handles one node per iteration and drops all the locks in between, so the objcg gets reparented in the iteration for the objcg's node while the LRU list gets spliced in the iteration for the folio's node. Any LRU operation on that folio in between resolves its lruvec through the objcg, and thus takes the lru_lock of the wrong memcg, not the lru_lock of the list the folio is actually on. Fix this by selecting the objcg by folio_nid() at charge time, and by re-deriving it for the destination node in mem_cgroup_migrate() and mem_cgroup_replace_folio().
Where it lives
The fix touches these files. If the subsystem is one you do not use, the practical exposure is lower, though the package is still the vulnerable one.
mm/memcontrol.c
- What this is
- CONTROL GROUP - MEMORY RESOURCE CONTROLLER (MEMCG)MAINTAINERS section matched on mm/memcontrol.c · cgroups@vger.kernel.org · Maintained
Check it on the machine
grep -w CONFIG_MEMCG /boot/config-$(uname -r)Reads the booted kernel's own configuration, on the machine and nowhere else. =y is built in, =m is a module, and an is not set line means the code is not there.
Show whether Debian builds this, per release
Debian builds this code. Every release below compiles the affected file into the kernels it ships.
- bookworm, trixie, forky, sidy
- y
- built into the kernel image on every flavour - only a patch removes it
- Build switch
- CONFIG_MEMCG
From the configuration Debian publishes for every kernel flavour it builds. It covers only the architectures Debian ships a linux-config package for, and nothing about a kernel you built yourself. Debian's own status above stays authoritative about the source package.MAINTAINERS kbuild Makefiles Debian linux-config packages
Signals
- Published
- 2026-09-16 (33 days ago)source
- CVSS
- 7.8 high
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:Hsource recompute it - Attack vector
- local (AV:L)source
- EPSS
- 0.17%, higher than 5.3% of all CVEssource
- CISA KEV
- not listedthe KEV catalogue
- Debian urgency
- unimportantsource
- Subsystem
- mm
Upstream fixes
The versions the CNA records as introducing and fixing this, and the commit for each. source
| Introduced | Fixed in | Commit |
|---|---|---|
| 7.1 | 7.2.5 | 6165478eaa30 |
| 7.1 | 7.3 | bf4ade7dbd76 |
Why the CNA scored it this way
Quoted from the kernel CNA's own scoring file, word for word. A highlighted metric carries the most severe value CVSS v3.1 defines for it, which is what pushes the score up. source
- AV:LAttack vector, local
- The bug is reached only via local syscalls: creating/rmdiring a memory cgroup, NUMA placement or page migration (set_mempolicy, mbind with MPOL_MF_MOVE, move_pages), and LRU activity (mmap, madvise, mlock, munmap). It is not reachable from unauthenticated network packets.
- AC:LAttack complexity, low
- The attacker drives both sides of the race: they create the folio objcg/node mismatch (charge on one node, folio on another, or migrate_pages) and then rmdir the cgroup while another thread hammers LRU ops in the unlocked window between per-node reparent iterations, retrying at will.
- PR:LPrivileges required, low
- Offlining the memcg needs write access to a cgroup subtree, which Linux delegates to unprivileged users and cgroup namespaces (systemd user slices, containers). NUMA syscalls on the attacker’s own pages need no capability. This is not init-namespace root.
- UI:NUser interaction, none
- The attacker performs every step themselves: creating and removing the memory cgroup, placing or migrating folios across NUMA nodes, and exercising LRU paths. No separate victim action is required.
- S:UScope, unchanged
- Corruption is of in-kernel LRU list_heads and memcg per-node lruvecs in the same kernel security authority. This is local kernel memory corruption, not a VM escape or IOMMU bypass.
- C:HConfidentiality impact, high
- folio_lruvec_lock() takes the wrong lru_lock, so LRU ops can list_del/list_add a folio onto a dying memcg’s LRU; after css_free the lruvec is kfree’d while the folio remains linked, a kernel UAF that yields an arbitrary-read primitive.
- I:HIntegrity impact, high
- Concurrent list_add/list_del of folio->lru under different lruvec locks corrupts kernel list_head next/prev pointers and can write through attacker-influenced links, a classic list-UAF arbitrary-write / control-flow hijack primitive.
- A:HAvailability impact, high
- List corruption and use-after-free of the offlined memcg’s lruvec cause kernel oopses, panics, or hangs during reclaim, isolation, or folio free even when the UAF is not fully turned into code execution.