Skip to content

Commit cb2595c

Browse files
congwangjgunthorpe
authored andcommitted
infiniband: fix a possible use-after-free bug
ucma_process_join() will free the new allocated "mc" struct, if there is any error after that, especially the copy_to_user(). But in parallel, ucma_leave_multicast() could find this "mc" through idr_find() before ucma_process_join() frees it, since it is already published. So "mc" could be used in ucma_leave_multicast() after it is been allocated and freed in ucma_process_join(), since we don't refcnt it. Fix this by separating "publish" from ID allocation, so that we can get an ID first and publish it later after copy_to_user(). Fixes: c8f6a36 ("RDMA/cma: Add multicast communication support") Reported-by: Noam Rathaus <noamr@beyondsecurity.com> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
1 parent e4b1672 commit cb2595c

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

Diff for: drivers/infiniband/core/ucma.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ static struct ucma_multicast* ucma_alloc_multicast(struct ucma_context *ctx)
235235
return NULL;
236236

237237
mutex_lock(&mut);
238-
mc->id = idr_alloc(&multicast_idr, mc, 0, 0, GFP_KERNEL);
238+
mc->id = idr_alloc(&multicast_idr, NULL, 0, 0, GFP_KERNEL);
239239
mutex_unlock(&mut);
240240
if (mc->id < 0)
241241
goto error;
@@ -1421,6 +1421,10 @@ static ssize_t ucma_process_join(struct ucma_file *file,
14211421
goto err3;
14221422
}
14231423

1424+
mutex_lock(&mut);
1425+
idr_replace(&multicast_idr, mc, mc->id);
1426+
mutex_unlock(&mut);
1427+
14241428
mutex_unlock(&file->mut);
14251429
ucma_put_ctx(ctx);
14261430
return 0;

0 commit comments

Comments
 (0)