aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-12-10 06:10:45 -0500
committerSteve French <smfrench@gmail.com>2012-12-11 12:48:49 -0500
commit839db3d10a5ba792d6533b8bb3380f52ac877344 (patch)
tree5ef4cdeaa8d3fcb0a5ce6fa63da3f315d4661485
parent62a1a439e0fdd4ec8a80dc00fcbb9f26b5c34de1 (diff)
cifs: fix up handling of prefixpath= option
Currently the code takes care to ensure that the prefixpath has a leading '/' delimiter. What if someone passes us a prefixpath with a leading '\\' instead? The code doesn't properly handle that currently AFAICS. Let's just change the code to skip over any leading delimiter character when copying the prepath. Then, fix up the users of the prepath option to prefix it with the correct delimiter when they use it. Also, there's no need to limit the length of the prefixpath to 1k. If the server can handle it, why bother forbidding it? Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r--fs/cifs/connect.c34
-rw-r--r--fs/cifs/dir.c5
2 files changed, 12 insertions, 27 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 9c5c8b8c19fe..94c4484c9ea3 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1612,31 +1612,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1612 } 1612 }
1613 break; 1613 break;
1614 case Opt_prefixpath: 1614 case Opt_prefixpath:
1615 string = match_strdup(args); 1615 /* skip over any leading delimiter */
1616 if (string == NULL) 1616 if (*args[0].from == '/' || *args[0].from == '\\')
1617 goto out_nomem; 1617 args[0].from++;
1618
1619 temp_len = strnlen(string, 1024);
1620 if (string[0] != '/')
1621 temp_len++; /* missing leading slash */
1622 if (temp_len > 1024) {
1623 printk(KERN_WARNING "CIFS: prefix too long\n");
1624 goto cifs_parse_mount_err;
1625 }
1626
1627 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1628 if (vol->prepath == NULL) {
1629 printk(KERN_WARNING "CIFS: no memory "
1630 "for path prefix\n");
1631 goto cifs_parse_mount_err;
1632 }
1633
1634 if (string[0] != '/') {
1635 vol->prepath[0] = '/';
1636 strcpy(vol->prepath+1, string);
1637 } else
1638 strcpy(vol->prepath, string);
1639 1618
1619 kfree(vol->prepath);
1620 vol->prepath = match_strdup(args);
1621 if (vol->prepath == NULL)
1622 goto out_nomem;
1640 break; 1623 break;
1641 case Opt_iocharset: 1624 case Opt_iocharset:
1642 string = match_strdup(args); 1625 string = match_strdup(args);
@@ -3236,7 +3219,7 @@ build_unc_path_to_root(const struct smb_vol *vol,
3236 const struct cifs_sb_info *cifs_sb) 3219 const struct cifs_sb_info *cifs_sb)
3237{ 3220{
3238 char *full_path, *pos; 3221 char *full_path, *pos;
3239 unsigned int pplen = vol->prepath ? strlen(vol->prepath) : 0; 3222 unsigned int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0;
3240 unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1); 3223 unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1);
3241 3224
3242 full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL); 3225 full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL);
@@ -3247,6 +3230,7 @@ build_unc_path_to_root(const struct smb_vol *vol,
3247 pos = full_path + unc_len; 3230 pos = full_path + unc_len;
3248 3231
3249 if (pplen) { 3232 if (pplen) {
3233 *pos++ = CIFS_DIR_SEP(cifs_sb);
3250 strncpy(pos, vol->prepath, pplen); 3234 strncpy(pos, vol->prepath, pplen);
3251 pos += pplen; 3235 pos += pplen;
3252 } 3236 }
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 3b7e0c1266f7..8719bbe0dcc3 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -48,7 +48,7 @@ char *
48cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, 48cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
49 struct cifs_tcon *tcon) 49 struct cifs_tcon *tcon)
50{ 50{
51 int pplen = vol->prepath ? strlen(vol->prepath) : 0; 51 int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0;
52 int dfsplen; 52 int dfsplen;
53 char *full_path = NULL; 53 char *full_path = NULL;
54 54
@@ -69,7 +69,8 @@ cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
69 69
70 if (dfsplen) 70 if (dfsplen)
71 strncpy(full_path, tcon->treeName, dfsplen); 71 strncpy(full_path, tcon->treeName, dfsplen);
72 strncpy(full_path + dfsplen, vol->prepath, pplen); 72 full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb);
73 strncpy(full_path + dfsplen + 1, vol->prepath, pplen);
73 convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); 74 convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
74 full_path[dfsplen + pplen] = 0; /* add trailing null */ 75 full_path[dfsplen + pplen] = 0; /* add trailing null */
75 return full_path; 76 return full_path;