]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
cifs: make locking consistent around the server session status
authorSteve French <stfrench@microsoft.com>
Thu, 1 Jul 2021 17:22:47 +0000 (12:22 -0500)
committerSteve French <stfrench@microsoft.com>
Fri, 2 Jul 2021 23:35:25 +0000 (18:35 -0500)
There were three places where we were not taking the spinlock
around updates to server->tcpStatus when it was being modified.
To be consistent (also removes Coverity warning) and to remove
possibility of race best to lock all places where it is updated.
Two of the three were in initialization of the field and can't
race - but added lock around the other.

Addresses-Coverity: 1399512 ("Data race condition")
Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/transport.c

index 3100f8b66e60f06d0b7a24b809e992f7b040be0d..921680fb7931475c47b9d3b5371427ba4c74434c 100644 (file)
@@ -577,6 +577,7 @@ struct TCP_Server_Info {
        char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
        struct smb_version_operations   *ops;
        struct smb_version_values       *vals;
+       /* updates to tcpStatus protected by GlobalMid_Lock */
        enum statusEnum tcpStatus; /* what we think the status is */
        char *hostname; /* hostname portion of UNC string */
        struct socket *ssocket;
@@ -1785,7 +1786,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
+ *      updates to ses->status and TCP_Server_Info->tcpStatus
  *      updates to server->CurrentMid
  *  tcp_ses_lock protects:
  *     list operations on tcp and SMB session lists
index 5d269f583dac4bddda3179b45255419674fbe85d..01dc45178f66122d6305c85a089fa335098badb4 100644 (file)
@@ -1403,6 +1403,11 @@ smbd_connected:
                goto out_err_crypto_release;
        }
        tcp_ses->min_offload = ctx->min_offload;
+       /*
+        * at this point we are the only ones with the pointer
+        * to the struct since the kernel thread not created yet
+        * no need to spinlock this update of tcpStatus
+        */
        tcp_ses->tcpStatus = CifsNeedNegotiate;
 
        if ((ctx->max_credits < 20) || (ctx->max_credits > 60000))
index f65f9a692ca244a22593964aca0e708773b25914..75a95de320cfe2353848906378604cf8230a38e0 100644 (file)
@@ -431,7 +431,9 @@ unmask:
                 * be taken as the remainder of this one. We need to kill the
                 * socket so the server throws away the partial SMB
                 */
+               spin_lock(&GlobalMid_Lock);
                server->tcpStatus = CifsNeedReconnect;
+               spin_unlock(&GlobalMid_Lock);
                trace_smb3_partial_send_reconnect(server->CurrentMid,
                                                  server->conn_id, server->hostname);
        }