xref: /linux/fs/nfs/callback.c (revision 0526b56cbc3c489642bd6a5fe4b718dea7ef0ee8)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * linux/fs/nfs/callback.c
4  *
5  * Copyright (C) 2004 Trond Myklebust
6  *
7  * NFSv4 callback handling
8  */
9 
10 #include <linux/completion.h>
11 #include <linux/ip.h>
12 #include <linux/module.h>
13 #include <linux/sched/signal.h>
14 #include <linux/sunrpc/svc.h>
15 #include <linux/sunrpc/svcsock.h>
16 #include <linux/nfs_fs.h>
17 #include <linux/errno.h>
18 #include <linux/mutex.h>
19 #include <linux/freezer.h>
20 #include <linux/sunrpc/svcauth_gss.h>
21 #include <linux/sunrpc/bc_xprt.h>
22 
23 #include <net/inet_sock.h>
24 
25 #include "nfs4_fs.h"
26 #include "callback.h"
27 #include "internal.h"
28 #include "netns.h"
29 
30 #define NFSDBG_FACILITY NFSDBG_CALLBACK
31 
32 struct nfs_callback_data {
33 	unsigned int users;
34 	struct svc_serv *serv;
35 };
36 
37 static struct nfs_callback_data nfs_callback_info[NFS4_MAX_MINOR_VERSION + 1];
38 static DEFINE_MUTEX(nfs_callback_mutex);
39 static struct svc_program nfs4_callback_program;
40 
41 static int nfs4_callback_up_net(struct svc_serv *serv, struct net *net)
42 {
43 	const struct cred *cred = current_cred();
44 	int ret;
45 	struct nfs_net *nn = net_generic(net, nfs_net_id);
46 
47 	ret = svc_xprt_create(serv, "tcp", net, PF_INET,
48 			      nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS,
49 			      cred);
50 	if (ret <= 0)
51 		goto out_err;
52 	nn->nfs_callback_tcpport = ret;
53 	dprintk("NFS: Callback listener port = %u (af %u, net %x)\n",
54 		nn->nfs_callback_tcpport, PF_INET, net->ns.inum);
55 
56 	ret = svc_xprt_create(serv, "tcp", net, PF_INET6,
57 			      nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS,
58 			      cred);
59 	if (ret > 0) {
60 		nn->nfs_callback_tcpport6 = ret;
61 		dprintk("NFS: Callback listener port = %u (af %u, net %x)\n",
62 			nn->nfs_callback_tcpport6, PF_INET6, net->ns.inum);
63 	} else if (ret != -EAFNOSUPPORT)
64 		goto out_err;
65 	return 0;
66 
67 out_err:
68 	return (ret) ? ret : -ENOMEM;
69 }
70 
71 /*
72  * This is the NFSv4 callback kernel thread.
73  */
74 static int
75 nfs4_callback_svc(void *vrqstp)
76 {
77 	int err;
78 	struct svc_rqst *rqstp = vrqstp;
79 
80 	set_freezable();
81 
82 	while (!kthread_freezable_should_stop(NULL)) {
83 
84 		if (signal_pending(current))
85 			flush_signals(current);
86 		/*
87 		 * Listen for a request on the socket
88 		 */
89 		err = svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT);
90 		if (err == -EAGAIN || err == -EINTR)
91 			continue;
92 		svc_process(rqstp);
93 	}
94 
95 	svc_exit_thread(rqstp);
96 	return 0;
97 }
98 
99 #if defined(CONFIG_NFS_V4_1)
100 /*
101  * The callback service for NFSv4.1 callbacks
102  */
103 static int
104 nfs41_callback_svc(void *vrqstp)
105 {
106 	struct svc_rqst *rqstp = vrqstp;
107 	struct svc_serv *serv = rqstp->rq_server;
108 	struct rpc_rqst *req;
109 	int error;
110 	DEFINE_WAIT(wq);
111 
112 	set_freezable();
113 
114 	while (!kthread_freezable_should_stop(NULL)) {
115 
116 		if (signal_pending(current))
117 			flush_signals(current);
118 
119 		prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
120 		spin_lock_bh(&serv->sv_cb_lock);
121 		if (!list_empty(&serv->sv_cb_list)) {
122 			req = list_first_entry(&serv->sv_cb_list,
123 					struct rpc_rqst, rq_bc_list);
124 			list_del(&req->rq_bc_list);
125 			spin_unlock_bh(&serv->sv_cb_lock);
126 			finish_wait(&serv->sv_cb_waitq, &wq);
127 			dprintk("Invoking bc_svc_process()\n");
128 			error = bc_svc_process(serv, req, rqstp);
129 			dprintk("bc_svc_process() returned w/ error code= %d\n",
130 				error);
131 		} else {
132 			spin_unlock_bh(&serv->sv_cb_lock);
133 			if (!kthread_should_stop())
134 				schedule();
135 			finish_wait(&serv->sv_cb_waitq, &wq);
136 		}
137 	}
138 
139 	svc_exit_thread(rqstp);
140 	return 0;
141 }
142 
143 static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
144 		struct svc_serv *serv)
145 {
146 	if (minorversion)
147 		/*
148 		 * Save the svc_serv in the transport so that it can
149 		 * be referenced when the session backchannel is initialized
150 		 */
151 		xprt->bc_serv = serv;
152 }
153 #else
154 static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
155 		struct svc_serv *serv)
156 {
157 }
158 #endif /* CONFIG_NFS_V4_1 */
159 
160 static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt,
161 				  struct svc_serv *serv)
162 {
163 	int nrservs = nfs_callback_nr_threads;
164 	int ret;
165 
166 	nfs_callback_bc_serv(minorversion, xprt, serv);
167 
168 	if (nrservs < NFS4_MIN_NR_CALLBACK_THREADS)
169 		nrservs = NFS4_MIN_NR_CALLBACK_THREADS;
170 
171 	if (serv->sv_nrthreads == nrservs)
172 		return 0;
173 
174 	ret = svc_set_num_threads(serv, NULL, nrservs);
175 	if (ret) {
176 		svc_set_num_threads(serv, NULL, 0);
177 		return ret;
178 	}
179 	dprintk("nfs_callback_up: service started\n");
180 	return 0;
181 }
182 
183 static void nfs_callback_down_net(u32 minorversion, struct svc_serv *serv, struct net *net)
184 {
185 	struct nfs_net *nn = net_generic(net, nfs_net_id);
186 
187 	if (--nn->cb_users[minorversion])
188 		return;
189 
190 	dprintk("NFS: destroy per-net callback data; net=%x\n", net->ns.inum);
191 	svc_xprt_destroy_all(serv, net);
192 }
193 
194 static int nfs_callback_up_net(int minorversion, struct svc_serv *serv,
195 			       struct net *net, struct rpc_xprt *xprt)
196 {
197 	struct nfs_net *nn = net_generic(net, nfs_net_id);
198 	int ret;
199 
200 	if (nn->cb_users[minorversion]++)
201 		return 0;
202 
203 	dprintk("NFS: create per-net callback data; net=%x\n", net->ns.inum);
204 
205 	ret = svc_bind(serv, net);
206 	if (ret < 0) {
207 		printk(KERN_WARNING "NFS: bind callback service failed\n");
208 		goto err_bind;
209 	}
210 
211 	ret = 0;
212 	if (!IS_ENABLED(CONFIG_NFS_V4_1) || minorversion == 0)
213 		ret = nfs4_callback_up_net(serv, net);
214 	else if (xprt->ops->bc_setup)
215 		set_bc_enabled(serv);
216 	else
217 		ret = -EPROTONOSUPPORT;
218 
219 	if (ret < 0) {
220 		printk(KERN_ERR "NFS: callback service start failed\n");
221 		goto err_socks;
222 	}
223 	return 0;
224 
225 err_socks:
226 	svc_rpcb_cleanup(serv, net);
227 err_bind:
228 	nn->cb_users[minorversion]--;
229 	dprintk("NFS: Couldn't create callback socket: err = %d; "
230 			"net = %x\n", ret, net->ns.inum);
231 	return ret;
232 }
233 
234 static struct svc_serv *nfs_callback_create_svc(int minorversion)
235 {
236 	struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
237 	int (*threadfn)(void *data);
238 	struct svc_serv *serv;
239 
240 	/*
241 	 * Check whether we're already up and running.
242 	 */
243 	if (cb_info->serv)
244 		return svc_get(cb_info->serv);
245 
246 	/*
247 	 * Sanity check: if there's no task,
248 	 * we should be the first user ...
249 	 */
250 	if (cb_info->users)
251 		printk(KERN_WARNING "nfs_callback_create_svc: no kthread, %d users??\n",
252 			cb_info->users);
253 
254 	threadfn = nfs4_callback_svc;
255 #if defined(CONFIG_NFS_V4_1)
256 	if (minorversion)
257 		threadfn = nfs41_callback_svc;
258 #else
259 	if (minorversion)
260 		return ERR_PTR(-ENOTSUPP);
261 #endif
262 	serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE,
263 			  threadfn);
264 	if (!serv) {
265 		printk(KERN_ERR "nfs_callback_create_svc: create service failed\n");
266 		return ERR_PTR(-ENOMEM);
267 	}
268 	cb_info->serv = serv;
269 	/* As there is only one thread we need to over-ride the
270 	 * default maximum of 80 connections
271 	 */
272 	serv->sv_maxconn = 1024;
273 	dprintk("nfs_callback_create_svc: service created\n");
274 	return serv;
275 }
276 
277 /*
278  * Bring up the callback thread if it is not already up.
279  */
280 int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
281 {
282 	struct svc_serv *serv;
283 	struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
284 	int ret;
285 	struct net *net = xprt->xprt_net;
286 
287 	mutex_lock(&nfs_callback_mutex);
288 
289 	serv = nfs_callback_create_svc(minorversion);
290 	if (IS_ERR(serv)) {
291 		ret = PTR_ERR(serv);
292 		goto err_create;
293 	}
294 
295 	ret = nfs_callback_up_net(minorversion, serv, net, xprt);
296 	if (ret < 0)
297 		goto err_net;
298 
299 	ret = nfs_callback_start_svc(minorversion, xprt, serv);
300 	if (ret < 0)
301 		goto err_start;
302 
303 	cb_info->users++;
304 err_net:
305 	if (!cb_info->users)
306 		cb_info->serv = NULL;
307 	svc_put(serv);
308 err_create:
309 	mutex_unlock(&nfs_callback_mutex);
310 	return ret;
311 
312 err_start:
313 	nfs_callback_down_net(minorversion, serv, net);
314 	dprintk("NFS: Couldn't create server thread; err = %d\n", ret);
315 	goto err_net;
316 }
317 
318 /*
319  * Kill the callback thread if it's no longer being used.
320  */
321 void nfs_callback_down(int minorversion, struct net *net)
322 {
323 	struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
324 	struct svc_serv *serv;
325 
326 	mutex_lock(&nfs_callback_mutex);
327 	serv = cb_info->serv;
328 	nfs_callback_down_net(minorversion, serv, net);
329 	cb_info->users--;
330 	if (cb_info->users == 0) {
331 		svc_get(serv);
332 		svc_set_num_threads(serv, NULL, 0);
333 		svc_put(serv);
334 		dprintk("nfs_callback_down: service destroyed\n");
335 		cb_info->serv = NULL;
336 	}
337 	mutex_unlock(&nfs_callback_mutex);
338 }
339 
340 /* Boolean check of RPC_AUTH_GSS principal */
341 int
342 check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp)
343 {
344 	char *p = rqstp->rq_cred.cr_principal;
345 
346 	if (rqstp->rq_authop->flavour != RPC_AUTH_GSS)
347 		return 1;
348 
349 	/* No RPC_AUTH_GSS on NFSv4.1 back channel yet */
350 	if (clp->cl_minorversion != 0)
351 		return 0;
352 	/*
353 	 * It might just be a normal user principal, in which case
354 	 * userspace won't bother to tell us the name at all.
355 	 */
356 	if (p == NULL)
357 		return 0;
358 
359 	/*
360 	 * Did we get the acceptor from userland during the SETCLIENID
361 	 * negotiation?
362 	 */
363 	if (clp->cl_acceptor)
364 		return !strcmp(p, clp->cl_acceptor);
365 
366 	/*
367 	 * Otherwise try to verify it using the cl_hostname. Note that this
368 	 * doesn't work if a non-canonical hostname was used in the devname.
369 	 */
370 
371 	/* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */
372 
373 	if (memcmp(p, "nfs@", 4) != 0)
374 		return 0;
375 	p += 4;
376 	if (strcmp(p, clp->cl_hostname) != 0)
377 		return 0;
378 	return 1;
379 }
380 
381 /*
382  * pg_authenticate method for nfsv4 callback threads.
383  *
384  * The authflavor has been negotiated, so an incorrect flavor is a server
385  * bug. Deny packets with incorrect authflavor.
386  *
387  * All other checking done after NFS decoding where the nfs_client can be
388  * found in nfs4_callback_compound
389  */
390 static int nfs_callback_authenticate(struct svc_rqst *rqstp)
391 {
392 	rqstp->rq_auth_stat = rpc_autherr_badcred;
393 
394 	switch (rqstp->rq_authop->flavour) {
395 	case RPC_AUTH_NULL:
396 		if (rqstp->rq_proc != CB_NULL)
397 			return SVC_DENIED;
398 		break;
399 	case RPC_AUTH_GSS:
400 		/* No RPC_AUTH_GSS support yet in NFSv4.1 */
401 		 if (svc_is_backchannel(rqstp))
402 			return SVC_DENIED;
403 	}
404 
405 	rqstp->rq_auth_stat = rpc_auth_ok;
406 	return SVC_OK;
407 }
408 
409 /*
410  * Define NFS4 callback program
411  */
412 static const struct svc_version *nfs4_callback_version[] = {
413 	[1] = &nfs4_callback_version1,
414 	[4] = &nfs4_callback_version4,
415 };
416 
417 static struct svc_stat nfs4_callback_stats;
418 
419 static struct svc_program nfs4_callback_program = {
420 	.pg_prog = NFS4_CALLBACK,			/* RPC service number */
421 	.pg_nvers = ARRAY_SIZE(nfs4_callback_version),	/* Number of entries */
422 	.pg_vers = nfs4_callback_version,		/* version table */
423 	.pg_name = "NFSv4 callback",			/* service name */
424 	.pg_class = "nfs",				/* authentication class */
425 	.pg_stats = &nfs4_callback_stats,
426 	.pg_authenticate = nfs_callback_authenticate,
427 	.pg_init_request = svc_generic_init_request,
428 	.pg_rpcbind_set	= svc_generic_rpcbind_set,
429 };
430