Skip to content

Commit

Permalink
cifs: fix up handling of prefixpath= option
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jeff Layton authored and Steve French committed Dec 11, 2012
1 parent 62a1a43 commit 839db3d
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 27 deletions.
34 changes: 9 additions & 25 deletions fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -1612,31 +1612,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
}
break;
case Opt_prefixpath:
string = match_strdup(args);
if (string == NULL)
goto out_nomem;

temp_len = strnlen(string, 1024);
if (string[0] != '/')
temp_len++; /* missing leading slash */
if (temp_len > 1024) {
printk(KERN_WARNING "CIFS: prefix too long\n");
goto cifs_parse_mount_err;
}

vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
if (vol->prepath == NULL) {
printk(KERN_WARNING "CIFS: no memory "
"for path prefix\n");
goto cifs_parse_mount_err;
}

if (string[0] != '/') {
vol->prepath[0] = '/';
strcpy(vol->prepath+1, string);
} else
strcpy(vol->prepath, string);
/* skip over any leading delimiter */
if (*args[0].from == '/' || *args[0].from == '\\')
args[0].from++;

kfree(vol->prepath);
vol->prepath = match_strdup(args);
if (vol->prepath == NULL)
goto out_nomem;
break;
case Opt_iocharset:
string = match_strdup(args);
Expand Down Expand Up @@ -3236,7 +3219,7 @@ build_unc_path_to_root(const struct smb_vol *vol,
const struct cifs_sb_info *cifs_sb)
{
char *full_path, *pos;
unsigned int pplen = vol->prepath ? strlen(vol->prepath) : 0;
unsigned int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0;
unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1);

full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL);
Expand All @@ -3247,6 +3230,7 @@ build_unc_path_to_root(const struct smb_vol *vol,
pos = full_path + unc_len;

if (pplen) {
*pos++ = CIFS_DIR_SEP(cifs_sb);
strncpy(pos, vol->prepath, pplen);
pos += pplen;
}
Expand Down
5 changes: 3 additions & 2 deletions fs/cifs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ char *
cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
struct cifs_tcon *tcon)
{
int pplen = vol->prepath ? strlen(vol->prepath) : 0;
int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0;
int dfsplen;
char *full_path = NULL;

Expand All @@ -69,7 +69,8 @@ cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,

if (dfsplen)
strncpy(full_path, tcon->treeName, dfsplen);
strncpy(full_path + dfsplen, vol->prepath, pplen);
full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb);
strncpy(full_path + dfsplen + 1, vol->prepath, pplen);
convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
full_path[dfsplen + pplen] = 0; /* add trailing null */
return full_path;
Expand Down

0 comments on commit 839db3d

Please sign in to comment.