mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Allison Henderson <achender@kernel.org>
To: Jakub Kicinski <kuba@kernel.org>,
	ljp1205831794@gmail.com,  henrymei@tencent.com
Cc: netdev@vger.kernel.org, linux-rdma@vger.kernel.org,
	 rds-devel@oss.oracle.com, linux-kernel@vger.kernel.org,
	 kerneljasonxing@gmail.com, henrymei@tencent.com,
	corvus@tencent.com,  stable@vger.kernel.org
Subject: Re: [PATCH net v2] net: rds: fix uninitialized trans dereference in CM event handler
Date: Thu, 17 Sep 2026 00:37:53 -0700	[thread overview]
Message-ID: <9283f0fddfc18003aeddfd6521a84631a27df74f.camel@kernel.org> (raw)
In-Reply-To: <f61be21da825131657194f9fec83a77d7a92fe8a.camel@kernel.org>

On Thu, 2026-08-27 at 20:55 -0700, Allison Henderson wrote:
> On Thu, 2026-08-27 at 09:18 -0700, Jakub Kicinski wrote:
> > This is an AI-generated review of your patch. The human sending this
> > email has considered the AI review valid, or at least plausible.
> > ---
> > net: rds: fix uninitialized trans dereference in CM event handler
> > 
> > This initializes trans to &rds_ib_transport at declaration in
> > rds_rdma_cm_event_handler_cmn(), drops the conditional assignment based on
> > cm_id->device->node_type, and adds an early bail-out that returns 1 for any
> > event arriving on a device that is not RDMA_NODE_IB_CA.
> > 
> > > diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c
> > > index b15cf316b23a2..2c5481f1fcb4f 100644
> > > --- a/net/rds/rdma_transport.c
> > > +++ b/net/rds/rdma_transport.c
> > 
> > [ ... ]
> > 
> > > @@ -80,6 +77,12 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
> > >  		}
> > >  	}
> > >  
> > > +	/* Only the IB transport is supported. */
> > > +	if (cm_id->device->node_type != RDMA_NODE_IB_CA) {
> > > +		ret = 1;
> > > +		goto out;
> > > +	}
> > > +
> > 
> > [Severity: High]
> > Should this non-zero return be limited to RDMA_CM_EVENT_CONNECT_REQUEST?
> > As written it applies to every event type.
> > 
> > include/rdma/rdma_cm.h documents what a non-zero return means:
> > 
> > /**
> >  * rdma_cm_event_handler - Callback used to report user events.
> >  *
> >  * Notes: Users may not call rdma_destroy_id from this callback to destroy
> >  *   the passed in id, or a corresponding listen id.  Returning a
> >  *   non-zero value from the callback will destroy the passed in id.
> >  */
> > 
> > The cma dispatchers implement exactly that, for example addr_handler() and
> > cma_work_handler() in drivers/infiniband/core/cma.c:
> > 
> > 	if (cma_cm_event_handler(id_priv, &event)) {
> > 		destroy_id_handler_unlock(id_priv);
> > 		return;
> > 	}
> > 
> > But RDS keeps ownership of connection cm_ids.  rds_ib_conn_path_connect()
> > stores it:
> > 
> > 	ic->i_cm_id = rdma_create_id(&init_net, handler, conn,
> > 				     RDMA_PS_TCP, IB_QPT_RC);
> > 
> > and rds_ib_conn_path_shutdown() later dereferences and destroys the same
> > pointer, clearing it only afterwards:
> > 
> > 	if (ic->i_cm_id) {
> > 		rdsdebug("disconnecting cm %p\n", ic->i_cm_id);
> > 		err = rdma_disconnect(ic->i_cm_id);
> > 	...
> > 		rdma_destroy_id(ic->i_cm_id);
> > 	...
> > 		ic->i_cm_id = NULL;
> > 
> > So if any event other than CONNECT_REQUEST is delivered with conn != NULL on
> > a cm_id whose device node_type is not RDMA_NODE_IB_CA, does the core free the
> > cm_id while ic->i_cm_id still points at it?  Can the following conn drop,
> > socket close or module unload then hit freed memory in
> > rds_ib_conn_path_shutdown(), including a second rdma_destroy_id() on the same
> > id?
> > 
> > A reachable path without any race: rds_ib_laddr_check() short-circuits via
> > rds_ib_get_device(), which only walks the ipaddr_list of RDS's own IB
> > devices:
> > 
> > net/rds/ib_rdma.c:rds_ib_get_device() {
> > 	list_for_each_entry_rcu(rds_ibdev, &rds_ib_devices, list) {
> > 		list_for_each_entry_rcu(i_ipaddr, &rds_ibdev->ipaddr_list, list) {
> > 			if (i_ipaddr->ipaddr == ipaddr) {
> > 	...
> > }
> > 
> > while the device actually bound for the outgoing connection is picked later
> > by cma_acquire_dev_by_src_ip(), which walks the global cma dev_list and can
> > match a siw device on the same address.  siw_device_create() sets:
> > 
> > 	base_dev->node_type = RDMA_NODE_RNIC;
> > 
> > In that configuration, rdma_resolve_addr() from rds_ib_conn_path_connect()
> > binds a RDMA_NODE_RNIC device, and the resulting RDMA_CM_EVENT_ADDR_RESOLVED
> > with conn != NULL now returns 1, so addr_handler() destroys the id while RDS
> > still tracks it.
> > 
> > The same function a few lines above already documents the opposite
> > convention:
> > 
> > 		/* If the connection is being shut down, bail out
> > 		 * right away. We return 0 so cm_id doesn't get
> > 		 * destroyed prematurely */
> > 		if (rds_conn_state(conn) == RDS_CONN_DISCONNECTING) {
> > 			/* Reject incoming connections while we're tearing
> > 			 * down an existing one. */
> > 			if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST)
> > 				ret = 1;
> > 			goto out;
> > 		}
> > 
> > Separately, does the unconditional goto out also skip the rds_conn_drop()
> > that the ADDR_ERROR, ROUTE_ERROR, CONNECT_ERROR, UNREACHABLE,
> > DEVICE_REMOVAL, ADDR_CHANGE, DISCONNECTED and TIMEWAIT_EXIT cases perform,
> > leaving the RDS connection stuck in CONNECTING or UP with no error
> > propagated?
> > 
> > Would something along these lines match the existing convention, while still
> > dropping the conn for the remaining events:
> > 
> > 	ret = (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) ? 1 : 0;
> > 
> > or moving the node_type test into the RDMA_CM_EVENT_CONNECT_REQUEST case?
> 
> I think the cleaner solution here would be to hoist the check into the calling function.  So in
> rds_rdma_cm_event_handler_cmn():
> 
>         case RDMA_CM_EVENT_CONNECT_REQUEST:
> 		/* Only the IB transport is supported. */
>                 if (cm_id->device->node_type == RDMA_NODE_IB_CA)
>                         ret = trans->cm_handle_connect(cm_id, event, isv6);
>                 else
>                 	ret = 1;
>                 break;
> 
> Thanks for working on this!
> Allison
> 
Hi Aohan,

I know this thread is a bit old, but this bug popped up as a pre-existing bug for another set review.  Did you have an
interest in sending a v3?  I am fine to carry it forward if you're on to other things, but I wanted to check with you
first.  I'd preserve all your tags, sob, and reported-by.  Just let me know, I'm fine either way.

Thanks!
Allison

      reply	other threads:[~2026-09-17  7:37 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-25  2:12 Aohan Mei
2026-08-25  6:24 ` Allison Henderson
2026-08-27 16:18 ` Jakub Kicinski
2026-08-28  3:55   ` Allison Henderson
2026-09-17  7:37     ` Allison Henderson [this message]

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=9283f0fddfc18003aeddfd6521a84631a27df74f.camel@kernel.org \
    --to=achender@kernel.org \
    --cc=corvus@tencent.com \
    --cc=henrymei@tencent.com \
    --cc=kerneljasonxing@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=ljp1205831794@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=rds-devel@oss.oracle.com \
    --cc=stable@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 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®