Skip to content

Commit c4d3fc5

Browse files
pcacjrsmfrench
authored andcommitted
smb: client: fix dir separator in SMB1 UNIX mounts
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: 4fc3a43 ("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 Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 0b2f2b1 commit c4d3fc5

2 files changed

Lines changed: 13 additions & 16 deletions

File tree

fs/smb/client/connect.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3609,7 +3609,6 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
36093609
server = mnt_ctx->server;
36103610
ctx = mnt_ctx->fs_ctx;
36113611
cifs_sb = mnt_ctx->cifs_sb;
3612-
sbflags = cifs_sb_flags(cifs_sb);
36133612

36143613
/* search for existing tcon to this server share */
36153614
tcon = cifs_get_tcon(mnt_ctx->ses, ctx);
@@ -3624,9 +3623,10 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
36243623
* path (i.e., do not remap / and \ and do not map any special characters)
36253624
*/
36263625
if (tcon->posix_extensions) {
3627-
sbflags |= CIFS_MOUNT_POSIX_PATHS;
3628-
sbflags &= ~(CIFS_MOUNT_MAP_SFM_CHR |
3629-
CIFS_MOUNT_MAP_SPECIAL_CHR);
3626+
atomic_or(CIFS_MOUNT_POSIX_PATHS, &cifs_sb->mnt_cifs_flags);
3627+
atomic_andnot(CIFS_MOUNT_MAP_SFM_CHR |
3628+
CIFS_MOUNT_MAP_SPECIAL_CHR,
3629+
&cifs_sb->mnt_cifs_flags);
36303630
}
36313631

36323632
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
@@ -3650,6 +3650,7 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
36503650
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
36513651
tcon->unix_ext = 0; /* server does not support them */
36523652

3653+
sbflags = cifs_sb_flags(cifs_sb);
36533654
/* do not care if a following call succeed - informational */
36543655
if (!tcon->pipe && server->ops->qfs_tcon) {
36553656
server->ops->qfs_tcon(mnt_ctx->xid, tcon, cifs_sb);
@@ -3674,7 +3675,6 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
36743675

36753676
out:
36763677
mnt_ctx->tcon = tcon;
3677-
atomic_set(&cifs_sb->mnt_cifs_flags, sbflags);
36783678
return rc;
36793679
}
36803680

fs/smb/client/smb1ops.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
4949

5050
if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
5151
__u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
52-
unsigned int sbflags;
5352

5453
cifs_dbg(FYI, "unix caps which server supports %lld\n", cap);
5554
/*
@@ -76,29 +75,27 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
7675
if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
7776
cifs_dbg(VFS, "per-share encryption not supported yet\n");
7877

79-
if (cifs_sb)
80-
sbflags = cifs_sb_flags(cifs_sb);
81-
8278
cap &= CIFS_UNIX_CAP_MASK;
8379
if (ctx && ctx->no_psx_acl)
8480
cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
8581
else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
8682
cifs_dbg(FYI, "negotiated posix acl support\n");
87-
if (cifs_sb)
88-
sbflags |= CIFS_MOUNT_POSIXACL;
83+
if (cifs_sb) {
84+
atomic_or(CIFS_MOUNT_POSIXACL,
85+
&cifs_sb->mnt_cifs_flags);
86+
}
8987
}
9088

9189
if (ctx && ctx->posix_paths == 0)
9290
cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
9391
else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
9492
cifs_dbg(FYI, "negotiate posix pathnames\n");
95-
if (cifs_sb)
96-
sbflags |= CIFS_MOUNT_POSIX_PATHS;
93+
if (cifs_sb) {
94+
atomic_or(CIFS_MOUNT_POSIX_PATHS,
95+
&cifs_sb->mnt_cifs_flags);
96+
}
9797
}
9898

99-
if (cifs_sb)
100-
atomic_set(&cifs_sb->mnt_cifs_flags, sbflags);
101-
10299
cifs_dbg(FYI, "Negotiate caps 0x%x\n", (int)cap);
103100
#ifdef CONFIG_CIFS_DEBUG2
104101
if (cap & CIFS_UNIX_FCNTL_CAP)

0 commit comments

Comments
 (0)