]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
cifs: fix missing spinlock around update to ses->status
authorSteve French <stfrench@microsoft.com>
Thu, 24 Jun 2021 20:28:04 +0000 (15:28 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 14 Jul 2021 14:56:01 +0000 (16:56 +0200)
[ Upstream commit 0060a4f28a9ef45ae8163c0805e944a2b1546762 ]

In the other places where we update ses->status we protect the
updates via GlobalMid_Lock. So to be consistent add the same
locking around it in cifs_put_smb_ses where it was missing.

Addresses-Coverity: 1268904 ("Data race condition")
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/cifs/cifsglob.h
fs/cifs/connect.c

index 248ee81e015164b0e1a2595af31463e7223fdabd..6599069be690ebe6d507a3ba9119dc8306e0bb31 100644 (file)
@@ -979,7 +979,7 @@ struct cifs_ses {
        struct mutex session_mutex;
        struct TCP_Server_Info *server; /* pointer to server info */
        int ses_count;          /* reference counter */
-       enum statusEnum status;
+       enum statusEnum status;  /* updates protected by GlobalMid_Lock */
        unsigned overrideSecFlg;  /* if non-zero override global sec flags */
        char *serverOS;         /* name of operating system underlying server */
        char *serverNOS;        /* name of network operating system of server */
@@ -1863,6 +1863,7 @@ require use of the stronger protocol */
  *     list operations on pending_mid_q and oplockQ
  *      updates to XID counters, multiplex id  and SMB sequence numbers
  *      list operations on global DnotifyReqList
+ *      updates to ses->status
  *  tcp_ses_lock protects:
  *     list operations on tcp and SMB session lists
  *  tcon->open_file_lock protects the list of open files hanging off the tcon
index aabaebd1535f0bfc821f5abbaa3336625cb7ec8c..fb7088d57e46f9e7678857505233f4f802d797bb 100644 (file)
@@ -2829,9 +2829,12 @@ void cifs_put_smb_ses(struct cifs_ses *ses)
                spin_unlock(&cifs_tcp_ses_lock);
                return;
        }
+       spin_unlock(&cifs_tcp_ses_lock);
+
+       spin_lock(&GlobalMid_Lock);
        if (ses->status == CifsGood)
                ses->status = CifsExiting;
-       spin_unlock(&cifs_tcp_ses_lock);
+       spin_unlock(&GlobalMid_Lock);
 
        cifs_free_ipc(ses);