diff mbox

Add full_path_type arg to cifs_build_path_to_root()

Message ID 20160801143204.7377b5a4@aaptelpc (mailing list archive)
State New, archived
Headers show

Commit Message

Aurélien Aptel Aug. 1, 2016, 12:32 p.m. UTC
On Wed, 20 Apr 2016 18:16:34 +0200 Aurélien Aptel <aaptel@suse.com>
wrote:
> There are 2 ways to fix this:
> - never prefix an UNC path, even when using a DFS link i.e. remove all
>   code dealing with DFS from cifs_build_path_to_root)
> - add a new arg to decide the behaviour of cifs_build_path_to_root().

We have 2 customers reporting a bug involving this problem
internally at SUSE. I'm letting you know the first solution (patch
attached) will be in the next update of SUSE (SLE) kernels.
diff mbox

Patch

From df54ca09437a11438e1ec880c80c92e93ba98d71 Mon Sep 17 00:00:00 2001
From: Aurelien Aptel <aaptel@suse.com>
Date: Tue, 26 Apr 2016 17:59:06 +0200
Subject: [PATCH] fs/cifs: remove DFS handling from cifs_build_path_to_root()

This function is called from:
    - cifs_mount()
    - cifs_get_root()

The later expects a full path from the root, even in the presence of
a DFS link.

e.g. in the case of a DFS link like

    //A/shareA/link -> //B/shareB/sub/dir/

When doing a "cd link", cifs_get_root() was getting

    "//B/shareB//sub/dir"

Instead of

    "/sub/dir"

Resulting in

    sh: cd: link: No such file or directory

Thanks to Josef Cejka <jcejka@suse.com> for finding the bug&fix.

Reported-by: Fons Jongh <fons.dejongh@microfocus.com>
Signed-off-by: Aurelien Aptel <aaptel@suse.com>
---
 fs/cifs/dir.c | 23 ++++-------------------
 1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index fb0903f..05f7480 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -49,31 +49,16 @@  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) + 1 : 0;
-	int dfsplen;
+	int pplen = vol->prepath ? strlen(vol->prepath) : 0;
 	char *full_path = NULL;
 
-	/* if no prefix path, simply set path to the root of share to "" */
-	if (pplen == 0) {
-		full_path = kzalloc(1, GFP_KERNEL);
-		return full_path;
-	}
-
-	if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
-		dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
-	else
-		dfsplen = 0;
-
-	full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
+	full_path = kmalloc(pplen + 1, GFP_KERNEL);
 	if (full_path == NULL)
 		return full_path;
 
-	if (dfsplen)
-		strncpy(full_path, tcon->treeName, dfsplen);
-	full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb);
-	strncpy(full_path + dfsplen + 1, vol->prepath, pplen);
+	strncpy(full_path, vol->prepath, pplen);
 	convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
-	full_path[dfsplen + pplen] = 0; /* add trailing null */
+	full_path[pplen] = 0; /* add trailing null */
 	return full_path;
 }
 
-- 
2.1.4