All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiayuan Chen <jiayuan.chen@linux.dev>
To: willy@infradead.org
Cc: linux-mm@kvack.org, jiayuan.chen@linux.dev,
	Jiayuan Chen <jiayuan.chen@shopee.com>,
	syzbot+006987d1be3586e13555@syzkaller.appspotmail.com,
	Andrew Morton <akpm@linux-foundation.org>,
	linux-kernel@vger.kernel.org
Subject: [PATCH v1] radix-tree: fix memory leak of intermediate nodes on insert failure
Date: Wed, 25 Feb 2026 15:16:18 +0800	[thread overview]
Message-ID: <20260225071623.41275-1-jiayuan.chen@linux.dev> (raw)

From: Jiayuan Chen <jiayuan.chen@shopee.com>

__radix_tree_create() builds a path by allocating and immediately
linking intermediate nodes into the tree one by one.  If an allocation
fails partway through, the already-linked nodes remain in the tree
with no corresponding leaf entry.  These nodes are never reclaimed
because radix_tree_for_each_slot() only visits slots containing leaf
values and there is no radix_tree_destroy() to walk all structural
nodes.

The natural alternative—migrating callers to xarray and relying on
xa_destroy()—does not cover global or long-lived trees whose lifetime
is tied to the system.  xa_destroy() is never called for such trees,
so orphaned nodes would persist until reboot.

Fix this directly in __radix_tree_create() by tracking the first newly
linked slot.  On allocation failure, sever the partial path with
rcu_assign_pointer() and free the orphaned nodes via call_rcu() to
maintain RCU safety for concurrent readers.

Reported-by: syzbot+006987d1be3586e13555@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/000000000000bfba3a060bf4ffcf@google.com/T/
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com>
---
 lib/radix-tree.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 976b9bd02a1b..2bdf2be71b95 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -600,6 +600,11 @@ static int __radix_tree_create(struct radix_tree_root *root,
 		void __rcu ***slotp)
 {
 	struct radix_tree_node *node = NULL, *child;
+	/* Track newly allocated nodes for rollback on failure */
+	struct radix_tree_node *new_nodes[RADIX_TREE_MAX_PATH];
+	void __rcu **first_new_slot = NULL;
+	struct radix_tree_node *first_new_parent = NULL;
+	int new_count = 0, i;
 	void __rcu **slot = (void __rcu **)&root->xa_head;
 	unsigned long maxindex;
 	unsigned int shift, offset = 0;
@@ -623,8 +628,23 @@ static int __radix_tree_create(struct radix_tree_root *root,
 			/* Have to add a child node.  */
 			child = radix_tree_node_alloc(gfp, node, root, shift,
 							offset, 0, 0);
-			if (!child)
+			if (!child) {
+				/* Rollback: sever and free all newly allocated nodes */
+				if (first_new_slot) {
+					rcu_assign_pointer(*first_new_slot, NULL);
+					if (first_new_parent)
+						first_new_parent->count--;
+					for (i = 0; i < new_count; i++)
+						radix_tree_node_free(new_nodes[i]);
+				}
 				return -ENOMEM;
+			}
+			/* Record first new slot and parent for potential rollback */
+			if (!first_new_slot) {
+				first_new_slot = slot;
+				first_new_parent = node;
+			}
+			new_nodes[new_count++] = child;
 			rcu_assign_pointer(*slot, node_to_entry(child));
 			if (node)
 				node->count++;
-- 
2.43.0



             reply	other threads:[~2026-02-25  7:17 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-25  7:16 Jiayuan Chen [this message]
2026-02-25 14:13 ` [PATCH v1] radix-tree: fix memory leak of intermediate nodes on insert failure Matthew Wilcox

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=20260225071623.41275-1-jiayuan.chen@linux.dev \
    --to=jiayuan.chen@linux.dev \
    --cc=akpm@linux-foundation.org \
    --cc=jiayuan.chen@shopee.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=syzbot+006987d1be3586e13555@syzkaller.appspotmail.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 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.