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