]> www.infradead.org Git - users/dwmw2/linux.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:53:19 +0000 (16:53 +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 b16c994414ab0ab301bcc32b8f4e58f46a5e3057..9c0e348cb00f7f4e29d23c965921d84d255464f6 100644 (file)
@@ -964,7 +964,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 */
@@ -1814,6 +1814,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 ab9eeb5ff8e5745453ff77c8475fbad4755ef8c2..da0720f41ebcbc70062bafff127bd5d932982273 100644 (file)
@@ -3049,9 +3049,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);