From 3476c28c9addfa253f505e6bd87f1f5598b961d0 Mon Sep 17 00:00:00 2001 From: Li RongQing Date: Wed, 26 Aug 2026 15:32:16 +0800 Subject: [PATCH] RDMA/mad: Fix receive buffer leak when PKey enforcement fails ib_mad_complete_recv() initializes mad_recv_wc->rmpp_list and then runs ib_mad_enforce_security() before linking recv_buf onto that list. On failure it calls ib_free_recv_mad(), which only walks rmpp_list and frees the ib_mad_private of every buffer found there. As the list is still empty at that point, nothing is freed at all. The caller cannot clean up either: ib_mad_recv_done() sets recv to NULL right after ib_mad_complete_recv() returns, assuming the MAD layer took ownership of the buffer. Every MAD that fails the PKey check therefore leaks one ib_mad_private (about 300 bytes per IB port MAD, ~2K for OPA), and a remote node can trigger this repeatedly by sending MADs with a wrong PKey. Link recv_buf onto rmpp_list right after the list is initialized, so the error path has something to free. Fixes: 47a2b338fe63 ("IB/core: Enforce security on management datagrams") Signed-off-by: Li RongQing Link: https://patch.msgid.link/20260826073216.2367-1-lirongqing@baidu.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/core/mad.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index e0b3b36b8b14..3c91f00d09c6 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -2059,6 +2059,8 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, int ret; INIT_LIST_HEAD(&mad_recv_wc->rmpp_list); + list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list); + ret = ib_mad_enforce_security(mad_agent_priv, mad_recv_wc->wc->pkey_index); if (ret) { @@ -2067,7 +2069,6 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, return; } - list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list); if (is_kernel_rmpp_data_response(mad_agent_priv, mad_recv_wc)) { spin_lock_irqsave(&mad_agent_priv->lock, flags); mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);