]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
SUNRPC: release lower rpc_clnt if killed waiting for XPRT_LOCKED
authorChuck Lever <chuck.lever@oracle.com>
Mon, 4 May 2026 10:28:18 +0000 (06:28 -0400)
committerAnna Schumaker <anna.schumaker@hammerspace.com>
Wed, 8 Jul 2026 18:07:19 +0000 (14:07 -0400)
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>
net/sunrpc/xprtsock.c

index 2e1fe601336151d50b936afbb5df1114ffb07551..3eccd4923e6c66f4a23ca0983b553831d633edc0 100644 (file)
@@ -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) {