File Index
Files and directories
Sign in
FILE

fs_context.c

File preview with syntax highlighting.

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