Linux RDMA and InfiniBand development
 help / color / mirror / Atom feed
* [PATCH rdma-rc 1/2] RDMA/ucma: Lock the handler in ucma_write_cm_event()
@ 2026-07-27  8:06 Norbert Szetei
  2026-07-27  8:08 ` [PATCH rdma-rc 2/2] RDMA/ucma: Lock the handler in ucma_set_ib_path() Norbert Szetei
  2026-08-11 16:54 ` [PATCH rdma-rc 1/2] RDMA/ucma: Lock the handler in ucma_write_cm_event() Jason Gunthorpe
  0 siblings, 2 replies; 5+ messages in thread
From: Norbert Szetei @ 2026-07-27  8:06 UTC (permalink / raw)
  To: linux-rdma; +Cc: Jason Gunthorpe, Leon Romanovsky

ctx->file may only be changed under the handler lock and the xa_lock, which
is what stops uevents being queued for a ctx while ucma_migrate_id() moves
it to another file.  The CM core takes that lock before invoking
ucma_event_handler(), but the write() paths that queue uevents themselves
do not.

ucma_write_cm_event() re-reads ctx->file for each of its four dereferences,
so ucma_migrate_id() can swap it mid-sequence:

	mutex_lock(&ctx->file->mut);			/* file A */
	list_add_tail(&uevent->list, &ctx->file->event_list);	/* file B */
	mutex_unlock(&ctx->file->mut);			/* file B */
	wake_up_interruptible(&ctx->file->poll_wait);	/* file B */

The window is the mutex_lock() itself: the writer sleeps in it while the
migration reassigns ctx->file.  The list_add_tail() then runs on file B's
event_list holding only file A's mutex:

  list_add corruption. prev->next should be next (ffff888101320f30),
    but was ffff88814a08c418. (prev=ffff88814a075c18).
  kernel BUG at lib/list_debug.c:32!
  Call Trace:
   ucma_write_cm_event+0x36e/0x5e0

and file A's mut is left held forever, wedging its next writer in D state.
The uevent is also stranded on a list ucma_cleanup_ctx_events() will not
walk, so it outlives its context.  /dev/infiniband/rdma_cm is 0666 and no
RDMA device is involved, so an unprivileged user reaches all of this.

Take the handler lock, as ucma_cleanup_mc_events() does; ctx->cm_id is
pinned by the ucma_get_ctx() reference.

Fixes: a3c9d0fcd371 ("RDMA/ucma: Support write an event into a CM")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
---
 drivers/infiniband/core/ucma.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 878561fa1cb5..ba4dfa7f12de 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -1784,10 +1784,12 @@ static ssize_t ucma_write_cm_event(struct ucma_file *file,
 	memcpy(uevent->resp.param.arg32, &event.param.arg,
 	       sizeof(event.param.arg));
 
+	rdma_lock_handler(ctx->cm_id);
 	mutex_lock(&ctx->file->mut);
 	list_add_tail(&uevent->list, &ctx->file->event_list);
 	mutex_unlock(&ctx->file->mut);
 	wake_up_interruptible(&ctx->file->poll_wait);
+	rdma_unlock_handler(ctx->cm_id);
 
 out:
 	ucma_put_ctx(ctx);
-- 
2.55.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-08-11 17:46 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-27  8:06 [PATCH rdma-rc 1/2] RDMA/ucma: Lock the handler in ucma_write_cm_event() Norbert Szetei
2026-07-27  8:08 ` [PATCH rdma-rc 2/2] RDMA/ucma: Lock the handler in ucma_set_ib_path() Norbert Szetei
2026-08-11 17:46   ` Jason Gunthorpe
2026-08-11 16:54 ` [PATCH rdma-rc 1/2] RDMA/ucma: Lock the handler in ucma_write_cm_event() Jason Gunthorpe
2026-08-11 17:22   ` Jason Gunthorpe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox