xref: /linux/fs/nfs/fs_context.c (revision a4eb44a6435d6d8f9e642407a4a06f65eb90ca04)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * linux/fs/nfs/fs_context.c
4  *
5  * Copyright (C) 1992 Rick Sladkey
6  * Conversion to new mount api Copyright (C) David Howells
7  *
8  * NFS mount handling.
9  *
10  * Split from fs/nfs/super.c by David Howells <dhowells@redhat.com>
11  */
12 
13 #include <linux/compat.h>
14 #include <linux/module.h>
15 #include <linux/fs.h>
16 #include <linux/fs_context.h>
17 #include <linux/fs_parser.h>
18 #include <linux/nfs_fs.h>
19 #include <linux/nfs_mount.h>
20 #include <linux/nfs4_mount.h>
21 #include "nfs.h"
22 #include "internal.h"
23 
24 #define NFSDBG_FACILITY		NFSDBG_MOUNT
25 
26 #if IS_ENABLED(CONFIG_NFS_V3)
27 #define NFS_DEFAULT_VERSION 3
28 #else
29 #define NFS_DEFAULT_VERSION 2
30 #endif
31 
32 #define NFS_MAX_CONNECTIONS 16
33 
34 enum nfs_param {
35 	Opt_ac,
36 	Opt_acdirmax,
37 	Opt_acdirmin,
38 	Opt_acl,
39 	Opt_acregmax,
40 	Opt_acregmin,
41 	Opt_actimeo,
42 	Opt_addr,
43 	Opt_bg,
44 	Opt_bsize,
45 	Opt_clientaddr,
46 	Opt_cto,
47 	Opt_fg,
48 	Opt_fscache,
49 	Opt_fscache_flag,
50 	Opt_hard,
51 	Opt_intr,
52 	Opt_local_lock,
53 	Opt_lock,
54 	Opt_lookupcache,
55 	Opt_migration,
56 	Opt_minorversion,
57 	Opt_mountaddr,
58 	Opt_mounthost,
59 	Opt_mountport,
60 	Opt_mountproto,
61 	Opt_mountvers,
62 	Opt_namelen,
63 	Opt_nconnect,
64 	Opt_max_connect,
65 	Opt_port,
66 	Opt_posix,
67 	Opt_proto,
68 	Opt_rdirplus,
69 	Opt_rdma,
70 	Opt_resvport,
71 	Opt_retrans,
72 	Opt_retry,
73 	Opt_rsize,
74 	Opt_sec,
75 	Opt_sharecache,
76 	Opt_sloppy,
77 	Opt_soft,
78 	Opt_softerr,
79 	Opt_softreval,
80 	Opt_source,
81 	Opt_tcp,
82 	Opt_timeo,
83 	Opt_udp,
84 	Opt_v,
85 	Opt_vers,
86 	Opt_wsize,
87 	Opt_write,
88 };
89 
90 enum {
91 	Opt_local_lock_all,
92 	Opt_local_lock_flock,
93 	Opt_local_lock_none,
94 	Opt_local_lock_posix,
95 };
96 
97 static const struct constant_table nfs_param_enums_local_lock[] = {
98 	{ "all",		Opt_local_lock_all },
99 	{ "flock",	Opt_local_lock_flock },
100 	{ "posix",	Opt_local_lock_posix },
101 	{ "none",		Opt_local_lock_none },
102 	{}
103 };
104 
105 enum {
106 	Opt_lookupcache_all,
107 	Opt_lookupcache_none,
108 	Opt_lookupcache_positive,
109 };
110 
111 static const struct constant_table nfs_param_enums_lookupcache[] = {
112 	{ "all",		Opt_lookupcache_all },
113 	{ "none",		Opt_lookupcache_none },
114 	{ "pos",		Opt_lookupcache_positive },
115 	{ "positive",		Opt_lookupcache_positive },
116 	{}
117 };
118 
119 enum {
120 	Opt_write_lazy,
121 	Opt_write_eager,
122 	Opt_write_wait,
123 };
124 
125 static const struct constant_table nfs_param_enums_write[] = {
126 	{ "lazy",		Opt_write_lazy },
127 	{ "eager",		Opt_write_eager },
128 	{ "wait",		Opt_write_wait },
129 	{}
130 };
131 
132 static const struct fs_parameter_spec nfs_fs_parameters[] = {
133 	fsparam_flag_no("ac",		Opt_ac),
134 	fsparam_u32   ("acdirmax",	Opt_acdirmax),
135 	fsparam_u32   ("acdirmin",	Opt_acdirmin),
136 	fsparam_flag_no("acl",		Opt_acl),
137 	fsparam_u32   ("acregmax",	Opt_acregmax),
138 	fsparam_u32   ("acregmin",	Opt_acregmin),
139 	fsparam_u32   ("actimeo",	Opt_actimeo),
140 	fsparam_string("addr",		Opt_addr),
141 	fsparam_flag  ("bg",		Opt_bg),
142 	fsparam_u32   ("bsize",		Opt_bsize),
143 	fsparam_string("clientaddr",	Opt_clientaddr),
144 	fsparam_flag_no("cto",		Opt_cto),
145 	fsparam_flag  ("fg",		Opt_fg),
146 	fsparam_flag_no("fsc",		Opt_fscache_flag),
147 	fsparam_string("fsc",		Opt_fscache),
148 	fsparam_flag  ("hard",		Opt_hard),
149 	__fsparam(NULL, "intr",		Opt_intr,
150 		  fs_param_neg_with_no|fs_param_deprecated, NULL),
151 	fsparam_enum  ("local_lock",	Opt_local_lock, nfs_param_enums_local_lock),
152 	fsparam_flag_no("lock",		Opt_lock),
153 	fsparam_enum  ("lookupcache",	Opt_lookupcache, nfs_param_enums_lookupcache),
154 	fsparam_flag_no("migration",	Opt_migration),
155 	fsparam_u32   ("minorversion",	Opt_minorversion),
156 	fsparam_string("mountaddr",	Opt_mountaddr),
157 	fsparam_string("mounthost",	Opt_mounthost),
158 	fsparam_u32   ("mountport",	Opt_mountport),
159 	fsparam_string("mountproto",	Opt_mountproto),
160 	fsparam_u32   ("mountvers",	Opt_mountvers),
161 	fsparam_u32   ("namlen",	Opt_namelen),
162 	fsparam_u32   ("nconnect",	Opt_nconnect),
163 	fsparam_u32   ("max_connect",	Opt_max_connect),
164 	fsparam_string("nfsvers",	Opt_vers),
165 	fsparam_u32   ("port",		Opt_port),
166 	fsparam_flag_no("posix",	Opt_posix),
167 	fsparam_string("proto",		Opt_proto),
168 	fsparam_flag_no("rdirplus",	Opt_rdirplus),
169 	fsparam_flag  ("rdma",		Opt_rdma),
170 	fsparam_flag_no("resvport",	Opt_resvport),
171 	fsparam_u32   ("retrans",	Opt_retrans),
172 	fsparam_string("retry",		Opt_retry),
173 	fsparam_u32   ("rsize",		Opt_rsize),
174 	fsparam_string("sec",		Opt_sec),
175 	fsparam_flag_no("sharecache",	Opt_sharecache),
176 	fsparam_flag  ("sloppy",	Opt_sloppy),
177 	fsparam_flag  ("soft",		Opt_soft),
178 	fsparam_flag  ("softerr",	Opt_softerr),
179 	fsparam_flag  ("softreval",	Opt_softreval),
180 	fsparam_string("source",	Opt_source),
181 	fsparam_flag  ("tcp",		Opt_tcp),
182 	fsparam_u32   ("timeo",		Opt_timeo),
183 	fsparam_flag  ("udp",		Opt_udp),
184 	fsparam_flag  ("v2",		Opt_v),
185 	fsparam_flag  ("v3",		Opt_v),
186 	fsparam_flag  ("v4",		Opt_v),
187 	fsparam_flag  ("v4.0",		Opt_v),
188 	fsparam_flag  ("v4.1",		Opt_v),
189 	fsparam_flag  ("v4.2",		Opt_v),
190 	fsparam_string("vers",		Opt_vers),
191 	fsparam_enum  ("write",		Opt_write, nfs_param_enums_write),
192 	fsparam_u32   ("wsize",		Opt_wsize),
193 	{}
194 };
195 
196 enum {
197 	Opt_vers_2,
198 	Opt_vers_3,
199 	Opt_vers_4,
200 	Opt_vers_4_0,
201 	Opt_vers_4_1,
202 	Opt_vers_4_2,
203 };
204 
205 static const struct constant_table nfs_vers_tokens[] = {
206 	{ "2",		Opt_vers_2 },
207 	{ "3",		Opt_vers_3 },
208 	{ "4",		Opt_vers_4 },
209 	{ "4.0",	Opt_vers_4_0 },
210 	{ "4.1",	Opt_vers_4_1 },
211 	{ "4.2",	Opt_vers_4_2 },
212 	{}
213 };
214 
215 enum {
216 	Opt_xprt_rdma,
217 	Opt_xprt_rdma6,
218 	Opt_xprt_tcp,
219 	Opt_xprt_tcp6,
220 	Opt_xprt_udp,
221 	Opt_xprt_udp6,
222 	nr__Opt_xprt
223 };
224 
225 static const struct constant_table nfs_xprt_protocol_tokens[] = {
226 	{ "rdma",	Opt_xprt_rdma },
227 	{ "rdma6",	Opt_xprt_rdma6 },
228 	{ "tcp",	Opt_xprt_tcp },
229 	{ "tcp6",	Opt_xprt_tcp6 },
230 	{ "udp",	Opt_xprt_udp },
231 	{ "udp6",	Opt_xprt_udp6 },
232 	{}
233 };
234 
235 enum {
236 	Opt_sec_krb5,
237 	Opt_sec_krb5i,
238 	Opt_sec_krb5p,
239 	Opt_sec_lkey,
240 	Opt_sec_lkeyi,
241 	Opt_sec_lkeyp,
242 	Opt_sec_none,
243 	Opt_sec_spkm,
244 	Opt_sec_spkmi,
245 	Opt_sec_spkmp,
246 	Opt_sec_sys,
247 	nr__Opt_sec
248 };
249 
250 static const struct constant_table nfs_secflavor_tokens[] = {
251 	{ "krb5",	Opt_sec_krb5 },
252 	{ "krb5i",	Opt_sec_krb5i },
253 	{ "krb5p",	Opt_sec_krb5p },
254 	{ "lkey",	Opt_sec_lkey },
255 	{ "lkeyi",	Opt_sec_lkeyi },
256 	{ "lkeyp",	Opt_sec_lkeyp },
257 	{ "none",	Opt_sec_none },
258 	{ "null",	Opt_sec_none },
259 	{ "spkm3",	Opt_sec_spkm },
260 	{ "spkm3i",	Opt_sec_spkmi },
261 	{ "spkm3p",	Opt_sec_spkmp },
262 	{ "sys",	Opt_sec_sys },
263 	{}
264 };
265 
266 /*
267  * Sanity-check a server address provided by the mount command.
268  *
269  * Address family must be initialized, and address must not be
270  * the ANY address for that family.
271  */
272 static int nfs_verify_server_address(struct sockaddr *addr)
273 {
274 	switch (addr->sa_family) {
275 	case AF_INET: {
276 		struct sockaddr_in *sa = (struct sockaddr_in *)addr;
277 		return sa->sin_addr.s_addr != htonl(INADDR_ANY);
278 	}
279 	case AF_INET6: {
280 		struct in6_addr *sa = &((struct sockaddr_in6 *)addr)->sin6_addr;
281 		return !ipv6_addr_any(sa);
282 	}
283 	}
284 
285 	dfprintk(MOUNT, "NFS: Invalid IP address specified\n");
286 	return 0;
287 }
288 
289 #ifdef CONFIG_NFS_DISABLE_UDP_SUPPORT
290 static bool nfs_server_transport_udp_invalid(const struct nfs_fs_context *ctx)
291 {
292 	return true;
293 }
294 #else
295 static bool nfs_server_transport_udp_invalid(const struct nfs_fs_context *ctx)
296 {
297 	if (ctx->version == 4)
298 		return true;
299 	return false;
300 }
301 #endif
302 
303 /*
304  * Sanity check the NFS transport protocol.
305  */
306 static int nfs_validate_transport_protocol(struct fs_context *fc,
307 					   struct nfs_fs_context *ctx)
308 {
309 	switch (ctx->nfs_server.protocol) {
310 	case XPRT_TRANSPORT_UDP:
311 		if (nfs_server_transport_udp_invalid(ctx))
312 			goto out_invalid_transport_udp;
313 		break;
314 	case XPRT_TRANSPORT_TCP:
315 	case XPRT_TRANSPORT_RDMA:
316 		break;
317 	default:
318 		ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
319 	}
320 	return 0;
321 out_invalid_transport_udp:
322 	return nfs_invalf(fc, "NFS: Unsupported transport protocol udp");
323 }
324 
325 /*
326  * For text based NFSv2/v3 mounts, the mount protocol transport default
327  * settings should depend upon the specified NFS transport.
328  */
329 static void nfs_set_mount_transport_protocol(struct nfs_fs_context *ctx)
330 {
331 	if (ctx->mount_server.protocol == XPRT_TRANSPORT_UDP ||
332 	    ctx->mount_server.protocol == XPRT_TRANSPORT_TCP)
333 			return;
334 	switch (ctx->nfs_server.protocol) {
335 	case XPRT_TRANSPORT_UDP:
336 		ctx->mount_server.protocol = XPRT_TRANSPORT_UDP;
337 		break;
338 	case XPRT_TRANSPORT_TCP:
339 	case XPRT_TRANSPORT_RDMA:
340 		ctx->mount_server.protocol = XPRT_TRANSPORT_TCP;
341 	}
342 }
343 
344 /*
345  * Add 'flavor' to 'auth_info' if not already present.
346  * Returns true if 'flavor' ends up in the list, false otherwise
347  */
348 static int nfs_auth_info_add(struct fs_context *fc,
349 			     struct nfs_auth_info *auth_info,
350 			     rpc_authflavor_t flavor)
351 {
352 	unsigned int i;
353 	unsigned int max_flavor_len = ARRAY_SIZE(auth_info->flavors);
354 
355 	/* make sure this flavor isn't already in the list */
356 	for (i = 0; i < auth_info->flavor_len; i++) {
357 		if (flavor == auth_info->flavors[i])
358 			return 0;
359 	}
360 
361 	if (auth_info->flavor_len + 1 >= max_flavor_len)
362 		return nfs_invalf(fc, "NFS: too many sec= flavors");
363 
364 	auth_info->flavors[auth_info->flavor_len++] = flavor;
365 	return 0;
366 }
367 
368 /*
369  * Parse the value of the 'sec=' option.
370  */
371 static int nfs_parse_security_flavors(struct fs_context *fc,
372 				      struct fs_parameter *param)
373 {
374 	struct nfs_fs_context *ctx = nfs_fc2context(fc);
375 	rpc_authflavor_t pseudoflavor;
376 	char *string = param->string, *p;
377 	int ret;
378 
379 	dfprintk(MOUNT, "NFS: parsing %s=%s option\n", param->key, param->string);
380 
381 	while ((p = strsep(&string, ":")) != NULL) {
382 		if (!*p)
383 			continue;
384 		switch (lookup_constant(nfs_secflavor_tokens, p, -1)) {
385 		case Opt_sec_none:
386 			pseudoflavor = RPC_AUTH_NULL;
387 			break;
388 		case Opt_sec_sys:
389 			pseudoflavor = RPC_AUTH_UNIX;
390 			break;
391 		case Opt_sec_krb5:
392 			pseudoflavor = RPC_AUTH_GSS_KRB5;
393 			break;
394 		case Opt_sec_krb5i:
395 			pseudoflavor = RPC_AUTH_GSS_KRB5I;
396 			break;
397 		case Opt_sec_krb5p:
398 			pseudoflavor = RPC_AUTH_GSS_KRB5P;
399 			break;
400 		case Opt_sec_lkey:
401 			pseudoflavor = RPC_AUTH_GSS_LKEY;
402 			break;
403 		case Opt_sec_lkeyi:
404 			pseudoflavor = RPC_AUTH_GSS_LKEYI;
405 			break;
406 		case Opt_sec_lkeyp:
407 			pseudoflavor = RPC_AUTH_GSS_LKEYP;
408 			break;
409 		case Opt_sec_spkm:
410 			pseudoflavor = RPC_AUTH_GSS_SPKM;
411 			break;
412 		case Opt_sec_spkmi:
413 			pseudoflavor = RPC_AUTH_GSS_SPKMI;
414 			break;
415 		case Opt_sec_spkmp:
416 			pseudoflavor = RPC_AUTH_GSS_SPKMP;
417 			break;
418 		default:
419 			return nfs_invalf(fc, "NFS: sec=%s option not recognized", p);
420 		}
421 
422 		ret = nfs_auth_info_add(fc, &ctx->auth_info, pseudoflavor);
423 		if (ret < 0)
424 			return ret;
425 	}
426 
427 	return 0;
428 }
429 
430 static int nfs_parse_version_string(struct fs_context *fc,
431 				    const char *string)
432 {
433 	struct nfs_fs_context *ctx = nfs_fc2context(fc);
434 
435 	ctx->flags &= ~NFS_MOUNT_VER3;
436 	switch (lookup_constant(nfs_vers_tokens, string, -1)) {
437 	case Opt_vers_2:
438 		ctx->version = 2;
439 		break;
440 	case Opt_vers_3:
441 		ctx->flags |= NFS_MOUNT_VER3;
442 		ctx->version = 3;
443 		break;
444 	case Opt_vers_4:
445 		/* Backward compatibility option. In future,
446 		 * the mount program should always supply
447 		 * a NFSv4 minor version number.
448 		 */
449 		ctx->version = 4;
450 		break;
451 	case Opt_vers_4_0:
452 		ctx->version = 4;
453 		ctx->minorversion = 0;
454 		break;
455 	case Opt_vers_4_1:
456 		ctx->version = 4;
457 		ctx->minorversion = 1;
458 		break;
459 	case Opt_vers_4_2:
460 		ctx->version = 4;
461 		ctx->minorversion = 2;
462 		break;
463 	default:
464 		return nfs_invalf(fc, "NFS: Unsupported NFS version");
465 	}
466 	return 0;
467 }
468 
469 /*
470  * Parse a single mount parameter.
471  */
472 static int nfs_fs_context_parse_param(struct fs_context *fc,
473 				      struct fs_parameter *param)
474 {
475 	struct fs_parse_result result;
476 	struct nfs_fs_context *ctx = nfs_fc2context(fc);
477 	unsigned short protofamily, mountfamily;
478 	unsigned int len;
479 	int ret, opt;
480 
481 	dfprintk(MOUNT, "NFS:   parsing nfs mount option '%s'\n", param->key);
482 
483 	opt = fs_parse(fc, nfs_fs_parameters, param, &result);
484 	if (opt < 0)
485 		return ctx->sloppy ? 1 : opt;
486 
487 	if (fc->security)
488 		ctx->has_sec_mnt_opts = 1;
489 
490 	switch (opt) {
491 	case Opt_source:
492 		if (fc->source)
493 			return nfs_invalf(fc, "NFS: Multiple sources not supported");
494 		fc->source = param->string;
495 		param->string = NULL;
496 		break;
497 
498 		/*
499 		 * boolean options:  foo/nofoo
500 		 */
501 	case Opt_soft:
502 		ctx->flags |= NFS_MOUNT_SOFT;
503 		ctx->flags &= ~NFS_MOUNT_SOFTERR;
504 		break;
505 	case Opt_softerr:
506 		ctx->flags |= NFS_MOUNT_SOFTERR | NFS_MOUNT_SOFTREVAL;
507 		ctx->flags &= ~NFS_MOUNT_SOFT;
508 		break;
509 	case Opt_hard:
510 		ctx->flags &= ~(NFS_MOUNT_SOFT |
511 				NFS_MOUNT_SOFTERR |
512 				NFS_MOUNT_SOFTREVAL);
513 		break;
514 	case Opt_softreval:
515 		if (result.negated)
516 			ctx->flags &= ~NFS_MOUNT_SOFTREVAL;
517 		else
518 			ctx->flags &= NFS_MOUNT_SOFTREVAL;
519 		break;
520 	case Opt_posix:
521 		if (result.negated)
522 			ctx->flags &= ~NFS_MOUNT_POSIX;
523 		else
524 			ctx->flags |= NFS_MOUNT_POSIX;
525 		break;
526 	case Opt_cto:
527 		if (result.negated)
528 			ctx->flags |= NFS_MOUNT_NOCTO;
529 		else
530 			ctx->flags &= ~NFS_MOUNT_NOCTO;
531 		break;
532 	case Opt_ac:
533 		if (result.negated)
534 			ctx->flags |= NFS_MOUNT_NOAC;
535 		else
536 			ctx->flags &= ~NFS_MOUNT_NOAC;
537 		break;
538 	case Opt_lock:
539 		if (result.negated) {
540 			ctx->flags |= NFS_MOUNT_NONLM;
541 			ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
542 		} else {
543 			ctx->flags &= ~NFS_MOUNT_NONLM;
544 			ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
545 		}
546 		break;
547 	case Opt_udp:
548 		ctx->flags &= ~NFS_MOUNT_TCP;
549 		ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP;
550 		break;
551 	case Opt_tcp:
552 	case Opt_rdma:
553 		ctx->flags |= NFS_MOUNT_TCP; /* for side protocols */
554 		ret = xprt_find_transport_ident(param->key);
555 		if (ret < 0)
556 			goto out_bad_transport;
557 		ctx->nfs_server.protocol = ret;
558 		break;
559 	case Opt_acl:
560 		if (result.negated)
561 			ctx->flags |= NFS_MOUNT_NOACL;
562 		else
563 			ctx->flags &= ~NFS_MOUNT_NOACL;
564 		break;
565 	case Opt_rdirplus:
566 		if (result.negated)
567 			ctx->flags |= NFS_MOUNT_NORDIRPLUS;
568 		else
569 			ctx->flags &= ~NFS_MOUNT_NORDIRPLUS;
570 		break;
571 	case Opt_sharecache:
572 		if (result.negated)
573 			ctx->flags |= NFS_MOUNT_UNSHARED;
574 		else
575 			ctx->flags &= ~NFS_MOUNT_UNSHARED;
576 		break;
577 	case Opt_resvport:
578 		if (result.negated)
579 			ctx->flags |= NFS_MOUNT_NORESVPORT;
580 		else
581 			ctx->flags &= ~NFS_MOUNT_NORESVPORT;
582 		break;
583 	case Opt_fscache_flag:
584 		if (result.negated)
585 			ctx->options &= ~NFS_OPTION_FSCACHE;
586 		else
587 			ctx->options |= NFS_OPTION_FSCACHE;
588 		kfree(ctx->fscache_uniq);
589 		ctx->fscache_uniq = NULL;
590 		break;
591 	case Opt_fscache:
592 		ctx->options |= NFS_OPTION_FSCACHE;
593 		kfree(ctx->fscache_uniq);
594 		ctx->fscache_uniq = param->string;
595 		param->string = NULL;
596 		break;
597 	case Opt_migration:
598 		if (result.negated)
599 			ctx->options &= ~NFS_OPTION_MIGRATION;
600 		else
601 			ctx->options |= NFS_OPTION_MIGRATION;
602 		break;
603 
604 		/*
605 		 * options that take numeric values
606 		 */
607 	case Opt_port:
608 		if (result.uint_32 > USHRT_MAX)
609 			goto out_of_bounds;
610 		ctx->nfs_server.port = result.uint_32;
611 		break;
612 	case Opt_rsize:
613 		ctx->rsize = result.uint_32;
614 		break;
615 	case Opt_wsize:
616 		ctx->wsize = result.uint_32;
617 		break;
618 	case Opt_bsize:
619 		ctx->bsize = result.uint_32;
620 		break;
621 	case Opt_timeo:
622 		if (result.uint_32 < 1 || result.uint_32 > INT_MAX)
623 			goto out_of_bounds;
624 		ctx->timeo = result.uint_32;
625 		break;
626 	case Opt_retrans:
627 		if (result.uint_32 > INT_MAX)
628 			goto out_of_bounds;
629 		ctx->retrans = result.uint_32;
630 		break;
631 	case Opt_acregmin:
632 		ctx->acregmin = result.uint_32;
633 		break;
634 	case Opt_acregmax:
635 		ctx->acregmax = result.uint_32;
636 		break;
637 	case Opt_acdirmin:
638 		ctx->acdirmin = result.uint_32;
639 		break;
640 	case Opt_acdirmax:
641 		ctx->acdirmax = result.uint_32;
642 		break;
643 	case Opt_actimeo:
644 		ctx->acregmin = result.uint_32;
645 		ctx->acregmax = result.uint_32;
646 		ctx->acdirmin = result.uint_32;
647 		ctx->acdirmax = result.uint_32;
648 		break;
649 	case Opt_namelen:
650 		ctx->namlen = result.uint_32;
651 		break;
652 	case Opt_mountport:
653 		if (result.uint_32 > USHRT_MAX)
654 			goto out_of_bounds;
655 		ctx->mount_server.port = result.uint_32;
656 		break;
657 	case Opt_mountvers:
658 		if (result.uint_32 < NFS_MNT_VERSION ||
659 		    result.uint_32 > NFS_MNT3_VERSION)
660 			goto out_of_bounds;
661 		ctx->mount_server.version = result.uint_32;
662 		break;
663 	case Opt_minorversion:
664 		if (result.uint_32 > NFS4_MAX_MINOR_VERSION)
665 			goto out_of_bounds;
666 		ctx->minorversion = result.uint_32;
667 		break;
668 
669 		/*
670 		 * options that take text values
671 		 */
672 	case Opt_v:
673 		ret = nfs_parse_version_string(fc, param->key + 1);
674 		if (ret < 0)
675 			return ret;
676 		break;
677 	case Opt_vers:
678 		ret = nfs_parse_version_string(fc, param->string);
679 		if (ret < 0)
680 			return ret;
681 		break;
682 	case Opt_sec:
683 		ret = nfs_parse_security_flavors(fc, param);
684 		if (ret < 0)
685 			return ret;
686 		break;
687 
688 	case Opt_proto:
689 		protofamily = AF_INET;
690 		switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) {
691 		case Opt_xprt_udp6:
692 			protofamily = AF_INET6;
693 			fallthrough;
694 		case Opt_xprt_udp:
695 			ctx->flags &= ~NFS_MOUNT_TCP;
696 			ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP;
697 			break;
698 		case Opt_xprt_tcp6:
699 			protofamily = AF_INET6;
700 			fallthrough;
701 		case Opt_xprt_tcp:
702 			ctx->flags |= NFS_MOUNT_TCP;
703 			ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
704 			break;
705 		case Opt_xprt_rdma6:
706 			protofamily = AF_INET6;
707 			fallthrough;
708 		case Opt_xprt_rdma:
709 			/* vector side protocols to TCP */
710 			ctx->flags |= NFS_MOUNT_TCP;
711 			ret = xprt_find_transport_ident(param->string);
712 			if (ret < 0)
713 				goto out_bad_transport;
714 			ctx->nfs_server.protocol = ret;
715 			break;
716 		default:
717 			goto out_bad_transport;
718 		}
719 
720 		ctx->protofamily = protofamily;
721 		break;
722 
723 	case Opt_mountproto:
724 		mountfamily = AF_INET;
725 		switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) {
726 		case Opt_xprt_udp6:
727 			mountfamily = AF_INET6;
728 			fallthrough;
729 		case Opt_xprt_udp:
730 			ctx->mount_server.protocol = XPRT_TRANSPORT_UDP;
731 			break;
732 		case Opt_xprt_tcp6:
733 			mountfamily = AF_INET6;
734 			fallthrough;
735 		case Opt_xprt_tcp:
736 			ctx->mount_server.protocol = XPRT_TRANSPORT_TCP;
737 			break;
738 		case Opt_xprt_rdma: /* not used for side protocols */
739 		default:
740 			goto out_bad_transport;
741 		}
742 		ctx->mountfamily = mountfamily;
743 		break;
744 
745 	case Opt_addr:
746 		len = rpc_pton(fc->net_ns, param->string, param->size,
747 			       &ctx->nfs_server.address,
748 			       sizeof(ctx->nfs_server._address));
749 		if (len == 0)
750 			goto out_invalid_address;
751 		ctx->nfs_server.addrlen = len;
752 		break;
753 	case Opt_clientaddr:
754 		kfree(ctx->client_address);
755 		ctx->client_address = param->string;
756 		param->string = NULL;
757 		break;
758 	case Opt_mounthost:
759 		kfree(ctx->mount_server.hostname);
760 		ctx->mount_server.hostname = param->string;
761 		param->string = NULL;
762 		break;
763 	case Opt_mountaddr:
764 		len = rpc_pton(fc->net_ns, param->string, param->size,
765 			       &ctx->mount_server.address,
766 			       sizeof(ctx->mount_server._address));
767 		if (len == 0)
768 			goto out_invalid_address;
769 		ctx->mount_server.addrlen = len;
770 		break;
771 	case Opt_nconnect:
772 		if (result.uint_32 < 1 || result.uint_32 > NFS_MAX_CONNECTIONS)
773 			goto out_of_bounds;
774 		ctx->nfs_server.nconnect = result.uint_32;
775 		break;
776 	case Opt_max_connect:
777 		if (result.uint_32 < 1 || result.uint_32 > NFS_MAX_TRANSPORTS)
778 			goto out_of_bounds;
779 		ctx->nfs_server.max_connect = result.uint_32;
780 		break;
781 	case Opt_lookupcache:
782 		switch (result.uint_32) {
783 		case Opt_lookupcache_all:
784 			ctx->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE);
785 			break;
786 		case Opt_lookupcache_positive:
787 			ctx->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE;
788 			ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG;
789 			break;
790 		case Opt_lookupcache_none:
791 			ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE;
792 			break;
793 		default:
794 			goto out_invalid_value;
795 		}
796 		break;
797 	case Opt_local_lock:
798 		switch (result.uint_32) {
799 		case Opt_local_lock_all:
800 			ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK |
801 				       NFS_MOUNT_LOCAL_FCNTL);
802 			break;
803 		case Opt_local_lock_flock:
804 			ctx->flags |= NFS_MOUNT_LOCAL_FLOCK;
805 			break;
806 		case Opt_local_lock_posix:
807 			ctx->flags |= NFS_MOUNT_LOCAL_FCNTL;
808 			break;
809 		case Opt_local_lock_none:
810 			ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK |
811 					NFS_MOUNT_LOCAL_FCNTL);
812 			break;
813 		default:
814 			goto out_invalid_value;
815 		}
816 		break;
817 	case Opt_write:
818 		switch (result.uint_32) {
819 		case Opt_write_lazy:
820 			ctx->flags &=
821 				~(NFS_MOUNT_WRITE_EAGER | NFS_MOUNT_WRITE_WAIT);
822 			break;
823 		case Opt_write_eager:
824 			ctx->flags |= NFS_MOUNT_WRITE_EAGER;
825 			ctx->flags &= ~NFS_MOUNT_WRITE_WAIT;
826 			break;
827 		case Opt_write_wait:
828 			ctx->flags |=
829 				NFS_MOUNT_WRITE_EAGER | NFS_MOUNT_WRITE_WAIT;
830 			break;
831 		default:
832 			goto out_invalid_value;
833 		}
834 		break;
835 
836 		/*
837 		 * Special options
838 		 */
839 	case Opt_sloppy:
840 		ctx->sloppy = true;
841 		dfprintk(MOUNT, "NFS:   relaxing parsing rules\n");
842 		break;
843 	}
844 
845 	return 0;
846 
847 out_invalid_value:
848 	return nfs_invalf(fc, "NFS: Bad mount option value specified");
849 out_invalid_address:
850 	return nfs_invalf(fc, "NFS: Bad IP address specified");
851 out_of_bounds:
852 	return nfs_invalf(fc, "NFS: Value for '%s' out of range", param->key);
853 out_bad_transport:
854 	return nfs_invalf(fc, "NFS: Unrecognized transport protocol");
855 }
856 
857 /*
858  * Split fc->source into "hostname:export_path".
859  *
860  * The leftmost colon demarks the split between the server's hostname
861  * and the export path.  If the hostname starts with a left square
862  * bracket, then it may contain colons.
863  *
864  * Note: caller frees hostname and export path, even on error.
865  */
866 static int nfs_parse_source(struct fs_context *fc,
867 			    size_t maxnamlen, size_t maxpathlen)
868 {
869 	struct nfs_fs_context *ctx = nfs_fc2context(fc);
870 	const char *dev_name = fc->source;
871 	size_t len;
872 	const char *end;
873 
874 	if (unlikely(!dev_name || !*dev_name)) {
875 		dfprintk(MOUNT, "NFS: device name not specified\n");
876 		return -EINVAL;
877 	}
878 
879 	/* Is the host name protected with square brakcets? */
880 	if (*dev_name == '[') {
881 		end = strchr(++dev_name, ']');
882 		if (end == NULL || end[1] != ':')
883 			goto out_bad_devname;
884 
885 		len = end - dev_name;
886 		end++;
887 	} else {
888 		const char *comma;
889 
890 		end = strchr(dev_name, ':');
891 		if (end == NULL)
892 			goto out_bad_devname;
893 		len = end - dev_name;
894 
895 		/* kill possible hostname list: not supported */
896 		comma = memchr(dev_name, ',', len);
897 		if (comma)
898 			len = comma - dev_name;
899 	}
900 
901 	if (len > maxnamlen)
902 		goto out_hostname;
903 
904 	kfree(ctx->nfs_server.hostname);
905 
906 	/* N.B. caller will free nfs_server.hostname in all cases */
907 	ctx->nfs_server.hostname = kmemdup_nul(dev_name, len, GFP_KERNEL);
908 	if (!ctx->nfs_server.hostname)
909 		goto out_nomem;
910 	len = strlen(++end);
911 	if (len > maxpathlen)
912 		goto out_path;
913 	ctx->nfs_server.export_path = kmemdup_nul(end, len, GFP_KERNEL);
914 	if (!ctx->nfs_server.export_path)
915 		goto out_nomem;
916 
917 	dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", ctx->nfs_server.export_path);
918 	return 0;
919 
920 out_bad_devname:
921 	return nfs_invalf(fc, "NFS: device name not in host:path format");
922 out_nomem:
923 	nfs_errorf(fc, "NFS: not enough memory to parse device name");
924 	return -ENOMEM;
925 out_hostname:
926 	nfs_errorf(fc, "NFS: server hostname too long");
927 	return -ENAMETOOLONG;
928 out_path:
929 	nfs_errorf(fc, "NFS: export pathname too long");
930 	return -ENAMETOOLONG;
931 }
932 
933 static inline bool is_remount_fc(struct fs_context *fc)
934 {
935 	return fc->root != NULL;
936 }
937 
938 /*
939  * Parse monolithic NFS2/NFS3 mount data
940  * - fills in the mount root filehandle
941  *
942  * For option strings, user space handles the following behaviors:
943  *
944  * + DNS: mapping server host name to IP address ("addr=" option)
945  *
946  * + failure mode: how to behave if a mount request can't be handled
947  *   immediately ("fg/bg" option)
948  *
949  * + retry: how often to retry a mount request ("retry=" option)
950  *
951  * + breaking back: trying proto=udp after proto=tcp, v2 after v3,
952  *   mountproto=tcp after mountproto=udp, and so on
953  */
954 static int nfs23_parse_monolithic(struct fs_context *fc,
955 				  struct nfs_mount_data *data)
956 {
957 	struct nfs_fs_context *ctx = nfs_fc2context(fc);
958 	struct nfs_fh *mntfh = ctx->mntfh;
959 	struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address;
960 	int extra_flags = NFS_MOUNT_LEGACY_INTERFACE;
961 	int ret;
962 
963 	if (data == NULL)
964 		goto out_no_data;
965 
966 	ctx->version = NFS_DEFAULT_VERSION;
967 	switch (data->version) {
968 	case 1:
969 		data->namlen = 0;
970 		fallthrough;
971 	case 2:
972 		data->bsize = 0;
973 		fallthrough;
974 	case 3:
975 		if (data->flags & NFS_MOUNT_VER3)
976 			goto out_no_v3;
977 		data->root.size = NFS2_FHSIZE;
978 		memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
979 		/* Turn off security negotiation */
980 		extra_flags |= NFS_MOUNT_SECFLAVOUR;
981 		fallthrough;
982 	case 4:
983 		if (data->flags & NFS_MOUNT_SECFLAVOUR)
984 			goto out_no_sec;
985 		fallthrough;
986 	case 5:
987 		memset(data->context, 0, sizeof(data->context));
988 		fallthrough;
989 	case 6:
990 		if (data->flags & NFS_MOUNT_VER3) {
991 			if (data->root.size > NFS3_FHSIZE || data->root.size == 0)
992 				goto out_invalid_fh;
993 			mntfh->size = data->root.size;
994 			ctx->version = 3;
995 		} else {
996 			mntfh->size = NFS2_FHSIZE;
997 			ctx->version = 2;
998 		}
999 
1000 
1001 		memcpy(mntfh->data, data->root.data, mntfh->size);
1002 		if (mntfh->size < sizeof(mntfh->data))
1003 			memset(mntfh->data + mntfh->size, 0,
1004 			       sizeof(mntfh->data) - mntfh->size);
1005 
1006 		/*
1007 		 * for proto == XPRT_TRANSPORT_UDP, which is what uses
1008 		 * to_exponential, implying shift: limit the shift value
1009 		 * to BITS_PER_LONG (majortimeo is unsigned long)
1010 		 */
1011 		if (!(data->flags & NFS_MOUNT_TCP)) /* this will be UDP */
1012 			if (data->retrans >= 64) /* shift value is too large */
1013 				goto out_invalid_data;
1014 
1015 		/*
1016 		 * Translate to nfs_fs_context, which nfs_fill_super
1017 		 * can deal with.
1018 		 */
1019 		ctx->flags	= data->flags & NFS_MOUNT_FLAGMASK;
1020 		ctx->flags	|= extra_flags;
1021 		ctx->rsize	= data->rsize;
1022 		ctx->wsize	= data->wsize;
1023 		ctx->timeo	= data->timeo;
1024 		ctx->retrans	= data->retrans;
1025 		ctx->acregmin	= data->acregmin;
1026 		ctx->acregmax	= data->acregmax;
1027 		ctx->acdirmin	= data->acdirmin;
1028 		ctx->acdirmax	= data->acdirmax;
1029 		ctx->need_mount	= false;
1030 
1031 		memcpy(sap, &data->addr, sizeof(data->addr));
1032 		ctx->nfs_server.addrlen = sizeof(data->addr);
1033 		ctx->nfs_server.port = ntohs(data->addr.sin_port);
1034 		if (sap->sa_family != AF_INET ||
1035 		    !nfs_verify_server_address(sap))
1036 			goto out_no_address;
1037 
1038 		if (!(data->flags & NFS_MOUNT_TCP))
1039 			ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP;
1040 		/* N.B. caller will free nfs_server.hostname in all cases */
1041 		ctx->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL);
1042 		if (!ctx->nfs_server.hostname)
1043 			goto out_nomem;
1044 
1045 		ctx->namlen		= data->namlen;
1046 		ctx->bsize		= data->bsize;
1047 
1048 		if (data->flags & NFS_MOUNT_SECFLAVOUR)
1049 			ctx->selected_flavor = data->pseudoflavor;
1050 		else
1051 			ctx->selected_flavor = RPC_AUTH_UNIX;
1052 
1053 		if (!(data->flags & NFS_MOUNT_NONLM))
1054 			ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK|
1055 					 NFS_MOUNT_LOCAL_FCNTL);
1056 		else
1057 			ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK|
1058 					NFS_MOUNT_LOCAL_FCNTL);
1059 
1060 		/*
1061 		 * The legacy version 6 binary mount data from userspace has a
1062 		 * field used only to transport selinux information into the
1063 		 * kernel.  To continue to support that functionality we
1064 		 * have a touch of selinux knowledge here in the NFS code. The
1065 		 * userspace code converted context=blah to just blah so we are
1066 		 * converting back to the full string selinux understands.
1067 		 */
1068 		if (data->context[0]){
1069 #ifdef CONFIG_SECURITY_SELINUX
1070 			int ret;
1071 
1072 			data->context[NFS_MAX_CONTEXT_LEN] = '\0';
1073 			ret = vfs_parse_fs_string(fc, "context",
1074 						  data->context, strlen(data->context));
1075 			if (ret < 0)
1076 				return ret;
1077 #else
1078 			return -EINVAL;
1079 #endif
1080 		}
1081 
1082 		break;
1083 	default:
1084 		goto generic;
1085 	}
1086 
1087 	ret = nfs_validate_transport_protocol(fc, ctx);
1088 	if (ret)
1089 		return ret;
1090 
1091 	ctx->skip_reconfig_option_check = true;
1092 	return 0;
1093 
1094 generic:
1095 	return generic_parse_monolithic(fc, data);
1096 
1097 out_no_data:
1098 	if (is_remount_fc(fc)) {
1099 		ctx->skip_reconfig_option_check = true;
1100 		return 0;
1101 	}
1102 	return nfs_invalf(fc, "NFS: mount program didn't pass any mount data");
1103 
1104 out_no_v3:
1105 	return nfs_invalf(fc, "NFS: nfs_mount_data version does not support v3");
1106 
1107 out_no_sec:
1108 	return nfs_invalf(fc, "NFS: nfs_mount_data version supports only AUTH_SYS");
1109 
1110 out_nomem:
1111 	dfprintk(MOUNT, "NFS: not enough memory to handle mount options");
1112 	return -ENOMEM;
1113 
1114 out_no_address:
1115 	return nfs_invalf(fc, "NFS: mount program didn't pass remote address");
1116 
1117 out_invalid_fh:
1118 	return nfs_invalf(fc, "NFS: invalid root filehandle");
1119 
1120 out_invalid_data:
1121 	return nfs_invalf(fc, "NFS: invalid binary mount data");
1122 }
1123 
1124 #if IS_ENABLED(CONFIG_NFS_V4)
1125 struct compat_nfs_string {
1126 	compat_uint_t len;
1127 	compat_uptr_t data;
1128 };
1129 
1130 static inline void compat_nfs_string(struct nfs_string *dst,
1131 				     struct compat_nfs_string *src)
1132 {
1133 	dst->data = compat_ptr(src->data);
1134 	dst->len = src->len;
1135 }
1136 
1137 struct compat_nfs4_mount_data_v1 {
1138 	compat_int_t version;
1139 	compat_int_t flags;
1140 	compat_int_t rsize;
1141 	compat_int_t wsize;
1142 	compat_int_t timeo;
1143 	compat_int_t retrans;
1144 	compat_int_t acregmin;
1145 	compat_int_t acregmax;
1146 	compat_int_t acdirmin;
1147 	compat_int_t acdirmax;
1148 	struct compat_nfs_string client_addr;
1149 	struct compat_nfs_string mnt_path;
1150 	struct compat_nfs_string hostname;
1151 	compat_uint_t host_addrlen;
1152 	compat_uptr_t host_addr;
1153 	compat_int_t proto;
1154 	compat_int_t auth_flavourlen;
1155 	compat_uptr_t auth_flavours;
1156 };
1157 
1158 static void nfs4_compat_mount_data_conv(struct nfs4_mount_data *data)
1159 {
1160 	struct compat_nfs4_mount_data_v1 *compat =
1161 			(struct compat_nfs4_mount_data_v1 *)data;
1162 
1163 	/* copy the fields backwards */
1164 	data->auth_flavours = compat_ptr(compat->auth_flavours);
1165 	data->auth_flavourlen = compat->auth_flavourlen;
1166 	data->proto = compat->proto;
1167 	data->host_addr = compat_ptr(compat->host_addr);
1168 	data->host_addrlen = compat->host_addrlen;
1169 	compat_nfs_string(&data->hostname, &compat->hostname);
1170 	compat_nfs_string(&data->mnt_path, &compat->mnt_path);
1171 	compat_nfs_string(&data->client_addr, &compat->client_addr);
1172 	data->acdirmax = compat->acdirmax;
1173 	data->acdirmin = compat->acdirmin;
1174 	data->acregmax = compat->acregmax;
1175 	data->acregmin = compat->acregmin;
1176 	data->retrans = compat->retrans;
1177 	data->timeo = compat->timeo;
1178 	data->wsize = compat->wsize;
1179 	data->rsize = compat->rsize;
1180 	data->flags = compat->flags;
1181 	data->version = compat->version;
1182 }
1183 
1184 /*
1185  * Validate NFSv4 mount options
1186  */
1187 static int nfs4_parse_monolithic(struct fs_context *fc,
1188 				 struct nfs4_mount_data *data)
1189 {
1190 	struct nfs_fs_context *ctx = nfs_fc2context(fc);
1191 	struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address;
1192 	int ret;
1193 	char *c;
1194 
1195 	if (!data) {
1196 		if (is_remount_fc(fc))
1197 			goto done;
1198 		return nfs_invalf(fc,
1199 			"NFS4: mount program didn't pass any mount data");
1200 	}
1201 
1202 	ctx->version = 4;
1203 
1204 	if (data->version != 1)
1205 		return generic_parse_monolithic(fc, data);
1206 
1207 	if (in_compat_syscall())
1208 		nfs4_compat_mount_data_conv(data);
1209 
1210 	if (data->host_addrlen > sizeof(ctx->nfs_server.address))
1211 		goto out_no_address;
1212 	if (data->host_addrlen == 0)
1213 		goto out_no_address;
1214 	ctx->nfs_server.addrlen = data->host_addrlen;
1215 	if (copy_from_user(sap, data->host_addr, data->host_addrlen))
1216 		return -EFAULT;
1217 	if (!nfs_verify_server_address(sap))
1218 		goto out_no_address;
1219 	ctx->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port);
1220 
1221 	if (data->auth_flavourlen) {
1222 		rpc_authflavor_t pseudoflavor;
1223 
1224 		if (data->auth_flavourlen > 1)
1225 			goto out_inval_auth;
1226 		if (copy_from_user(&pseudoflavor, data->auth_flavours,
1227 				   sizeof(pseudoflavor)))
1228 			return -EFAULT;
1229 		ctx->selected_flavor = pseudoflavor;
1230 	} else {
1231 		ctx->selected_flavor = RPC_AUTH_UNIX;
1232 	}
1233 
1234 	c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
1235 	if (IS_ERR(c))
1236 		return PTR_ERR(c);
1237 	ctx->nfs_server.hostname = c;
1238 
1239 	c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN);
1240 	if (IS_ERR(c))
1241 		return PTR_ERR(c);
1242 	ctx->nfs_server.export_path = c;
1243 	dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c);
1244 
1245 	c = strndup_user(data->client_addr.data, 16);
1246 	if (IS_ERR(c))
1247 		return PTR_ERR(c);
1248 	ctx->client_address = c;
1249 
1250 	/*
1251 	 * Translate to nfs_fs_context, which nfs_fill_super
1252 	 * can deal with.
1253 	 */
1254 
1255 	ctx->flags	= data->flags & NFS4_MOUNT_FLAGMASK;
1256 	ctx->rsize	= data->rsize;
1257 	ctx->wsize	= data->wsize;
1258 	ctx->timeo	= data->timeo;
1259 	ctx->retrans	= data->retrans;
1260 	ctx->acregmin	= data->acregmin;
1261 	ctx->acregmax	= data->acregmax;
1262 	ctx->acdirmin	= data->acdirmin;
1263 	ctx->acdirmax	= data->acdirmax;
1264 	ctx->nfs_server.protocol = data->proto;
1265 	ret = nfs_validate_transport_protocol(fc, ctx);
1266 	if (ret)
1267 		return ret;
1268 done:
1269 	ctx->skip_reconfig_option_check = true;
1270 	return 0;
1271 
1272 out_inval_auth:
1273 	return nfs_invalf(fc, "NFS4: Invalid number of RPC auth flavours %d",
1274 		      data->auth_flavourlen);
1275 
1276 out_no_address:
1277 	return nfs_invalf(fc, "NFS4: mount program didn't pass remote address");
1278 }
1279 #endif
1280 
1281 /*
1282  * Parse a monolithic block of data from sys_mount().
1283  */
1284 static int nfs_fs_context_parse_monolithic(struct fs_context *fc,
1285 					   void *data)
1286 {
1287 	if (fc->fs_type == &nfs_fs_type)
1288 		return nfs23_parse_monolithic(fc, data);
1289 
1290 #if IS_ENABLED(CONFIG_NFS_V4)
1291 	if (fc->fs_type == &nfs4_fs_type)
1292 		return nfs4_parse_monolithic(fc, data);
1293 #endif
1294 
1295 	return nfs_invalf(fc, "NFS: Unsupported monolithic data version");
1296 }
1297 
1298 /*
1299  * Validate the preparsed information in the config.
1300  */
1301 static int nfs_fs_context_validate(struct fs_context *fc)
1302 {
1303 	struct nfs_fs_context *ctx = nfs_fc2context(fc);
1304 	struct nfs_subversion *nfs_mod;
1305 	struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address;
1306 	int max_namelen = PAGE_SIZE;
1307 	int max_pathlen = NFS_MAXPATHLEN;
1308 	int port = 0;
1309 	int ret;
1310 
1311 	if (!fc->source)
1312 		goto out_no_device_name;
1313 
1314 	/* Check for sanity first. */
1315 	if (ctx->minorversion && ctx->version != 4)
1316 		goto out_minorversion_mismatch;
1317 
1318 	if (ctx->options & NFS_OPTION_MIGRATION &&
1319 	    (ctx->version != 4 || ctx->minorversion != 0))
1320 		goto out_migration_misuse;
1321 
1322 	/* Verify that any proto=/mountproto= options match the address
1323 	 * families in the addr=/mountaddr= options.
1324 	 */
1325 	if (ctx->protofamily != AF_UNSPEC &&
1326 	    ctx->protofamily != ctx->nfs_server.address.sa_family)
1327 		goto out_proto_mismatch;
1328 
1329 	if (ctx->mountfamily != AF_UNSPEC) {
1330 		if (ctx->mount_server.addrlen) {
1331 			if (ctx->mountfamily != ctx->mount_server.address.sa_family)
1332 				goto out_mountproto_mismatch;
1333 		} else {
1334 			if (ctx->mountfamily != ctx->nfs_server.address.sa_family)
1335 				goto out_mountproto_mismatch;
1336 		}
1337 	}
1338 
1339 	if (!nfs_verify_server_address(sap))
1340 		goto out_no_address;
1341 
1342 	ret = nfs_validate_transport_protocol(fc, ctx);
1343 	if (ret)
1344 		return ret;
1345 
1346 	if (ctx->version == 4) {
1347 		if (IS_ENABLED(CONFIG_NFS_V4)) {
1348 			if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA)
1349 				port = NFS_RDMA_PORT;
1350 			else
1351 				port = NFS_PORT;
1352 			max_namelen = NFS4_MAXNAMLEN;
1353 			max_pathlen = NFS4_MAXPATHLEN;
1354 			ctx->flags &= ~(NFS_MOUNT_NONLM | NFS_MOUNT_NOACL |
1355 					NFS_MOUNT_VER3 | NFS_MOUNT_LOCAL_FLOCK |
1356 					NFS_MOUNT_LOCAL_FCNTL);
1357 		} else {
1358 			goto out_v4_not_compiled;
1359 		}
1360 	} else {
1361 		nfs_set_mount_transport_protocol(ctx);
1362 		if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA)
1363 			port = NFS_RDMA_PORT;
1364 	}
1365 
1366 	nfs_set_port(sap, &ctx->nfs_server.port, port);
1367 
1368 	ret = nfs_parse_source(fc, max_namelen, max_pathlen);
1369 	if (ret < 0)
1370 		return ret;
1371 
1372 	/* Load the NFS protocol module if we haven't done so yet */
1373 	if (!ctx->nfs_mod) {
1374 		nfs_mod = get_nfs_version(ctx->version);
1375 		if (IS_ERR(nfs_mod)) {
1376 			ret = PTR_ERR(nfs_mod);
1377 			goto out_version_unavailable;
1378 		}
1379 		ctx->nfs_mod = nfs_mod;
1380 	}
1381 
1382 	/* Ensure the filesystem context has the correct fs_type */
1383 	if (fc->fs_type != ctx->nfs_mod->nfs_fs) {
1384 		module_put(fc->fs_type->owner);
1385 		__module_get(ctx->nfs_mod->nfs_fs->owner);
1386 		fc->fs_type = ctx->nfs_mod->nfs_fs;
1387 	}
1388 	return 0;
1389 
1390 out_no_device_name:
1391 	return nfs_invalf(fc, "NFS: Device name not specified");
1392 out_v4_not_compiled:
1393 	nfs_errorf(fc, "NFS: NFSv4 is not compiled into kernel");
1394 	return -EPROTONOSUPPORT;
1395 out_no_address:
1396 	return nfs_invalf(fc, "NFS: mount program didn't pass remote address");
1397 out_mountproto_mismatch:
1398 	return nfs_invalf(fc, "NFS: Mount server address does not match mountproto= option");
1399 out_proto_mismatch:
1400 	return nfs_invalf(fc, "NFS: Server address does not match proto= option");
1401 out_minorversion_mismatch:
1402 	return nfs_invalf(fc, "NFS: Mount option vers=%u does not support minorversion=%u",
1403 			  ctx->version, ctx->minorversion);
1404 out_migration_misuse:
1405 	return nfs_invalf(fc, "NFS: 'Migration' not supported for this NFS version");
1406 out_version_unavailable:
1407 	nfs_errorf(fc, "NFS: Version unavailable");
1408 	return ret;
1409 }
1410 
1411 /*
1412  * Create an NFS superblock by the appropriate method.
1413  */
1414 static int nfs_get_tree(struct fs_context *fc)
1415 {
1416 	struct nfs_fs_context *ctx = nfs_fc2context(fc);
1417 	int err = nfs_fs_context_validate(fc);
1418 
1419 	if (err)
1420 		return err;
1421 	if (!ctx->internal)
1422 		return ctx->nfs_mod->rpc_ops->try_get_tree(fc);
1423 	else
1424 		return nfs_get_tree_common(fc);
1425 }
1426 
1427 /*
1428  * Handle duplication of a configuration.  The caller copied *src into *sc, but
1429  * it can't deal with resource pointers in the filesystem context, so we have
1430  * to do that.  We need to clear pointers, copy data or get extra refs as
1431  * appropriate.
1432  */
1433 static int nfs_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc)
1434 {
1435 	struct nfs_fs_context *src = nfs_fc2context(src_fc), *ctx;
1436 
1437 	ctx = kmemdup(src, sizeof(struct nfs_fs_context), GFP_KERNEL);
1438 	if (!ctx)
1439 		return -ENOMEM;
1440 
1441 	ctx->mntfh = nfs_alloc_fhandle();
1442 	if (!ctx->mntfh) {
1443 		kfree(ctx);
1444 		return -ENOMEM;
1445 	}
1446 	nfs_copy_fh(ctx->mntfh, src->mntfh);
1447 
1448 	__module_get(ctx->nfs_mod->owner);
1449 	ctx->client_address		= NULL;
1450 	ctx->mount_server.hostname	= NULL;
1451 	ctx->nfs_server.export_path	= NULL;
1452 	ctx->nfs_server.hostname	= NULL;
1453 	ctx->fscache_uniq		= NULL;
1454 	ctx->clone_data.fattr		= NULL;
1455 	fc->fs_private = ctx;
1456 	return 0;
1457 }
1458 
1459 static void nfs_fs_context_free(struct fs_context *fc)
1460 {
1461 	struct nfs_fs_context *ctx = nfs_fc2context(fc);
1462 
1463 	if (ctx) {
1464 		if (ctx->server)
1465 			nfs_free_server(ctx->server);
1466 		if (ctx->nfs_mod)
1467 			put_nfs_version(ctx->nfs_mod);
1468 		kfree(ctx->client_address);
1469 		kfree(ctx->mount_server.hostname);
1470 		kfree(ctx->nfs_server.export_path);
1471 		kfree(ctx->nfs_server.hostname);
1472 		kfree(ctx->fscache_uniq);
1473 		nfs_free_fhandle(ctx->mntfh);
1474 		nfs_free_fattr(ctx->clone_data.fattr);
1475 		kfree(ctx);
1476 	}
1477 }
1478 
1479 static const struct fs_context_operations nfs_fs_context_ops = {
1480 	.free			= nfs_fs_context_free,
1481 	.dup			= nfs_fs_context_dup,
1482 	.parse_param		= nfs_fs_context_parse_param,
1483 	.parse_monolithic	= nfs_fs_context_parse_monolithic,
1484 	.get_tree		= nfs_get_tree,
1485 	.reconfigure		= nfs_reconfigure,
1486 };
1487 
1488 /*
1489  * Prepare superblock configuration.  We use the namespaces attached to the
1490  * context.  This may be the current process's namespaces, or it may be a
1491  * container's namespaces.
1492  */
1493 static int nfs_init_fs_context(struct fs_context *fc)
1494 {
1495 	struct nfs_fs_context *ctx;
1496 
1497 	ctx = kzalloc(sizeof(struct nfs_fs_context), GFP_KERNEL);
1498 	if (unlikely(!ctx))
1499 		return -ENOMEM;
1500 
1501 	ctx->mntfh = nfs_alloc_fhandle();
1502 	if (unlikely(!ctx->mntfh)) {
1503 		kfree(ctx);
1504 		return -ENOMEM;
1505 	}
1506 
1507 	ctx->protofamily	= AF_UNSPEC;
1508 	ctx->mountfamily	= AF_UNSPEC;
1509 	ctx->mount_server.port	= NFS_UNSPEC_PORT;
1510 
1511 	if (fc->root) {
1512 		/* reconfigure, start with the current config */
1513 		struct nfs_server *nfss = fc->root->d_sb->s_fs_info;
1514 		struct net *net = nfss->nfs_client->cl_net;
1515 
1516 		ctx->flags		= nfss->flags;
1517 		ctx->rsize		= nfss->rsize;
1518 		ctx->wsize		= nfss->wsize;
1519 		ctx->retrans		= nfss->client->cl_timeout->to_retries;
1520 		ctx->selected_flavor	= nfss->client->cl_auth->au_flavor;
1521 		ctx->acregmin		= nfss->acregmin / HZ;
1522 		ctx->acregmax		= nfss->acregmax / HZ;
1523 		ctx->acdirmin		= nfss->acdirmin / HZ;
1524 		ctx->acdirmax		= nfss->acdirmax / HZ;
1525 		ctx->timeo		= 10U * nfss->client->cl_timeout->to_initval / HZ;
1526 		ctx->nfs_server.port	= nfss->port;
1527 		ctx->nfs_server.addrlen	= nfss->nfs_client->cl_addrlen;
1528 		ctx->version		= nfss->nfs_client->rpc_ops->version;
1529 		ctx->minorversion	= nfss->nfs_client->cl_minorversion;
1530 
1531 		memcpy(&ctx->nfs_server.address, &nfss->nfs_client->cl_addr,
1532 			ctx->nfs_server.addrlen);
1533 
1534 		if (fc->net_ns != net) {
1535 			put_net(fc->net_ns);
1536 			fc->net_ns = get_net(net);
1537 		}
1538 
1539 		ctx->nfs_mod = nfss->nfs_client->cl_nfs_mod;
1540 		__module_get(ctx->nfs_mod->owner);
1541 	} else {
1542 		/* defaults */
1543 		ctx->timeo		= NFS_UNSPEC_TIMEO;
1544 		ctx->retrans		= NFS_UNSPEC_RETRANS;
1545 		ctx->acregmin		= NFS_DEF_ACREGMIN;
1546 		ctx->acregmax		= NFS_DEF_ACREGMAX;
1547 		ctx->acdirmin		= NFS_DEF_ACDIRMIN;
1548 		ctx->acdirmax		= NFS_DEF_ACDIRMAX;
1549 		ctx->nfs_server.port	= NFS_UNSPEC_PORT;
1550 		ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1551 		ctx->selected_flavor	= RPC_AUTH_MAXFLAVOR;
1552 		ctx->minorversion	= 0;
1553 		ctx->need_mount		= true;
1554 
1555 		fc->s_iflags		|= SB_I_STABLE_WRITES;
1556 	}
1557 	fc->fs_private = ctx;
1558 	fc->ops = &nfs_fs_context_ops;
1559 	return 0;
1560 }
1561 
1562 struct file_system_type nfs_fs_type = {
1563 	.owner			= THIS_MODULE,
1564 	.name			= "nfs",
1565 	.init_fs_context	= nfs_init_fs_context,
1566 	.parameters		= nfs_fs_parameters,
1567 	.kill_sb		= nfs_kill_super,
1568 	.fs_flags		= FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
1569 };
1570 MODULE_ALIAS_FS("nfs");
1571 EXPORT_SYMBOL_GPL(nfs_fs_type);
1572 
1573 #if IS_ENABLED(CONFIG_NFS_V4)
1574 struct file_system_type nfs4_fs_type = {
1575 	.owner			= THIS_MODULE,
1576 	.name			= "nfs4",
1577 	.init_fs_context	= nfs_init_fs_context,
1578 	.parameters		= nfs_fs_parameters,
1579 	.kill_sb		= nfs_kill_super,
1580 	.fs_flags		= FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
1581 };
1582 MODULE_ALIAS_FS("nfs4");
1583 MODULE_ALIAS("nfs4");
1584 EXPORT_SYMBOL_GPL(nfs4_fs_type);
1585 #endif /* CONFIG_NFS_V4 */
1586