Commit 4f5c10f1 authored by Steve French's avatar Steve French

smb3: allow skipping signature verification for perf sensitive configurations

Add new mount option "signloosely" which enables signing but skips the
sometimes expensive signing checks in the responses (signatures are
calculated and sent correctly in the SMB2/SMB3 requests even with this
mount option but skipped in the responses).  Although weaker for security
(and also data integrity in case a packet were corrupted), this can provide
enough of a performance benefit (calculating the signature to verify a
packet can be expensive especially for large packets) to be useful in
some cases.
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
Reviewed-by: default avatarRonnie Sahlberg <lsahlber@redhat.com>
parent f90f9797
...@@ -542,6 +542,7 @@ struct smb_vol { ...@@ -542,6 +542,7 @@ struct smb_vol {
umode_t dir_mode; umode_t dir_mode;
enum securityEnum sectype; /* sectype requested via mnt opts */ enum securityEnum sectype; /* sectype requested via mnt opts */
bool sign; /* was signing requested via mnt opts? */ bool sign; /* was signing requested via mnt opts? */
bool ignore_signature:1;
bool retry:1; bool retry:1;
bool intr:1; bool intr:1;
bool setuids:1; bool setuids:1;
...@@ -681,6 +682,7 @@ struct TCP_Server_Info { ...@@ -681,6 +682,7 @@ struct TCP_Server_Info {
char server_GUID[16]; char server_GUID[16];
__u16 sec_mode; __u16 sec_mode;
bool sign; /* is signing enabled on this connection? */ 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 */ bool session_estab; /* mark when very first sess is established */
int echo_credits; /* echo reserved slots */ int echo_credits; /* echo reserved slots */
int oplock_credits; /* oplock break reserved slots */ int oplock_credits; /* oplock break reserved slots */
......
...@@ -91,7 +91,7 @@ enum { ...@@ -91,7 +91,7 @@ enum {
Opt_serverino, Opt_noserverino, Opt_serverino, Opt_noserverino,
Opt_rwpidforward, Opt_cifsacl, Opt_nocifsacl, Opt_rwpidforward, Opt_cifsacl, Opt_nocifsacl,
Opt_acl, Opt_noacl, Opt_locallease, 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_fsc, Opt_mfsymlinks,
Opt_multiuser, Opt_sloppy, Opt_nosharesock, Opt_multiuser, Opt_sloppy, Opt_nosharesock,
Opt_persistent, Opt_nopersistent, Opt_persistent, Opt_nopersistent,
...@@ -183,6 +183,7 @@ static const match_table_t cifs_mount_option_tokens = { ...@@ -183,6 +183,7 @@ static const match_table_t cifs_mount_option_tokens = {
{ Opt_noacl, "noacl" }, { Opt_noacl, "noacl" },
{ Opt_locallease, "locallease" }, { Opt_locallease, "locallease" },
{ Opt_sign, "sign" }, { Opt_sign, "sign" },
{ Opt_ignore_signature, "signloosely" },
{ Opt_seal, "seal" }, { Opt_seal, "seal" },
{ Opt_noac, "noac" }, { Opt_noac, "noac" },
{ Opt_fsc, "fsc" }, { Opt_fsc, "fsc" },
...@@ -1877,6 +1878,10 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, ...@@ -1877,6 +1878,10 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
case Opt_sign: case Opt_sign:
vol->sign = true; vol->sign = true;
break; break;
case Opt_ignore_signature:
vol->sign = true;
vol->ignore_signature = true;
break;
case Opt_seal: case Opt_seal:
/* we do not do the following in secFlags because seal /* we do not do the following in secFlags because seal
* is a per tree connection (mount) not a per socket * 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) ...@@ -2608,6 +2613,9 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
if (server->rdma != vol->rdma) if (server->rdma != vol->rdma)
return 0; return 0;
if (server->ignore_signature != vol->ignore_signature)
return 0;
return 1; return 1;
} }
...@@ -2785,7 +2793,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) ...@@ -2785,7 +2793,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
tcp_ses->tcpStatus = CifsNeedNegotiate; tcp_ses->tcpStatus = CifsNeedNegotiate;
tcp_ses->nr_targets = 1; tcp_ses->nr_targets = 1;
tcp_ses->ignore_signature = volume_info->ignore_signature;
/* thread spawned, put it on the list */ /* thread spawned, put it on the list */
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); 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) ...@@ -3235,7 +3243,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
ses->sectype = volume_info->sectype; ses->sectype = volume_info->sectype;
ses->sign = volume_info->sign; ses->sign = volume_info->sign;
mutex_lock(&ses->session_mutex); mutex_lock(&ses->session_mutex);
rc = cifs_negotiate_protocol(xid, ses); rc = cifs_negotiate_protocol(xid, ses);
if (!rc) if (!rc)
......
...@@ -522,6 +522,7 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) ...@@ -522,6 +522,7 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
if ((shdr->Command == SMB2_NEGOTIATE) || if ((shdr->Command == SMB2_NEGOTIATE) ||
(shdr->Command == SMB2_SESSION_SETUP) || (shdr->Command == SMB2_SESSION_SETUP) ||
(shdr->Command == SMB2_OPLOCK_BREAK) || (shdr->Command == SMB2_OPLOCK_BREAK) ||
server->ignore_signature ||
(!server->session_estab)) (!server->session_estab))
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment