Re: [PATCH 5/6] cifs: fix up handling of prefixpath= option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2012/11/16 Jeff Layton <jlayton@xxxxxxxxxx>:
> 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?
>
> Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
> ---
>  fs/cifs/connect.c | 34 +++++++++-------------------------
>  fs/cifs/smb1ops.c |  5 +++--
>  fs/cifs/smb2ops.c |  2 +-
>  3 files changed, 13 insertions(+), 28 deletions(-)
>
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 89f426f..b1f352a 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -1603,31 +1603,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);
> @@ -3238,7 +3221,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);
> @@ -3249,6 +3232,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;
>         }
> diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
> index 56cc4be..50e9613 100644
> --- a/fs/cifs/smb1ops.c
> +++ b/fs/cifs/smb1ops.c
> @@ -579,7 +579,7 @@ static 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;
>
> @@ -600,7 +600,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;
> diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
> index 4d9dbe0..1baa82d 100644
> --- a/fs/cifs/smb2ops.c
> +++ b/fs/cifs/smb2ops.c
> @@ -266,7 +266,7 @@ static char *
>  smb2_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;
>         char *full_path = NULL;
>
>         /* if no prefix path, simply set path to the root of share to "" */
> --
> 1.7.11.7
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reviewed-by: Pavel Shilovsky <piastry@xxxxxxxxxxx>

-- 
Best regards,
Pavel Shilovsky.
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux