|
@@ -1665,99 +1665,59 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
|
|
return nfs_walk_authlist(args, &request);
|
|
return nfs_walk_authlist(args, &request);
|
|
}
|
|
}
|
|
|
|
|
|
-static int nfs_parse_simple_hostname(const char *dev_name,
|
|
|
|
- char **hostname, size_t maxnamlen,
|
|
|
|
- char **export_path, size_t maxpathlen)
|
|
|
|
|
|
+/*
|
|
|
|
+ * Split "dev_name" into "hostname:export_path".
|
|
|
|
+ *
|
|
|
|
+ * The leftmost colon demarks the split between the server's hostname
|
|
|
|
+ * and the export path. If the hostname starts with a left square
|
|
|
|
+ * bracket, then it may contain colons.
|
|
|
|
+ *
|
|
|
|
+ * Note: caller frees hostname and export path, even on error.
|
|
|
|
+ */
|
|
|
|
+static int nfs_parse_devname(const char *dev_name,
|
|
|
|
+ char **hostname, size_t maxnamlen,
|
|
|
|
+ char **export_path, size_t maxpathlen)
|
|
{
|
|
{
|
|
size_t len;
|
|
size_t len;
|
|
- char *colon, *comma;
|
|
|
|
-
|
|
|
|
- colon = strchr(dev_name, ':');
|
|
|
|
- if (colon == NULL)
|
|
|
|
- goto out_bad_devname;
|
|
|
|
-
|
|
|
|
- len = colon - dev_name;
|
|
|
|
- if (len > maxnamlen)
|
|
|
|
- goto out_hostname;
|
|
|
|
-
|
|
|
|
- /* N.B. caller will free nfs_server.hostname in all cases */
|
|
|
|
- *hostname = kstrndup(dev_name, len, GFP_KERNEL);
|
|
|
|
- if (!*hostname)
|
|
|
|
- goto out_nomem;
|
|
|
|
|
|
+ char *end;
|
|
|
|
|
|
- /* kill possible hostname list: not supported */
|
|
|
|
- comma = strchr(*hostname, ',');
|
|
|
|
- if (comma != NULL) {
|
|
|
|
- if (comma == *hostname)
|
|
|
|
|
|
+ /* Is the host name protected with square brakcets? */
|
|
|
|
+ if (*dev_name == '[') {
|
|
|
|
+ end = strchr(++dev_name, ']');
|
|
|
|
+ if (end == NULL || end[1] != ':')
|
|
goto out_bad_devname;
|
|
goto out_bad_devname;
|
|
- *comma = '\0';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- colon++;
|
|
|
|
- len = strlen(colon);
|
|
|
|
- if (len > maxpathlen)
|
|
|
|
- goto out_path;
|
|
|
|
- *export_path = kstrndup(colon, len, GFP_KERNEL);
|
|
|
|
- if (!*export_path)
|
|
|
|
- goto out_nomem;
|
|
|
|
-
|
|
|
|
- dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *export_path);
|
|
|
|
- return 0;
|
|
|
|
|
|
|
|
-out_bad_devname:
|
|
|
|
- dfprintk(MOUNT, "NFS: device name not in host:path format\n");
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
-out_nomem:
|
|
|
|
- dfprintk(MOUNT, "NFS: not enough memory to parse device name\n");
|
|
|
|
- return -ENOMEM;
|
|
|
|
-
|
|
|
|
-out_hostname:
|
|
|
|
- dfprintk(MOUNT, "NFS: server hostname too long\n");
|
|
|
|
- return -ENAMETOOLONG;
|
|
|
|
-
|
|
|
|
-out_path:
|
|
|
|
- dfprintk(MOUNT, "NFS: export pathname too long\n");
|
|
|
|
- return -ENAMETOOLONG;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
- * Hostname has square brackets around it because it contains one or
|
|
|
|
- * more colons. We look for the first closing square bracket, and a
|
|
|
|
- * colon must follow it.
|
|
|
|
- */
|
|
|
|
-static int nfs_parse_protected_hostname(const char *dev_name,
|
|
|
|
- char **hostname, size_t maxnamlen,
|
|
|
|
- char **export_path, size_t maxpathlen)
|
|
|
|
-{
|
|
|
|
- size_t len;
|
|
|
|
- char *start, *end;
|
|
|
|
|
|
+ len = end - dev_name;
|
|
|
|
+ end++;
|
|
|
|
+ } else {
|
|
|
|
+ char *comma;
|
|
|
|
|
|
- start = (char *)(dev_name + 1);
|
|
|
|
|
|
+ end = strchr(dev_name, ':');
|
|
|
|
+ if (end == NULL)
|
|
|
|
+ goto out_bad_devname;
|
|
|
|
+ len = end - dev_name;
|
|
|
|
|
|
- end = strchr(start, ']');
|
|
|
|
- if (end == NULL)
|
|
|
|
- goto out_bad_devname;
|
|
|
|
- if (*(end + 1) != ':')
|
|
|
|
- goto out_bad_devname;
|
|
|
|
|
|
+ /* kill possible hostname list: not supported */
|
|
|
|
+ comma = strchr(dev_name, ',');
|
|
|
|
+ if (comma != NULL && comma < end)
|
|
|
|
+ *comma = 0;
|
|
|
|
+ }
|
|
|
|
|
|
- len = end - start;
|
|
|
|
if (len > maxnamlen)
|
|
if (len > maxnamlen)
|
|
goto out_hostname;
|
|
goto out_hostname;
|
|
|
|
|
|
/* N.B. caller will free nfs_server.hostname in all cases */
|
|
/* N.B. caller will free nfs_server.hostname in all cases */
|
|
- *hostname = kstrndup(start, len, GFP_KERNEL);
|
|
|
|
|
|
+ *hostname = kstrndup(dev_name, len, GFP_KERNEL);
|
|
if (*hostname == NULL)
|
|
if (*hostname == NULL)
|
|
goto out_nomem;
|
|
goto out_nomem;
|
|
-
|
|
|
|
- end += 2;
|
|
|
|
- len = strlen(end);
|
|
|
|
|
|
+ len = strlen(++end);
|
|
if (len > maxpathlen)
|
|
if (len > maxpathlen)
|
|
goto out_path;
|
|
goto out_path;
|
|
*export_path = kstrndup(end, len, GFP_KERNEL);
|
|
*export_path = kstrndup(end, len, GFP_KERNEL);
|
|
if (!*export_path)
|
|
if (!*export_path)
|
|
goto out_nomem;
|
|
goto out_nomem;
|
|
|
|
|
|
|
|
+ dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *export_path);
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
out_bad_devname:
|
|
out_bad_devname:
|
|
@@ -1777,29 +1737,6 @@ out_path:
|
|
return -ENAMETOOLONG;
|
|
return -ENAMETOOLONG;
|
|
}
|
|
}
|
|
|
|
|
|
-/*
|
|
|
|
- * Split "dev_name" into "hostname:export_path".
|
|
|
|
- *
|
|
|
|
- * The leftmost colon demarks the split between the server's hostname
|
|
|
|
- * and the export path. If the hostname starts with a left square
|
|
|
|
- * bracket, then it may contain colons.
|
|
|
|
- *
|
|
|
|
- * Note: caller frees hostname and export path, even on error.
|
|
|
|
- */
|
|
|
|
-static int nfs_parse_devname(const char *dev_name,
|
|
|
|
- char **hostname, size_t maxnamlen,
|
|
|
|
- char **export_path, size_t maxpathlen)
|
|
|
|
-{
|
|
|
|
- if (*dev_name == '[')
|
|
|
|
- return nfs_parse_protected_hostname(dev_name,
|
|
|
|
- hostname, maxnamlen,
|
|
|
|
- export_path, maxpathlen);
|
|
|
|
-
|
|
|
|
- return nfs_parse_simple_hostname(dev_name,
|
|
|
|
- hostname, maxnamlen,
|
|
|
|
- export_path, maxpathlen);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Validate the NFS2/NFS3 mount data
|
|
* Validate the NFS2/NFS3 mount data
|
|
* - fills in the mount root filehandle
|
|
* - fills in the mount root filehandle
|