From: Changyul Lee <lcy8047@gmail.com>
To: Jason Gunthorpe <jgg@ziepe.ca>, Leon Romanovsky <leon@kernel.org>
Cc: linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org,
Changyul Lee <lcy8047@gmail.com>
Subject: [PATCH] RDMA/cm: Read the remote_id_table root under cm.lock
Date: Wed, 11 Nov 2026 14:19:13 -0500 [thread overview]
Message-ID: <20261111191913.98044-1-lcy8047@gmail.com> (raw)
cm_find_remote_id() reads the root of cm.remote_id_table before it
takes cm.lock. While it waits for the lock, cm_destroy_id() or
cm_reset_to_idle() on another CPU can remove that cm_timewait_info from
the tree and free it, and the lookup then starts from freed memory.
This lookup is done for a REJ with reason IB_CM_REJ_TIMEOUT.
Read the root after taking cm.lock.
Fixes: cfa68b0d0440 ("RDMA/cm: Make find_remote_id() return a cm_id_private")
Signed-off-by: Changyul Lee <lcy8047@gmail.com>
---
Found with a static analysis tool we are developing.
Reproduced in QEMU (x86_64, KASAN) on rdma_rxe over virtio-net, with a
test module that connects to a listener on the same device through
rdma_cm and destroys each active cm_id while it is in IB_CM_REQ_SENT,
so a REJ with IB_CM_REJ_TIMEOUT is sent. Another kthread destroys the
passive cm_ids. The window was widened for the test with an msleep(20)
between reading the root and taking cm.lock. Without this patch, KASAN
reported 46 to 48 slab-use-after-free reads in cm_work_handler() per
20 second run in three runs, on a cm_timewait_info allocated by
cm_create_timewait_info() and freed by cm_destroy_id() through
cm_reset_to_idle(). With it, there was no KASAN report in three runs.
drivers/infiniband/core/cm.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 1a2c2775b14d..5347b7519a8d 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -734,11 +734,12 @@ cm_insert_remote_id(struct cm_timewait_info *timewait_info)
static struct cm_id_private *cm_find_remote_id(__be64 remote_ca_guid,
__be32 remote_id)
{
- struct rb_node *node = cm.remote_id_table.rb_node;
+ struct rb_node *node;
struct cm_timewait_info *timewait_info;
struct cm_id_private *res = NULL;
spin_lock_irq(&cm.lock);
+ node = cm.remote_id_table.rb_node;
while (node) {
timewait_info = rb_entry(node, struct cm_timewait_info,
remote_id_node);
base-commit: 7475ea8b58616b33c04afb976cf0fbaad9dd63fb
--
2.43.0
next reply other threads:[~2026-11-11 19:19 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-11 19:19 Changyul Lee [this message]
2026-11-11 20:08 ` [PATCH] RDMA/cm: Read the remote_id_table root under cm.lock sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261111191913.98044-1-lcy8047@gmail.com \
--to=lcy8047@gmail.com \
--cc=jgg@ziepe.ca \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.