From: Harry Yoo <harry.yoo@oracle.com>
To: syzbot <syzbot+cae7809e9dc1459e4e63@syzkaller.appspotmail.com>
Cc: akpm@linux-foundation.org, catalin.marinas@arm.com,
chao@kernel.org, hao.li@linux.dev, jaegeuk@kernel.org,
jannh@google.com, liam.howlett@oracle.com, linkinjeon@kernel.org,
linux-f2fs-devel@lists.sourceforge.net,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, lorenzo.stoakes@oracle.com, pfalcato@suse.de,
sj1557.seo@samsung.com, syzkaller-bugs@googlegroups.com,
vbabka@kernel.org, vbabka@suse.cz, wangqing7171@gmail.com
Subject: Re: [syzbot] [mm?] [f2fs?] [exfat?] memory leak in __kfree_rcu_sheaf
Date: Tue, 10 Mar 2026 15:11:05 +0900 [thread overview]
Message-ID: <aa-1-Y3v3D1hzPvL@hyeyoo> (raw)
In-Reply-To: <69af95db.a00a0220.d013.0001.GAE@google.com>
#syz test
diff --git a/Documentation/dev-tools/kmemleak.rst b/Documentation/dev-tools/kmemleak.rst
index 7d784e03f3f9..da2c849d4735 100644
--- a/Documentation/dev-tools/kmemleak.rst
+++ b/Documentation/dev-tools/kmemleak.rst
@@ -163,6 +163,7 @@ See the include/linux/kmemleak.h header for the functions prototype.
- ``kmemleak_not_leak`` - mark an object as not a leak
- ``kmemleak_transient_leak`` - mark an object as a transient leak
- ``kmemleak_ignore`` - do not scan or report an object as leak
+- ``kmemleak_unignore`` - undo a previous kmemleak_ignore()
- ``kmemleak_scan_area`` - add scan areas inside a memory block
- ``kmemleak_no_scan`` - do not scan a memory block
- ``kmemleak_erase`` - erase an old value in a pointer variable
diff --git a/include/linux/kmemleak.h b/include/linux/kmemleak.h
index fbd424b2abb1..4eec0560be09 100644
--- a/include/linux/kmemleak.h
+++ b/include/linux/kmemleak.h
@@ -28,6 +28,7 @@ extern void kmemleak_update_trace(const void *ptr) __ref;
extern void kmemleak_not_leak(const void *ptr) __ref;
extern void kmemleak_transient_leak(const void *ptr) __ref;
extern void kmemleak_ignore(const void *ptr) __ref;
+extern void kmemleak_unignore(const void *ptr, int min_count) __ref;
extern void kmemleak_ignore_percpu(const void __percpu *ptr) __ref;
extern void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) __ref;
extern void kmemleak_no_scan(const void *ptr) __ref;
@@ -104,6 +105,10 @@ static inline void kmemleak_ignore_percpu(const void __percpu *ptr)
static inline void kmemleak_ignore(const void *ptr)
{
}
+
+static inline void kmemleak_unignore(const void *ptr, int min_count)
+{
+}
static inline void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp)
{
}
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index d79acf5c5100..871e20ba3d7b 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -909,6 +909,8 @@ static void __paint_it(struct kmemleak_object *object, int color)
object->min_count = color;
if (color == KMEMLEAK_BLACK)
object->flags |= OBJECT_NO_SCAN;
+ else
+ object->flags &= ~OBJECT_NO_SCAN;
}
static void paint_it(struct kmemleak_object *object, int color)
@@ -1292,6 +1294,24 @@ void __ref kmemleak_ignore(const void *ptr)
}
EXPORT_SYMBOL(kmemleak_ignore);
+/**
+ * kmemleak_unignore - undo a previous kmemleak_ignore() on an object
+ * @ptr: pointer to beginning of the object
+ * @min_count: minimum number of references the object must have to be
+ * considered a non-leak (see kmemleak_alloc() for details)
+ *
+ * Calling this function undoes a prior kmemleak_ignore() by restoring the
+ * given min_count, making the object visible to kmemleak again.
+ */
+void __ref kmemleak_unignore(const void *ptr, int min_count)
+{
+ pr_debug("%s(0x%px)\n", __func__, ptr);
+
+ if (kmemleak_enabled && ptr && !IS_ERR(ptr))
+ paint_ptr((unsigned long)ptr, min_count, 0);
+}
+EXPORT_SYMBOL(kmemleak_unignore);
+
/**
* kmemleak_scan_area - limit the range to be scanned in an allocated object
* @ptr: pointer to beginning or inside the object. This also
diff --git a/mm/slab_common.c b/mm/slab_common.c
index d5a70a831a2a..73f4668d870d 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -1954,8 +1954,14 @@ void kvfree_call_rcu(struct rcu_head *head, void *ptr)
if (!head)
might_sleep();
- if (!IS_ENABLED(CONFIG_PREEMPT_RT) && kfree_rcu_sheaf(ptr))
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT) && kfree_rcu_sheaf(ptr)) {
+ /*
+ * The object is now queued for deferred freeing via an RCU
+ * sheaf. Tell kmemleak to ignore it.
+ */
+ kmemleak_ignore(ptr);
return;
+ }
// Queue the object but don't yet schedule the batch.
if (debug_rcu_head_queue(ptr)) {
diff --git a/mm/slub.c b/mm/slub.c
index 20cb4f3b636d..3bfe113ae326 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3014,8 +3014,10 @@ static void pcs_flush_all(struct kmem_cache *s)
free_empty_sheaf(s, spare);
}
- if (rcu_free)
+ if (rcu_free) {
+ kmemleak_ignore(rcu_free);
call_rcu(&rcu_free->rcu_head, rcu_free_sheaf_nobarn);
+ }
sheaf_flush_main(s);
}
@@ -3035,6 +3037,7 @@ static void __pcs_flush_all_cpu(struct kmem_cache *s, unsigned int cpu)
}
if (pcs->rcu_free) {
+ kmemleak_ignore(pcs->rcu_free);
call_rcu(&pcs->rcu_free->rcu_head, rcu_free_sheaf_nobarn);
pcs->rcu_free = NULL;
}
@@ -4031,8 +4034,10 @@ static void flush_rcu_sheaf(struct work_struct *w)
local_unlock(&s->cpu_sheaves->lock);
- if (rcu_free)
+ if (rcu_free) {
+ kmemleak_ignore(rcu_free);
call_rcu(&rcu_free->rcu_head, rcu_free_sheaf_nobarn);
+ }
}
@@ -5832,6 +5837,7 @@ static void rcu_free_sheaf(struct rcu_head *head)
if (data_race(barn->nr_full) < MAX_FULL_SHEAVES) {
stat(s, BARN_PUT);
+ kmemleak_unignore(sheaf, 1);
barn_put_full_sheaf(barn, sheaf);
return;
}
@@ -5842,6 +5848,7 @@ static void rcu_free_sheaf(struct rcu_head *head)
empty:
if (barn && data_race(barn->nr_empty) < MAX_EMPTY_SHEAVES) {
+ kmemleak_unignore(sheaf, 1);
barn_put_empty_sheaf(barn, sheaf);
return;
}
@@ -5948,8 +5955,10 @@ bool __kfree_rcu_sheaf(struct kmem_cache *s, void *obj)
* we flush before local_unlock to make sure a racing
* flush_all_rcu_sheaves() doesn't miss this sheaf
*/
- if (rcu_sheaf)
+ if (rcu_sheaf) {
+ kmemleak_ignore(rcu_sheaf);
call_rcu(&rcu_sheaf->rcu_head, rcu_free_sheaf);
+ }
local_unlock(&s->cpu_sheaves->lock);
@@ -7538,6 +7547,7 @@ static void early_kmem_cache_node_alloc(int node)
slab->freelist = get_freepointer(kmem_cache_node, n);
slab->inuse = 1;
kmem_cache_node->node[node] = n;
+ kmemleak_alloc(n, kmem_cache_node->size, 1, GFP_NOWAIT);
init_kmem_cache_node(n, NULL);
inc_slabs_node(kmem_cache_node, node, slab->objects);
base-commit: c23719abc3308df7ed3ad35650ad211fb2d2003d
--
2.43.0
next prev parent reply other threads:[~2026-03-10 6:11 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-09 18:26 [syzbot] [mm?] [f2fs?] [exfat?] memory leak in __kfree_rcu_sheaf syzbot
2026-03-02 3:41 ` Qing Wang
2026-03-02 3:57 ` syzbot
2026-03-02 8:39 ` Vlastimil Babka (SUSE)
2026-03-04 1:30 ` Harry Yoo
2026-03-04 13:39 ` Vlastimil Babka (SUSE)
2026-03-06 19:35 ` Catalin Marinas
2026-03-08 11:02 ` Catalin Marinas
2026-03-08 12:31 ` syzbot
2026-03-08 11:04 ` Catalin Marinas
2026-03-08 12:42 ` syzbot
2026-03-09 10:46 ` Harry Yoo
2026-03-09 11:11 ` syzbot
2026-03-09 12:17 ` Harry Yoo
2026-03-09 20:31 ` Catalin Marinas
2026-03-11 3:04 ` Harry Yoo
2026-03-11 3:20 ` Harry Yoo
2026-03-10 3:39 ` Harry Yoo
2026-03-10 3:54 ` syzbot
2026-03-10 6:11 ` Harry Yoo [this message]
2026-03-10 6:29 ` syzbot
2026-03-10 8:10 ` Harry Yoo
2026-03-10 9:40 ` syzbot
2026-03-18 2:34 ` Harry Yoo
2026-03-18 3:08 ` syzbot
2026-03-18 4:10 ` Harry Yoo
2026-03-18 5:02 ` syzbot
2026-03-11 9:57 ` Qing Wang
2026-03-11 10:17 ` syzbot
2026-03-11 10:48 ` Qing Wang
2026-03-11 11:03 ` syzbot
2026-03-11 11:23 ` Harry Yoo
2026-03-20 0:06 ` Harry Yoo
2026-03-20 10:34 ` syzbot
2026-03-20 11:20 ` 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=aa-1-Y3v3D1hzPvL@hyeyoo \
--to=harry.yoo@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=catalin.marinas@arm.com \
--cc=chao@kernel.org \
--cc=hao.li@linux.dev \
--cc=jaegeuk@kernel.org \
--cc=jannh@google.com \
--cc=liam.howlett@oracle.com \
--cc=linkinjeon@kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=lorenzo.stoakes@oracle.com \
--cc=pfalcato@suse.de \
--cc=sj1557.seo@samsung.com \
--cc=syzbot+cae7809e9dc1459e4e63@syzkaller.appspotmail.com \
--cc=syzkaller-bugs@googlegroups.com \
--cc=vbabka@kernel.org \
--cc=vbabka@suse.cz \
--cc=wangqing7171@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox