[PATCH] RDMA/ucma: Serialize join and leave on copy_to_user failure

Quanye Yang via B4 Relay posted 1 patch 3 weeks, 5 days ago
drivers/infiniband/core/ucma.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
[PATCH] RDMA/ucma: Serialize join and leave on copy_to_user failure
Posted by Quanye Yang via B4 Relay 3 weeks, 5 days ago
From: Quanye Yang <quanyeyang@proton.me>

rdma_join_multicast() queues RoCE work that later reads the ucma_multicast
through event->param.ud.private_data, then list_add()s the CMA multicast
at the head of id_priv->mc_list. rdma_leave_multicast() matches only by
sockaddr and destroys the first hit.

ucma_process_join() used to drop ctx->mutex after a successful join and
retake it only if copy_to_user() failed. Two concurrent JOIN_MCAST calls
with the same address can therefore insert a second CMA entry before the
first thread's leave. leave then cancels the newer work and the older
worker still dereferences the ucma_multicast that the first thread frees.

Keep ctx->mutex held from rdma_join_multicast() through copy_to_user() and,
on -EFAULT, through rdma_leave_multicast() so leave cannot miss this join.
Do not leave if join itself failed: that path never published this address
on mc_list, and a leave-by-addr would destroy an earlier successful join.

Reported-by: syzbot+a6ffe86390c8a6afc818@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a6ffe86390c8a6afc818
Fixes: fe454dc31e84 ("RDMA/ucma: Fix use-after-free bug in ucma_create_uevent")
Cc: stable@vger.kernel.org
Signed-off-by: Quanye Yang <quanyeyang@proton.me>
---
KASAN + rxe, virtme-ng. The syzbot C repro (two concurrent JOIN_MCAST
with response=0) no longer reports slab-use-after-free in
ucma_create_uevent.

Based on linus/master
---
 drivers/infiniband/core/ucma.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 4929636f7c53..c3611e2f3248 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -1556,27 +1556,27 @@ static ssize_t ucma_process_join(struct ucma_file *file,
 	mutex_lock(&ctx->mutex);
 	ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *)&mc->addr,
 				  join_state, mc);
-	mutex_unlock(&ctx->mutex);
-	if (ret)
+	if (ret) {
+		mutex_unlock(&ctx->mutex);
 		goto err_xa_erase;
+	}
 
 	resp.id = mc->id;
 	if (copy_to_user(u64_to_user_ptr(cmd->response),
 			 &resp, sizeof(resp))) {
 		ret = -EFAULT;
-		goto err_leave_multicast;
+		rdma_leave_multicast(ctx->cm_id, (struct sockaddr *)&mc->addr);
+		mutex_unlock(&ctx->mutex);
+		ucma_cleanup_mc_events(mc);
+		goto err_xa_erase;
 	}
+	mutex_unlock(&ctx->mutex);
 
 	xa_store(&multicast_table, mc->id, mc, 0);
 
 	ucma_put_ctx(ctx);
 	return 0;
 
-err_leave_multicast:
-	mutex_lock(&ctx->mutex);
-	rdma_leave_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr);
-	mutex_unlock(&ctx->mutex);
-	ucma_cleanup_mc_events(mc);
 err_xa_erase:
 	xa_lock(&multicast_table);
 	list_del(&mc->list);

---
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
change-id: 20260831-rdma-ucma-mc-uaf-9b7a089b90a3

Best regards,
--  
Quanye Yang <quanyeyang@proton.me>
Re: [PATCH] RDMA/ucma: Serialize join and leave on copy_to_user failure
Posted by Leon Romanovsky 2 weeks, 6 days ago
On Mon, 31 Aug 2026 20:30:58 +0800, Quanye Yang wrote:
> rdma_join_multicast() queues RoCE work that later reads the ucma_multicast
> through event->param.ud.private_data, then list_add()s the CMA multicast
> at the head of id_priv->mc_list. rdma_leave_multicast() matches only by
> sockaddr and destroys the first hit.
> 
> ucma_process_join() used to drop ctx->mutex after a successful join and
> retake it only if copy_to_user() failed. Two concurrent JOIN_MCAST calls
> with the same address can therefore insert a second CMA entry before the
> first thread's leave. leave then cancels the newer work and the older
> worker still dereferences the ucma_multicast that the first thread frees.
> 
> [...]

Applied, thanks!

[1/1] RDMA/ucma: Serialize join and leave on copy_to_user failure
      https://git.kernel.org/rdma/rdma/c/662ade4de9ff5e

Best regards,
-- 
Leon Romanovsky <leon@kernel.org>