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