Commit 839db3d10a5ba792d6533b8bb3380f52ac877344
Committed by
Steve French
1 parent
62a1a439e0
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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>
Showing 2 changed files with 12 additions and 27 deletions Side-by-side Diff
fs/cifs/connect.c
... | ... | @@ -1612,31 +1612,14 @@ |
1612 | 1612 | } |
1613 | 1613 | break; |
1614 | 1614 | case Opt_prefixpath: |
1615 | - string = match_strdup(args); | |
1616 | - if (string == NULL) | |
1617 | - goto out_nomem; | |
1615 | + /* skip over any leading delimiter */ | |
1616 | + if (*args[0].from == '/' || *args[0].from == '\\') | |
1617 | + args[0].from++; | |
1618 | 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 | - | |
1619 | + kfree(vol->prepath); | |
1620 | + vol->prepath = match_strdup(args); | |
1621 | + if (vol->prepath == NULL) | |
1622 | + goto out_nomem; | |
1640 | 1623 | break; |
1641 | 1624 | case Opt_iocharset: |
1642 | 1625 | string = match_strdup(args); |
... | ... | @@ -3236,7 +3219,7 @@ |
3236 | 3219 | const struct cifs_sb_info *cifs_sb) |
3237 | 3220 | { |
3238 | 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 | 3223 | unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1); |
3241 | 3224 | |
3242 | 3225 | full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL); |
... | ... | @@ -3247,6 +3230,7 @@ |
3247 | 3230 | pos = full_path + unc_len; |
3248 | 3231 | |
3249 | 3232 | if (pplen) { |
3233 | + *pos++ = CIFS_DIR_SEP(cifs_sb); | |
3250 | 3234 | strncpy(pos, vol->prepath, pplen); |
3251 | 3235 | pos += pplen; |
3252 | 3236 | } |
fs/cifs/dir.c
... | ... | @@ -48,7 +48,7 @@ |
48 | 48 | cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, |
49 | 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 | 52 | int dfsplen; |
53 | 53 | char *full_path = NULL; |
54 | 54 | |
... | ... | @@ -69,7 +69,8 @@ |
69 | 69 | |
70 | 70 | if (dfsplen) |
71 | 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 | 74 | convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); |
74 | 75 | full_path[dfsplen + pplen] = 0; /* add trailing null */ |
75 | 76 | return full_path; |