CVE-2026-74576
Fecha de publicación:
15/08/2026
*** Pendiente de traducción *** In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
mm/slab: prevent unbounded recursion in free path with new kmalloc type<br />
<br />
Commit 280ea9c3154b ("mm/slab: avoid allocating slabobj_ext array from<br />
its own slab") avoided recursive allocation of obj_exts from kmalloc<br />
caches of the same size, by bumping the obj_exts array&#39;s allocation<br />
size whenever the array size equals the size of the object being<br />
allocated.<br />
<br />
However, as reported by Danielle Costantino and Shakeel Butt,<br />
even slabs from kmalloc caches of different sizes can form a cycle<br />
by allocating obj_exts arrays from each other [1]:<br />
<br />
What happened: a KMALLOC_NORMAL slab&#39;s obj_exts array (used by<br />
allocation profiling / memcg accounting) is itself kmalloc()&#39;d from a<br />
KMALLOC_NORMAL cache, so the "slab holds another slab&#39;s obj_exts array"<br />
relation can form cycles. With sizeof(struct slabobj_ext) == 16 and<br />
the host&#39;s geometry:<br />
<br />
- kmalloc-512 has 64 objects/slab -> array is 64*16 == 1024 bytes,<br />
served from kmalloc-1k;<br />
- kmalloc-1k has 32 objects/slab -> array is 32*16 == 512 bytes,<br />
served from kmalloc-512.<br />
<br />
A kmalloc-512 slab and a kmalloc-1k slab therefore hold each other&#39;s<br />
obj_exts array. Discarding one frees the other&#39;s array, which empties<br />
and discards that slab, which frees the first&#39;s array, and so on:<br />
__free_slab() -> free_slab_obj_exts() -> kfree() -> discard_slab() -><br />
__free_slab() recurses along the cycle until the stack is exhausted.<br />
<br />
With memory allocation profiling, this allows unbounded recursion<br />
in the free path and led to a stack overflow on a production host in<br />
the Meta fleet [1]:<br />
<br />
BUG: TASK stack guard page was hit<br />
Oops: stack guard page<br />
RIP: 0010:kfree+0x8/0x5d0<br />
Call Trace:<br />
__free_slab+0x66/0xc0<br />
kfree+0x3f0/0x5d0<br />
... ( ~125x __free_slab kfree ) ...<br />
<br />
do_syscall_64<br />
<br />
It is proposed [1] to resolve this issue by always serving the obj_exts<br />
array allocation from kmalloc caches (or large kmalloc) of sizes larger<br />
than the object size. However, as pointed out by Vlastimil Babka [2],<br />
this can waste an excessive amount of memory as slabs from large<br />
kmalloc sizes (e.g. kmalloc-8k) generally need obj_exts arrays much<br />
smaller than the object size.<br />
<br />
Therefore, rather than bumping the size, let us take a different<br />
approach; disallow formation of cycles between kmalloc types when<br />
allocating obj_exts arrays. Currently, all obj_exts arrays are served<br />
from normal kmalloc caches. Cycles cannot be created if obj_exts arrays<br />
of normal kmalloc caches are served from a special kmalloc type that can<br />
never have obj_exts arrays.<br />
<br />
To achieve this, create a new kmalloc type called KMALLOC_NO_OBJ_EXT.<br />
KMALLOC_NO_OBJ_EXT caches are created with SLAB_NO_OBJ_EXT flag when<br />
either 1) memory allocation profiling is not permanently disabled,<br />
or 2) kmalloc types with a priority higher than KMALLOC_CGROUP are<br />
aliased with KMALLOC_NORMAL.<br />
<br />
Sheaf bootstrapping for KMALLOC_NO_OBJ_EXT caches now must be deferred<br />
because allocation of a barn can trigger obj_exts array allocation of<br />
normal kmalloc caches when the KMALLOC_NO_OBJ_EXT cache for that size<br />
is not ready yet. For simplicity, perform bootstrapping of sheaves for<br />
all kmalloc caches later.<br />
<br />
Introduce a new slab alloc flag, SLAB_ALLOC_NO_OBJ_EXT, to prevent<br />
allocation of obj_exts arrays, and let kmalloc_slab() override the type<br />
to KMALLOC_NO_OBJ_EXT when specified. Note that kmalloc_type() remains<br />
unchanged because kmalloc_flags() bypasses the kmalloc fastpath.<br />
<br />
Do not pass SLAB_ALLOC_NO_RECURSE to kmalloc_flags() in<br />
alloc_slab_obj_exts() and instead use SLAB_ALLOC_NO_OBJ_EXT only when<br />
the objects are allocated from normal kmalloc caches. While this<br />
prevents unbounded recursive allocation of obj_exts, it allows<br />
KMALLOC_NO_OBJ_EXT caches to have sheaves.<br />
<br />
Since sheaf allocations specify SLAB_ALLOC_NO_RECURSE that prevents<br />
allocation of both sheaves and obj_exts arrays, the recursion depth<br />
is bounded.<br />
<br />
obj_exts arrays for non-<br />
---truncated---
Gravedad: Pendiente de análisis
Última modificación:
15/08/2026