From 56da3c20bc16cd9056e44352713873b31efe917c Mon Sep 17 00:00:00 2001 From: Luke Yue Date: Sat, 18 Jan 2025 23:53:13 +0800 Subject: [PATCH] librdmacm: prevent NULL pointer access during device initialization When an RNIC with node_guid 0 is present, rdma_resolve_addr succeeds with ADDR_RESOLVED but subsequent device initialization can fail. This occurs because ucma_query_addr and ucma_query_route skip device initialization when the kernel returns a zero node_guid, leading to NULL pointer access in ucma_process_addr_resolved. Add explicit NULL checks for id->verbs after ucma_query_addr and ucma_query_route calls. Return ENODEV error if device initialization fails, ensuring proper error propagation instead of crashes. Note: ucma_query_addr must still return success in this case as it's used for probing AF_IB support, which intentionally skips device initialization. Fixes: 71623251b05a ("librdmacm: replace query_route call with separate queries") Signed-off-by: Luke Yue --- librdmacm/cma.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/librdmacm/cma.c b/librdmacm/cma.c index 4a137458c..93c7fd683 100644 --- a/librdmacm/cma.c +++ b/librdmacm/cma.c @@ -2252,17 +2252,30 @@ int rdma_ack_cm_event(struct rdma_cm_event *event) static void ucma_process_addr_resolved(struct cma_event *evt) { + struct rdma_cm_id *id = &evt->id_priv->id; + if (af_ib_support) { - evt->event.status = ucma_query_addr(&evt->id_priv->id); + evt->event.status = ucma_query_addr(id); + if (!evt->event.status && !id->verbs) + goto err_dev; + if (!evt->event.status && - evt->id_priv->id.verbs->device->transport_type == IBV_TRANSPORT_IB) - evt->event.status = ucma_query_gid(&evt->id_priv->id); + id->verbs->device->transport_type == IBV_TRANSPORT_IB) { + evt->event.status = ucma_query_gid(id); + } } else { - evt->event.status = ucma_query_route(&evt->id_priv->id); + evt->event.status = ucma_query_route(id); + if (!evt->event.status && !id->verbs) + goto err_dev; } if (evt->event.status) evt->event.event = RDMA_CM_EVENT_ADDR_ERROR; + return; + +err_dev: + evt->event.status = ERR(ENODEV); + evt->event.event = RDMA_CM_EVENT_ADDR_ERROR; } static void ucma_process_route_resolved(struct cma_event *evt)