Re: [PATCH v2] smb: client: preserve leading slash for POSIX absolute symlink targets

Ralph Boehme <[email protected]>
Newsgroups org.kernel.vger.linux-cifs
Message-ID <[email protected]>
acked

On 7/5/26 11:17 PM, Steve French wrote:
> When creating a native SMB symbolic link (CIFS_SYMLINK_TYPE_NATIVE) whose
> target is an absolute path on a mount that uses POSIX paths, the leading
> path separator was silently dropped from the stored symlink target.
> 
> create_native_symlink() converted the target to UTF-16 with
> cifs_convert_path_to_utf16().  That helper is intended for share-relative
> SMB paths and therefore unconditionally strips a leading path separator.
> For an absolute POSIX symlink target the leading '/' is significant, so a
> target of "/foo/bar" was stored - and read back - as "foo/bar", even
> though the reparse point was still flagged as absolute
> (SYMLINK_FLAG_RELATIVE cleared).
> 
> On a POSIX paths mount the symlink target is stored verbatim, so convert
> it directly with cifs_strndup_to_utf16() instead.  This preserves the
> leading separator, avoids the leading-backslash stripping that
> cifs_convert_path_to_utf16() also performs (a backslash is a valid POSIX
> filename character), and uses NO_MAP_UNI_RSVD to match the readback path
> in smb2_parse_native_symlink(), which always converts the target with
> cifs_strndup_from_utf16() / NO_MAP_UNI_RSVD.  This mirrors how the NFS and
> WSL reparse symlink creators convert their targets.
> 
> The NT-style absolute symlink handling, which needs the "\??\" prefix and
> drive-letter colon preserved, continues to use cifs_convert_path_to_utf16()
> together with the existing masking of those bytes.
> 
> Fixes: 12b466eb52d9 ("cifs: Fix creating and resolving absolute NT-style symlinks")
> Signed-off-by: Steve French <[email protected]>
> ---
>   fs/smb/client/reparse.c | 17 ++++++++++++++++-
>   1 file changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c
> index cd1e1eaee67a..5cc5b0410d48 100644
> --- a/fs/smb/client/reparse.c
> +++ b/fs/smb/client/reparse.c
> @@ -67,6 +67,7 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode,
>   	char *sym = NULL;
>   	struct kvec iov;
>   	bool directory;
> +	int path_len;
>   	int rc = 0;
>   
>   	if (strlen(symname) > REPARSE_SYM_PATH_MAX)
> @@ -168,7 +169,21 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode,
>   	if (!(sbflags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/')
>   		sym[0] = sym[1] = sym[2] = sym[5] = '_';
>   
> -	path = cifs_convert_path_to_utf16(sym, cifs_sb);
> +	/*
> +	 * On a POSIX paths mount the symlink target is stored verbatim, so
> +	 * convert it with cifs_strndup_to_utf16().  cifs_convert_path_to_utf16()
> +	 * must not be used here: it strips a leading path separator (it is
> +	 * meant for share-relative SMB paths), which would corrupt an absolute
> +	 * POSIX symlink target such as "/foo/bar".  Using NO_MAP_UNI_RSVD also
> +	 * matches the readback path in smb2_parse_native_symlink().
> +	 */
> +	if (sbflags & CIFS_MOUNT_POSIX_PATHS)
> +		path = cifs_strndup_to_utf16(sym, strlen(sym), &path_len,
> +					     cifs_sb->local_nls,
> +					     NO_MAP_UNI_RSVD);
> +	else
> +		path = cifs_convert_path_to_utf16(sym, cifs_sb);
> +
>   	if (!path) {
>   		rc = -ENOMEM;
>   		goto out;
OpenPGP_signature.asc (application/pgp-signature, 840 B)
-----BEGIN PGP SIGNATURE-----

wsF5BAABCAAjFiEE+uLGCIokJSBRxVnkqh6bcSY5nkYFAmpLOlwFAwAAAAAACgkQqh6bcSY5nkZH
aA//QcuR9EfUxuuL+BoO/SsCVYM49mJFGsNVELT5UmrbY+5Td7MFbIJ5qys7cbK8GPMc2e/rG3EH
tdTbjQsTpGNIq83RQQ8isi/tlMBbREzOCC9ASD6fqpw0DAz/5kGkY9jvZJFzkWaL3UNAJ2BQ8HBg
/G/smHzaSVmnGQqQNEBnIeCEISZW+OFH93BrxxF9pZBHGMzW2RcQXuAZCDigLWXtPAp3f5jeC8EI
q2QZVy8VuEsy5I53IM6dIn8HuwXk7oOtEwURzNoLkpMI0sSNcUCYAa6UcPl0b+IInAOOaWh2iPj2
8qPN0u6GEnVM21eX6HBBMGm1DBAOkG+ppn6Dgp6PTmcNwpYHsc29IqwBRsiuPb96HOGpcBJzLuWY
6HPMZEDsYPz0v6gdkMhiO7iBdWwip5DN0Rs9/1HqxEECroUXUNuqfG/9RHH8V4CA/gDmasHAeBIl
ISzUY/hlgpZ28hGXqVgKwGjUsY25EMgGojBBCJQMdEpKPs4+QzNnxUFmt0m4WLoiQdAZcNcP9AW7
IqQOiUlcjmUN2AtTaLKtW4jrHymJMoqTF1bVL2r1BeKnK0I8gFNL77qW8IXtfbdFgI883+79IdiK
nEiviZjI5ERM8tsnGcMlPv4x6y2SYEfHhQFwrWZdbOmUCkaeL6Ox76Frdf9SaxCZMW0jSYE61jRT
1kc=
=ZVrV
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.