| From foo@baz Sat Jul 28 10:25:26 CEST 2018 |
| From: Cong Wang <xiyou.wangcong@gmail.com> |
| Date: Fri, 1 Jun 2018 11:31:44 -0700 |
| Subject: infiniband: fix a possible use-after-free bug |
| |
| From: Cong Wang <xiyou.wangcong@gmail.com> |
| |
| [ Upstream commit cb2595c1393b4a5211534e6f0a0fbad369e21ad8 ] |
| |
| 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: c8f6a362bf3e ("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> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/infiniband/core/ucma.c | 6 +++++- |
| 1 file changed, 5 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/infiniband/core/ucma.c |
| +++ b/drivers/infiniband/core/ucma.c |
| @@ -218,7 +218,7 @@ static struct ucma_multicast* ucma_alloc |
| return NULL; |
| |
| mutex_lock(&mut); |
| - mc->id = idr_alloc(&multicast_idr, mc, 0, 0, GFP_KERNEL); |
| + mc->id = idr_alloc(&multicast_idr, NULL, 0, 0, GFP_KERNEL); |
| mutex_unlock(&mut); |
| if (mc->id < 0) |
| goto error; |
| @@ -1404,6 +1404,10 @@ static ssize_t ucma_process_join(struct |
| goto err3; |
| } |
| |
| + mutex_lock(&mut); |
| + idr_replace(&multicast_idr, mc, mc->id); |
| + mutex_unlock(&mut); |
| + |
| mutex_unlock(&file->mut); |
| ucma_put_ctx(ctx); |
| return 0; |