Re: [syzbot] [mm?] [f2fs?] [exfat?] memory leak in __kfree_rcu_sheaf

Vlastimil Babka (SUSE)
2026-03-04T13:39:53Z

On 3/4/26 2:30 AM, Harry Yoo wrote:
> [+Cc adding Catalin for kmemleak bits]
>
> On Mon, Mar 02, 2026 at 09:39:48AM +0100, Vlastimil Babka (SUSE) wrote:
>> On 3/2/26 04:41, Qing Wang wrote:
>>> #syz test
>>>
>>> diff --git a/mm/slub.c b/mm/slub.c
>>> index cdc1e652ec52..387979b89120 100644
>>> --- a/mm/slub.c
>>> +++ b/mm/slub.c
>>> @@ -6307,15 +6307,21 @@ bool __kfree_rcu_sheaf(struct kmem_cache *s, void *obj)
>>> goto fail;
>>>
>>> if (!local_trylock(&s->cpu_sheaves->lock)) {
>>> - barn_put_empty_sheaf(barn, empty);
>>> + if (barn && data_race(barn->nr_empty) < MAX_EMPTY_SHEAVES)
>>> + barn_put_empty_sheaf(barn, empty);
>>> + else
>>> + free_empty_sheaf(s, empty);
>>> goto fail;
>>> }
>>>
>>> pcs = this_cpu_ptr(s->cpu_sheaves);
>>>
>>> - if (unlikely(pcs->rcu_free))
>>> - barn_put_empty_sheaf(barn, empty);
>>> - else
>>> + if (unlikely(pcs->rcu_free)) {
>>> + if (barn && data_race(barn->nr_empty) < MAX_EMPTY_SHEAVES)
>>> + barn_put_empty_sheaf(barn, empty);
>>> + else
>>> + free_empty_sheaf(s, empty);
>>> + } else
>>> pcs->rcu_free = empty;
>>> }
>>
>> I don't think this would fix any leak, and syzbot agrees. It would limit the
>> empty sheaves in barn more strictly, but they are not leaked.
>> Hm I don't see any leak in __kfree_rcu_sheaf() or rcu_free_sheaf(). Wonder
>> if kmemleak lacks visibility into barns or pcs's as roots for searching what
>> objects are considered referenced, or something?
>
> Objects that are allocated from slab and percpu allocator should be
> properly tracked by kmemleak. But those allocated with
> gfpflags_allow_spinning() == false are not tracked by kmemleak.
>
> When barns and sheaves are allocated early (!gfpflags_allow_spinning()
> due to gfp_allowed_mask) and it skips kmemleak_alloc_recursive(),
> it could produce false positives because from kmemleak's point of view,
> the objects are not reachable from the root set (data section, stack,
> etc.).

Good point.

> To me it seems kmemleak should gain allow_spin == false support
> sooner or later.

Or we figure out how to deal with the false allow_spin == false during
boot. Here I'm a bit confused how exactly it happens because AFAICS in
slub we apply gfp_allowed_mask only when allocating a new slab, and in
slab_post_alloc_hook() we apply it to init_mask. That is indeed passed
to kmemleak_alloc_recursive() but not used for the
gfpflags_allow_spinning() decision. kmemleak_alloc_recursive() should
succeed because nobody should be holding any locks that would require
spinning.

Unless it's some interaction with deferred pages like the one fixed by
commit fd3634312a04f33?