Linux RDMA and InfiniBand development
 help / color / mirror / Atom feed
* [PATCH] RDMA/cm: fix timewait leak and AV cleanup on ib_send_cm_req() errors
@ 2026-05-07  9:43 Chenguang Zhao
  2026-05-13 14:22 ` Leon Romanovsky
  0 siblings, 1 reply; 2+ messages in thread
From: Chenguang Zhao @ 2026-05-07  9:43 UTC (permalink / raw)
  To: Jason Gunthorpe, Leon Romanovsky
  Cc: Chenguang Zhao, Vlad Dumitrescu, Sean Hefty, Håkon Bugge,
	Kees Cook, linux-rdma

cm_create_timewait_info() success was followed by error returns that
never freed cm_id_priv->timewait_info, leaking it and tripping the
WARN_ON(timewait_info) on a later ib_send_cm_req().

After cm_move_av_from_path(), cm_alloc_priv_msg() and ib_post_send_mad()
failures must cm_destroy_av() the moved primary/alternate cm_id_priv
state before unlock; fold both cases into shared cleanup with kfree of
timewait_info.

Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
---
 drivers/infiniband/core/cm.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 6ab9a0aee1ec..7544206fa057 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -1542,13 +1542,13 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
 	ret = cm_init_av_by_path(param->primary_path,
 				 param->ppath_sgid_attr, &av);
 	if (ret)
-		return ret;
+		goto err_free_tw;
 	if (param->alternate_path) {
 		ret = cm_init_av_by_path(param->alternate_path, NULL,
 					 &alt_av);
 		if (ret) {
 			cm_destroy_av(&av);
-			return ret;
+			goto err_free_tw;
 		}
 	}
 	cm_id->service_id = param->service_id;
@@ -1577,7 +1577,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
 	msg = cm_alloc_priv_msg(cm_id_priv, IB_CM_REQ_SENT);
 	if (IS_ERR(msg)) {
 		ret = PTR_ERR(msg);
-		goto out_unlock;
+		goto err_destroy_id_av;
 	}
 
 	req_msg = (struct cm_req_msg *)msg->mad;
@@ -1590,15 +1590,21 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
 	trace_icm_send_req(&cm_id_priv->id);
 	ret = ib_post_send_mad(msg, NULL);
 	if (ret)
-		goto out_free;
+		goto err_free_msg;
 	BUG_ON(cm_id->state != IB_CM_IDLE);
 	cm_id->state = IB_CM_REQ_SENT;
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 	return 0;
-out_free:
+err_free_msg:
 	cm_free_priv_msg(msg);
-out_unlock:
+err_destroy_id_av:
+	if (param->alternate_path)
+		cm_destroy_av(&cm_id_priv->alt_av);
+	cm_destroy_av(&cm_id_priv->av);
 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+err_free_tw:
+	kfree(cm_id_priv->timewait_info);
+	cm_id_priv->timewait_info = NULL;
 	return ret;
 }
 EXPORT_SYMBOL(ib_send_cm_req);
-- 
2.25.1


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

end of thread, other threads:[~2026-05-13 14:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-07  9:43 [PATCH] RDMA/cm: fix timewait leak and AV cleanup on ib_send_cm_req() errors Chenguang Zhao
2026-05-13 14:22 ` Leon Romanovsky

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