smb3: allow skipping signature verification for perf sensitive configurations
authorSteve French <stfrench@microsoft.com>
Wed, 4 Sep 2019 02:18:49 +0000 (21:18 -0500)
committerSteve French <stfrench@microsoft.com>
Mon, 16 Sep 2019 16:43:38 +0000 (11:43 -0500)
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: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/smb2transport.c

index fa5abe3..1f53dee 100644 (file)
@@ -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 */
index 85f8d94..17882ce 100644 (file)
@@ -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 @@ smbd_connected:
        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)
index b02242e..148d794 100644 (file)
@@ -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;