]> www.infradead.org Git - users/hch/dma-mapping.git/commitdiff
Revert "smb: client: make SHA-512 TFM ephemeral"
authorSteve French <stfrench@microsoft.com>
Tue, 1 Oct 2024 01:03:44 +0000 (20:03 -0500)
committerSteve French <stfrench@microsoft.com>
Tue, 1 Oct 2024 03:07:45 +0000 (22:07 -0500)
The original patch causes a crash with signed mounts when using
the SMB2.1 dialect

RIP: 0010:smb2_calc_signature+0x10e/0x460 [cifs]
Code: 46 30 00 00 00 00 49 c7 46 38 00 00 00 00 0f 85 3e 01 00 00 48 8b 83 a8 02 00 00 48 89 85 68 ff ff ff 49 8b b4 24 58 01 00 00 <48> 8b 38 ba 10 00 00 00 e8 55 0f 0c e0 41 89 c7 85 c0 0f 85 44 01
RSP: 0018:ffffb349422fb5c8 EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffff98028765b800 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff980200f2b100 RDI: 0000000000000000
RBP: ffffb349422fb680 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: ffff980235e37800
R13: ffffb349422fb900 R14: ffff98027c160700 R15: ffff98028765b820
FS:  000074139b98f780(0000) GS:ffff98097b980000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 000000011cb78006 CR4: 00000000003726f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 <TASK>
 ? show_regs+0x6c/0x80
 ? __die+0x24/0x80
 ? page_fault_oops+0x175/0x5c0
 ? hrtimer_try_to_cancel.part.0+0x55/0xf0
 ? do_user_addr_fault+0x4b2/0x870
 ? exc_page_fault+0x85/0x1c0
 ? asm_exc_page_fault+0x27/0x30
 ? smb2_calc_signature+0x10e/0x460 [cifs]
 ? smb2_calc_signature+0xa7/0x460 [cifs]
 ? kmem_cache_alloc_noprof+0x101/0x300
 smb2_sign_rqst+0xa2/0xe0 [cifs]
 smb2_setup_request+0x12d/0x240 [cifs]
 compound_send_recv+0x304/0x1220 [cifs]
 cifs_send_recv+0x22/0x40 [cifs]
 SMB2_tcon+0x2d9/0x8c0 [cifs]
 cifs_get_smb_ses+0x910/0xef0 [cifs]
 ? cifs_get_smb_ses+0x910/0xef0 [cifs]
 cifs_mount_get_session+0x6a/0x250 [cifs]

Reported-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Suggested-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
This reverts commit 220d83b52c7d16ec3c168b82f4e6ce59c645f7ab.

fs/smb/client/cifsencrypt.c
fs/smb/client/cifsglob.h
fs/smb/client/sess.c
fs/smb/client/smb2misc.c
fs/smb/client/smb2proto.h
fs/smb/client/smb2transport.c

index 2d851f596a727ef5e4b426944b99f1bb4474d184..464e6ccdfa5f8f9e6d181eda8397a81da303a6f1 100644 (file)
@@ -700,6 +700,7 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server)
        cifs_free_hash(&server->secmech.aes_cmac);
        cifs_free_hash(&server->secmech.hmacsha256);
        cifs_free_hash(&server->secmech.md5);
+       cifs_free_hash(&server->secmech.sha512);
 
        if (!SERVER_IS_CHAN(server)) {
                if (server->secmech.enc) {
index 315aac5dec0515930385353b72fbf597b71106b3..da35c160e7dd43a48bbc5586239e16c4016b3f01 100644 (file)
@@ -180,6 +180,7 @@ struct session_key {
 struct cifs_secmech {
        struct shash_desc *md5; /* md5 hash function, for CIFS/SMB1 signatures */
        struct shash_desc *hmacsha256; /* hmac-sha256 hash function, for SMB2 signatures */
+       struct shash_desc *sha512; /* sha512 hash function, for SMB3.1.1 preauth hash */
        struct shash_desc *aes_cmac; /* block-cipher based MAC function, for SMB3 signatures */
 
        struct crypto_aead *enc; /* smb3 encryption AEAD TFM (AES-CCM and AES-GCM) */
index 03c0b484a4b5ae289556934f53eea0b4fe2f5ef1..3216f786908fbb2ac8345cf5929fadf8ec6920d4 100644 (file)
@@ -624,7 +624,7 @@ cifs_ses_add_channel(struct cifs_ses *ses,
         * to sign packets before we generate the channel signing key
         * (we sign with the session key)
         */
-       rc = smb3_crypto_shash_allocate(chan->server);
+       rc = smb311_crypto_shash_allocate(chan->server);
        if (rc) {
                cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
                mutex_unlock(&ses->session_mutex);
index bdeb12ff53e3c0247a736e7b3aa9e03082395d76..f3c4b70b77b94f3797362ecc0fdb32608f87aea5 100644 (file)
@@ -906,41 +906,41 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server,
                || (hdr->Status !=
                    cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))))
                return 0;
+
 ok:
-       rc = cifs_alloc_hash("sha512", &sha512);
-       if (rc) {
-               cifs_dbg(VFS, "%s: Could not allocate SHA512 shash, rc=%d\n", __func__, rc);
+       rc = smb311_crypto_shash_allocate(server);
+       if (rc)
                return rc;
-       }
 
+       sha512 = server->secmech.sha512;
        rc = crypto_shash_init(sha512);
        if (rc) {
-               cifs_dbg(VFS, "%s: Could not init SHA512 shash, rc=%d\n", __func__, rc);
-               goto err_free;
+               cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__);
+               return rc;
        }
 
        rc = crypto_shash_update(sha512, ses->preauth_sha_hash,
                                 SMB2_PREAUTH_HASH_SIZE);
        if (rc) {
-               cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc);
-               goto err_free;
+               cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__);
+               return rc;
        }
 
        for (i = 0; i < nvec; i++) {
                rc = crypto_shash_update(sha512, iov[i].iov_base, iov[i].iov_len);
                if (rc) {
-                       cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc);
-                       goto err_free;
+                       cifs_dbg(VFS, "%s: Could not update sha512 shash\n",
+                                __func__);
+                       return rc;
                }
        }
 
        rc = crypto_shash_final(sha512, ses->preauth_sha_hash);
        if (rc) {
-               cifs_dbg(VFS, "%s: Could not finalize SHA12 shash, rc=%d\n", __func__, rc);
-               goto err_free;
+               cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n",
+                        __func__);
+               return rc;
        }
-err_free:
-       cifs_free_hash(&sha512);
 
        return 0;
 }
index 56a896ff7cd9f33e2e165f0d762358cf85fb0836..c7e1b149877a044df8a47569966dc34c59c183f3 100644 (file)
@@ -291,7 +291,7 @@ extern int smb2_validate_and_copy_iov(unsigned int offset,
 extern void smb2_copy_fs_info_to_kstatfs(
         struct smb2_fs_full_size_info *pfs_inf,
         struct kstatfs *kst);
-extern int smb3_crypto_shash_allocate(struct TCP_Server_Info *server);
+extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server);
 extern int smb311_update_preauth_hash(struct cifs_ses *ses,
                                      struct TCP_Server_Info *server,
                                      struct kvec *iov, int nvec);
index f7e04c40d22e0a5b9589d2e0a847bebcee77547e..c8bf0000f73bdcd4329efa90e655c2618637f450 100644 (file)
@@ -26,7 +26,8 @@
 #include "../common/smb2status.h"
 #include "smb2glob.h"
 
-int smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
+static int
+smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
 {
        struct cifs_secmech *p = &server->secmech;
        int rc;
@@ -45,6 +46,33 @@ err:
        return rc;
 }
 
+int
+smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
+{
+       struct cifs_secmech *p = &server->secmech;
+       int rc = 0;
+
+       rc = cifs_alloc_hash("hmac(sha256)", &p->hmacsha256);
+       if (rc)
+               return rc;
+
+       rc = cifs_alloc_hash("cmac(aes)", &p->aes_cmac);
+       if (rc)
+               goto err;
+
+       rc = cifs_alloc_hash("sha512", &p->sha512);
+       if (rc)
+               goto err;
+
+       return 0;
+
+err:
+       cifs_free_hash(&p->aes_cmac);
+       cifs_free_hash(&p->hmacsha256);
+       return rc;
+}
+
+
 static
 int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
 {