Skip to content

Commit 2f4e429

Browse files
sprasad-microsoftsmfrench
authored andcommitted
cifs: lock chan_lock outside match_session
Coverity had rightly indicated a possible deadlock due to chan_lock being done inside match_session. All callers of match_* functions should pick up the necessary locks and call them. Signed-off-by: Shyam Prasad N <[email protected]> Reviewed-by: Paulo Alcantara (SUSE) <[email protected]> Cc: [email protected] Fixes: 724244c ("cifs: protect session channel fields with chan_lock") Signed-off-by: Steve French <[email protected]>
1 parent 2f0e4f0 commit 2f4e429

File tree

1 file changed

+7
-6
lines changed

1 file changed

+7
-6
lines changed

fs/cifs/connect.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,7 +1721,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
17211721
return ERR_PTR(rc);
17221722
}
17231723

1724-
/* this function must be called with ses_lock held */
1724+
/* this function must be called with ses_lock and chan_lock held */
17251725
static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)
17261726
{
17271727
if (ctx->sectype != Unspecified &&
@@ -1732,12 +1732,8 @@ static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)
17321732
* If an existing session is limited to less channels than
17331733
* requested, it should not be reused
17341734
*/
1735-
spin_lock(&ses->chan_lock);
1736-
if (ses->chan_max < ctx->max_channels) {
1737-
spin_unlock(&ses->chan_lock);
1735+
if (ses->chan_max < ctx->max_channels)
17381736
return 0;
1739-
}
1740-
spin_unlock(&ses->chan_lock);
17411737

17421738
switch (ses->sectype) {
17431739
case Kerberos:
@@ -1865,10 +1861,13 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
18651861
spin_unlock(&ses->ses_lock);
18661862
continue;
18671863
}
1864+
spin_lock(&ses->chan_lock);
18681865
if (!match_session(ses, ctx)) {
1866+
spin_unlock(&ses->chan_lock);
18691867
spin_unlock(&ses->ses_lock);
18701868
continue;
18711869
}
1870+
spin_unlock(&ses->chan_lock);
18721871
spin_unlock(&ses->ses_lock);
18731872

18741873
++ses->ses_count;
@@ -2693,6 +2692,7 @@ cifs_match_super(struct super_block *sb, void *data)
26932692

26942693
spin_lock(&tcp_srv->srv_lock);
26952694
spin_lock(&ses->ses_lock);
2695+
spin_lock(&ses->chan_lock);
26962696
spin_lock(&tcon->tc_lock);
26972697
if (!match_server(tcp_srv, ctx, dfs_super_cmp) ||
26982698
!match_session(ses, ctx) ||
@@ -2705,6 +2705,7 @@ cifs_match_super(struct super_block *sb, void *data)
27052705
rc = compare_mount_options(sb, mnt_data);
27062706
out:
27072707
spin_unlock(&tcon->tc_lock);
2708+
spin_unlock(&ses->chan_lock);
27082709
spin_unlock(&ses->ses_lock);
27092710
spin_unlock(&tcp_srv->srv_lock);
27102711

0 commit comments

Comments
 (0)