Commit 44caa356 authored by Erez Shitrit's avatar Erez Shitrit Committed by Ben Hutchings

IB/core: Fix use after free in send_leave function

commit 68c6bcdd upstream.

The function send_leave sets the member: group->query_id
(group->query_id = ret) after calling the sa_query, but leave_handler
can be executed before the setting and it might delete the group object,
and will get a memory corruption.

Additionally, this patch gets rid of group->query_id variable which is
not used.

Fixes: faec2f7b ('IB/sa: Track multicast join/leave requests')
Signed-off-by: default avatarErez Shitrit <erezsh@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent 05554fc3
...@@ -106,7 +106,6 @@ struct mcast_group { ...@@ -106,7 +106,6 @@ struct mcast_group {
atomic_t refcount; atomic_t refcount;
enum mcast_group_state state; enum mcast_group_state state;
struct ib_sa_query *query; struct ib_sa_query *query;
int query_id;
u16 pkey_index; u16 pkey_index;
u8 leave_state; u8 leave_state;
int retries; int retries;
...@@ -339,11 +338,7 @@ static int send_join(struct mcast_group *group, struct mcast_member *member) ...@@ -339,11 +338,7 @@ static int send_join(struct mcast_group *group, struct mcast_member *member)
member->multicast.comp_mask, member->multicast.comp_mask,
3000, GFP_KERNEL, join_handler, group, 3000, GFP_KERNEL, join_handler, group,
&group->query); &group->query);
if (ret >= 0) { return (ret > 0) ? 0 : ret;
group->query_id = ret;
ret = 0;
}
return ret;
} }
static int send_leave(struct mcast_group *group, u8 leave_state) static int send_leave(struct mcast_group *group, u8 leave_state)
...@@ -363,11 +358,7 @@ static int send_leave(struct mcast_group *group, u8 leave_state) ...@@ -363,11 +358,7 @@ static int send_leave(struct mcast_group *group, u8 leave_state)
IB_SA_MCMEMBER_REC_JOIN_STATE, IB_SA_MCMEMBER_REC_JOIN_STATE,
3000, GFP_KERNEL, leave_handler, 3000, GFP_KERNEL, leave_handler,
group, &group->query); group, &group->query);
if (ret >= 0) { return (ret > 0) ? 0 : ret;
group->query_id = ret;
ret = 0;
}
return ret;
} }
static void join_group(struct mcast_group *group, struct mcast_member *member, static void join_group(struct mcast_group *group, struct mcast_member *member,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment