From: Florian Schmaus <florian.schmaus@codasip.com>
To: Andrew Morton <akpm@linux-foundation.org>,
"Liam R. Howlett" <liam@infradead.org>,
Alice Ryhl <aliceryhl@google.com>,
Andrew Ballance <andrewjballance@gmail.com>,
"Matthew Wilcox (Oracle)" <willy@infradead.org>,
Suren Baghdasaryan <surenb@google.com>
Cc: linux-kernel@vger.kernel.org, maple-tree@lists.infradead.org,
linux-mm@kvack.org,
Florian Schmaus <florian.schmaus@codasip.com>,
"Liam R. Howlett" <liam@infradead.org>
Subject: [PATCH 3/3] maple_tree: add a test for destroying RCU-mode trees
Date: Thu, 15 Oct 2026 17:11:17 +0200 [thread overview]
Message-ID: <20261015-maple-tree-fix-slab-corruption-v1-3-160d97f7304c@codasip.com> (raw)
In-Reply-To: <20261015-maple-tree-fix-slab-corruption-v1-0-160d97f7304c@codasip.com>
Destroying an RCU-mode tree that is not an allocation tree defers freeing
its nodes to mt_free_walk(). This path had two bugs, both caused by the
metadata that a maple_range_64 node may keep in its last slot:
- mt_destroy_walk() took the last child of a full node for metadata and
corrupted it.
- mt_free_walk() took the metadata of a node with 15 children for a child
and dereferenced it.
Add check_rcu_destroy(), which builds RCU-mode trees with 120 ranges
(a full root) and 2768 ranges (height 4, where a non-root internal node
has 15 children), then destroys them and waits for the RCU callbacks.
The second case crashes without its fix. The first one corrupts memory
silently and needs KASAN, or ASan in the userspace test harness, to be
detected.
Signed-off-by: Florian Schmaus <florian.schmaus@codasip.com>
---
lib/test_maple_tree.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/lib/test_maple_tree.c b/lib/test_maple_tree.c
index b9367c61e8b5..aea62269810b 100644
--- a/lib/test_maple_tree.c
+++ b/lib/test_maple_tree.c
@@ -286,6 +286,36 @@ static noinline void __init check_seq(struct maple_tree *mt, unsigned long max,
#endif
}
+/*
+ * Destroy RCU-mode trees that are not allocation trees, so that the nodes are
+ * freed by mt_free_walk() from an RCU callback. With the ranges and gaps
+ * stored below, the sizes give the tree shapes (on 64-bit) that used to break
+ * this path:
+ *
+ * - 120 ranges: a full root. mt_destroy_walk() took its last child for
+ * metadata and zeroed part of the child pointer.
+ * - 2768 ranges: height 4, and a non-root internal node has 15 children.
+ * mt_free_walk() took the metadata in its last slot for a child.
+ *
+ * Without its fix, the first case corrupts memory silently and is only
+ * detected with KASAN, or with ASan in the userspace test harness.
+ */
+static noinline void __init check_rcu_destroy(struct maple_tree *mt)
+{
+ unsigned long sizes[] = { 120, 2768 };
+ unsigned long i, j;
+
+ for (i = 0; i < ARRAY_SIZE(sizes); i++) {
+ mt_init_flags(mt, MT_FLAGS_USE_RCU);
+ for (j = 0; j < sizes[i]; j++)
+ MT_BUG_ON(mt, mtree_store_range(mt, j * 10, j * 10 + 5,
+ xa_mk_value(j),
+ GFP_KERNEL));
+ mtree_destroy(mt);
+ rcu_barrier();
+ }
+}
+
static noinline void __init check_lb_not_empty(struct maple_tree *mt)
{
unsigned long i, j;
@@ -3804,6 +3834,8 @@ static int __init maple_tree_seed(void)
check_mas_store_gfp(&tree);
mtree_destroy(&tree);
+ check_rcu_destroy(&tree);
+
/* Test ranges (store and insert) */
mt_init_flags(&tree, 0);
check_ranges(&tree);
--
2.55.0
prev parent reply other threads:[~2026-10-15 15:11 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 15:11 [PATCH 0/3] maple_tree: fix two bugs when freeing " Florian Schmaus
2026-10-15 15:11 ` [PATCH 1/3] maple_tree: do not descend into metadata in mt_free_walk() Florian Schmaus
2026-10-15 15:11 ` [PATCH 2/3] maple_tree: do not clear the metadata of a full dead node Florian Schmaus
2026-10-15 15:11 ` Florian Schmaus [this message]
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=20261015-maple-tree-fix-slab-corruption-v1-3-160d97f7304c@codasip.com \
--to=florian.schmaus@codasip.com \
--cc=akpm@linux-foundation.org \
--cc=aliceryhl@google.com \
--cc=andrewjballance@gmail.com \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=maple-tree@lists.infradead.org \
--cc=surenb@google.com \
--cc=willy@infradead.org \
/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
all inboxes | Powered by JetHome®