original development tree for Linux kernel GTP module; now long in mainline.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

607 lines
16 KiB

cifs: fix bad error handling in crypto code Jarod reported an Oops like when testing with fips=1: CIFS VFS: could not allocate crypto hmacmd5 CIFS VFS: could not crypto alloc hmacmd5 rc -2 CIFS VFS: Error -2 during NTLMSSP authentication CIFS VFS: Send error in SessSetup = -2 BUG: unable to handle kernel NULL pointer dereference at 000000000000004e IP: [<ffffffff812b5c7a>] crypto_destroy_tfm+0x1a/0x90 PGD 0 Oops: 0000 [#1] SMP Modules linked in: md4 nls_utf8 cifs dns_resolver fscache kvm serio_raw virtio_balloon virtio_net mperf i2c_piix4 cirrus drm_kms_helper ttm drm i2c_core virtio_blk ata_generic pata_acpi CPU: 1 PID: 639 Comm: mount.cifs Not tainted 3.11.0-0.rc3.git0.1.fc20.x86_64 #1 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 task: ffff88007bf496e0 ti: ffff88007b080000 task.ti: ffff88007b080000 RIP: 0010:[<ffffffff812b5c7a>] [<ffffffff812b5c7a>] crypto_destroy_tfm+0x1a/0x90 RSP: 0018:ffff88007b081d10 EFLAGS: 00010282 RAX: 0000000000001f1f RBX: ffff880037422000 RCX: ffff88007b081fd8 RDX: 000000000000001f RSI: 0000000000000006 RDI: fffffffffffffffe RBP: ffff88007b081d30 R08: ffff880037422000 R09: ffff88007c090100 R10: 0000000000000000 R11: 00000000fffffffe R12: fffffffffffffffe R13: ffff880037422000 R14: ffff880037422000 R15: 00000000fffffffe FS: 00007fc322f4f780(0000) GS:ffff88007fc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 000000000000004e CR3: 000000007bdaa000 CR4: 00000000000006e0 Stack: ffffffff81085845 ffff880037422000 ffff8800375e7400 ffff880037422000 ffff88007b081d48 ffffffffa0176022 ffff880037422000 ffff88007b081d60 ffffffffa015c07b ffff880037600600 ffff88007b081dc8 ffffffffa01610e1 Call Trace: [<ffffffff81085845>] ? __cancel_work_timer+0x75/0xf0 [<ffffffffa0176022>] cifs_crypto_shash_release+0x82/0xf0 [cifs] [<ffffffffa015c07b>] cifs_put_tcp_session+0x8b/0xe0 [cifs] [<ffffffffa01610e1>] cifs_mount+0x9d1/0xad0 [cifs] [<ffffffffa014ff50>] cifs_do_mount+0xa0/0x4d0 [cifs] [<ffffffff811ab6e9>] mount_fs+0x39/0x1b0 [<ffffffff811c466f>] vfs_kern_mount+0x5f/0xf0 [<ffffffff811c6a9e>] do_mount+0x23e/0xa20 [<ffffffff811c66e6>] ? copy_mount_options+0x36/0x170 [<ffffffff811c7303>] SyS_mount+0x83/0xc0 [<ffffffff8165c8d9>] system_call_fastpath+0x16/0x1b Code: eb 9e 66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 89 e5 41 55 41 54 49 89 fc 53 48 83 ec 08 48 85 ff 74 46 <48> 83 7e 48 00 48 8b 5e 50 74 4b 48 89 f7 e8 83 fc ff ff 4c 8b RIP [<ffffffff812b5c7a>] crypto_destroy_tfm+0x1a/0x90 RSP <ffff88007b081d10> CR2: 000000000000004e The cifs code allocates some crypto structures. If that fails, it returns an error, but it leaves the pointers set to their PTR_ERR values. Then later when it tries to clean up, it sees that those values are non-NULL and then passes them to the routine that frees them. Fix this by setting the pointers to NULL after collecting the error code in this situation. Cc: Sachin Prabhu <sprabhu@redhat.com> Reported-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
8 years ago
cifs: fix bad error handling in crypto code Jarod reported an Oops like when testing with fips=1: CIFS VFS: could not allocate crypto hmacmd5 CIFS VFS: could not crypto alloc hmacmd5 rc -2 CIFS VFS: Error -2 during NTLMSSP authentication CIFS VFS: Send error in SessSetup = -2 BUG: unable to handle kernel NULL pointer dereference at 000000000000004e IP: [<ffffffff812b5c7a>] crypto_destroy_tfm+0x1a/0x90 PGD 0 Oops: 0000 [#1] SMP Modules linked in: md4 nls_utf8 cifs dns_resolver fscache kvm serio_raw virtio_balloon virtio_net mperf i2c_piix4 cirrus drm_kms_helper ttm drm i2c_core virtio_blk ata_generic pata_acpi CPU: 1 PID: 639 Comm: mount.cifs Not tainted 3.11.0-0.rc3.git0.1.fc20.x86_64 #1 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 task: ffff88007bf496e0 ti: ffff88007b080000 task.ti: ffff88007b080000 RIP: 0010:[<ffffffff812b5c7a>] [<ffffffff812b5c7a>] crypto_destroy_tfm+0x1a/0x90 RSP: 0018:ffff88007b081d10 EFLAGS: 00010282 RAX: 0000000000001f1f RBX: ffff880037422000 RCX: ffff88007b081fd8 RDX: 000000000000001f RSI: 0000000000000006 RDI: fffffffffffffffe RBP: ffff88007b081d30 R08: ffff880037422000 R09: ffff88007c090100 R10: 0000000000000000 R11: 00000000fffffffe R12: fffffffffffffffe R13: ffff880037422000 R14: ffff880037422000 R15: 00000000fffffffe FS: 00007fc322f4f780(0000) GS:ffff88007fc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 000000000000004e CR3: 000000007bdaa000 CR4: 00000000000006e0 Stack: ffffffff81085845 ffff880037422000 ffff8800375e7400 ffff880037422000 ffff88007b081d48 ffffffffa0176022 ffff880037422000 ffff88007b081d60 ffffffffa015c07b ffff880037600600 ffff88007b081dc8 ffffffffa01610e1 Call Trace: [<ffffffff81085845>] ? __cancel_work_timer+0x75/0xf0 [<ffffffffa0176022>] cifs_crypto_shash_release+0x82/0xf0 [cifs] [<ffffffffa015c07b>] cifs_put_tcp_session+0x8b/0xe0 [cifs] [<ffffffffa01610e1>] cifs_mount+0x9d1/0xad0 [cifs] [<ffffffffa014ff50>] cifs_do_mount+0xa0/0x4d0 [cifs] [<ffffffff811ab6e9>] mount_fs+0x39/0x1b0 [<ffffffff811c466f>] vfs_kern_mount+0x5f/0xf0 [<ffffffff811c6a9e>] do_mount+0x23e/0xa20 [<ffffffff811c66e6>] ? copy_mount_options+0x36/0x170 [<ffffffff811c7303>] SyS_mount+0x83/0xc0 [<ffffffff8165c8d9>] system_call_fastpath+0x16/0x1b Code: eb 9e 66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 89 e5 41 55 41 54 49 89 fc 53 48 83 ec 08 48 85 ff 74 46 <48> 83 7e 48 00 48 8b 5e 50 74 4b 48 89 f7 e8 83 fc ff ff 4c 8b RIP [<ffffffff812b5c7a>] crypto_destroy_tfm+0x1a/0x90 RSP <ffff88007b081d10> CR2: 000000000000004e The cifs code allocates some crypto structures. If that fails, it returns an error, but it leaves the pointers set to their PTR_ERR values. Then later when it tries to clean up, it sees that those values are non-NULL and then passes them to the routine that frees them. Fix this by setting the pointers to NULL after collecting the error code in this situation. Cc: Sachin Prabhu <sprabhu@redhat.com> Reported-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
8 years ago
cifs: fix bad error handling in crypto code Jarod reported an Oops like when testing with fips=1: CIFS VFS: could not allocate crypto hmacmd5 CIFS VFS: could not crypto alloc hmacmd5 rc -2 CIFS VFS: Error -2 during NTLMSSP authentication CIFS VFS: Send error in SessSetup = -2 BUG: unable to handle kernel NULL pointer dereference at 000000000000004e IP: [<ffffffff812b5c7a>] crypto_destroy_tfm+0x1a/0x90 PGD 0 Oops: 0000 [#1] SMP Modules linked in: md4 nls_utf8 cifs dns_resolver fscache kvm serio_raw virtio_balloon virtio_net mperf i2c_piix4 cirrus drm_kms_helper ttm drm i2c_core virtio_blk ata_generic pata_acpi CPU: 1 PID: 639 Comm: mount.cifs Not tainted 3.11.0-0.rc3.git0.1.fc20.x86_64 #1 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 task: ffff88007bf496e0 ti: ffff88007b080000 task.ti: ffff88007b080000 RIP: 0010:[<ffffffff812b5c7a>] [<ffffffff812b5c7a>] crypto_destroy_tfm+0x1a/0x90 RSP: 0018:ffff88007b081d10 EFLAGS: 00010282 RAX: 0000000000001f1f RBX: ffff880037422000 RCX: ffff88007b081fd8 RDX: 000000000000001f RSI: 0000000000000006 RDI: fffffffffffffffe RBP: ffff88007b081d30 R08: ffff880037422000 R09: ffff88007c090100 R10: 0000000000000000 R11: 00000000fffffffe R12: fffffffffffffffe R13: ffff880037422000 R14: ffff880037422000 R15: 00000000fffffffe FS: 00007fc322f4f780(0000) GS:ffff88007fc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 000000000000004e CR3: 000000007bdaa000 CR4: 00000000000006e0 Stack: ffffffff81085845 ffff880037422000 ffff8800375e7400 ffff880037422000 ffff88007b081d48 ffffffffa0176022 ffff880037422000 ffff88007b081d60 ffffffffa015c07b ffff880037600600 ffff88007b081dc8 ffffffffa01610e1 Call Trace: [<ffffffff81085845>] ? __cancel_work_timer+0x75/0xf0 [<ffffffffa0176022>] cifs_crypto_shash_release+0x82/0xf0 [cifs] [<ffffffffa015c07b>] cifs_put_tcp_session+0x8b/0xe0 [cifs] [<ffffffffa01610e1>] cifs_mount+0x9d1/0xad0 [cifs] [<ffffffffa014ff50>] cifs_do_mount+0xa0/0x4d0 [cifs] [<ffffffff811ab6e9>] mount_fs+0x39/0x1b0 [<ffffffff811c466f>] vfs_kern_mount+0x5f/0xf0 [<ffffffff811c6a9e>] do_mount+0x23e/0xa20 [<ffffffff811c66e6>] ? copy_mount_options+0x36/0x170 [<ffffffff811c7303>] SyS_mount+0x83/0xc0 [<ffffffff8165c8d9>] system_call_fastpath+0x16/0x1b Code: eb 9e 66 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 89 e5 41 55 41 54 49 89 fc 53 48 83 ec 08 48 85 ff 74 46 <48> 83 7e 48 00 48 8b 5e 50 74 4b 48 89 f7 e8 83 fc ff ff 4c 8b RIP [<ffffffff812b5c7a>] crypto_destroy_tfm+0x1a/0x90 RSP <ffff88007b081d10> CR2: 000000000000004e The cifs code allocates some crypto structures. If that fails, it returns an error, but it leaves the pointers set to their PTR_ERR values. Then later when it tries to clean up, it sees that those values are non-NULL and then passes them to the routine that frees them. Fix this by setting the pointers to NULL after collecting the error code in this situation. Cc: Sachin Prabhu <sprabhu@redhat.com> Reported-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
8 years ago
  1. /*
  2. * fs/cifs/smb2transport.c
  3. *
  4. * Copyright (C) International Business Machines Corp., 2002, 2011
  5. * Etersoft, 2012
  6. * Author(s): Steve French (sfrench@us.ibm.com)
  7. * Jeremy Allison (jra@samba.org) 2006
  8. * Pavel Shilovsky (pshilovsky@samba.org) 2012
  9. *
  10. * This library is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU Lesser General Public License as published
  12. * by the Free Software Foundation; either version 2.1 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  18. * the GNU Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public License
  21. * along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. */
  24. #include <linux/fs.h>
  25. #include <linux/list.h>
  26. #include <linux/wait.h>
  27. #include <linux/net.h>
  28. #include <linux/delay.h>
  29. #include <linux/uaccess.h>
  30. #include <asm/processor.h>
  31. #include <linux/mempool.h>
  32. #include <linux/highmem.h>
  33. #include "smb2pdu.h"
  34. #include "cifsglob.h"
  35. #include "cifsproto.h"
  36. #include "smb2proto.h"
  37. #include "cifs_debug.h"
  38. #include "smb2status.h"
  39. #include "smb2glob.h"
  40. static int
  41. smb2_crypto_shash_allocate(struct TCP_Server_Info *server)
  42. {
  43. int rc;
  44. unsigned int size;
  45. if (server->secmech.sdeschmacsha256 != NULL)
  46. return 0; /* already allocated */
  47. server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0);
  48. if (IS_ERR(server->secmech.hmacsha256)) {
  49. cifs_dbg(VFS, "could not allocate crypto hmacsha256\n");
  50. rc = PTR_ERR(server->secmech.hmacsha256);
  51. server->secmech.hmacsha256 = NULL;
  52. return rc;
  53. }
  54. size = sizeof(struct shash_desc) +
  55. crypto_shash_descsize(server->secmech.hmacsha256);
  56. server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL);
  57. if (!server->secmech.sdeschmacsha256) {
  58. crypto_free_shash(server->secmech.hmacsha256);
  59. server->secmech.hmacsha256 = NULL;
  60. return -ENOMEM;
  61. }
  62. server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
  63. server->secmech.sdeschmacsha256->shash.flags = 0x0;
  64. return 0;
  65. }
  66. static int
  67. smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
  68. {
  69. unsigned int size;
  70. int rc;
  71. if (server->secmech.sdesccmacaes != NULL)
  72. return 0; /* already allocated */
  73. rc = smb2_crypto_shash_allocate(server);
  74. if (rc)
  75. return rc;
  76. server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0);
  77. if (IS_ERR(server->secmech.cmacaes)) {
  78. cifs_dbg(VFS, "could not allocate crypto cmac-aes");
  79. kfree(server->secmech.sdeschmacsha256);
  80. server->secmech.sdeschmacsha256 = NULL;
  81. crypto_free_shash(server->secmech.hmacsha256);
  82. server->secmech.hmacsha256 = NULL;
  83. rc = PTR_ERR(server->secmech.cmacaes);
  84. server->secmech.cmacaes = NULL;
  85. return rc;
  86. }
  87. size = sizeof(struct shash_desc) +
  88. crypto_shash_descsize(server->secmech.cmacaes);
  89. server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL);
  90. if (!server->secmech.sdesccmacaes) {
  91. cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__);
  92. kfree(server->secmech.sdeschmacsha256);
  93. server->secmech.sdeschmacsha256 = NULL;
  94. crypto_free_shash(server->secmech.hmacsha256);
  95. crypto_free_shash(server->secmech.cmacaes);
  96. server->secmech.hmacsha256 = NULL;
  97. server->secmech.cmacaes = NULL;
  98. return -ENOMEM;
  99. }
  100. server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes;
  101. server->secmech.sdesccmacaes->shash.flags = 0x0;
  102. return 0;
  103. }
  104. static struct cifs_ses *
  105. smb2_find_smb_ses(struct smb2_hdr *smb2hdr, struct TCP_Server_Info *server)
  106. {
  107. struct cifs_ses *ses;
  108. spin_lock(&cifs_tcp_ses_lock);
  109. list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
  110. if (ses->Suid != smb2hdr->SessionId)
  111. continue;
  112. spin_unlock(&cifs_tcp_ses_lock);
  113. return ses;
  114. }
  115. spin_unlock(&cifs_tcp_ses_lock);
  116. return NULL;
  117. }
  118. int
  119. smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
  120. {
  121. int i, rc;
  122. unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
  123. unsigned char *sigptr = smb2_signature;
  124. struct kvec *iov = rqst->rq_iov;
  125. int n_vec = rqst->rq_nvec;
  126. struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
  127. struct cifs_ses *ses;
  128. ses = smb2_find_smb_ses(smb2_pdu, server);
  129. if (!ses) {
  130. cifs_dbg(VFS, "%s: Could not find session\n", __func__);
  131. return 0;
  132. }
  133. memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
  134. memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
  135. rc = smb2_crypto_shash_allocate(server);
  136. if (rc) {
  137. cifs_dbg(VFS, "%s: shah256 alloc failed\n", __func__);
  138. return rc;
  139. }
  140. rc = crypto_shash_setkey(server->secmech.hmacsha256,
  141. ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
  142. if (rc) {
  143. cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
  144. return rc;
  145. }
  146. rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash);
  147. if (rc) {
  148. cifs_dbg(VFS, "%s: Could not init sha256", __func__);
  149. return rc;
  150. }
  151. for (i = 0; i < n_vec; i++) {
  152. if (iov[i].iov_len == 0)
  153. continue;
  154. if (iov[i].iov_base == NULL) {
  155. cifs_dbg(VFS, "null iovec entry\n");
  156. return -EIO;
  157. }
  158. /*
  159. * The first entry includes a length field (which does not get
  160. * signed that occupies the first 4 bytes before the header).
  161. */
  162. if (i == 0) {
  163. if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
  164. break; /* nothing to sign or corrupt header */
  165. rc =
  166. crypto_shash_update(
  167. &server->secmech.sdeschmacsha256->shash,
  168. iov[i].iov_base + 4, iov[i].iov_len - 4);
  169. } else {
  170. rc =
  171. crypto_shash_update(
  172. &server->secmech.sdeschmacsha256->shash,
  173. iov[i].iov_base, iov[i].iov_len);
  174. }
  175. if (rc) {
  176. cifs_dbg(VFS, "%s: Could not update with payload\n",
  177. __func__);
  178. return rc;
  179. }
  180. }
  181. /* now hash over the rq_pages array */
  182. for (i = 0; i < rqst->rq_npages; i++) {
  183. struct kvec p_iov;
  184. cifs_rqst_page_to_kvec(rqst, i, &p_iov);
  185. crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
  186. p_iov.iov_base, p_iov.iov_len);
  187. kunmap(rqst->rq_pages[i]);
  188. }
  189. rc = crypto_shash_final(&server->secmech.sdeschmacsha256->shash,
  190. sigptr);
  191. if (rc)
  192. cifs_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
  193. memcpy(smb2_pdu->Signature, sigptr, SMB2_SIGNATURE_SIZE);
  194. return rc;
  195. }
  196. int
  197. generate_smb3signingkey(struct cifs_ses *ses)
  198. {
  199. unsigned char zero = 0x0;
  200. __u8 i[4] = {0, 0, 0, 1};
  201. __u8 L[4] = {0, 0, 0, 128};
  202. int rc = 0;
  203. unsigned char prfhash[SMB2_HMACSHA256_SIZE];
  204. unsigned char *hashptr = prfhash;
  205. memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
  206. memset(ses->smb3signingkey, 0x0, SMB3_SIGNKEY_SIZE);
  207. rc = smb3_crypto_shash_allocate(ses->server);
  208. if (rc) {
  209. cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
  210. goto smb3signkey_ret;
  211. }
  212. rc = crypto_shash_setkey(ses->server->secmech.hmacsha256,
  213. ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
  214. if (rc) {
  215. cifs_dbg(VFS, "%s: Could not set with session key\n", __func__);
  216. goto smb3signkey_ret;
  217. }
  218. rc = crypto_shash_init(&ses->server->secmech.sdeschmacsha256->shash);
  219. if (rc) {
  220. cifs_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
  221. goto smb3signkey_ret;
  222. }
  223. rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
  224. i, 4);
  225. if (rc) {
  226. cifs_dbg(VFS, "%s: Could not update with n\n", __func__);
  227. goto smb3signkey_ret;
  228. }
  229. rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
  230. "SMB2AESCMAC", 12);
  231. if (rc) {
  232. cifs_dbg(VFS, "%s: Could not update with label\n", __func__);
  233. goto smb3signkey_ret;
  234. }
  235. rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
  236. &zero, 1);
  237. if (rc) {
  238. cifs_dbg(VFS, "%s: Could not update with zero\n", __func__);
  239. goto smb3signkey_ret;
  240. }
  241. rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
  242. "SmbSign", 8);
  243. if (rc) {
  244. cifs_dbg(VFS, "%s: Could not update with context\n", __func__);
  245. goto smb3signkey_ret;
  246. }
  247. rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
  248. L, 4);
  249. if (rc) {
  250. cifs_dbg(VFS, "%s: Could not update with L\n", __func__);
  251. goto smb3signkey_ret;
  252. }
  253. rc = crypto_shash_final(&ses->server->secmech.sdeschmacsha256->shash,
  254. hashptr);
  255. if (rc) {
  256. cifs_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
  257. goto smb3signkey_ret;
  258. }
  259. memcpy(ses->smb3signingkey, hashptr, SMB3_SIGNKEY_SIZE);
  260. smb3signkey_ret:
  261. return rc;
  262. }
  263. int
  264. smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
  265. {
  266. int i;
  267. int rc = 0;
  268. unsigned char smb3_signature[SMB2_CMACAES_SIZE];
  269. unsigned char *sigptr = smb3_signature;
  270. struct kvec *iov = rqst->rq_iov;
  271. int n_vec = rqst->rq_nvec;
  272. struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
  273. struct cifs_ses *ses;
  274. ses = smb2_find_smb_ses(smb2_pdu, server);
  275. if (!ses) {
  276. cifs_dbg(VFS, "%s: Could not find session\n", __func__);
  277. return 0;
  278. }
  279. memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
  280. memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
  281. rc = crypto_shash_setkey(server->secmech.cmacaes,
  282. ses->smb3signingkey, SMB2_CMACAES_SIZE);
  283. if (rc) {
  284. cifs_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
  285. return rc;
  286. }
  287. /*
  288. * we already allocate sdesccmacaes when we init smb3 signing key,
  289. * so unlike smb2 case we do not have to check here if secmech are
  290. * initialized
  291. */
  292. rc = crypto_shash_init(&server->secmech.sdesccmacaes->shash);
  293. if (rc) {
  294. cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
  295. return rc;
  296. }
  297. for (i = 0; i < n_vec; i++) {
  298. if (iov[i].iov_len == 0)
  299. continue;
  300. if (iov[i].iov_base == NULL) {
  301. cifs_dbg(VFS, "null iovec entry");
  302. return -EIO;
  303. }
  304. /*
  305. * The first entry includes a length field (which does not get
  306. * signed that occupies the first 4 bytes before the header).
  307. */
  308. if (i == 0) {
  309. if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
  310. break; /* nothing to sign or corrupt header */
  311. rc =
  312. crypto_shash_update(
  313. &server->secmech.sdesccmacaes->shash,
  314. iov[i].iov_base + 4, iov[i].iov_len - 4);
  315. } else {
  316. rc =
  317. crypto_shash_update(
  318. &server->secmech.sdesccmacaes->shash,
  319. iov[i].iov_base, iov[i].iov_len);
  320. }
  321. if (rc) {
  322. cifs_dbg(VFS, "%s: Couldn't update cmac aes with payload\n",
  323. __func__);
  324. return rc;
  325. }
  326. }
  327. /* now hash over the rq_pages array */
  328. for (i = 0; i < rqst->rq_npages; i++) {
  329. struct kvec p_iov;
  330. cifs_rqst_page_to_kvec(rqst, i, &p_iov);
  331. crypto_shash_update(&server->secmech.sdesccmacaes->shash,
  332. p_iov.iov_base, p_iov.iov_len);
  333. kunmap(rqst->rq_pages[i]);
  334. }
  335. rc = crypto_shash_final(&server->secmech.sdesccmacaes->shash,
  336. sigptr);
  337. if (rc)
  338. cifs_dbg(VFS, "%s: Could not generate cmac aes\n", __func__);
  339. memcpy(smb2_pdu->Signature, sigptr, SMB2_SIGNATURE_SIZE);
  340. return rc;
  341. }
  342. /* must be called with server->srv_mutex held */
  343. static int
  344. smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
  345. {
  346. int rc = 0;
  347. struct smb2_hdr *smb2_pdu = rqst->rq_iov[0].iov_base;
  348. if (!(smb2_pdu->Flags & SMB2_FLAGS_SIGNED) ||
  349. server->tcpStatus == CifsNeedNegotiate)
  350. return rc;
  351. if (!server->session_estab) {
  352. strncpy(smb2_pdu->Signature, "BSRSPYL", 8);
  353. return rc;
  354. }
  355. rc = server->ops->calc_signature(rqst, server);
  356. return rc;
  357. }
  358. int
  359. smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
  360. {
  361. unsigned int rc;
  362. char server_response_sig[16];
  363. struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
  364. if ((smb2_pdu->Command == SMB2_NEGOTIATE) ||
  365. (smb2_pdu->Command == SMB2_SESSION_SETUP) ||
  366. (smb2_pdu->Command == SMB2_OPLOCK_BREAK) ||
  367. (!server->session_estab))
  368. return 0;
  369. /*
  370. * BB what if signatures are supposed to be on for session but
  371. * server does not send one? BB
  372. */
  373. /* Do not need to verify session setups with signature "BSRSPYL " */
  374. if (memcmp(smb2_pdu->Signature, "BSRSPYL ", 8) == 0)
  375. cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
  376. smb2_pdu->Command);
  377. /*
  378. * Save off the origiginal signature so we can modify the smb and check
  379. * our calculated signature against what the server sent.
  380. */
  381. memcpy(server_response_sig, smb2_pdu->Signature, SMB2_SIGNATURE_SIZE);
  382. memset(smb2_pdu->Signature, 0, SMB2_SIGNATURE_SIZE);
  383. mutex_lock(&server->srv_mutex);
  384. rc = server->ops->calc_signature(rqst, server);
  385. mutex_unlock(&server->srv_mutex);
  386. if (rc)
  387. return rc;
  388. if (memcmp(server_response_sig, smb2_pdu->Signature,
  389. SMB2_SIGNATURE_SIZE))
  390. return -EACCES;
  391. else
  392. return 0;
  393. }
  394. /*
  395. * Set message id for the request. Should be called after wait_for_free_request
  396. * and when srv_mutex is held.
  397. */
  398. static inline void
  399. smb2_seq_num_into_buf(struct TCP_Server_Info *server, struct smb2_hdr *hdr)
  400. {
  401. hdr->MessageId = get_next_mid64(server);
  402. }
  403. static struct mid_q_entry *
  404. smb2_mid_entry_alloc(const struct smb2_hdr *smb_buffer,
  405. struct TCP_Server_Info *server)
  406. {
  407. struct mid_q_entry *temp;
  408. if (server == NULL) {
  409. cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
  410. return NULL;
  411. }
  412. temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
  413. if (temp == NULL)
  414. return temp;
  415. else {
  416. memset(temp, 0, sizeof(struct mid_q_entry));
  417. temp->mid = smb_buffer->MessageId; /* always LE */
  418. temp->pid = current->pid;
  419. temp->command = smb_buffer->Command; /* Always LE */
  420. temp->when_alloc = jiffies;
  421. temp->server = server;
  422. /*
  423. * The default is for the mid to be synchronous, so the
  424. * default callback just wakes up the current task.
  425. */
  426. temp->callback = cifs_wake_up_task;
  427. temp->callback_data = current;
  428. }
  429. atomic_inc(&midCount);
  430. temp->mid_state = MID_REQUEST_ALLOCATED;
  431. return temp;
  432. }
  433. static int
  434. smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_hdr *buf,
  435. struct mid_q_entry **mid)
  436. {
  437. if (ses->server->tcpStatus == CifsExiting)
  438. return -ENOENT;
  439. if (ses->server->tcpStatus == CifsNeedReconnect) {
  440. cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
  441. return -EAGAIN;
  442. }
  443. if (ses->status == CifsNew) {
  444. if ((buf->Command != SMB2_SESSION_SETUP) &&
  445. (buf->Command != SMB2_NEGOTIATE))
  446. return -EAGAIN;
  447. /* else ok - we are setting up session */
  448. }
  449. if (ses->status == CifsExiting) {
  450. if (buf->Command != SMB2_LOGOFF)
  451. return -EAGAIN;
  452. /* else ok - we are shutting down the session */
  453. }
  454. *mid = smb2_mid_entry_alloc(buf, ses->server);
  455. if (*mid == NULL)
  456. return -ENOMEM;
  457. spin_lock(&GlobalMid_Lock);
  458. list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q);
  459. spin_unlock(&GlobalMid_Lock);
  460. return 0;
  461. }
  462. int
  463. smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
  464. bool log_error)
  465. {
  466. unsigned int len = get_rfc1002_length(mid->resp_buf);
  467. struct kvec iov;
  468. struct smb_rqst rqst = { .rq_iov = &iov,
  469. .rq_nvec = 1 };
  470. iov.iov_base = (char *)mid->resp_buf;
  471. iov.iov_len = get_rfc1002_length(mid->resp_buf) + 4;
  472. dump_smb(mid->resp_buf, min_t(u32, 80, len));
  473. /* convert the length into a more usable form */
  474. if (len > 24 && server->sign) {
  475. int rc;
  476. rc = smb2_verify_signature(&rqst, server);
  477. if (rc)
  478. cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
  479. rc);
  480. }
  481. return map_smb2_to_linux_error(mid->resp_buf, log_error);
  482. }
  483. struct mid_q_entry *
  484. smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
  485. {
  486. int rc;
  487. struct smb2_hdr *hdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
  488. struct mid_q_entry *mid;
  489. smb2_seq_num_into_buf(ses->server, hdr);
  490. rc = smb2_get_mid_entry(ses, hdr, &mid);
  491. if (rc)
  492. return ERR_PTR(rc);
  493. rc = smb2_sign_rqst(rqst, ses->server);
  494. if (rc) {
  495. cifs_delete_mid(mid);
  496. return ERR_PTR(rc);
  497. }
  498. return mid;
  499. }
  500. struct mid_q_entry *
  501. smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
  502. {
  503. int rc;
  504. struct smb2_hdr *hdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
  505. struct mid_q_entry *mid;
  506. smb2_seq_num_into_buf(server, hdr);
  507. mid = smb2_mid_entry_alloc(hdr, server);
  508. if (mid == NULL)
  509. return ERR_PTR(-ENOMEM);
  510. rc = smb2_sign_rqst(rqst, server);
  511. if (rc) {
  512. DeleteMidQEntry(mid);
  513. return ERR_PTR(rc);
  514. }
  515. return mid;
  516. }