summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrique Carvalho <henrique.carvalho@suse.com>2025-03-11 15:23:59 -0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-03-22 12:50:49 -0700
commitfb0800cbea02e061f2e1b80d218f12b1381e36c2 (patch)
treeecd4c18b9f9fee57c51fc92188b0d44fbe765892
parent7dc9abfa00ab8d45190b1619ffb801858a1b6ab0 (diff)
downloadlinux-fb0800cbea02e061f2e1b80d218f12b1381e36c2.tar.gz
linux-fb0800cbea02e061f2e1b80d218f12b1381e36c2.tar.bz2
linux-fb0800cbea02e061f2e1b80d218f12b1381e36c2.zip
smb: client: Fix match_session bug preventing session reuse
[ Upstream commit 605b249ea96770ac4fac4b8510a99e0f8442be5e ] Fix a bug in match_session() that can causes the session to not be reused in some cases. Reproduction steps: mount.cifs //server/share /mnt/a -o credentials=creds mount.cifs //server/share /mnt/b -o credentials=creds,sec=ntlmssp cat /proc/fs/cifs/DebugData | grep SessionId | wc -l mount.cifs //server/share /mnt/b -o credentials=creds,sec=ntlmssp mount.cifs //server/share /mnt/a -o credentials=creds cat /proc/fs/cifs/DebugData | grep SessionId | wc -l Cc: stable@vger.kernel.org Reviewed-by: Enzo Matsumiya <ematsumiya@suse.de> Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--fs/smb/client/connect.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index dbcaaa274abd..198681d14153 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -1884,9 +1884,8 @@ out_err:
/* this function must be called with ses_lock and chan_lock held */
static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)
{
- if (ctx->sectype != Unspecified &&
- ctx->sectype != ses->sectype)
- return 0;
+ struct TCP_Server_Info *server = ses->server;
+ enum securityEnum ctx_sec, ses_sec;
if (ctx->dfs_root_ses != ses->dfs_root_ses)
return 0;
@@ -1898,11 +1897,20 @@ static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)
if (ses->chan_max < ctx->max_channels)
return 0;
- switch (ses->sectype) {
+ ctx_sec = server->ops->select_sectype(server, ctx->sectype);
+ ses_sec = server->ops->select_sectype(server, ses->sectype);
+
+ if (ctx_sec != ses_sec)
+ return 0;
+
+ switch (ctx_sec) {
+ case IAKerb:
case Kerberos:
if (!uid_eq(ctx->cred_uid, ses->cred_uid))
return 0;
break;
+ case NTLMv2:
+ case RawNTLMSSP:
default:
/* NULL username means anonymous session */
if (ses->user_name == NULL) {