UBUNTU-CVE-2026-93241: Medium severity ubuntu/linux vulnerability
In the Linux kernel, the following vulnerability has been resolved: memcg: bypass the reclaim and oom killer for dying tasks once oomreaper is done At Meta, we are seeing instances where an OOM killed job is stuck in the exit path for several hours. In one particular case, the job was stuck for more than 8 hours and I had to manually remove the memory.max limits to allow the process to exit. The job was a single process job and had ~55 GiB memory.max and zswap enabled. It had almost 0 anon in memory and ~111 GiB in zswap compressed to ~51 GiB zswap pool (i.e. almost all of memory.current was zswap). Nothing was left on the LRUs to reclaim. On further inspection, I observed ~20k threads of that process stuck with the following stack: [<0>] memcgroupoutofmemory+0x4e/0xa0 [<0>] chargememcg+0x8bf/0x990 [<0>] memcgroupswapinchargefolio+0x4e/0x80 [<0>] readswapcacheasync+0x10c/0x260 [<0>] swapinreadahead+0x116/0x3f0 [<0>] doswappage+0x13c/0x1ce0 [<0>] handlemmfault+0x61d/0x11f0 [<0>] douseraddrfault+0x3e7/0x6d0 [<0>] excpagefault+0x8f/0x110 [<0>] asmexcpagefault+0x22/0x30 [<0>] getuser8+0x14/0x20 [<0>] futexcleanup+0x27/0x1c0 [<0>] futexexitrelease+0x47/0x60 [<0>] doexit+0x107/0x940 [<0>] dogroupexit+0x81/0xa0 [<0>] getsignal+0x2b1/0x6e0 [<0>] archdosignalorrestart+0x1a/0x1c0 [<0>] exittousermodeloop+0xa8/0x1c0 [<0>] dosyscall64+0x152/0x250 [<0>] entrySYSCALL64afterhwframe+0x4b/0x53 In addition the dmesg was filled with "Out of memory and no killable processes..." messages. I have no idea why oom reaper was not able to reap/unmap the process. My guess is that since oom reaper tries to acquire mmaplock in read mode limited number of times and then gives up, there might be a thread of that process which had mmaplock in write mode at that time. My initial suspicion was the futexcleanup and kernel page fault causing infinite fault and charge retries but that was put to rest in previous discussions happened on similar problem [1]. My current theory is that it is just a simple slow serialization behind the oomlock. Unlike page allocator, memcg charge code takes the oomlock without the "try". Though memcg oom code uses mutexlockkillable(), note that in the call stack getsignal() consumes SIGKILL (or sigdelset(SIGKILL)) before calling dogroupexit(). So this mutexlockkillable() is just a mutexlock() here. Therefore 10s of thousands of threads are waiting on oomlock and one by one they get -EFAULT from getuser() in the futex cleanup code and bails out. Discussion from [1] led to commit a75ffa26122b ("memcg, oom: do not bypass oom killer for dying tasks") which routes dying tasks into the OOM path precisely so the oomreaper can reap their mm and free the memory asynchronously. But the reaper is best-effort and one-shot: if it cannot take mmaplock for read (e.g. a sibling thread holds it for write) it sets MMFOOMSKIP and never retries, leaving only the glacial oomlock-serialized synchronous drain. Once MMFOOMSKIP is set there is no more asynchronous reclaim coming for the mm, so a dying task charging against it has nothing left to wait for: it frees its memory only once it finishes exiting. Running reclaim and the (no-victim) OOM killer for it is then pointless, and doing it for 10s of thousands of exiting threads is what serializes them behind oomlock. So before reclaim, if current is an OOM victim whose reaper is done, fail the charge. Reproduced with 20k threads, each parking a robust futex head on its own zswapped page, OOM-group-killed while a sibling holds mmaplock for write so the reaper gives up and sets MMFOOMSKIP. Tested on next-20260728 and baseline show ~90 seconds exit time while with the patch the exit time reduced to ~3 seconds.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
ubuntu/linux-hwe-7.0to a version that resolves this vulnerability.Fixed in 7.0.0-42.42~24.04.1 - Upgrade
Upgrade
ubuntu/linux-riscv-7.0to a version that resolves this vulnerability.Fixed in 7.0.0-42.42.1~24.04.1 - Upgrade
Upgrade
ubuntu/linuxto a version that resolves this vulnerability.Fixed in 7.0.0-42.42 - Upgrade
Upgrade
ubuntu/linux-awsto a version that resolves this vulnerability.Fixed in 7.0.0-1016.17 - Upgrade
Upgrade
ubuntu/linux-gcpto a version that resolves this vulnerability.Fixed in 7.0.0-1016.18 - Upgrade
Upgrade
ubuntu/linux-ibmto a version that resolves this vulnerability.Fixed in 7.0.0-1017.17 - Upgrade
Upgrade
ubuntu/linux-oem-7.0to a version that resolves this vulnerability.Fixed in 7.0.0-1017.17 - Upgrade
Upgrade
ubuntu/linux-oracleto a version that resolves this vulnerability.Fixed in 7.0.0-1015.16 - Upgrade
Upgrade
ubuntu/linux-riscvto a version that resolves this vulnerability.Fixed in 7.0.0-42.42.1
Event History
Frequently Asked Questions
Who is most likely to be affected?
Systems running the listed Ubuntu Linux kernel packages are relevant. The reported scenario involves a memory-cgroup-limited job that has been OOM killed, with zswap enabled and most of its accounted memory held in zswap rather than reclaimable LRUs.
What access and conditions are needed to trigger the issue?
The severity vector indicates local access and low privileges are required, along with additional attack preconditions. The observed failure occurs while an OOM-killed task exits and threads fault swapped pages, causing memory-cgroup charging to re-enter reclaim or OOM handling after the OOM reaper has completed.
What can be done if a kernel update cannot be applied immediately?
In the reported case, manually removing the affected job's memory.max limit allowed the process to exit. This is a recovery measure for a stuck job, not a confirmed general mitigation.
How can administrators recognize a possible occurrence?
An OOM-killed job may remain stuck in its exit path for hours. Threads may be blocked in stacks involving mem_cgroup_out_of_memory, charge_memcg, swapin, page faults, and futex cleanup; the reported case had many such threads and little or no anonymous memory left on reclaimable LRUs.