Commit 839db3d10a5ba792d6533b8bb3380f52ac877344

Authored by Jeff Layton
Committed by Steve French
1 parent 62a1a439e0

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

... ... @@ -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 }
... ... @@ -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;