public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] smb: client: fix dir separator in SMB1 UNIX mounts
@ 2026-04-17  0:15 Paulo Alcantara
  2026-04-17  1:37 ` Steve French
  0 siblings, 1 reply; 2+ messages in thread
From: Paulo Alcantara @ 2026-04-17  0:15 UTC (permalink / raw)
  To: Steve French
  Cc: Kris Karas (Bug Reporting), Paulo Alcantara (Red Hat),
	David Howells, linux-cifs, stable

When calling cifs_mount_get_tcon() with SMB1 UNIX mounts,
@cifs_sb->mnt_cifs_flags needs to be read or updated only after
calling reset_cifs_unix_caps(), otherwise it might end up with missing
CIFS_MOUNT_POSIXACL and CIFS_MOUNT_POSIX_PATHS bits.

This fixes the wrong dir separator used in paths caused by the missing
CIFS_MOUNT_POSIX_PATHS bit in cifs_sb_info::mnt_cifs_flags.

Reported-by: "Kris Karas (Bug Reporting)" <bugs-a21@moonlit-rail.com>
Closes: https://lore.kernel.org/r/f758f4ff-4d54-4244-931d-38f469c3ff14@moonlit-rail.com
Fixes: 4fc3a433c139 ("smb: client: use atomic_t for mnt_cifs_flags")
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
Cc: David Howells <dhowells@redhat.com>
Cc: linux-cifs@vger.kernel.org
Cc: stable@vger.kernel.org
---
 fs/smb/client/connect.c | 10 +++++-----
 fs/smb/client/smb1ops.c | 19 ++++++++-----------
 2 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 69b38f0ccf2b..e9eeb9f8a561 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -3610,7 +3610,6 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
 	server = mnt_ctx->server;
 	ctx = mnt_ctx->fs_ctx;
 	cifs_sb = mnt_ctx->cifs_sb;
-	sbflags = cifs_sb_flags(cifs_sb);
 
 	/* search for existing tcon to this server share */
 	tcon = cifs_get_tcon(mnt_ctx->ses, ctx);
@@ -3625,9 +3624,10 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
 	 * path (i.e., do not remap / and \ and do not map any special characters)
 	 */
 	if (tcon->posix_extensions) {
-		sbflags |= CIFS_MOUNT_POSIX_PATHS;
-		sbflags &= ~(CIFS_MOUNT_MAP_SFM_CHR |
-			     CIFS_MOUNT_MAP_SPECIAL_CHR);
+		atomic_or(CIFS_MOUNT_POSIX_PATHS, &cifs_sb->mnt_cifs_flags);
+		atomic_andnot(CIFS_MOUNT_MAP_SFM_CHR |
+			      CIFS_MOUNT_MAP_SPECIAL_CHR,
+			      &cifs_sb->mnt_cifs_flags);
 	}
 
 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
@@ -3651,6 +3651,7 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
 		tcon->unix_ext = 0; /* server does not support them */
 
+	sbflags = cifs_sb_flags(cifs_sb);
 	/* do not care if a following call succeed - informational */
 	if (!tcon->pipe && server->ops->qfs_tcon) {
 		server->ops->qfs_tcon(mnt_ctx->xid, tcon, cifs_sb);
@@ -3675,7 +3676,6 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
 
 out:
 	mnt_ctx->tcon = tcon;
-	atomic_set(&cifs_sb->mnt_cifs_flags, sbflags);
 	return rc;
 }
 
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index 9694117050a6..e198e3dda917 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -49,7 +49,6 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
 
 	if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
 		__u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
-		unsigned int sbflags;
 
 		cifs_dbg(FYI, "unix caps which server supports %lld\n", cap);
 		/*
@@ -76,29 +75,27 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
 		if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
 			cifs_dbg(VFS, "per-share encryption not supported yet\n");
 
-		if (cifs_sb)
-			sbflags = cifs_sb_flags(cifs_sb);
-
 		cap &= CIFS_UNIX_CAP_MASK;
 		if (ctx && ctx->no_psx_acl)
 			cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
 		else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
 			cifs_dbg(FYI, "negotiated posix acl support\n");
-			if (cifs_sb)
-				sbflags |= CIFS_MOUNT_POSIXACL;
+			if (cifs_sb) {
+				atomic_or(CIFS_MOUNT_POSIXACL,
+					  &cifs_sb->mnt_cifs_flags);
+			}
 		}
 
 		if (ctx && ctx->posix_paths == 0)
 			cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
 		else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
 			cifs_dbg(FYI, "negotiate posix pathnames\n");
-			if (cifs_sb)
-				sbflags |= CIFS_MOUNT_POSIX_PATHS;
+			if (cifs_sb) {
+				atomic_or(CIFS_MOUNT_POSIX_PATHS,
+					  &cifs_sb->mnt_cifs_flags);
+			}
 		}
 
-		if (cifs_sb)
-			atomic_set(&cifs_sb->mnt_cifs_flags, sbflags);
-
 		cifs_dbg(FYI, "Negotiate caps 0x%x\n", (int)cap);
 #ifdef CONFIG_CIFS_DEBUG2
 		if (cap & CIFS_UNIX_FCNTL_CAP)
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] smb: client: fix dir separator in SMB1 UNIX mounts
  2026-04-17  0:15 [PATCH] smb: client: fix dir separator in SMB1 UNIX mounts Paulo Alcantara
@ 2026-04-17  1:37 ` Steve French
  0 siblings, 0 replies; 2+ messages in thread
From: Steve French @ 2026-04-17  1:37 UTC (permalink / raw)
  To: Paulo Alcantara
  Cc: Kris Karas (Bug Reporting), David Howells, linux-cifs, stable

merged into cifs-2.6.git for-next

On Thu, Apr 16, 2026 at 7:15 PM Paulo Alcantara <pc@manguebit.org> wrote:
>
> When calling cifs_mount_get_tcon() with SMB1 UNIX mounts,
> @cifs_sb->mnt_cifs_flags needs to be read or updated only after
> calling reset_cifs_unix_caps(), otherwise it might end up with missing
> CIFS_MOUNT_POSIXACL and CIFS_MOUNT_POSIX_PATHS bits.
>
> This fixes the wrong dir separator used in paths caused by the missing
> CIFS_MOUNT_POSIX_PATHS bit in cifs_sb_info::mnt_cifs_flags.
>
> Reported-by: "Kris Karas (Bug Reporting)" <bugs-a21@moonlit-rail.com>
> Closes: https://lore.kernel.org/r/f758f4ff-4d54-4244-931d-38f469c3ff14@moonlit-rail.com
> Fixes: 4fc3a433c139 ("smb: client: use atomic_t for mnt_cifs_flags")
> Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
> Cc: David Howells <dhowells@redhat.com>
> Cc: linux-cifs@vger.kernel.org
> Cc: stable@vger.kernel.org
> ---
>  fs/smb/client/connect.c | 10 +++++-----
>  fs/smb/client/smb1ops.c | 19 ++++++++-----------
>  2 files changed, 13 insertions(+), 16 deletions(-)
>
> diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
> index 69b38f0ccf2b..e9eeb9f8a561 100644
> --- a/fs/smb/client/connect.c
> +++ b/fs/smb/client/connect.c
> @@ -3610,7 +3610,6 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
>         server = mnt_ctx->server;
>         ctx = mnt_ctx->fs_ctx;
>         cifs_sb = mnt_ctx->cifs_sb;
> -       sbflags = cifs_sb_flags(cifs_sb);
>
>         /* search for existing tcon to this server share */
>         tcon = cifs_get_tcon(mnt_ctx->ses, ctx);
> @@ -3625,9 +3624,10 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
>          * path (i.e., do not remap / and \ and do not map any special characters)
>          */
>         if (tcon->posix_extensions) {
> -               sbflags |= CIFS_MOUNT_POSIX_PATHS;
> -               sbflags &= ~(CIFS_MOUNT_MAP_SFM_CHR |
> -                            CIFS_MOUNT_MAP_SPECIAL_CHR);
> +               atomic_or(CIFS_MOUNT_POSIX_PATHS, &cifs_sb->mnt_cifs_flags);
> +               atomic_andnot(CIFS_MOUNT_MAP_SFM_CHR |
> +                             CIFS_MOUNT_MAP_SPECIAL_CHR,
> +                             &cifs_sb->mnt_cifs_flags);
>         }
>
>  #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
> @@ -3651,6 +3651,7 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
>  #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
>                 tcon->unix_ext = 0; /* server does not support them */
>
> +       sbflags = cifs_sb_flags(cifs_sb);
>         /* do not care if a following call succeed - informational */
>         if (!tcon->pipe && server->ops->qfs_tcon) {
>                 server->ops->qfs_tcon(mnt_ctx->xid, tcon, cifs_sb);
> @@ -3675,7 +3676,6 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
>
>  out:
>         mnt_ctx->tcon = tcon;
> -       atomic_set(&cifs_sb->mnt_cifs_flags, sbflags);
>         return rc;
>  }
>
> diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
> index 9694117050a6..e198e3dda917 100644
> --- a/fs/smb/client/smb1ops.c
> +++ b/fs/smb/client/smb1ops.c
> @@ -49,7 +49,6 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
>
>         if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
>                 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
> -               unsigned int sbflags;
>
>                 cifs_dbg(FYI, "unix caps which server supports %lld\n", cap);
>                 /*
> @@ -76,29 +75,27 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
>                 if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
>                         cifs_dbg(VFS, "per-share encryption not supported yet\n");
>
> -               if (cifs_sb)
> -                       sbflags = cifs_sb_flags(cifs_sb);
> -
>                 cap &= CIFS_UNIX_CAP_MASK;
>                 if (ctx && ctx->no_psx_acl)
>                         cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
>                 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
>                         cifs_dbg(FYI, "negotiated posix acl support\n");
> -                       if (cifs_sb)
> -                               sbflags |= CIFS_MOUNT_POSIXACL;
> +                       if (cifs_sb) {
> +                               atomic_or(CIFS_MOUNT_POSIXACL,
> +                                         &cifs_sb->mnt_cifs_flags);
> +                       }
>                 }
>
>                 if (ctx && ctx->posix_paths == 0)
>                         cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
>                 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
>                         cifs_dbg(FYI, "negotiate posix pathnames\n");
> -                       if (cifs_sb)
> -                               sbflags |= CIFS_MOUNT_POSIX_PATHS;
> +                       if (cifs_sb) {
> +                               atomic_or(CIFS_MOUNT_POSIX_PATHS,
> +                                         &cifs_sb->mnt_cifs_flags);
> +                       }
>                 }
>
> -               if (cifs_sb)
> -                       atomic_set(&cifs_sb->mnt_cifs_flags, sbflags);
> -
>                 cifs_dbg(FYI, "Negotiate caps 0x%x\n", (int)cap);
>  #ifdef CONFIG_CIFS_DEBUG2
>                 if (cap & CIFS_UNIX_FCNTL_CAP)
> --
> 2.53.0
>


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-04-17  1:37 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-17  0:15 [PATCH] smb: client: fix dir separator in SMB1 UNIX mounts Paulo Alcantara
2026-04-17  1:37 ` Steve French

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox