From: Aohan Mei 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. The iWARP transport was dropped long ago and IB is the only transport left, so make that explicit: initialize trans to &rds_ib_transport at declaration, drop the conditional assignment, and reject events from non-IB devices before the event switch. Fixes: dcdede0406d3 ("RDS: Drop stale iWARP RDMA transport") Reported-by: TencentOS Corvus AI Cc: stable@vger.kernel.org Assisted-by: CodeBuddy:Kimi-K3 Signed-off-by: Aohan Mei --- v2: - Enforce the IB transport directly instead of NULL-guarding trans, as suggested by Allison Henderson. v1: https://lore.kernel.org/netdev/20260824111701.2979194-1-ljp1205831794@gmail.com net/rds/rdma_transport.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c index b15cf316b23a..2c5481f1fcb4 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 = &rds_ib_transport; int ret = 0; int *err; u8 len; @@ -60,9 +60,6 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id, rdsdebug("conn %p id %p handling event %u (%s)\n", conn, cm_id, event->event, rdma_event_msg(event->event)); - if (cm_id->device->node_type == RDMA_NODE_IB_CA) - trans = &rds_ib_transport; - /* Prevent shutdown from tearing down the connection * while we're executing. */ if (conn) { @@ -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; + } + switch (event->event) { case RDMA_CM_EVENT_CONNECT_REQUEST: ret = trans->cm_handle_connect(cm_id, event, isv6); -- 2.43.7