Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

SUNRPC: Ensure that the gssproxy client can start in a connected state

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>

+35
+1
include/linux/sunrpc/clnt.h
··· 160 160 #define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT (1UL << 9) 161 161 #define RPC_CLNT_CREATE_SOFTERR (1UL << 10) 162 162 #define RPC_CLNT_CREATE_REUSEPORT (1UL << 11) 163 + #define RPC_CLNT_CREATE_CONNECTED (1UL << 12) 163 164 164 165 struct rpc_clnt *rpc_create(struct rpc_create_args *args); 165 166 struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
+1
net/sunrpc/auth_gss/gss_rpc_upcall.c
··· 98 98 * done without the correct namespace: 99 99 */ 100 100 .flags = RPC_CLNT_CREATE_NOPING | 101 + RPC_CLNT_CREATE_CONNECTED | 101 102 RPC_CLNT_CREATE_NO_IDLE_TIMEOUT 102 103 }; 103 104 struct rpc_clnt *clnt;
+33
net/sunrpc/clnt.c
··· 76 76 static int rpc_decode_header(struct rpc_task *task, 77 77 struct xdr_stream *xdr); 78 78 static int rpc_ping(struct rpc_clnt *clnt); 79 + static int rpc_ping_noreply(struct rpc_clnt *clnt); 79 80 static void rpc_check_timeout(struct rpc_task *task); 80 81 81 82 static void rpc_register_client(struct rpc_clnt *clnt) ··· 480 479 481 480 if (!(args->flags & RPC_CLNT_CREATE_NOPING)) { 482 481 int err = rpc_ping(clnt); 482 + if (err != 0) { 483 + rpc_shutdown_client(clnt); 484 + return ERR_PTR(err); 485 + } 486 + } else if (args->flags & RPC_CLNT_CREATE_CONNECTED) { 487 + int err = rpc_ping_noreply(clnt); 483 488 if (err != 0) { 484 489 rpc_shutdown_client(clnt); 485 490 return ERR_PTR(err); ··· 2716 2709 .p_decode = rpcproc_decode_null, 2717 2710 }; 2718 2711 2712 + static const struct rpc_procinfo rpcproc_null_noreply = { 2713 + .p_encode = rpcproc_encode_null, 2714 + }; 2715 + 2719 2716 static void 2720 2717 rpc_null_call_prepare(struct rpc_task *task, void *data) 2721 2718 { ··· 2766 2755 int status; 2767 2756 2768 2757 task = rpc_call_null_helper(clnt, NULL, NULL, 0, NULL, NULL); 2758 + if (IS_ERR(task)) 2759 + return PTR_ERR(task); 2760 + status = task->tk_status; 2761 + rpc_put_task(task); 2762 + return status; 2763 + } 2764 + 2765 + static int rpc_ping_noreply(struct rpc_clnt *clnt) 2766 + { 2767 + struct rpc_message msg = { 2768 + .rpc_proc = &rpcproc_null_noreply, 2769 + }; 2770 + struct rpc_task_setup task_setup_data = { 2771 + .rpc_client = clnt, 2772 + .rpc_message = &msg, 2773 + .callback_ops = &rpc_null_ops, 2774 + .flags = RPC_TASK_SOFT | RPC_TASK_SOFTCONN | RPC_TASK_NULLCREDS, 2775 + }; 2776 + struct rpc_task *task; 2777 + int status; 2778 + 2779 + task = rpc_run_task(&task_setup_data); 2769 2780 if (IS_ERR(task)) 2770 2781 return PTR_ERR(task); 2771 2782 status = task->tk_status;