diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index fa5abe3a8514..1f53dee211d8 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -542,6 +542,7 @@ struct smb_vol { umode_t dir_mode; enum securityEnum sectype; /* sectype requested via mnt opts */ bool sign; /* was signing requested via mnt opts? */ + bool ignore_signature:1; bool retry:1; bool intr:1; bool setuids:1; @@ -681,6 +682,7 @@ struct TCP_Server_Info { char server_GUID[16]; __u16 sec_mode; bool sign; /* is signing enabled on this connection? */ + bool ignore_signature:1; /* skip validation of signatures in SMB2/3 rsp */ bool session_estab; /* mark when very first sess is established */ int echo_credits; /* echo reserved slots */ int oplock_credits; /* oplock break reserved slots */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 85f8d943a05a..17882cede197 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -91,7 +91,7 @@ enum { Opt_serverino, Opt_noserverino, Opt_rwpidforward, Opt_cifsacl, Opt_nocifsacl, Opt_acl, Opt_noacl, Opt_locallease, - Opt_sign, Opt_seal, Opt_noac, + Opt_sign, Opt_ignore_signature, Opt_seal, Opt_noac, Opt_fsc, Opt_mfsymlinks, Opt_multiuser, Opt_sloppy, Opt_nosharesock, Opt_persistent, Opt_nopersistent, @@ -183,6 +183,7 @@ static const match_table_t cifs_mount_option_tokens = { { Opt_noacl, "noacl" }, { Opt_locallease, "locallease" }, { Opt_sign, "sign" }, + { Opt_ignore_signature, "signloosely" }, { Opt_seal, "seal" }, { Opt_noac, "noac" }, { Opt_fsc, "fsc" }, @@ -1877,6 +1878,10 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, case Opt_sign: vol->sign = true; break; + case Opt_ignore_signature: + vol->sign = true; + vol->ignore_signature = true; + break; case Opt_seal: /* we do not do the following in secFlags because seal * is a per tree connection (mount) not a per socket @@ -2608,6 +2613,9 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol) if (server->rdma != vol->rdma) return 0; + if (server->ignore_signature != vol->ignore_signature) + return 0; + return 1; } @@ -2785,7 +2793,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) tcp_ses->tcpStatus = CifsNeedNegotiate; tcp_ses->nr_targets = 1; - + tcp_ses->ignore_signature = volume_info->ignore_signature; /* thread spawned, put it on the list */ spin_lock(&cifs_tcp_ses_lock); list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); @@ -3235,7 +3243,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) ses->sectype = volume_info->sectype; ses->sign = volume_info->sign; - mutex_lock(&ses->session_mutex); rc = cifs_negotiate_protocol(xid, ses); if (!rc) diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index b02242eacb55..148d7942c796 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c @@ -522,6 +522,7 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) if ((shdr->Command == SMB2_NEGOTIATE) || (shdr->Command == SMB2_SESSION_SETUP) || (shdr->Command == SMB2_OPLOCK_BREAK) || + server->ignore_signature || (!server->session_estab)) return 0;