* [PATCH rdma-rc] RDMA/ucma: free a queued CONNECT_REQUEST with its new context
@ 2026-11-09 3:20 Yuehong Wu
2026-11-11 13:38 ` Leon Romanovsky
0 siblings, 1 reply; 2+ messages in thread
From: Yuehong Wu @ 2026-11-09 3:20 UTC (permalink / raw)
To: linux-rdma; +Cc: Jason Gunthorpe, Leon Romanovsky, linux-kernel
ucma_cleanup_ctx_events() only frees the events that belong to the
context being destroyed. A CONNECT_REQUEST uevent that has not been
delivered to user space belongs to the listening context, but it also
keeps the newly created connection context in uevent->conn_req_ctx, and
that context is already reachable from user space because
ucma_finish_ctx() published its id before the event was queued.
If user space destroys the new id while the event is still queued, i.e.
before it fetches it with get_event, the event is skipped here and stays
in the listener's event list with a pointer to a context that
ucma_destroy_private_ctx() then frees. Destroying the listener later
(which is what closing its file does) reaches the
uevent->conn_req_ctx->id lookup in the xa_cmpxchg() below with a
dangling pointer, and when the freed context was reallocated the
comparison can match an unrelated live context, which is then detached
from the id table and freed.
The match in commit 8ae291cc95e4 ("RDMA/ucma: Do not miss ctx
destruction steps in some cases") replaced "uevent->ctx == ctx ||
uevent->conn_req_ctx == ctx" with a plain "uevent->ctx != ctx" test and
lost the case where the new context is the one being destroyed.
Free the event in that case and return the backlog slot it consumed: it
was never delivered to user space, so it can no longer be acted upon.
Fixes: 8ae291cc95e4 ("RDMA/ucma: Do not miss ctx destruction steps in some cases")
Cc: <stable@vger.kernel.org>
Signed-off-by: Yuehong Wu <wuyuehong@cmss.chinamobile.com>
---
Validated in a QEMU/KVM guest running this tree with CONFIG_KASAN=y and
CONFIG_RDMA_RXE=y. A reproducer creates an rxe device, queues a
CONNECT_REQUEST, sees it with poll() without fetching it, finds the new
connection id by trying the small integer ids that belong to its own
file, destroys that id and then the listener. The unpatched kernel
reports
BUG: KASAN: slab-use-after-free in ucma_destroy_private_ctx+0x1c0/0x4f0
Read of size 4 at addr ff11000102295a00 by task c9repro/302
Allocated by task 12:
ucma_alloc_ctx+0x2b/0x170
ucma_event_handler+0x1ad/0x3a0
Freed by task 302:
ucma_destroy_private_ctx+0x468/0x4f0
ucma_destroy_id+0x180/0x1e0
With this patch the same sequence run four times produces no report, and
a probe shows the queued event is dropped when the new context is
destroyed.
Note: ucma_migrate_id() can move the new context to another file, which
leaves its queued CONNECT_REQUEST in the original file's event list.
That cross-file case predates 8ae291cc95e4 and is left for a separate
fix.
drivers/infiniband/core/ucma.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -534,8 +534,23 @@ static int ucma_cleanup_ctx_events(struct ucma_context *ctx)
/* Cleanup events not yet reported to the user.*/
mutex_lock(&ctx->file->mut);
list_for_each_entry_safe(uevent, tmp, &ctx->file->event_list, list) {
- if (uevent->ctx != ctx)
+ /*
+ * A CONNECT_REQUEST that has not been delivered to user
+ * space belongs to the listening context but also holds the
+ * new one. If the new context is destroyed first, the id it
+ * was published under is gone, so drop the event instead of
+ * leaving a dangling conn_req_ctx in the event list.
+ */
+ if (uevent->ctx != ctx) {
+ if (uevent->resp.event == RDMA_CM_EVENT_CONNECT_REQUEST &&
+ uevent->conn_req_ctx == ctx) {
+ list_del(&uevent->list);
+ /* Return the slot taken for this request. */
+ atomic_inc(&uevent->ctx->backlog);
+ kfree(uevent);
+ }
continue;
+ }
if (uevent->resp.event == RDMA_CM_EVENT_CONNECT_REQUEST &&
xa_cmpxchg(&ctx_table, uevent->conn_req_ctx->id,
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH rdma-rc] RDMA/ucma: free a queued CONNECT_REQUEST with its new context
2026-11-09 3:20 [PATCH rdma-rc] RDMA/ucma: free a queued CONNECT_REQUEST with its new context Yuehong Wu
@ 2026-11-11 13:38 ` Leon Romanovsky
0 siblings, 0 replies; 2+ messages in thread
From: Leon Romanovsky @ 2026-11-11 13:38 UTC (permalink / raw)
To: Yuehong Wu; +Cc: linux-rdma, Jason Gunthorpe, linux-kernel
On Mon, Nov 09, 2026 at 11:20:00AM +0800, Yuehong Wu wrote:
> ucma_cleanup_ctx_events() only frees the events that belong to the
> context being destroyed. A CONNECT_REQUEST uevent that has not been
> delivered to user space belongs to the listening context, but it also
> keeps the newly created connection context in uevent->conn_req_ctx, and
> that context is already reachable from user space because
> ucma_finish_ctx() published its id before the event was queued.
>
> If user space destroys the new id while the event is still queued, i.e.
> before it fetches it with get_event, the event is skipped here and stays
> in the listener's event list with a pointer to a context that
> ucma_destroy_private_ctx() then frees. Destroying the listener later
> (which is what closing its file does) reaches the
> uevent->conn_req_ctx->id lookup in the xa_cmpxchg() below with a
> dangling pointer, and when the freed context was reallocated the
> comparison can match an unrelated live context, which is then detached
> from the id table and freed.
>
> The match in commit 8ae291cc95e4 ("RDMA/ucma: Do not miss ctx
> destruction steps in some cases") replaced "uevent->ctx == ctx ||
> uevent->conn_req_ctx == ctx" with a plain "uevent->ctx != ctx" test and
> lost the case where the new context is the one being destroyed.
>
> Free the event in that case and return the backlog slot it consumed: it
> was never delivered to user space, so it can no longer be acted upon.
>
> Fixes: 8ae291cc95e4 ("RDMA/ucma: Do not miss ctx destruction steps in some cases")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Yuehong Wu <wuyuehong@cmss.chinamobile.com>
> ---
> Validated in a QEMU/KVM guest running this tree with CONFIG_KASAN=y and
> CONFIG_RDMA_RXE=y. A reproducer creates an rxe device, queues a
> CONNECT_REQUEST, sees it with poll() without fetching it, finds the new
> connection id by trying the small integer ids that belong to its own
> file, destroys that id and then the listener. The unpatched kernel
> reports
>
> BUG: KASAN: slab-use-after-free in ucma_destroy_private_ctx+0x1c0/0x4f0
> Read of size 4 at addr ff11000102295a00 by task c9repro/302
> Allocated by task 12:
> ucma_alloc_ctx+0x2b/0x170
> ucma_event_handler+0x1ad/0x3a0
> Freed by task 302:
> ucma_destroy_private_ctx+0x468/0x4f0
> ucma_destroy_id+0x180/0x1e0
>
> With this patch the same sequence run four times produces no report, and
> a probe shows the queued event is dropped when the new context is
> destroyed.
>
> Note: ucma_migrate_id() can move the new context to another file, which
> leaves its queued CONNECT_REQUEST in the original file's event list.
> That cross-file case predates 8ae291cc95e4 and is left for a separate
> fix.
>
> drivers/infiniband/core/ucma.c | 17 ++++++++++++++++-
> 1 file changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
> --- a/drivers/infiniband/core/ucma.c
> +++ b/drivers/infiniband/core/ucma.c
> @@ -534,8 +534,23 @@ static int ucma_cleanup_ctx_events(struct ucma_context *ctx)
> /* Cleanup events not yet reported to the user.*/
> mutex_lock(&ctx->file->mut);
> list_for_each_entry_safe(uevent, tmp, &ctx->file->event_list, list) {
> - if (uevent->ctx != ctx)
> + /*
> + * A CONNECT_REQUEST that has not been delivered to user
> + * space belongs to the listening context but also holds the
> + * new one.
I don't understand this sentence. conn_req_ctx is created and added to
event_list at the same function without any conditions.
Please explain with function call chain how your claim is possible.
Thanks
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-11 13:38 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-09 3:20 [PATCH rdma-rc] RDMA/ucma: free a queued CONNECT_REQUEST with its new context Yuehong Wu
2026-11-11 13:38 ` Leon Romanovsky
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®