diff options
| -rw-r--r-- | fs/nfs/internal.h | 9 | ||||
| -rw-r--r-- | fs/nfs/super.c | 55 |
2 files changed, 36 insertions, 28 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 2e485677019c..5e686a4d744e 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
| @@ -49,6 +49,11 @@ struct nfs_clone_mount { | |||
| 49 | #define NFS_MAX_SECFLAVORS (12) | 49 | #define NFS_MAX_SECFLAVORS (12) |
| 50 | 50 | ||
| 51 | /* | 51 | /* |
| 52 | * Value used if the user did not specify a port value. | ||
| 53 | */ | ||
| 54 | #define NFS_UNSPEC_PORT (-1) | ||
| 55 | |||
| 56 | /* | ||
| 52 | * In-kernel mount arguments | 57 | * In-kernel mount arguments |
| 53 | */ | 58 | */ |
| 54 | struct nfs_parsed_mount_data { | 59 | struct nfs_parsed_mount_data { |
| @@ -71,7 +76,7 @@ struct nfs_parsed_mount_data { | |||
| 71 | size_t addrlen; | 76 | size_t addrlen; |
| 72 | char *hostname; | 77 | char *hostname; |
| 73 | u32 version; | 78 | u32 version; |
| 74 | unsigned short port; | 79 | int port; |
| 75 | unsigned short protocol; | 80 | unsigned short protocol; |
| 76 | } mount_server; | 81 | } mount_server; |
| 77 | 82 | ||
| @@ -80,7 +85,7 @@ struct nfs_parsed_mount_data { | |||
| 80 | size_t addrlen; | 85 | size_t addrlen; |
| 81 | char *hostname; | 86 | char *hostname; |
| 82 | char *export_path; | 87 | char *export_path; |
| 83 | unsigned short port; | 88 | int port; |
| 84 | unsigned short protocol; | 89 | unsigned short protocol; |
| 85 | } nfs_server; | 90 | } nfs_server; |
| 86 | 91 | ||
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index f3a95df4b95f..05544336f7de 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
| @@ -747,6 +747,21 @@ static int nfs_verify_server_address(struct sockaddr *addr) | |||
| 747 | } | 747 | } |
| 748 | 748 | ||
| 749 | /* | 749 | /* |
| 750 | * Select between a default port value and a user-specified port value. | ||
| 751 | * If a zero value is set, then autobind will be used. | ||
| 752 | */ | ||
| 753 | static void nfs_set_default_port(struct sockaddr *sap, const int parsed_port, | ||
| 754 | const unsigned short default_port) | ||
| 755 | { | ||
| 756 | unsigned short port = default_port; | ||
| 757 | |||
| 758 | if (parsed_port != NFS_UNSPEC_PORT) | ||
| 759 | port = parsed_port; | ||
| 760 | |||
| 761 | rpc_set_port(sap, port); | ||
| 762 | } | ||
| 763 | |||
| 764 | /* | ||
| 750 | * Sanity check the NFS transport protocol. | 765 | * Sanity check the NFS transport protocol. |
| 751 | * | 766 | * |
| 752 | */ | 767 | */ |
| @@ -1415,11 +1430,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args, | |||
| 1415 | args->mount_server.addrlen = args->nfs_server.addrlen; | 1430 | args->mount_server.addrlen = args->nfs_server.addrlen; |
| 1416 | } | 1431 | } |
| 1417 | request.salen = args->mount_server.addrlen; | 1432 | request.salen = args->mount_server.addrlen; |
| 1418 | 1433 | nfs_set_default_port(request.sap, args->mount_server.port, 0); | |
| 1419 | /* | ||
| 1420 | * autobind will be used if mount_server.port == 0 | ||
| 1421 | */ | ||
| 1422 | rpc_set_port(request.sap, args->mount_server.port); | ||
| 1423 | 1434 | ||
| 1424 | /* | 1435 | /* |
| 1425 | * Now ask the mount server to map our export path | 1436 | * Now ask the mount server to map our export path |
| @@ -1597,6 +1608,7 @@ static int nfs_validate_mount_data(void *options, | |||
| 1597 | const char *dev_name) | 1608 | const char *dev_name) |
| 1598 | { | 1609 | { |
| 1599 | struct nfs_mount_data *data = (struct nfs_mount_data *)options; | 1610 | struct nfs_mount_data *data = (struct nfs_mount_data *)options; |
| 1611 | struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; | ||
| 1600 | 1612 | ||
| 1601 | if (data == NULL) | 1613 | if (data == NULL) |
| 1602 | goto out_no_data; | 1614 | goto out_no_data; |
| @@ -1608,8 +1620,8 @@ static int nfs_validate_mount_data(void *options, | |||
| 1608 | args->acregmax = NFS_DEF_ACREGMAX; | 1620 | args->acregmax = NFS_DEF_ACREGMAX; |
| 1609 | args->acdirmin = NFS_DEF_ACDIRMIN; | 1621 | args->acdirmin = NFS_DEF_ACDIRMIN; |
| 1610 | args->acdirmax = NFS_DEF_ACDIRMAX; | 1622 | args->acdirmax = NFS_DEF_ACDIRMAX; |
| 1611 | args->mount_server.port = 0; /* autobind unless user sets port */ | 1623 | args->mount_server.port = NFS_UNSPEC_PORT; |
| 1612 | args->nfs_server.port = 0; /* autobind unless user sets port */ | 1624 | args->nfs_server.port = NFS_UNSPEC_PORT; |
| 1613 | args->nfs_server.protocol = XPRT_TRANSPORT_TCP; | 1625 | args->nfs_server.protocol = XPRT_TRANSPORT_TCP; |
| 1614 | args->auth_flavors[0] = RPC_AUTH_UNIX; | 1626 | args->auth_flavors[0] = RPC_AUTH_UNIX; |
| 1615 | args->auth_flavor_len = 1; | 1627 | args->auth_flavor_len = 1; |
| @@ -1657,11 +1669,9 @@ static int nfs_validate_mount_data(void *options, | |||
| 1657 | args->acdirmin = data->acdirmin; | 1669 | args->acdirmin = data->acdirmin; |
| 1658 | args->acdirmax = data->acdirmax; | 1670 | args->acdirmax = data->acdirmax; |
| 1659 | 1671 | ||
| 1660 | memcpy(&args->nfs_server.address, &data->addr, | 1672 | memcpy(sap, &data->addr, sizeof(data->addr)); |
| 1661 | sizeof(data->addr)); | ||
| 1662 | args->nfs_server.addrlen = sizeof(data->addr); | 1673 | args->nfs_server.addrlen = sizeof(data->addr); |
| 1663 | if (!nfs_verify_server_address((struct sockaddr *) | 1674 | if (!nfs_verify_server_address(sap)) |
| 1664 | &args->nfs_server.address)) | ||
| 1665 | goto out_no_address; | 1675 | goto out_no_address; |
| 1666 | 1676 | ||
| 1667 | if (!(data->flags & NFS_MOUNT_TCP)) | 1677 | if (!(data->flags & NFS_MOUNT_TCP)) |
| @@ -1709,12 +1719,10 @@ static int nfs_validate_mount_data(void *options, | |||
| 1709 | if (nfs_parse_mount_options((char *)options, args) == 0) | 1719 | if (nfs_parse_mount_options((char *)options, args) == 0) |
| 1710 | return -EINVAL; | 1720 | return -EINVAL; |
| 1711 | 1721 | ||
| 1712 | if (!nfs_verify_server_address((struct sockaddr *) | 1722 | if (!nfs_verify_server_address(sap)) |
| 1713 | &args->nfs_server.address)) | ||
| 1714 | goto out_no_address; | 1723 | goto out_no_address; |
| 1715 | 1724 | ||
| 1716 | rpc_set_port((struct sockaddr *)&args->nfs_server.address, | 1725 | nfs_set_default_port(sap, args->nfs_server.port, 0); |
| 1717 | args->nfs_server.port); | ||
| 1718 | 1726 | ||
| 1719 | nfs_set_mount_transport_protocol(args); | 1727 | nfs_set_mount_transport_protocol(args); |
| 1720 | 1728 | ||
| @@ -2261,7 +2269,7 @@ static int nfs4_validate_mount_data(void *options, | |||
| 2261 | struct nfs_parsed_mount_data *args, | 2269 | struct nfs_parsed_mount_data *args, |
| 2262 | const char *dev_name) | 2270 | const char *dev_name) |
| 2263 | { | 2271 | { |
| 2264 | struct sockaddr_in *ap; | 2272 | struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; |
| 2265 | struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; | 2273 | struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; |
| 2266 | char *c; | 2274 | char *c; |
| 2267 | 2275 | ||
| @@ -2274,23 +2282,21 @@ static int nfs4_validate_mount_data(void *options, | |||
| 2274 | args->acregmax = NFS_DEF_ACREGMAX; | 2282 | args->acregmax = NFS_DEF_ACREGMAX; |
| 2275 | args->acdirmin = NFS_DEF_ACDIRMIN; | 2283 | args->acdirmin = NFS_DEF_ACDIRMIN; |
| 2276 | args->acdirmax = NFS_DEF_ACDIRMAX; | 2284 | args->acdirmax = NFS_DEF_ACDIRMAX; |
| 2277 | args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */ | 2285 | args->nfs_server.port = NFS_UNSPEC_PORT; |
| 2278 | args->auth_flavors[0] = RPC_AUTH_UNIX; | 2286 | args->auth_flavors[0] = RPC_AUTH_UNIX; |
| 2279 | args->auth_flavor_len = 1; | 2287 | args->auth_flavor_len = 1; |
| 2280 | args->minorversion = 0; | 2288 | args->minorversion = 0; |
| 2281 | 2289 | ||
| 2282 | switch (data->version) { | 2290 | switch (data->version) { |
| 2283 | case 1: | 2291 | case 1: |
| 2284 | ap = (struct sockaddr_in *)&args->nfs_server.address; | ||
| 2285 | if (data->host_addrlen > sizeof(args->nfs_server.address)) | 2292 | if (data->host_addrlen > sizeof(args->nfs_server.address)) |
| 2286 | goto out_no_address; | 2293 | goto out_no_address; |
| 2287 | if (data->host_addrlen == 0) | 2294 | if (data->host_addrlen == 0) |
| 2288 | goto out_no_address; | 2295 | goto out_no_address; |
| 2289 | args->nfs_server.addrlen = data->host_addrlen; | 2296 | args->nfs_server.addrlen = data->host_addrlen; |
| 2290 | if (copy_from_user(ap, data->host_addr, data->host_addrlen)) | 2297 | if (copy_from_user(sap, data->host_addr, data->host_addrlen)) |
| 2291 | return -EFAULT; | 2298 | return -EFAULT; |
| 2292 | if (!nfs_verify_server_address((struct sockaddr *) | 2299 | if (!nfs_verify_server_address(sap)) |
| 2293 | &args->nfs_server.address)) | ||
| 2294 | goto out_no_address; | 2300 | goto out_no_address; |
| 2295 | 2301 | ||
| 2296 | if (data->auth_flavourlen) { | 2302 | if (data->auth_flavourlen) { |
| @@ -2342,12 +2348,9 @@ static int nfs4_validate_mount_data(void *options, | |||
| 2342 | if (nfs_parse_mount_options((char *)options, args) == 0) | 2348 | if (nfs_parse_mount_options((char *)options, args) == 0) |
| 2343 | return -EINVAL; | 2349 | return -EINVAL; |
| 2344 | 2350 | ||
| 2345 | if (!nfs_verify_server_address((struct sockaddr *) | 2351 | if (!nfs_verify_server_address(sap)) |
| 2346 | &args->nfs_server.address)) | ||
| 2347 | return -EINVAL; | 2352 | return -EINVAL; |
| 2348 | 2353 | nfs_set_default_port(sap, args->nfs_server.port, NFS_PORT); | |
| 2349 | rpc_set_port((struct sockaddr *)&args->nfs_server.address, | ||
| 2350 | args->nfs_server.port); | ||
| 2351 | 2354 | ||
| 2352 | nfs_validate_transport_protocol(args); | 2355 | nfs_validate_transport_protocol(args); |
| 2353 | 2356 | ||
