Re: [syzbot] [arm-msm?] [net?] memory leak in radix_tree_insert

From: syzbot
Date: Mon Dec 11 2023 - 00:15:50 EST


For archival purposes, forwarding an incoming command email to
linux-kernel@xxxxxxxxxxxxxxx.

***

Subject: [arm-msm?] [net?] memory leak in radix_tree_insert
Author: lizhi.xu@xxxxxxxxxxxxx

#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 33cc938e65a9

diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index a89df8afa510..301a8c01816a 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -613,12 +613,13 @@ static int __radix_tree_create(struct radix_tree_root *root,
unsigned long index, struct radix_tree_node **nodep,
void __rcu ***slotp)
{
- struct radix_tree_node *node = NULL, *child;
+ struct radix_tree_node *node = NULL, *child, *orig;
void __rcu **slot = (void __rcu **)&root->xa_head;
unsigned long maxindex;
- unsigned int shift, offset = 0;
+ unsigned int shift, offset = 0, mmshift = 0;
unsigned long max = index;
gfp_t gfp = root_gfp_mask(root);
+ int ret;

shift = radix_tree_load_root(root, &child, &maxindex);

@@ -628,6 +629,7 @@ static int __radix_tree_create(struct radix_tree_root *root,
if (error < 0)
return error;
shift = error;
+ mmshift = error;
child = rcu_dereference_raw(root->xa_head);
}

@@ -637,8 +639,11 @@ 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)
- return -ENOMEM;
+ printk("nc: %p\n", child);
+ if (!child) {
+ ret = -ENOMEM;
+ goto freec;
+ }
rcu_assign_pointer(*slot, node_to_entry(child));
if (node)
node->count++;
@@ -656,6 +661,18 @@ static int __radix_tree_create(struct radix_tree_root *root,
if (slotp)
*slotp = slot;
return 0;
+freec:
+ if (mmshift > 0) {
+ struct radix_tree_node *pn;
+ while (shift < mmshift && node) {
+ printk("dc: %p\n", node);
+ pn = node->parent;
+ radix_tree_node_rcu_free(&node->rcu_head);
+ shift += RADIX_TREE_MAP_SHIFT;
+ node = pn;
+ }
+ }
+ return ret;
}

/*