| From fd13359f54ee854f00134abc6be32da94ec53dbf Mon Sep 17 00:00:00 2001 |
| From: Trond Myklebust <trond.myklebust@hammerspace.com> |
| Date: Sat, 7 May 2022 13:53:59 -0400 |
| Subject: SUNRPC: Ensure that the gssproxy client can start in a connected state |
| |
| From: Trond Myklebust <trond.myklebust@hammerspace.com> |
| |
| commit fd13359f54ee854f00134abc6be32da94ec53dbf upstream. |
| |
| Ensure that the gssproxy client connects to the server from the gssproxy |
| daemon process context so that the AF_LOCAL socket connection is done |
| using the correct path and namespaces. |
| |
| Fixes: 1d658336b05f ("SUNRPC: Add RPC based upcall mechanism for RPCGSS auth") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| include/linux/sunrpc/clnt.h | 1 + |
| net/sunrpc/auth_gss/gss_rpc_upcall.c | 1 + |
| net/sunrpc/clnt.c | 33 +++++++++++++++++++++++++++++++++ |
| 3 files changed, 35 insertions(+) |
| |
| --- a/include/linux/sunrpc/clnt.h |
| +++ b/include/linux/sunrpc/clnt.h |
| @@ -159,6 +159,7 @@ struct rpc_add_xprt_test { |
| #define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT (1UL << 9) |
| #define RPC_CLNT_CREATE_SOFTERR (1UL << 10) |
| #define RPC_CLNT_CREATE_REUSEPORT (1UL << 11) |
| +#define RPC_CLNT_CREATE_CONNECTED (1UL << 12) |
| |
| struct rpc_clnt *rpc_create(struct rpc_create_args *args); |
| struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *, |
| --- a/net/sunrpc/auth_gss/gss_rpc_upcall.c |
| +++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c |
| @@ -98,6 +98,7 @@ static int gssp_rpc_create(struct net *n |
| * done without the correct namespace: |
| */ |
| .flags = RPC_CLNT_CREATE_NOPING | |
| + RPC_CLNT_CREATE_CONNECTED | |
| RPC_CLNT_CREATE_NO_IDLE_TIMEOUT |
| }; |
| struct rpc_clnt *clnt; |
| --- a/net/sunrpc/clnt.c |
| +++ b/net/sunrpc/clnt.c |
| @@ -76,6 +76,7 @@ static int rpc_encode_header(struct rpc_ |
| static int rpc_decode_header(struct rpc_task *task, |
| struct xdr_stream *xdr); |
| static int rpc_ping(struct rpc_clnt *clnt); |
| +static int rpc_ping_noreply(struct rpc_clnt *clnt); |
| static void rpc_check_timeout(struct rpc_task *task); |
| |
| static void rpc_register_client(struct rpc_clnt *clnt) |
| @@ -483,6 +484,12 @@ static struct rpc_clnt *rpc_create_xprt( |
| rpc_shutdown_client(clnt); |
| return ERR_PTR(err); |
| } |
| + } else if (args->flags & RPC_CLNT_CREATE_CONNECTED) { |
| + int err = rpc_ping_noreply(clnt); |
| + if (err != 0) { |
| + rpc_shutdown_client(clnt); |
| + return ERR_PTR(err); |
| + } |
| } |
| |
| clnt->cl_softrtry = 1; |
| @@ -2704,6 +2711,10 @@ static const struct rpc_procinfo rpcproc |
| .p_decode = rpcproc_decode_null, |
| }; |
| |
| +static const struct rpc_procinfo rpcproc_null_noreply = { |
| + .p_encode = rpcproc_encode_null, |
| +}; |
| + |
| static void |
| rpc_null_call_prepare(struct rpc_task *task, void *data) |
| { |
| @@ -2753,6 +2764,28 @@ static int rpc_ping(struct rpc_clnt *cln |
| if (IS_ERR(task)) |
| return PTR_ERR(task); |
| status = task->tk_status; |
| + rpc_put_task(task); |
| + return status; |
| +} |
| + |
| +static int rpc_ping_noreply(struct rpc_clnt *clnt) |
| +{ |
| + struct rpc_message msg = { |
| + .rpc_proc = &rpcproc_null_noreply, |
| + }; |
| + struct rpc_task_setup task_setup_data = { |
| + .rpc_client = clnt, |
| + .rpc_message = &msg, |
| + .callback_ops = &rpc_null_ops, |
| + .flags = RPC_TASK_SOFT | RPC_TASK_SOFTCONN | RPC_TASK_NULLCREDS, |
| + }; |
| + struct rpc_task *task; |
| + int status; |
| + |
| + task = rpc_run_task(&task_setup_data); |
| + if (IS_ERR(task)) |
| + return PTR_ERR(task); |
| + status = task->tk_status; |
| rpc_put_task(task); |
| return status; |
| } |