From: Harry Yoo <harry@kernel.org>
To: Kuniyuki Iwashima <kuniyu@google.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>,
Andrew Morton <akpm@linux-foundation.org>,
Vlastimil Babka <vbabka@kernel.org>,
Alexander Potapenko <glider@google.com>,
Andrey Konovalov <andreyknvl@gmail.com>,
Dmitry Vyukov <dvyukov@google.com>,
Vincenzo Frascino <vincenzo.frascino@arm.com>,
Hao Li <hao.li@linux.dev>, Christoph Lameter <cl@gentwo.org>,
David Rientjes <rientjes@google.com>,
Roman Gushchin <roman.gushchin@linux.dev>,
kasan-dev@googlegroups.com, linux-mm@kvack.org
Subject: Re: [PATCH v3 1/2] mm/kasan: Detect double-free involving kfree_rcu_sheaf().
Date: Thu, 29 Oct 2026 14:07:21 +0000 [thread overview]
Message-ID: <auNQ9fjjyF5Xa0qb@thinkstation> (raw)
In-Reply-To: <20261028194014.3671161-2-kuniyu@google.com>
On Wed, Oct 28, 2026 at 07:39:19PM +0000, Kuniyuki Iwashima wrote:
> syzbot reported a weird use-after-free splat. [0]
>
> In the report, an object in the kmalloc-64 cache was freed via
> rcu_free_sheaf() while it was still in use, even though the
> object should always be freed with kfree() (in xfrm_hash_free()),
> implying that the object was a victim of a double-free involving
> kfree_rcu() somewhere else.
>
> When kvfree_call_rcu() frees an object via kfree_rcu_sheaf() and
> queues it into pcs->rcu_free, debug facilities are skipped, e.g.,
> kasan_slab_pre_free(), kasan_record_aux_stack(),
> debug_rcu_head_queue(), etc.
>
> As a result, KASAN cannot detect the double-free at the call site.
>
> If the object is still in the KASAN quarantine when the sheaf is
> flushed, KASAN can detect the double-free in rcu_free_sheaf(), but
> with no trace of the suspect.
>
> Worse yet, once the object is evicted from the quarantine and
> reallocated before the sheaf is flushed, rcu_free_sheaf() silently
> poisons the live object, resulting in a false-positive use-after-free
> report on the new user.
>
> If __kfree_rcu_sheaf() simply calls kasan_slab_pre_free(), we
> can detect the second kfree_rcu(), but only while the object is
> poisoned in the KASAN quarantine after the first free:
>
> kfree() --(poisoned)--------------------> kfree_rcu()
> kfree_rcu() -> rcu_free_sheaf() -(poisoned)-> kfree_rcu()
>
> An object queued in pcs->rcu_free remains unpoisoned until the
> sheaf becomes full and rcu_free_sheaf() runs after the RCU
> grace period, so a subsequent kfree_rcu() or kfree() before
> rcu_free_sheaf() cannot be detected by shadow bytes alone:
>
> kfree_rcu() -(unpoisoned)-> kfree_rcu() -> rcu_free_sheaf() (too late!)
> kfree_rcu() -(unpoisoned)-> kfree() -> rcu_free_sheaf() (too late!)
>
> These cases can be detected if we call debug_rcu_head_queue()
> before kfree_rcu_sheaf(), but ODEBUG splat only shows the second
> free.
>
> To detect these cases with KASAN, we just need a 1-bit flag
> to indicate the state, which can reuse an unused bit in struct
> kasan_track.pid. (PID_MAX_LIMIT is 1<<22)
>
> The bit is marked along with recording the stack trace when
> deferring slab frees in kfree_rcu_sheaf() and checked in
> check_slab_allocation() so that any double-free pattern above
> can be detected immediately.
Why do we not need the same thing when it bypasses kfree_rcu_sheaf()?
> Link: https://lore.kernel.org/all/6ac959ee.70ed5d86.2ac85.007d.GAE@google.com/ #[0]
> Fixes: ec66e0d59952 ("slab: add sheaf support for batching kfree_rcu() operations")
> Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
> Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
> Tested-by: Alexander Potapenko <glider@google.com>
> Reviewed-by: Alexander Potapenko <glider@google.com>
> Reviewed-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
> ---
> v2:
> * Add Fixes tag
> * Add kdoc for @after_rcu_delay of kasan_slab_pre_free()
> * Rename s/kasan_record_aux_stack_rcu/kasan_mark_rcu_free_pending/g
> * Add comment for __kasan_record_aux_stack()
> ---
> include/linux/kasan.h | 15 +++++++++++----
> mm/kasan/common.c | 13 ++++++++-----
> mm/kasan/generic.c | 17 ++++++++++++++++-
> mm/kasan/kasan.h | 34 +++++++++++++++++++++++++++++++++-
> mm/slub.c | 13 ++++++++++---
> 5 files changed, 78 insertions(+), 14 deletions(-)
--
Cheers,
Harry / Hyeonggon
next prev parent reply other threads:[~2026-10-29 14:07 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 19:39 [PATCH v3 0/2] mm/kasan: Detect double-free involving kfree_rcu_sheaf() Kuniyuki Iwashima
2026-10-28 19:39 ` [PATCH v3 1/2] " Kuniyuki Iwashima
2026-10-29 14:07 ` Harry Yoo [this message]
2026-10-29 19:27 ` Kuniyuki Iwashima
2026-10-28 19:39 ` [PATCH v3 2/2] mm/kasan/kunit: Add double-free tests " Kuniyuki Iwashima
2026-10-29 4:46 ` Andrew Morton
2026-10-29 4:51 ` Kuniyuki Iwashima
2026-10-29 13:53 ` Harry Yoo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=auNQ9fjjyF5Xa0qb@thinkstation \
--to=harry@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=andreyknvl@gmail.com \
--cc=cl@gentwo.org \
--cc=dvyukov@google.com \
--cc=glider@google.com \
--cc=hao.li@linux.dev \
--cc=kasan-dev@googlegroups.com \
--cc=kuniyu@google.com \
--cc=linux-mm@kvack.org \
--cc=rientjes@google.com \
--cc=roman.gushchin@linux.dev \
--cc=ryabinin.a.a@gmail.com \
--cc=vbabka@kernel.org \
--cc=vincenzo.frascino@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.