CVE-2026-97941: mm/slab: take n->list_lock in __slab_try_return_freelist() to avoid race
In the Linux kernel, the following vulnerability has been resolved:
mm/slab: take n->listlock in slabtryreturnfreelist() to avoid race
Commit ba7425312607 ("mm, slab: add an optimistic slabtryreturnfreelist()") incorrectly assumed that nobody has freed an object to the slab as long as slab->freelist is NULL and cmpxchg succeeds.
However, as reported by Hyunwoo Kim [1], other CPUs might have freed an object to the slab, insert the slab to the partial list, then allocated an object from the slab, and be in the middle of removing the slab from the list under n->listlock.
Since refillobjectsnode() puts the slab back on pc.slabs outside n->listlock, it might insert the slab into that list while the slab is concurrently being removed from n->partial. This led to a list corruption [1]:
listadd corruption. next->prev should be prev (ffff888100000248), but was dead000000000122. (next=ffffea000416e410). kernel BUG at lib/listdebug.c:29! Oops: invalid opcode: 0000 [#1] SMP NOPTI CPU: 1 UID: 65534 PID: 144 Comm: poc Not tainted 7.2.0-16172-gcf72cbb39da8-dirty #1 PREEMPT(lazy) RIP: 0010:listaddvalidorreport+0x80/0xd0 ... Call Trace: allocfromnewslab+0x183/0x300 slaballoc+0x31c/0x890 kmallocnoprof+0x3d4/0x800 lsmbloballoc+0x2d/0x50 securitymsgmsgalloc+0x26/0x90 loadmsg+0x1aa/0x210 domsgsnd+0x91/0x800 dosyscall64+0x109/0x5d0 entrySYSCALL64afterhwframe+0x77/0x7f ... Kernel panic - not syncing: Fatal exception
This is a classic ABA problem where cmpxchg succeeds but the state has changed since refillobjectsnode() took the freelist from the slab.
As Vlastimil Babka mentioned [2], it should be rare to return more than one slab (due to the racy read of slab->counters in getpartialnodebulk()). Therefore, instead of introducing additional complexity, acquire and release n->listlock twice in the worst case.
Return the slab directly to the partial list and hold n->listlock across the cmpxchg and addpartial(). This is similar to the initial version of commit ba7425312607 [3]. This is enough to avoid the race as the list manipulation is serialized by n->listlock. While at it, bring back unlikely() hint now that the condition is unlikely.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
Linux kernelto a version that resolves this vulnerability.Patch ba7425312607
Event History
Frequently Asked Questions
What conditions are needed to trigger this issue?
The race involves concurrent slab allocation and free activity on different CPUs while a slab is being added to or removed from the node partial list. It occurs when freelist handling and partial-list manipulation overlap without the required list lock.
What are the observable effects of the race?
The reported outcome is kernel list corruption, including a list_add corruption warning, followed by a kernel BUG in lib/list_debug.c and an invalid-opcode oops. Allocation paths such as alloc_from_new_slab may appear in the stack trace.
What should be done to remediate it?
Apply the available stable kernel fixes referenced by 570a6aaf6b52c6ec098f4811cdb52b1496f13d15 or 4a724bcf5d703e18957397914d79156fa2cf1174. The fix serializes the relevant freelist return operation with n->list_lock to prevent concurrent partial-list corruption.