mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 08:45:18 -04:00
svcrdma: Clear sc_cm_id when ADDR_CHANGE replacement fails
When svc_rdma_listen_handler() handles RDMA_CM_EVENT_ADDR_CHANGE,
it creates a replacement listener cm_id and returns 1, telling
the CM core to destroy the old one. If the replacement allocation
fails, sc_cm_id still points at the old cm_id that the CM core is
about to destroy. Any subsequent dereference of sc_cm_id --
such as svc_rdma_detach()'s rdma_disconnect() call -- is a
use-after-free.
NULL sc_cm_id on the failure path and guard svc_rdma_detach()'s
rdma_disconnect() call against NULL so that the listener can
be torn down safely when the server shuts down.
Fixes: d1b586e75e ("svcrdma: Handle ADDR_CHANGE CM event properly")
Cc: stable@vger.kernel.org
Acked-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260527-rdma-follow-on-v1-5-1b09bd87b6cd@oracle.com
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
@@ -330,6 +330,7 @@ static int svc_rdma_listen_handler(struct rdma_cm_id *cma_id,
|
||||
if (IS_ERR(listen_id)) {
|
||||
pr_err("Listener dead, address change failed for device %s\n",
|
||||
cma_id->device->name);
|
||||
cma_xprt->sc_cm_id = NULL;
|
||||
} else
|
||||
cma_xprt->sc_cm_id = listen_id;
|
||||
return 1;
|
||||
@@ -638,7 +639,8 @@ static void svc_rdma_detach(struct svc_xprt *xprt)
|
||||
struct svcxprt_rdma *rdma =
|
||||
container_of(xprt, struct svcxprt_rdma, sc_xprt);
|
||||
|
||||
rdma_disconnect(rdma->sc_cm_id);
|
||||
if (rdma->sc_cm_id)
|
||||
rdma_disconnect(rdma->sc_cm_id);
|
||||
|
||||
/*
|
||||
* Most close paths go through svc_rdma_xprt_deferred_close(),
|
||||
|
||||
Reference in New Issue
Block a user