]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xprtrdma: Check frwr_wp_create() during connect
authorChuck Lever <chuck.lever@oracle.com>
Thu, 4 Jun 2026 17:06:35 +0000 (13:06 -0400)
committerAnna Schumaker <anna.schumaker@hammerspace.com>
Wed, 10 Jun 2026 19:47:06 +0000 (15:47 -0400)
frwr_wp_create() creates the singleton Memory Region used to encode
padding for Write chunks whose payload length is not XDR-aligned. Its
failure paths return a negative errno and leave ep->re_write_pad_mr set
to NULL.

rpcrdma_xprt_connect() currently ignores that return value. If
frwr_wp_create() fails after the rest of the connection setup succeeds,
xprt_rdma_connect_worker() treats the connection attempt as successful
and sets XPRT_CONNECTED. A later NFS/RDMA read with a non-4-byte-aligned
receive page length reaches rpcrdma_encode_write_list(), passes the NULL
write-pad MR to encode_rdma_segment(), and dereferences it.

This is locally triggerable on an NFS/RDMA client after a connect or
reconnect hits a local MR allocation, DMA-map, MR-map, or post-send
failure; a remote peer alone cannot force the local MR setup failure.

Check the return value and fail the connect as -ENOTCONN, matching the
adjacent setup failures. This keeps XPRT_CONNECTED clear and lets the
normal reconnect path retry.

Fixes: 21037b8c2258 ("xprtrdma: Provide a buffer to pad Write chunks of unaligned length")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
net/sunrpc/xprtrdma/verbs.c

index a192b77ce739dcc2b20e099765fc853a417eecaa..74d173e5681dba7d1a476730ee5bd7c69aa02384 100644 (file)
@@ -549,7 +549,17 @@ int rpcrdma_xprt_connect(struct rpcrdma_xprt *r_xprt)
                goto out;
        }
        rpcrdma_mrs_create(r_xprt);
-       frwr_wp_create(r_xprt);
+
+       /*
+        * rpcrdma_encode_write_list() dereferences the write-pad
+        * MR with no NULL check, so fail the connect rather than
+        * publish a transport whose write-pad MR is NULL.
+        */
+       rc = frwr_wp_create(r_xprt);
+       if (rc) {
+               rc = -ENOTCONN;
+               goto out;
+       }
 
 out:
        trace_xprtrdma_connect(r_xprt, rc);