Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d82e08de authored by Peilin Ye's avatar Peilin Ye Committed by Greg Kroah-Hartman
Browse files

tipc: Fix memory leak in tipc_group_create_member()



[ Upstream commit bb3a420d47ab00d7e1e5083286cab15235a96680 ]

tipc_group_add_to_tree() returns silently if `key` matches `nkey` of an
existing node, causing tipc_group_create_member() to leak memory. Let
tipc_group_add_to_tree() return an error in such a case, so that
tipc_group_create_member() can handle it properly.

Fixes: 75da2163 ("tipc: introduce communication groups")
Reported-and-tested-by: default avatar <syzbot+f95d90c454864b3b5bc9@syzkaller.appspotmail.com>
Cc: Hillf Danton <hdanton@sina.com>
Link: https://syzkaller.appspot.com/bug?id=048390604fe1b60df34150265479202f10e13aff


Signed-off-by: default avatarPeilin Ye <yepeilin.cs@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d4c5a31a
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -273,7 +273,7 @@ static struct tipc_member *tipc_group_find_node(struct tipc_group *grp,
	return NULL;
}

static void tipc_group_add_to_tree(struct tipc_group *grp,
static int tipc_group_add_to_tree(struct tipc_group *grp,
				  struct tipc_member *m)
{
	u64 nkey, key = (u64)m->node << 32 | m->port;
@@ -291,10 +291,11 @@ static void tipc_group_add_to_tree(struct tipc_group *grp,
		else if (key > nkey)
			n = &(*n)->rb_right;
		else
			return;
			return -EEXIST;
	}
	rb_link_node(&m->tree_node, parent, n);
	rb_insert_color(&m->tree_node, &grp->members);
	return 0;
}

static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
@@ -302,6 +303,7 @@ static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
						    u32 instance, int state)
{
	struct tipc_member *m;
	int ret;

	m = kzalloc(sizeof(*m), GFP_ATOMIC);
	if (!m)
@@ -314,8 +316,12 @@ static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
	m->port = port;
	m->instance = instance;
	m->bc_acked = grp->bc_snd_nxt - 1;
	ret = tipc_group_add_to_tree(grp, m);
	if (ret < 0) {
		kfree(m);
		return NULL;
	}
	grp->member_cnt++;
	tipc_group_add_to_tree(grp, m);
	tipc_nlist_add(&grp->dests, m->node);
	m->state = state;
	return m;