Merge tag '5.19-rc6-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 14 Jul 2022 19:35:15 +0000 (12:35 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 14 Jul 2022 19:35:15 +0000 (12:35 -0700)
Pull cifs fixes from Steve French:
 "Three smb3 client fixes:

   - two multichannel fixes: fix a potential deadlock freeing a channel,
     and fix a race condition on failed creation of a new channel

   - mount failure fix: work around a server bug in some common older
     Samba servers by avoiding padding at the end of the negotiate
     protocol request"

* tag '5.19-rc6-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  smb3: workaround negprot bug in some Samba servers
  cifs: remove unnecessary locking of chan_lock while freeing session
  cifs: fix race condition with delayed threads

fs/cifs/connect.c
fs/cifs/sess.c
fs/cifs/smb2pdu.c

index fa29c9a..386bb52 100644 (file)
@@ -1918,7 +1918,6 @@ void cifs_put_smb_ses(struct cifs_ses *ses)
        list_del_init(&ses->smb_ses_list);
        spin_unlock(&cifs_tcp_ses_lock);
 
-       spin_lock(&ses->chan_lock);
        chan_count = ses->chan_count;
 
        /* close any extra channels */
@@ -1934,7 +1933,6 @@ void cifs_put_smb_ses(struct cifs_ses *ses)
                        ses->chans[i].server = NULL;
                }
        }
-       spin_unlock(&ses->chan_lock);
 
        sesInfoFree(ses);
        cifs_put_tcp_session(server, 0);
index b85718f..02c8b29 100644 (file)
@@ -474,6 +474,14 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
 
 out:
        if (rc && chan->server) {
+               /*
+                * we should avoid race with these delayed works before we
+                * remove this channel
+                */
+               cancel_delayed_work_sync(&chan->server->echo);
+               cancel_delayed_work_sync(&chan->server->resolve);
+               cancel_delayed_work_sync(&chan->server->reconnect);
+
                spin_lock(&ses->chan_lock);
                /* we rely on all bits beyond chan_count to be clear */
                cifs_chan_clear_need_reconnect(ses, chan->server);
@@ -484,10 +492,9 @@ out:
                 */
                WARN_ON(ses->chan_count < 1);
                spin_unlock(&ses->chan_lock);
-       }
 
-       if (rc && chan->server)
                cifs_put_tcp_session(chan->server, 0);
+       }
 
        return rc;
 }
index 12b4ddd..c705de3 100644 (file)
@@ -571,10 +571,6 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
        *total_len += ctxt_len;
        pneg_ctxt += ctxt_len;
 
-       build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt);
-       *total_len += sizeof(struct smb2_posix_neg_context);
-       pneg_ctxt += sizeof(struct smb2_posix_neg_context);
-
        /*
         * secondary channels don't have the hostname field populated
         * use the hostname field in the primary channel instead
@@ -586,9 +582,14 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
                                              hostname);
                *total_len += ctxt_len;
                pneg_ctxt += ctxt_len;
-               neg_context_count = 4;
-       } else /* second channels do not have a hostname */
                neg_context_count = 3;
+       } else
+               neg_context_count = 2;
+
+       build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt);
+       *total_len += sizeof(struct smb2_posix_neg_context);
+       pneg_ctxt += sizeof(struct smb2_posix_neg_context);
+       neg_context_count++;
 
        if (server->compress_algorithm) {
                build_compression_ctxt((struct smb2_compression_capabilities_context *)