summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2026-05-04 06:28:18 -0400
committerAnna Schumaker <anna.schumaker@hammerspace.com>2026-07-08 14:07:19 -0400
commit29bacb096d43bd04062f6655e50ceeed27fe6d2f (patch)
tree6b31f9c0b3550459e83fbfe529f18d78aeb2c2d1
parent8cdeaa50eae8dad34885515f62559ee83e7e8dda (diff)
SUNRPC: release lower rpc_clnt if killed waiting for XPRT_LOCKED
xs_tcp_tls_setup_socket() creates a temporary "lower" rpc_clnt with rpc_create() to drive the inner TLS handshake, then waits for XPRT_LOCKED on its xprt with TASK_KILLABLE so a stuck handshake can be aborted by signal. When the wait is interrupted, the function jumps to out_unlock without releasing lower_clnt. The success path and the out_close error path both call rpc_shutdown_client(lower_clnt); only the killed-wait path skips it, leaking the clnt and its underlying xprt. Call rpc_shutdown_client() on this path before joining out_unlock. xprt_release_write() is not needed here because XPRT_LOCKED was never acquired. Fixes: 26e8bfa30dac ("SUNRPC/TLS: Lock the lower_xprt during the tls handshake") Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Tested-by: Michael Nemanov <michael.nemanov@vastdata.com> Reviewed-by: Michael Nemanov <michael.nemanov@vastdata.com> Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
-rw-r--r--net/sunrpc/xprtsock.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 2e1fe6013361..3eccd4923e6c 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2734,8 +2734,11 @@ static void xs_tcp_tls_setup_socket(struct work_struct *work)
lower_xprt = rcu_dereference(lower_clnt->cl_xprt);
rcu_read_unlock();
- if (wait_on_bit_lock(&lower_xprt->state, XPRT_LOCKED, TASK_KILLABLE))
+ if (wait_on_bit_lock(&lower_xprt->state, XPRT_LOCKED, TASK_KILLABLE)) {
+ /* XPRT_LOCKED was never acquired. */
+ rpc_shutdown_client(lower_clnt);
goto out_unlock;
+ }
status = xs_tls_handshake_sync(lower_xprt, &upper_xprt->xprtsec);
if (status) {