Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Revert "smb: client: make SHA-512 TFM ephemeral"

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.

+49 -19
+1
fs/smb/client/cifsencrypt.c
··· 700 700 cifs_free_hash(&server->secmech.aes_cmac); 701 701 cifs_free_hash(&server->secmech.hmacsha256); 702 702 cifs_free_hash(&server->secmech.md5); 703 + cifs_free_hash(&server->secmech.sha512); 703 704 704 705 if (!SERVER_IS_CHAN(server)) { 705 706 if (server->secmech.enc) {
+1
fs/smb/client/cifsglob.h
··· 180 180 struct cifs_secmech { 181 181 struct shash_desc *md5; /* md5 hash function, for CIFS/SMB1 signatures */ 182 182 struct shash_desc *hmacsha256; /* hmac-sha256 hash function, for SMB2 signatures */ 183 + struct shash_desc *sha512; /* sha512 hash function, for SMB3.1.1 preauth hash */ 183 184 struct shash_desc *aes_cmac; /* block-cipher based MAC function, for SMB3 signatures */ 184 185 185 186 struct crypto_aead *enc; /* smb3 encryption AEAD TFM (AES-CCM and AES-GCM) */
+1 -1
fs/smb/client/sess.c
··· 624 624 * to sign packets before we generate the channel signing key 625 625 * (we sign with the session key) 626 626 */ 627 - rc = smb3_crypto_shash_allocate(chan->server); 627 + rc = smb311_crypto_shash_allocate(chan->server); 628 628 if (rc) { 629 629 cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__); 630 630 mutex_unlock(&ses->session_mutex);
+16 -16
fs/smb/client/smb2misc.c
··· 906 906 || (hdr->Status != 907 907 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED)))) 908 908 return 0; 909 - ok: 910 - rc = cifs_alloc_hash("sha512", &sha512); 911 - if (rc) { 912 - cifs_dbg(VFS, "%s: Could not allocate SHA512 shash, rc=%d\n", __func__, rc); 913 - return rc; 914 - } 915 909 910 + ok: 911 + rc = smb311_crypto_shash_allocate(server); 912 + if (rc) 913 + return rc; 914 + 915 + sha512 = server->secmech.sha512; 916 916 rc = crypto_shash_init(sha512); 917 917 if (rc) { 918 - cifs_dbg(VFS, "%s: Could not init SHA512 shash, rc=%d\n", __func__, rc); 919 - goto err_free; 918 + cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__); 919 + return rc; 920 920 } 921 921 922 922 rc = crypto_shash_update(sha512, ses->preauth_sha_hash, 923 923 SMB2_PREAUTH_HASH_SIZE); 924 924 if (rc) { 925 - cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc); 926 - goto err_free; 925 + cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__); 926 + return rc; 927 927 } 928 928 929 929 for (i = 0; i < nvec; i++) { 930 930 rc = crypto_shash_update(sha512, iov[i].iov_base, iov[i].iov_len); 931 931 if (rc) { 932 - cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc); 933 - goto err_free; 932 + cifs_dbg(VFS, "%s: Could not update sha512 shash\n", 933 + __func__); 934 + return rc; 934 935 } 935 936 } 936 937 937 938 rc = crypto_shash_final(sha512, ses->preauth_sha_hash); 938 939 if (rc) { 939 - cifs_dbg(VFS, "%s: Could not finalize SHA12 shash, rc=%d\n", __func__, rc); 940 - goto err_free; 940 + cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n", 941 + __func__); 942 + return rc; 941 943 } 942 - err_free: 943 - cifs_free_hash(&sha512); 944 944 945 945 return 0; 946 946 }
+1 -1
fs/smb/client/smb2proto.h
··· 291 291 extern void smb2_copy_fs_info_to_kstatfs( 292 292 struct smb2_fs_full_size_info *pfs_inf, 293 293 struct kstatfs *kst); 294 - extern int smb3_crypto_shash_allocate(struct TCP_Server_Info *server); 294 + extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server); 295 295 extern int smb311_update_preauth_hash(struct cifs_ses *ses, 296 296 struct TCP_Server_Info *server, 297 297 struct kvec *iov, int nvec);
+29 -1
fs/smb/client/smb2transport.c
··· 26 26 #include "../common/smb2status.h" 27 27 #include "smb2glob.h" 28 28 29 - int smb3_crypto_shash_allocate(struct TCP_Server_Info *server) 29 + static int 30 + smb3_crypto_shash_allocate(struct TCP_Server_Info *server) 30 31 { 31 32 struct cifs_secmech *p = &server->secmech; 32 33 int rc; ··· 45 44 cifs_free_hash(&p->hmacsha256); 46 45 return rc; 47 46 } 47 + 48 + int 49 + smb311_crypto_shash_allocate(struct TCP_Server_Info *server) 50 + { 51 + struct cifs_secmech *p = &server->secmech; 52 + int rc = 0; 53 + 54 + rc = cifs_alloc_hash("hmac(sha256)", &p->hmacsha256); 55 + if (rc) 56 + return rc; 57 + 58 + rc = cifs_alloc_hash("cmac(aes)", &p->aes_cmac); 59 + if (rc) 60 + goto err; 61 + 62 + rc = cifs_alloc_hash("sha512", &p->sha512); 63 + if (rc) 64 + goto err; 65 + 66 + return 0; 67 + 68 + err: 69 + cifs_free_hash(&p->aes_cmac); 70 + cifs_free_hash(&p->hmacsha256); 71 + return rc; 72 + } 73 + 48 74 49 75 static 50 76 int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)