cifs: remove any preceding delimiter from prefix_path
authorSachin Prabhu <sprabhu@redhat.com>
Mon, 8 Feb 2016 08:14:01 +0000 (13:44 +0530)
committerSteve French <smfrench@gmail.com>
Tue, 17 May 2016 19:09:33 +0000 (14:09 -0500)
We currently do not check if any delimiter exists before the prefix
path in cifs_compose_mount_options(). Consequently when building the
devname using cifs_build_devname() we can end up with multiple
delimiters separating the UNC and the prefix path.

An issue was reported by the customer mounting a folder within a DFS
share from a Netapp server which uses McAfee antivirus. We have
narrowed down the cause to the use of double backslashes in the file
name used to open the file. This was determined to be caused because of
additional delimiters as a result of the bug.

In addition to changes in cifs_build_devname(), we also fix
cifs_parse_devname() to ignore any preceding delimiter for the prefix
path.

The problem was originally reported on RHEL 6 in RHEL bz 1252721. This
is the upstream version of the fix. The fix was confirmed by looking at
the packet capture of a DFS mount.

Signed-off-by: Sachin Prabhu <sprabhu@redhat.com>
Signed-off-by: Steve French <smfrench@gmail.com>
fs/cifs/cifs_dfs_ref.c
fs/cifs/connect.c

index 94f2c8a9ae6d274202c9625fd88bdb73f7156190..ec9dbbcca3b9031c9aa26aee7468d9123a39a320 100644 (file)
@@ -151,8 +151,12 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
        if (sb_mountdata == NULL)
                return ERR_PTR(-EINVAL);
 
-       if (strlen(fullpath) - ref->path_consumed)
+       if (strlen(fullpath) - ref->path_consumed) {
                prepath = fullpath + ref->path_consumed;
+               /* skip initial delimiter */
+               if (*prepath == '/' || *prepath == '\\')
+                       prepath++;
+       }
 
        *devname = cifs_build_devname(ref->node_name, prepath);
        if (IS_ERR(*devname)) {
index 6f62ac821a8459228e50d7a4261482dd4b0d4abe..078b7311c3fa980015bb91dd29840e043c3d56eb 100644 (file)
@@ -1196,8 +1196,12 @@ cifs_parse_devname(const char *devname, struct smb_vol *vol)
 
        convert_delimiter(vol->UNC, '\\');
 
-       /* If pos is NULL, or is a bogus trailing delimiter then no prepath */
-       if (!*pos++ || !*pos)
+       /* skip any delimiter */
+       if (*pos == '/' || *pos == '\\')
+               pos++;
+
+       /* If pos is NULL then no prepath */
+       if (!*pos)
                return 0;
 
        vol->prepath = kstrdup(pos, GFP_KERNEL);