Re: [PATCH net] net: rds: fix uninitialized trans dereference in CM event handler

Allison Henderson <[email protected]>
Newsgroups org.kernel.vger.stable,org.kernel.vger.linux-kernel,org.kernel.vger.linux-rdma,org.kernel.vger.netdev
Message-ID <[email protected]>
On Mon, 2026-08-24 at 19:17 +0800, Aohan Mei wrote:
> From: Aohan Mei <[email protected]>
> 
> rds_rdma_cm_event_handler_cmn() assigns trans only when the RDMA
> device is an InfiniBand CA (RDMA_NODE_IB_CA).  On any other device
> type, e.g. an iWARP RNIC such as siw, trans stays uninitialized, but
> the event switch dereferences it: unconditionally in the
> RDMA_CM_EVENT_CONNECT_REQUEST case via trans->cm_handle_connect(),
> and (with a connection context) in the ROUTE_RESOLVED and
> ESTABLISHED cases.
> 
> An RDS listener on an iWARP device therefore crashes the kernel as
> soon as a connect request arrives: with CONFIG_INIT_STACK_ALL_ZERO
> the wild load becomes a NULL dereference at offset 0xa0
> (&trans->cm_handle_connect) in the iw_cm_wq workqueue.
> 
> GCC masks the bug in default builds by folding the uninitialized
> load into &rds_ib_transport; Clang-built kernels take the real
> uninitialized path and oops.
> 
> Reject events that arrive on device types without an RDS transport:
> initialize trans to NULL and bail out before the event switch when
> no transport matched.
> 
> Fixes: dcdede0406d3 ("RDS: Drop stale iWARP RDMA transport")
> Reported-by: TencentOS Corvus AI <[email protected]>
> Cc: [email protected]
> Assisted-by: CodeBuddy:Kimi-K3
> Signed-off-by: Aohan Mei <[email protected]>
> 
> 

Hi Aohan,

Thanks for catching this.  A few comments below:

> ---
>  net/rds/rdma_transport.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c
> index b15cf316b23a..ad9244a09848 100644
> --- a/net/rds/rdma_transport.c
> +++ b/net/rds/rdma_transport.c
> @@ -52,7 +52,7 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
>  {
>  	/* this can be null in the listening path */
>  	struct rds_connection *conn = cm_id->context;
> -	struct rds_transport *trans;
> +	struct rds_transport *trans = NULL;
>  	int ret = 0;
>  	int *err;
>  	u8 len;
> @@ -80,6 +80,14 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
>  		}
>  	}
>  
> +	/* No RDS transport exists for this device type (e.g. iWARP RNIC),
> +	 * so trans was never assigned; reject instead of dereferencing it.
> +	 */
> +	if (!trans) {
> +		ret = 1;
> +		goto out;
> +	}
> +

Support for iWarp was removed in dcdede0406d30e1 and this function only supports ib.  So we should probably just enforce
the ib transport:

	if (cm_id->device->node_type != RDMA_NODE_IB_CA) {
		ret = 1;
		goto out;
	}

Then we can just initialize trans to &rds_ib_transport at the top, and remove the conditional assignment that appears a
few lines up from here. 

Thanks!
Allison


>  	switch (event->event) {
>  	case RDMA_CM_EVENT_CONNECT_REQUEST:
>  		ret = trans->cm_handle_connect(cm_id, event, isv6);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.