Commit ff8abbd2 authored by Paulo Alcantara's avatar Paulo Alcantara Committed by Steve French
Browse files

smb: client: fix regression with native SMB symlinks



Some users and customers reported that their backup/copy tools started
to fail when the directory being copied contained symlink targets that
the client couldn't parse - even when those symlinks weren't followed.

Fix this by allowing lstat(2) and readlink(2) to succeed even when the
client can't resolve the symlink target, restoring old behavior.

Cc: linux-cifs@vger.kernel.org
Cc: stable@vger.kernel.org
Reported-by: default avatarRemy Monsen <monsen@monsen.cc>
Closes: https://lore.kernel.org/r/CAN+tdP7y=jqw3pBndZAGjQv0ObFq8Q=+PUDHgB36HdEz9QA6FQ@mail.gmail.com


Reported-by: default avatarPierguido Lambri <plambri@redhat.com>
Fixes: 12b466eb ("cifs: Fix creating and resolving absolute NT-style symlinks")
Signed-off-by: default avatarPaulo Alcantara (Red Hat) <pc@manguebit.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 86731a2a
Loading
Loading
Loading
Loading
+4 −16
Original line number Diff line number Diff line
@@ -875,15 +875,8 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
			abs_path += sizeof("\\DosDevices\\")-1;
		else if (strstarts(abs_path, "\\GLOBAL??\\"))
			abs_path += sizeof("\\GLOBAL??\\")-1;
		else {
			/* Unhandled absolute symlink, points outside of DOS/Win32 */
			cifs_dbg(VFS,
				 "absolute symlink '%s' cannot be converted from NT format "
				 "because points to unknown target\n",
				 smb_target);
			rc = -EIO;
			goto out;
		}
		else
			goto out_unhandled_target;

		/* Sometimes path separator after \?? is double backslash */
		if (abs_path[0] == '\\')
@@ -910,13 +903,7 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
			abs_path++;
			abs_path[0] = drive_letter;
		} else {
			/* Unhandled absolute symlink. Report an error. */
			cifs_dbg(VFS,
				 "absolute symlink '%s' cannot be converted from NT format "
				 "because points to unknown target\n",
				 smb_target);
			rc = -EIO;
			goto out;
			goto out_unhandled_target;
		}

		abs_path_len = strlen(abs_path)+1;
@@ -966,6 +953,7 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
		 * These paths have same format as Linux symlinks, so no
		 * conversion is needed.
		 */
out_unhandled_target:
		linux_target = smb_target;
		smb_target = NULL;
	}