diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-04 17:09:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-04 17:09:27 -0400 |
commit | a8f8e8ac766ddb8702ef9baf01b7ae4f8d3a940c (patch) | |
tree | c1fb03d543dc85acf972e245eaaa39a23cdffcbd | |
parent | 2bd99df54f43b659ddaab8922adbaf3bcf3753ed (diff) | |
parent | 07108d0e7c7fbbf9c6d76c0af2f1813e4f3f0800 (diff) |
Merge tag '4.17-SMB3-Fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs updates from Steve French:
"Includes SMB3.11 security improvements, as well as various fixes for
stable and some debugging improvements"
* tag '4.17-SMB3-Fixes' of git://git.samba.org/sfrench/cifs-2.6:
cifs: Add minor debug message during negprot
smb3: Fix root directory when server returns inode number of zero
cifs: fix sparse warning on previous patch in a few printks
cifs: add server->vals->header_preamble_size
cifs: smbd: disconnect transport on RDMA errors
cifs: smbd: avoid reconnect lockup
Don't log confusing message on reconnect by default
Don't log expected error on DFS referral request
fs: cifs: Replace _free_xid call in cifs_root_iget function
SMB3.1.1 dialect is no longer experimental
Tree connect for SMB3.1.1 must be signed for non-encrypted shares
fix smb3-encryption breakage when CONFIG_DEBUG_SG=y
CIFS: fix sha512 check in cifs_crypto_secmech_release
CIFS: implement v3.11 preauth integrity
CIFS: add sha512 secmech
CIFS: refactor crypto shash/sdesc allocation&free
Update README file for cifs.ko
Update TODO list for cifs.ko
cifs: fix memory leak in SMB2_open()
CIFS: SMBD: fix spelling mistake: "faield" and "legnth"
-rw-r--r-- | Documentation/filesystems/cifs/README | 29 | ||||
-rw-r--r-- | Documentation/filesystems/cifs/TODO | 25 | ||||
-rw-r--r-- | fs/cifs/Kconfig | 8 | ||||
-rw-r--r-- | fs/cifs/cifsencrypt.c | 85 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 1 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 9 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 5 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 6 | ||||
-rw-r--r-- | fs/cifs/connect.c | 18 | ||||
-rw-r--r-- | fs/cifs/inode.c | 38 | ||||
-rw-r--r-- | fs/cifs/link.c | 27 | ||||
-rw-r--r-- | fs/cifs/misc.c | 54 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 1 | ||||
-rw-r--r-- | fs/cifs/smb2maperror.c | 2 | ||||
-rw-r--r-- | fs/cifs/smb2misc.c | 89 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 76 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 57 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.h | 3 | ||||
-rw-r--r-- | fs/cifs/smb2proto.h | 5 | ||||
-rw-r--r-- | fs/cifs/smb2transport.c | 97 | ||||
-rw-r--r-- | fs/cifs/smbdirect.c | 23 | ||||
-rw-r--r-- | fs/cifs/smbencrypt.c | 27 | ||||
-rw-r--r-- | fs/cifs/transport.c | 20 |
23 files changed, 435 insertions, 270 deletions
diff --git a/Documentation/filesystems/cifs/README b/Documentation/filesystems/cifs/README index a9da51553ba3..99ce3d25003d 100644 --- a/Documentation/filesystems/cifs/README +++ b/Documentation/filesystems/cifs/README | |||
@@ -11,13 +11,14 @@ Information Foundation. CIFS and now SMB3 has now become a defacto | |||
11 | standard for interoperating between Macs and Windows and major NAS appliances. | 11 | standard for interoperating between Macs and Windows and major NAS appliances. |
12 | 12 | ||
13 | Please see | 13 | Please see |
14 | MS-SMB2 (for detailed SMB2/SMB3/SMB3.1.1 protocol specification) | ||
14 | http://protocolfreedom.org/ and | 15 | http://protocolfreedom.org/ and |
15 | http://samba.org/samba/PFIF/ | 16 | http://samba.org/samba/PFIF/ |
16 | for more details. | 17 | for more details. |
17 | 18 | ||
18 | 19 | ||
19 | For questions or bug reports please contact: | 20 | For questions or bug reports please contact: |
20 | sfrench@samba.org (sfrench@us.ibm.com) | 21 | smfrench@gmail.com |
21 | 22 | ||
22 | See the project page at: https://wiki.samba.org/index.php/LinuxCIFS_utils | 23 | See the project page at: https://wiki.samba.org/index.php/LinuxCIFS_utils |
23 | 24 | ||
@@ -37,15 +38,15 @@ Installation instructions: | |||
37 | ========================= | 38 | ========================= |
38 | If you have built the CIFS vfs as module (successfully) simply | 39 | If you have built the CIFS vfs as module (successfully) simply |
39 | type "make modules_install" (or if you prefer, manually copy the file to | 40 | type "make modules_install" (or if you prefer, manually copy the file to |
40 | the modules directory e.g. /lib/modules/2.4.10-4GB/kernel/fs/cifs/cifs.o). | 41 | the modules directory e.g. /lib/modules/2.4.10-4GB/kernel/fs/cifs/cifs.ko). |
41 | 42 | ||
42 | If you have built the CIFS vfs into the kernel itself, follow the instructions | 43 | If you have built the CIFS vfs into the kernel itself, follow the instructions |
43 | for your distribution on how to install a new kernel (usually you | 44 | for your distribution on how to install a new kernel (usually you |
44 | would simply type "make install"). | 45 | would simply type "make install"). |
45 | 46 | ||
46 | If you do not have the utility mount.cifs (in the Samba 3.0 source tree and on | 47 | If you do not have the utility mount.cifs (in the Samba 4.x source tree and on |
47 | the CIFS VFS web site) copy it to the same directory in which mount.smbfs and | 48 | the CIFS VFS web site) copy it to the same directory in which mount helpers |
48 | similar files reside (usually /sbin). Although the helper software is not | 49 | reside (usually /sbin). Although the helper software is not |
49 | required, mount.cifs is recommended. Most distros include a "cifs-utils" | 50 | required, mount.cifs is recommended. Most distros include a "cifs-utils" |
50 | package that includes this utility so it is recommended to install this. | 51 | package that includes this utility so it is recommended to install this. |
51 | 52 | ||
@@ -118,10 +119,13 @@ this can become unwieldy when potential mount targets include many | |||
118 | or unpredictable UNC names. | 119 | or unpredictable UNC names. |
119 | 120 | ||
120 | Samba Considerations | 121 | Samba Considerations |
121 | ==================== | 122 | ==================== |
122 | To get the maximum benefit from the CIFS VFS, we recommend using a server that | 123 | Most current servers support SMB2.1 and SMB3 which are more secure, |
123 | supports the SNIA CIFS Unix Extensions standard (e.g. Samba 2.2.5 or later or | 124 | but there are useful protocol extensions for the older less secure CIFS |
124 | Samba 3.0) but the CIFS vfs works fine with a wide variety of CIFS servers. | 125 | dialect, so to get the maximum benefit if mounting using the older dialect |
126 | (CIFS/SMB1), we recommend using a server that supports the SNIA CIFS | ||
127 | Unix Extensions standard (e.g. almost any version of Samba ie version | ||
128 | 2.2.5 or later) but the CIFS vfs works fine with a wide variety of CIFS servers. | ||
125 | Note that uid, gid and file permissions will display default values if you do | 129 | Note that uid, gid and file permissions will display default values if you do |
126 | not have a server that supports the Unix extensions for CIFS (such as Samba | 130 | not have a server that supports the Unix extensions for CIFS (such as Samba |
127 | 2.2.5 or later). To enable the Unix CIFS Extensions in the Samba server, add | 131 | 2.2.5 or later). To enable the Unix CIFS Extensions in the Samba server, add |
@@ -603,11 +607,6 @@ Stats Lists summary resource usage information as well as per | |||
603 | in the kernel configuration. | 607 | in the kernel configuration. |
604 | 608 | ||
605 | Configuration pseudo-files: | 609 | Configuration pseudo-files: |
606 | PacketSigningEnabled If set to one, cifs packet signing is enabled | ||
607 | and will be used if the server requires | ||
608 | it. If set to two, cifs packet signing is | ||
609 | required even if the server considers packet | ||
610 | signing optional. (default 1) | ||
611 | SecurityFlags Flags which control security negotiation and | 610 | SecurityFlags Flags which control security negotiation and |
612 | also packet signing. Authentication (may/must) | 611 | also packet signing. Authentication (may/must) |
613 | flags (e.g. for NTLM and/or NTLMv2) may be combined with | 612 | flags (e.g. for NTLM and/or NTLMv2) may be combined with |
@@ -666,8 +665,6 @@ traceSMB If set to one, debug information is logged to the | |||
666 | LookupCacheEnable If set to one, inode information is kept cached | 665 | LookupCacheEnable If set to one, inode information is kept cached |
667 | for one second improving performance of lookups | 666 | for one second improving performance of lookups |
668 | (default 1) | 667 | (default 1) |
669 | OplockEnabled If set to one, safe distributed caching enabled. | ||
670 | (default 1) | ||
671 | LinuxExtensionsEnabled If set to one then the client will attempt to | 668 | LinuxExtensionsEnabled If set to one then the client will attempt to |
672 | use the CIFS "UNIX" extensions which are optional | 669 | use the CIFS "UNIX" extensions which are optional |
673 | protocol enhancements that allow CIFS servers | 670 | protocol enhancements that allow CIFS servers |
diff --git a/Documentation/filesystems/cifs/TODO b/Documentation/filesystems/cifs/TODO index 396ecfd6ff4a..c5adf149b57f 100644 --- a/Documentation/filesystems/cifs/TODO +++ b/Documentation/filesystems/cifs/TODO | |||
@@ -1,4 +1,4 @@ | |||
1 | Version 2.04 September 13, 2017 | 1 | Version 2.11 September 13, 2017 |
2 | 2 | ||
3 | A Partial List of Missing Features | 3 | A Partial List of Missing Features |
4 | ================================== | 4 | ================================== |
@@ -8,10 +8,10 @@ for visible, important contributions to this module. Here | |||
8 | is a partial list of the known problems and missing features: | 8 | is a partial list of the known problems and missing features: |
9 | 9 | ||
10 | a) SMB3 (and SMB3.02) missing optional features: | 10 | a) SMB3 (and SMB3.02) missing optional features: |
11 | - RDMA (started) | 11 | - multichannel (started), integration with RDMA |
12 | - multichannel (started) | ||
13 | - directory leases (improved metadata caching) | 12 | - directory leases (improved metadata caching) |
14 | - T10 copy offload (copy chunk is only mechanism supported) | 13 | - T10 copy offload (copy chunk, and "Duplicate Extents" ioctl |
14 | currently the only two server side copy mechanisms supported) | ||
15 | 15 | ||
16 | b) improved sparse file support | 16 | b) improved sparse file support |
17 | 17 | ||
@@ -21,9 +21,8 @@ using Directory Leases | |||
21 | d) quota support (needs minor kernel change since quota calls | 21 | d) quota support (needs minor kernel change since quota calls |
22 | to make it to network filesystems or deviceless filesystems) | 22 | to make it to network filesystems or deviceless filesystems) |
23 | 23 | ||
24 | e) Better optimize open to reduce redundant opens (using reference | 24 | e) Compounding (in progress) to reduce number of roundtrips, and also |
25 | counts more) and to improve use of compounding in SMB3 to reduce | 25 | better optimize open to reduce redundant opens (using reference counts more). |
26 | number of roundtrips. | ||
27 | 26 | ||
28 | f) Finish inotify support so kde and gnome file list windows | 27 | f) Finish inotify support so kde and gnome file list windows |
29 | will autorefresh (partially complete by Asser). Needs minor kernel | 28 | will autorefresh (partially complete by Asser). Needs minor kernel |
@@ -35,7 +34,8 @@ the CIFS statistics (started) | |||
35 | h) implement support for security and trusted categories of xattrs | 34 | h) implement support for security and trusted categories of xattrs |
36 | (requires minor protocol extension) to enable better support for SELINUX | 35 | (requires minor protocol extension) to enable better support for SELINUX |
37 | 36 | ||
38 | i) Implement O_DIRECT flag on open (already supported on mount) | 37 | i) Add support for tree connect contexts (see MS-SMB2) a new SMB3.1.1 protocol |
38 | feature (may be especially useful for virtualization). | ||
39 | 39 | ||
40 | j) Create UID mapping facility so server UIDs can be mapped on a per | 40 | j) Create UID mapping facility so server UIDs can be mapped on a per |
41 | mount or a per server basis to client UIDs or nobody if no mapping | 41 | mount or a per server basis to client UIDs or nobody if no mapping |
@@ -53,13 +53,16 @@ viewing them. | |||
53 | 53 | ||
54 | o) mount helper GUI (to simplify the various configuration options on mount) | 54 | o) mount helper GUI (to simplify the various configuration options on mount) |
55 | 55 | ||
56 | p) autonegotiation of dialects (offering more than one dialect ie SMB3.02, | 56 | p) Add support for witness protocol (perhaps ioctl to cifs.ko from user space |
57 | SMB3, SMB2.1 not just SMB3). | 57 | tool listening on witness protocol RPC) to allow for notification of share |
58 | move, server failover, and server adapter changes. And also improve other | ||
59 | failover scenarios, e.g. when client knows multiple DFS entries point to | ||
60 | different servers, and the server we are connected to has gone down. | ||
58 | 61 | ||
59 | q) Allow mount.cifs to be more verbose in reporting errors with dialect | 62 | q) Allow mount.cifs to be more verbose in reporting errors with dialect |
60 | or unsupported feature errors. | 63 | or unsupported feature errors. |
61 | 64 | ||
62 | r) updating cifs documentation, and user guid. | 65 | r) updating cifs documentation, and user guide. |
63 | 66 | ||
64 | s) Addressing bugs found by running a broader set of xfstests in standard | 67 | s) Addressing bugs found by running a broader set of xfstests in standard |
65 | file system xfstest suite. | 68 | file system xfstest suite. |
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig index 687da62daf4e..741749a98614 100644 --- a/fs/cifs/Kconfig +++ b/fs/cifs/Kconfig | |||
@@ -187,13 +187,13 @@ config CIFS_NFSD_EXPORT | |||
187 | Allows NFS server to export a CIFS mounted share (nfsd over cifs) | 187 | Allows NFS server to export a CIFS mounted share (nfsd over cifs) |
188 | 188 | ||
189 | config CIFS_SMB311 | 189 | config CIFS_SMB311 |
190 | bool "SMB3.1.1 network file system support (Experimental)" | 190 | bool "SMB3.1.1 network file system support" |
191 | depends on CIFS | 191 | depends on CIFS |
192 | select CRYPTO_SHA512 | ||
192 | 193 | ||
193 | help | 194 | help |
194 | This enables experimental support for the newest, SMB3.1.1, dialect. | 195 | This enables support for the newest, and most secure dialect, SMB3.11. |
195 | This dialect includes improved security negotiation features. | 196 | If unsure, say Y |
196 | If unsure, say N | ||
197 | 197 | ||
198 | config CIFS_SMB_DIRECT | 198 | config CIFS_SMB_DIRECT |
199 | bool "SMB Direct support (Experimental)" | 199 | bool "SMB Direct support (Experimental)" |
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index f2b0a7f124da..a6ef088e057b 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
@@ -36,37 +36,6 @@ | |||
36 | #include <crypto/skcipher.h> | 36 | #include <crypto/skcipher.h> |
37 | #include <crypto/aead.h> | 37 | #include <crypto/aead.h> |
38 | 38 | ||
39 | static int | ||
40 | cifs_crypto_shash_md5_allocate(struct TCP_Server_Info *server) | ||
41 | { | ||
42 | int rc; | ||
43 | unsigned int size; | ||
44 | |||
45 | if (server->secmech.sdescmd5 != NULL) | ||
46 | return 0; /* already allocated */ | ||
47 | |||
48 | server->secmech.md5 = crypto_alloc_shash("md5", 0, 0); | ||
49 | if (IS_ERR(server->secmech.md5)) { | ||
50 | cifs_dbg(VFS, "could not allocate crypto md5\n"); | ||
51 | rc = PTR_ERR(server->secmech.md5); | ||
52 | server->secmech.md5 = NULL; | ||
53 | return rc; | ||
54 | } | ||
55 | |||
56 | size = sizeof(struct shash_desc) + | ||
57 | crypto_shash_descsize(server->secmech.md5); | ||
58 | server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL); | ||
59 | if (!server->secmech.sdescmd5) { | ||
60 | crypto_free_shash(server->secmech.md5); | ||
61 | server->secmech.md5 = NULL; | ||
62 | return -ENOMEM; | ||
63 | } | ||
64 | server->secmech.sdescmd5->shash.tfm = server->secmech.md5; | ||
65 | server->secmech.sdescmd5->shash.flags = 0x0; | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | int __cifs_calc_signature(struct smb_rqst *rqst, | 39 | int __cifs_calc_signature(struct smb_rqst *rqst, |
71 | struct TCP_Server_Info *server, char *signature, | 40 | struct TCP_Server_Info *server, char *signature, |
72 | struct shash_desc *shash) | 41 | struct shash_desc *shash) |
@@ -132,13 +101,10 @@ static int cifs_calc_signature(struct smb_rqst *rqst, | |||
132 | if (!rqst->rq_iov || !signature || !server) | 101 | if (!rqst->rq_iov || !signature || !server) |
133 | return -EINVAL; | 102 | return -EINVAL; |
134 | 103 | ||
135 | if (!server->secmech.sdescmd5) { | 104 | rc = cifs_alloc_hash("md5", &server->secmech.md5, |
136 | rc = cifs_crypto_shash_md5_allocate(server); | 105 | &server->secmech.sdescmd5); |
137 | if (rc) { | 106 | if (rc) |
138 | cifs_dbg(VFS, "%s: Can't alloc md5 crypto\n", __func__); | 107 | return -1; |
139 | return -1; | ||
140 | } | ||
141 | } | ||
142 | 108 | ||
143 | rc = crypto_shash_init(&server->secmech.sdescmd5->shash); | 109 | rc = crypto_shash_init(&server->secmech.sdescmd5->shash); |
144 | if (rc) { | 110 | if (rc) { |
@@ -663,37 +629,6 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash) | |||
663 | return rc; | 629 | return rc; |
664 | } | 630 | } |
665 | 631 | ||
666 | static int crypto_hmacmd5_alloc(struct TCP_Server_Info *server) | ||
667 | { | ||
668 | int rc; | ||
669 | unsigned int size; | ||
670 | |||
671 | /* check if already allocated */ | ||
672 | if (server->secmech.sdeschmacmd5) | ||
673 | return 0; | ||
674 | |||
675 | server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0); | ||
676 | if (IS_ERR(server->secmech.hmacmd5)) { | ||
677 | cifs_dbg(VFS, "could not allocate crypto hmacmd5\n"); | ||
678 | rc = PTR_ERR(server->secmech.hmacmd5); | ||
679 | server->secmech.hmacmd5 = NULL; | ||
680 | return rc; | ||
681 | } | ||
682 | |||
683 | size = sizeof(struct shash_desc) + | ||
684 | crypto_shash_descsize(server->secmech.hmacmd5); | ||
685 | server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL); | ||
686 | if (!server->secmech.sdeschmacmd5) { | ||
687 | crypto_free_shash(server->secmech.hmacmd5); | ||
688 | server->secmech.hmacmd5 = NULL; | ||
689 | return -ENOMEM; | ||
690 | } | ||
691 | server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5; | ||
692 | server->secmech.sdeschmacmd5->shash.flags = 0x0; | ||
693 | |||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | int | 632 | int |
698 | setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) | 633 | setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) |
699 | { | 634 | { |
@@ -757,9 +692,10 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) | |||
757 | 692 | ||
758 | mutex_lock(&ses->server->srv_mutex); | 693 | mutex_lock(&ses->server->srv_mutex); |
759 | 694 | ||
760 | rc = crypto_hmacmd5_alloc(ses->server); | 695 | rc = cifs_alloc_hash("hmac(md5)", |
696 | &ses->server->secmech.hmacmd5, | ||
697 | &ses->server->secmech.sdeschmacmd5); | ||
761 | if (rc) { | 698 | if (rc) { |
762 | cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc); | ||
763 | goto unlock; | 699 | goto unlock; |
764 | } | 700 | } |
765 | 701 | ||
@@ -893,6 +829,11 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server) | |||
893 | server->secmech.md5 = NULL; | 829 | server->secmech.md5 = NULL; |
894 | } | 830 | } |
895 | 831 | ||
832 | if (server->secmech.sha512) { | ||
833 | crypto_free_shash(server->secmech.sha512); | ||
834 | server->secmech.sha512 = NULL; | ||
835 | } | ||
836 | |||
896 | if (server->secmech.hmacmd5) { | 837 | if (server->secmech.hmacmd5) { |
897 | crypto_free_shash(server->secmech.hmacmd5); | 838 | crypto_free_shash(server->secmech.hmacmd5); |
898 | server->secmech.hmacmd5 = NULL; | 839 | server->secmech.hmacmd5 = NULL; |
@@ -916,4 +857,6 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server) | |||
916 | server->secmech.sdeschmacmd5 = NULL; | 857 | server->secmech.sdeschmacmd5 = NULL; |
917 | kfree(server->secmech.sdescmd5); | 858 | kfree(server->secmech.sdescmd5); |
918 | server->secmech.sdescmd5 = NULL; | 859 | server->secmech.sdescmd5 = NULL; |
860 | kfree(server->secmech.sdescsha512); | ||
861 | server->secmech.sdescsha512 = NULL; | ||
919 | } | 862 | } |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 32cdea67bbfd..f715609b13f3 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -1486,6 +1486,7 @@ MODULE_SOFTDEP("pre: nls"); | |||
1486 | MODULE_SOFTDEP("pre: aes"); | 1486 | MODULE_SOFTDEP("pre: aes"); |
1487 | MODULE_SOFTDEP("pre: cmac"); | 1487 | MODULE_SOFTDEP("pre: cmac"); |
1488 | MODULE_SOFTDEP("pre: sha256"); | 1488 | MODULE_SOFTDEP("pre: sha256"); |
1489 | MODULE_SOFTDEP("pre: sha512"); | ||
1489 | MODULE_SOFTDEP("pre: aead2"); | 1490 | MODULE_SOFTDEP("pre: aead2"); |
1490 | MODULE_SOFTDEP("pre: ccm"); | 1491 | MODULE_SOFTDEP("pre: ccm"); |
1491 | module_init(init_cifs) | 1492 | module_init(init_cifs) |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 48f7c197cd2d..2282562e78a1 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -130,10 +130,12 @@ struct cifs_secmech { | |||
130 | struct crypto_shash *md5; /* md5 hash function */ | 130 | struct crypto_shash *md5; /* md5 hash function */ |
131 | struct crypto_shash *hmacsha256; /* hmac-sha256 hash function */ | 131 | struct crypto_shash *hmacsha256; /* hmac-sha256 hash function */ |
132 | struct crypto_shash *cmacaes; /* block-cipher based MAC function */ | 132 | struct crypto_shash *cmacaes; /* block-cipher based MAC function */ |
133 | struct crypto_shash *sha512; /* sha512 hash function */ | ||
133 | struct sdesc *sdeschmacmd5; /* ctxt to generate ntlmv2 hash, CR1 */ | 134 | struct sdesc *sdeschmacmd5; /* ctxt to generate ntlmv2 hash, CR1 */ |
134 | struct sdesc *sdescmd5; /* ctxt to generate cifs/smb signature */ | 135 | struct sdesc *sdescmd5; /* ctxt to generate cifs/smb signature */ |
135 | struct sdesc *sdeschmacsha256; /* ctxt to generate smb2 signature */ | 136 | struct sdesc *sdeschmacsha256; /* ctxt to generate smb2 signature */ |
136 | struct sdesc *sdesccmacaes; /* ctxt to generate smb3 signature */ | 137 | struct sdesc *sdesccmacaes; /* ctxt to generate smb3 signature */ |
138 | struct sdesc *sdescsha512; /* ctxt to generate smb3.11 signing key */ | ||
137 | struct crypto_aead *ccmaesencrypt; /* smb3 encryption aead */ | 139 | struct crypto_aead *ccmaesencrypt; /* smb3 encryption aead */ |
138 | struct crypto_aead *ccmaesdecrypt; /* smb3 decryption aead */ | 140 | struct crypto_aead *ccmaesdecrypt; /* smb3 decryption aead */ |
139 | }; | 141 | }; |
@@ -466,6 +468,7 @@ struct smb_version_values { | |||
466 | __u32 exclusive_lock_type; | 468 | __u32 exclusive_lock_type; |
467 | __u32 shared_lock_type; | 469 | __u32 shared_lock_type; |
468 | __u32 unlock_lock_type; | 470 | __u32 unlock_lock_type; |
471 | size_t header_preamble_size; | ||
469 | size_t header_size; | 472 | size_t header_size; |
470 | size_t max_header_size; | 473 | size_t max_header_size; |
471 | size_t read_rsp_size; | 474 | size_t read_rsp_size; |
@@ -673,7 +676,8 @@ struct TCP_Server_Info { | |||
673 | unsigned int max_read; | 676 | unsigned int max_read; |
674 | unsigned int max_write; | 677 | unsigned int max_write; |
675 | #ifdef CONFIG_CIFS_SMB311 | 678 | #ifdef CONFIG_CIFS_SMB311 |
676 | __u8 preauth_sha_hash[64]; /* save initital negprot hash */ | 679 | /* save initital negprot hash */ |
680 | __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; | ||
677 | #endif /* 3.1.1 */ | 681 | #endif /* 3.1.1 */ |
678 | struct delayed_work reconnect; /* reconnect workqueue job */ | 682 | struct delayed_work reconnect; /* reconnect workqueue job */ |
679 | struct mutex reconnect_mutex; /* prevent simultaneous reconnects */ | 683 | struct mutex reconnect_mutex; /* prevent simultaneous reconnects */ |
@@ -862,7 +866,7 @@ struct cifs_ses { | |||
862 | __u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE]; | 866 | __u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE]; |
863 | __u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE]; | 867 | __u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE]; |
864 | #ifdef CONFIG_CIFS_SMB311 | 868 | #ifdef CONFIG_CIFS_SMB311 |
865 | __u8 preauth_sha_hash[64]; | 869 | __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; |
866 | #endif /* 3.1.1 */ | 870 | #endif /* 3.1.1 */ |
867 | }; | 871 | }; |
868 | 872 | ||
@@ -1466,6 +1470,7 @@ struct dfs_info3_param { | |||
1466 | #define CIFS_FATTR_NEED_REVAL 0x4 | 1470 | #define CIFS_FATTR_NEED_REVAL 0x4 |
1467 | #define CIFS_FATTR_INO_COLLISION 0x8 | 1471 | #define CIFS_FATTR_INO_COLLISION 0x8 |
1468 | #define CIFS_FATTR_UNKNOWN_NLINK 0x10 | 1472 | #define CIFS_FATTR_UNKNOWN_NLINK 0x10 |
1473 | #define CIFS_FATTR_FAKE_ROOT_INO 0x20 | ||
1469 | 1474 | ||
1470 | struct cifs_fattr { | 1475 | struct cifs_fattr { |
1471 | u32 cf_flags; | 1476 | u32 cf_flags; |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 93d565186698..365a414a75e9 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -542,4 +542,9 @@ enum securityEnum cifs_select_sectype(struct TCP_Server_Info *, | |||
542 | struct cifs_aio_ctx *cifs_aio_ctx_alloc(void); | 542 | struct cifs_aio_ctx *cifs_aio_ctx_alloc(void); |
543 | void cifs_aio_ctx_release(struct kref *refcount); | 543 | void cifs_aio_ctx_release(struct kref *refcount); |
544 | int setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw); | 544 | int setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw); |
545 | |||
546 | int cifs_alloc_hash(const char *name, struct crypto_shash **shash, | ||
547 | struct sdesc **sdesc); | ||
548 | void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc); | ||
549 | |||
545 | #endif /* _CIFSPROTO_H */ | 550 | #endif /* _CIFSPROTO_H */ |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 9ceebf30eb22..59c09a596c0a 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -1454,7 +1454,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) | |||
1454 | unsigned int data_offset, data_len; | 1454 | unsigned int data_offset, data_len; |
1455 | struct cifs_readdata *rdata = mid->callback_data; | 1455 | struct cifs_readdata *rdata = mid->callback_data; |
1456 | char *buf = server->smallbuf; | 1456 | char *buf = server->smallbuf; |
1457 | unsigned int buflen = get_rfc1002_length(buf) + 4; | 1457 | unsigned int buflen = get_rfc1002_length(buf) + |
1458 | server->vals->header_preamble_size; | ||
1458 | bool use_rdma_mr = false; | 1459 | bool use_rdma_mr = false; |
1459 | 1460 | ||
1460 | cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n", | 1461 | cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n", |
@@ -1504,7 +1505,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) | |||
1504 | return cifs_readv_discard(server, mid); | 1505 | return cifs_readv_discard(server, mid); |
1505 | } | 1506 | } |
1506 | 1507 | ||
1507 | data_offset = server->ops->read_data_offset(buf) + 4; | 1508 | data_offset = server->ops->read_data_offset(buf) + |
1509 | server->vals->header_preamble_size; | ||
1508 | if (data_offset < server->total_read) { | 1510 | if (data_offset < server->total_read) { |
1509 | /* | 1511 | /* |
1510 | * win2k8 sometimes sends an offset of 0 when the read | 1512 | * win2k8 sometimes sends an offset of 0 when the read |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index a726f524fb84..4e0808f40195 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -775,7 +775,8 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid) | |||
775 | unsigned int pdu_length = get_rfc1002_length(buf); | 775 | unsigned int pdu_length = get_rfc1002_length(buf); |
776 | 776 | ||
777 | /* make sure this will fit in a large buffer */ | 777 | /* make sure this will fit in a large buffer */ |
778 | if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - 4) { | 778 | if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - |
779 | server->vals->header_preamble_size) { | ||
779 | cifs_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length); | 780 | cifs_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length); |
780 | cifs_reconnect(server); | 781 | cifs_reconnect(server); |
781 | wake_up(&server->response_q); | 782 | wake_up(&server->response_q); |
@@ -791,7 +792,9 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid) | |||
791 | 792 | ||
792 | /* now read the rest */ | 793 | /* now read the rest */ |
793 | length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1, | 794 | length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1, |
794 | pdu_length - HEADER_SIZE(server) + 1 + 4); | 795 | pdu_length - HEADER_SIZE(server) + 1 |
796 | + server->vals->header_preamble_size); | ||
797 | |||
795 | if (length < 0) | 798 | if (length < 0) |
796 | return length; | 799 | return length; |
797 | server->total_read += length; | 800 | server->total_read += length; |
@@ -884,7 +887,8 @@ cifs_demultiplex_thread(void *p) | |||
884 | continue; | 887 | continue; |
885 | 888 | ||
886 | /* make sure we have enough to get to the MID */ | 889 | /* make sure we have enough to get to the MID */ |
887 | if (pdu_length < HEADER_SIZE(server) - 1 - 4) { | 890 | if (pdu_length < HEADER_SIZE(server) - 1 - |
891 | server->vals->header_preamble_size) { | ||
888 | cifs_dbg(VFS, "SMB response too short (%u bytes)\n", | 892 | cifs_dbg(VFS, "SMB response too short (%u bytes)\n", |
889 | pdu_length); | 893 | pdu_length); |
890 | cifs_reconnect(server); | 894 | cifs_reconnect(server); |
@@ -893,8 +897,10 @@ cifs_demultiplex_thread(void *p) | |||
893 | } | 897 | } |
894 | 898 | ||
895 | /* read down to the MID */ | 899 | /* read down to the MID */ |
896 | length = cifs_read_from_socket(server, buf + 4, | 900 | length = cifs_read_from_socket(server, |
897 | HEADER_SIZE(server) - 1 - 4); | 901 | buf + server->vals->header_preamble_size, |
902 | HEADER_SIZE(server) - 1 | ||
903 | - server->vals->header_preamble_size); | ||
898 | if (length < 0) | 904 | if (length < 0) |
899 | continue; | 905 | continue; |
900 | server->total_read += length; | 906 | server->total_read += length; |
@@ -4306,7 +4312,7 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, | |||
4306 | server->sec_mode, server->capabilities, server->timeAdj); | 4312 | server->sec_mode, server->capabilities, server->timeAdj); |
4307 | 4313 | ||
4308 | if (ses->auth_key.response) { | 4314 | if (ses->auth_key.response) { |
4309 | cifs_dbg(VFS, "Free previous auth_key.response = %p\n", | 4315 | cifs_dbg(FYI, "Free previous auth_key.response = %p\n", |
4310 | ses->auth_key.response); | 4316 | ses->auth_key.response); |
4311 | kfree(ses->auth_key.response); | 4317 | kfree(ses->auth_key.response); |
4312 | ses->auth_key.response = NULL; | 4318 | ses->auth_key.response = NULL; |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 8f9a8cc7cc62..f856df4adae3 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -707,6 +707,18 @@ cgfi_exit: | |||
707 | return rc; | 707 | return rc; |
708 | } | 708 | } |
709 | 709 | ||
710 | /* Simple function to return a 64 bit hash of string. Rarely called */ | ||
711 | static __u64 simple_hashstr(const char *str) | ||
712 | { | ||
713 | const __u64 hash_mult = 1125899906842597L; /* a big enough prime */ | ||
714 | __u64 hash = 0; | ||
715 | |||
716 | while (*str) | ||
717 | hash = (hash + (__u64) *str++) * hash_mult; | ||
718 | |||
719 | return hash; | ||
720 | } | ||
721 | |||
710 | int | 722 | int |
711 | cifs_get_inode_info(struct inode **inode, const char *full_path, | 723 | cifs_get_inode_info(struct inode **inode, const char *full_path, |
712 | FILE_ALL_INFO *data, struct super_block *sb, int xid, | 724 | FILE_ALL_INFO *data, struct super_block *sb, int xid, |
@@ -816,6 +828,14 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, | |||
816 | tmprc); | 828 | tmprc); |
817 | fattr.cf_uniqueid = iunique(sb, ROOT_I); | 829 | fattr.cf_uniqueid = iunique(sb, ROOT_I); |
818 | cifs_autodisable_serverino(cifs_sb); | 830 | cifs_autodisable_serverino(cifs_sb); |
831 | } else if ((fattr.cf_uniqueid == 0) && | ||
832 | strlen(full_path) == 0) { | ||
833 | /* some servers ret bad root ino ie 0 */ | ||
834 | cifs_dbg(FYI, "Invalid (0) inodenum\n"); | ||
835 | fattr.cf_flags |= | ||
836 | CIFS_FATTR_FAKE_ROOT_INO; | ||
837 | fattr.cf_uniqueid = | ||
838 | simple_hashstr(tcon->treeName); | ||
819 | } | 839 | } |
820 | } | 840 | } |
821 | } else | 841 | } else |
@@ -832,6 +852,16 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, | |||
832 | &fattr.cf_uniqueid, data); | 852 | &fattr.cf_uniqueid, data); |
833 | if (tmprc) | 853 | if (tmprc) |
834 | fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; | 854 | fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; |
855 | else if ((fattr.cf_uniqueid == 0) && | ||
856 | strlen(full_path) == 0) { | ||
857 | /* | ||
858 | * Reuse existing root inode num since | ||
859 | * inum zero for root causes ls of . and .. to | ||
860 | * not be returned | ||
861 | */ | ||
862 | cifs_dbg(FYI, "Srv ret 0 inode num for root\n"); | ||
863 | fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; | ||
864 | } | ||
835 | } else | 865 | } else |
836 | fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; | 866 | fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; |
837 | } | 867 | } |
@@ -893,6 +923,9 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, | |||
893 | } | 923 | } |
894 | 924 | ||
895 | cgii_exit: | 925 | cgii_exit: |
926 | if ((*inode) && ((*inode)->i_ino == 0)) | ||
927 | cifs_dbg(FYI, "inode number of zero returned\n"); | ||
928 | |||
896 | kfree(buf); | 929 | kfree(buf); |
897 | cifs_put_tlink(tlink); | 930 | cifs_put_tlink(tlink); |
898 | return rc; | 931 | return rc; |
@@ -1066,10 +1099,7 @@ iget_no_retry: | |||
1066 | 1099 | ||
1067 | out: | 1100 | out: |
1068 | kfree(path); | 1101 | kfree(path); |
1069 | /* can not call macro free_xid here since in a void func | 1102 | free_xid(xid); |
1070 | * TODO: This is no longer true | ||
1071 | */ | ||
1072 | _free_xid(xid); | ||
1073 | return inode; | 1103 | return inode; |
1074 | } | 1104 | } |
1075 | 1105 | ||
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 60b5a11ee11b..889a840172eb 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -50,25 +50,12 @@ static int | |||
50 | symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) | 50 | symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) |
51 | { | 51 | { |
52 | int rc; | 52 | int rc; |
53 | unsigned int size; | 53 | struct crypto_shash *md5 = NULL; |
54 | struct crypto_shash *md5; | 54 | struct sdesc *sdescmd5 = NULL; |
55 | struct sdesc *sdescmd5; | 55 | |
56 | 56 | rc = cifs_alloc_hash("md5", &md5, &sdescmd5); | |
57 | md5 = crypto_alloc_shash("md5", 0, 0); | 57 | if (rc) |
58 | if (IS_ERR(md5)) { | ||
59 | rc = PTR_ERR(md5); | ||
60 | cifs_dbg(VFS, "%s: Crypto md5 allocation error %d\n", | ||
61 | __func__, rc); | ||
62 | return rc; | ||
63 | } | ||
64 | size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); | ||
65 | sdescmd5 = kmalloc(size, GFP_KERNEL); | ||
66 | if (!sdescmd5) { | ||
67 | rc = -ENOMEM; | ||
68 | goto symlink_hash_err; | 58 | goto symlink_hash_err; |
69 | } | ||
70 | sdescmd5->shash.tfm = md5; | ||
71 | sdescmd5->shash.flags = 0x0; | ||
72 | 59 | ||
73 | rc = crypto_shash_init(&sdescmd5->shash); | 60 | rc = crypto_shash_init(&sdescmd5->shash); |
74 | if (rc) { | 61 | if (rc) { |
@@ -85,9 +72,7 @@ symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) | |||
85 | cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); | 72 | cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); |
86 | 73 | ||
87 | symlink_hash_err: | 74 | symlink_hash_err: |
88 | crypto_free_shash(md5); | 75 | cifs_free_hash(&md5, &sdescmd5); |
89 | kfree(sdescmd5); | ||
90 | |||
91 | return rc; | 76 | return rc; |
92 | } | 77 | } |
93 | 78 | ||
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index a0dbced4a45c..460084a8eac5 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -848,3 +848,57 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw) | |||
848 | iov_iter_bvec(&ctx->iter, ITER_BVEC | rw, ctx->bv, npages, ctx->len); | 848 | iov_iter_bvec(&ctx->iter, ITER_BVEC | rw, ctx->bv, npages, ctx->len); |
849 | return 0; | 849 | return 0; |
850 | } | 850 | } |
851 | |||
852 | /** | ||
853 | * cifs_alloc_hash - allocate hash and hash context together | ||
854 | * | ||
855 | * The caller has to make sure @sdesc is initialized to either NULL or | ||
856 | * a valid context. Both can be freed via cifs_free_hash(). | ||
857 | */ | ||
858 | int | ||
859 | cifs_alloc_hash(const char *name, | ||
860 | struct crypto_shash **shash, struct sdesc **sdesc) | ||
861 | { | ||
862 | int rc = 0; | ||
863 | size_t size; | ||
864 | |||
865 | if (*sdesc != NULL) | ||
866 | return 0; | ||
867 | |||
868 | *shash = crypto_alloc_shash(name, 0, 0); | ||
869 | if (IS_ERR(*shash)) { | ||
870 | cifs_dbg(VFS, "could not allocate crypto %s\n", name); | ||
871 | rc = PTR_ERR(*shash); | ||
872 | *shash = NULL; | ||
873 | *sdesc = NULL; | ||
874 | return rc; | ||
875 | } | ||
876 | |||
877 | size = sizeof(struct shash_desc) + crypto_shash_descsize(*shash); | ||
878 | *sdesc = kmalloc(size, GFP_KERNEL); | ||
879 | if (*sdesc == NULL) { | ||
880 | cifs_dbg(VFS, "no memory left to allocate crypto %s\n", name); | ||
881 | crypto_free_shash(*shash); | ||
882 | *shash = NULL; | ||
883 | return -ENOMEM; | ||
884 | } | ||
885 | |||
886 | (*sdesc)->shash.tfm = *shash; | ||
887 | (*sdesc)->shash.flags = 0x0; | ||
888 | return 0; | ||
889 | } | ||
890 | |||
891 | /** | ||
892 | * cifs_free_hash - free hash and hash context together | ||
893 | * | ||
894 | * Freeing a NULL hash or context is safe. | ||
895 | */ | ||
896 | void | ||
897 | cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc) | ||
898 | { | ||
899 | kfree(*sdesc); | ||
900 | *sdesc = NULL; | ||
901 | if (*shash) | ||
902 | crypto_free_shash(*shash); | ||
903 | *shash = NULL; | ||
904 | } | ||
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 3d495e440c87..aff8ce8ba34d 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -1122,6 +1122,7 @@ struct smb_version_values smb1_values = { | |||
1122 | .exclusive_lock_type = 0, | 1122 | .exclusive_lock_type = 0, |
1123 | .shared_lock_type = LOCKING_ANDX_SHARED_LOCK, | 1123 | .shared_lock_type = LOCKING_ANDX_SHARED_LOCK, |
1124 | .unlock_lock_type = 0, | 1124 | .unlock_lock_type = 0, |
1125 | .header_preamble_size = 4, | ||
1125 | .header_size = sizeof(struct smb_hdr), | 1126 | .header_size = sizeof(struct smb_hdr), |
1126 | .max_header_size = MAX_CIFS_HDR_SIZE, | 1127 | .max_header_size = MAX_CIFS_HDR_SIZE, |
1127 | .read_rsp_size = sizeof(READ_RSP), | 1128 | .read_rsp_size = sizeof(READ_RSP), |
diff --git a/fs/cifs/smb2maperror.c b/fs/cifs/smb2maperror.c index 62c88dfed57b..3bfc9c990724 100644 --- a/fs/cifs/smb2maperror.c +++ b/fs/cifs/smb2maperror.c | |||
@@ -745,7 +745,7 @@ static const struct status_to_posix_error smb2_error_map_table[] = { | |||
745 | "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT"}, | 745 | "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT"}, |
746 | {STATUS_DOMAIN_TRUST_INCONSISTENT, -EIO, | 746 | {STATUS_DOMAIN_TRUST_INCONSISTENT, -EIO, |
747 | "STATUS_DOMAIN_TRUST_INCONSISTENT"}, | 747 | "STATUS_DOMAIN_TRUST_INCONSISTENT"}, |
748 | {STATUS_FS_DRIVER_REQUIRED, -EIO, "STATUS_FS_DRIVER_REQUIRED"}, | 748 | {STATUS_FS_DRIVER_REQUIRED, -EOPNOTSUPP, "STATUS_FS_DRIVER_REQUIRED"}, |
749 | {STATUS_IMAGE_ALREADY_LOADED_AS_DLL, -EIO, | 749 | {STATUS_IMAGE_ALREADY_LOADED_AS_DLL, -EIO, |
750 | "STATUS_IMAGE_ALREADY_LOADED_AS_DLL"}, | 750 | "STATUS_IMAGE_ALREADY_LOADED_AS_DLL"}, |
751 | {STATUS_NETWORK_OPEN_RESTRICTION, -EIO, | 751 | {STATUS_NETWORK_OPEN_RESTRICTION, -EIO, |
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index 76d03abaa38c..5406e95f5d92 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c | |||
@@ -150,7 +150,8 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr) | |||
150 | } | 150 | } |
151 | return 1; | 151 | return 1; |
152 | } | 152 | } |
153 | if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE - 4) { | 153 | if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE - |
154 | srvr->vals->header_preamble_size) { | ||
154 | cifs_dbg(VFS, "SMB length greater than maximum, mid=%llu\n", | 155 | cifs_dbg(VFS, "SMB length greater than maximum, mid=%llu\n", |
155 | mid); | 156 | mid); |
156 | return 1; | 157 | return 1; |
@@ -189,26 +190,26 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr) | |||
189 | } | 190 | } |
190 | } | 191 | } |
191 | 192 | ||
192 | if (4 + len != length) { | 193 | if (srvr->vals->header_preamble_size + len != length) { |
193 | cifs_dbg(VFS, "Total length %u RFC1002 length %u mismatch mid %llu\n", | 194 | cifs_dbg(VFS, "Total length %u RFC1002 length %zu mismatch mid %llu\n", |
194 | length, 4 + len, mid); | 195 | length, srvr->vals->header_preamble_size + len, mid); |
195 | return 1; | 196 | return 1; |
196 | } | 197 | } |
197 | 198 | ||
198 | clc_len = smb2_calc_size(hdr); | 199 | clc_len = smb2_calc_size(hdr); |
199 | 200 | ||
200 | if (4 + len != clc_len) { | 201 | if (srvr->vals->header_preamble_size + len != clc_len) { |
201 | cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n", | 202 | cifs_dbg(FYI, "Calculated size %u length %zu mismatch mid %llu\n", |
202 | clc_len, 4 + len, mid); | 203 | clc_len, srvr->vals->header_preamble_size + len, mid); |
203 | /* create failed on symlink */ | 204 | /* create failed on symlink */ |
204 | if (command == SMB2_CREATE_HE && | 205 | if (command == SMB2_CREATE_HE && |
205 | shdr->Status == STATUS_STOPPED_ON_SYMLINK) | 206 | shdr->Status == STATUS_STOPPED_ON_SYMLINK) |
206 | return 0; | 207 | return 0; |
207 | /* Windows 7 server returns 24 bytes more */ | 208 | /* Windows 7 server returns 24 bytes more */ |
208 | if (clc_len + 20 == len && command == SMB2_OPLOCK_BREAK_HE) | 209 | if (clc_len + 24 - srvr->vals->header_preamble_size == len && command == SMB2_OPLOCK_BREAK_HE) |
209 | return 0; | 210 | return 0; |
210 | /* server can return one byte more due to implied bcc[0] */ | 211 | /* server can return one byte more due to implied bcc[0] */ |
211 | if (clc_len == 4 + len + 1) | 212 | if (clc_len == srvr->vals->header_preamble_size + len + 1) |
212 | return 0; | 213 | return 0; |
213 | 214 | ||
214 | /* | 215 | /* |
@@ -218,10 +219,10 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr) | |||
218 | * Log the server error (once), but allow it and continue | 219 | * Log the server error (once), but allow it and continue |
219 | * since the frame is parseable. | 220 | * since the frame is parseable. |
220 | */ | 221 | */ |
221 | if (clc_len < 4 /* RFC1001 header size */ + len) { | 222 | if (clc_len < srvr->vals->header_preamble_size /* RFC1001 header size */ + len) { |
222 | printk_once(KERN_WARNING | 223 | printk_once(KERN_WARNING |
223 | "SMB2 server sent bad RFC1001 len %d not %d\n", | 224 | "SMB2 server sent bad RFC1001 len %d not %zu\n", |
224 | len, clc_len - 4); | 225 | len, clc_len - srvr->vals->header_preamble_size); |
225 | return 0; | 226 | return 0; |
226 | } | 227 | } |
227 | 228 | ||
@@ -706,3 +707,67 @@ smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server) | |||
706 | 707 | ||
707 | return 0; | 708 | return 0; |
708 | } | 709 | } |
710 | |||
711 | #ifdef CONFIG_CIFS_SMB311 | ||
712 | /** | ||
713 | * smb311_update_preauth_hash - update @ses hash with the packet data in @iov | ||
714 | * | ||
715 | * Assumes @iov does not contain the rfc1002 length and iov[0] has the | ||
716 | * SMB2 header. | ||
717 | */ | ||
718 | int | ||
719 | smb311_update_preauth_hash(struct cifs_ses *ses, struct kvec *iov, int nvec) | ||
720 | { | ||
721 | int i, rc; | ||
722 | struct sdesc *d; | ||
723 | struct smb2_sync_hdr *hdr; | ||
724 | |||
725 | if (ses->server->tcpStatus == CifsGood) { | ||
726 | /* skip non smb311 connections */ | ||
727 | if (ses->server->dialect != SMB311_PROT_ID) | ||
728 | return 0; | ||
729 | |||
730 | /* skip last sess setup response */ | ||
731 | hdr = (struct smb2_sync_hdr *)iov[0].iov_base; | ||
732 | if (hdr->Flags & SMB2_FLAGS_SIGNED) | ||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | rc = smb311_crypto_shash_allocate(ses->server); | ||
737 | if (rc) | ||
738 | return rc; | ||
739 | |||
740 | d = ses->server->secmech.sdescsha512; | ||
741 | rc = crypto_shash_init(&d->shash); | ||
742 | if (rc) { | ||
743 | cifs_dbg(VFS, "%s: could not init sha512 shash\n", __func__); | ||
744 | return rc; | ||
745 | } | ||
746 | |||
747 | rc = crypto_shash_update(&d->shash, ses->preauth_sha_hash, | ||
748 | SMB2_PREAUTH_HASH_SIZE); | ||
749 | if (rc) { | ||
750 | cifs_dbg(VFS, "%s: could not update sha512 shash\n", __func__); | ||
751 | return rc; | ||
752 | } | ||
753 | |||
754 | for (i = 0; i < nvec; i++) { | ||
755 | rc = crypto_shash_update(&d->shash, | ||
756 | iov[i].iov_base, iov[i].iov_len); | ||
757 | if (rc) { | ||
758 | cifs_dbg(VFS, "%s: could not update sha512 shash\n", | ||
759 | __func__); | ||
760 | return rc; | ||
761 | } | ||
762 | } | ||
763 | |||
764 | rc = crypto_shash_final(&d->shash, ses->preauth_sha_hash); | ||
765 | if (rc) { | ||
766 | cifs_dbg(VFS, "%s: could not finalize sha512 shash\n", | ||
767 | __func__); | ||
768 | return rc; | ||
769 | } | ||
770 | |||
771 | return 0; | ||
772 | } | ||
773 | #endif | ||
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index eb68e2fcc500..968b1d43a1ea 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -1412,7 +1412,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, | |||
1412 | } while (rc == -EAGAIN); | 1412 | } while (rc == -EAGAIN); |
1413 | 1413 | ||
1414 | if (rc) { | 1414 | if (rc) { |
1415 | if (rc != -ENOENT) | 1415 | if ((rc != -ENOENT) && (rc != -EOPNOTSUPP)) |
1416 | cifs_dbg(VFS, "ioctl error in smb2_get_dfs_refer rc=%d\n", rc); | 1416 | cifs_dbg(VFS, "ioctl error in smb2_get_dfs_refer rc=%d\n", rc); |
1417 | goto out; | 1417 | goto out; |
1418 | } | 1418 | } |
@@ -1457,6 +1457,8 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
1457 | unsigned int sub_offset; | 1457 | unsigned int sub_offset; |
1458 | unsigned int print_len; | 1458 | unsigned int print_len; |
1459 | unsigned int print_offset; | 1459 | unsigned int print_offset; |
1460 | struct cifs_ses *ses = tcon->ses; | ||
1461 | struct TCP_Server_Info *server = ses->server; | ||
1460 | 1462 | ||
1461 | cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); | 1463 | cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); |
1462 | 1464 | ||
@@ -1479,7 +1481,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
1479 | } | 1481 | } |
1480 | 1482 | ||
1481 | if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) || | 1483 | if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) || |
1482 | get_rfc1002_length(err_buf) + 4 < SMB2_SYMLINK_STRUCT_SIZE) { | 1484 | get_rfc1002_length(err_buf) + server->vals->header_preamble_size < SMB2_SYMLINK_STRUCT_SIZE) { |
1483 | kfree(utf16_path); | 1485 | kfree(utf16_path); |
1484 | return -ENOENT; | 1486 | return -ENOENT; |
1485 | } | 1487 | } |
@@ -1492,13 +1494,13 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
1492 | print_len = le16_to_cpu(symlink->PrintNameLength); | 1494 | print_len = le16_to_cpu(symlink->PrintNameLength); |
1493 | print_offset = le16_to_cpu(symlink->PrintNameOffset); | 1495 | print_offset = le16_to_cpu(symlink->PrintNameOffset); |
1494 | 1496 | ||
1495 | if (get_rfc1002_length(err_buf) + 4 < | 1497 | if (get_rfc1002_length(err_buf) + server->vals->header_preamble_size < |
1496 | SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) { | 1498 | SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) { |
1497 | kfree(utf16_path); | 1499 | kfree(utf16_path); |
1498 | return -ENOENT; | 1500 | return -ENOENT; |
1499 | } | 1501 | } |
1500 | 1502 | ||
1501 | if (get_rfc1002_length(err_buf) + 4 < | 1503 | if (get_rfc1002_length(err_buf) + server->vals->header_preamble_size < |
1502 | SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) { | 1504 | SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) { |
1503 | kfree(utf16_path); | 1505 | kfree(utf16_path); |
1504 | return -ENOENT; | 1506 | return -ENOENT; |
@@ -2050,7 +2052,8 @@ smb2_dir_needs_close(struct cifsFileInfo *cfile) | |||
2050 | } | 2052 | } |
2051 | 2053 | ||
2052 | static void | 2054 | static void |
2053 | fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, struct smb_rqst *old_rq) | 2055 | fill_transform_hdr(struct TCP_Server_Info *server, |
2056 | struct smb2_transform_hdr *tr_hdr, struct smb_rqst *old_rq) | ||
2054 | { | 2057 | { |
2055 | struct smb2_sync_hdr *shdr = | 2058 | struct smb2_sync_hdr *shdr = |
2056 | (struct smb2_sync_hdr *)old_rq->rq_iov[1].iov_base; | 2059 | (struct smb2_sync_hdr *)old_rq->rq_iov[1].iov_base; |
@@ -2062,10 +2065,19 @@ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, struct smb_rqst *old_rq) | |||
2062 | tr_hdr->Flags = cpu_to_le16(0x01); | 2065 | tr_hdr->Flags = cpu_to_le16(0x01); |
2063 | get_random_bytes(&tr_hdr->Nonce, SMB3_AES128CMM_NONCE); | 2066 | get_random_bytes(&tr_hdr->Nonce, SMB3_AES128CMM_NONCE); |
2064 | memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8); | 2067 | memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8); |
2065 | inc_rfc1001_len(tr_hdr, sizeof(struct smb2_transform_hdr) - 4); | 2068 | inc_rfc1001_len(tr_hdr, sizeof(struct smb2_transform_hdr) - server->vals->header_preamble_size); |
2066 | inc_rfc1001_len(tr_hdr, orig_len); | 2069 | inc_rfc1001_len(tr_hdr, orig_len); |
2067 | } | 2070 | } |
2068 | 2071 | ||
2072 | /* We can not use the normal sg_set_buf() as we will sometimes pass a | ||
2073 | * stack object as buf. | ||
2074 | */ | ||
2075 | static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf, | ||
2076 | unsigned int buflen) | ||
2077 | { | ||
2078 | sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); | ||
2079 | } | ||
2080 | |||
2069 | static struct scatterlist * | 2081 | static struct scatterlist * |
2070 | init_sg(struct smb_rqst *rqst, u8 *sign) | 2082 | init_sg(struct smb_rqst *rqst, u8 *sign) |
2071 | { | 2083 | { |
@@ -2080,16 +2092,16 @@ init_sg(struct smb_rqst *rqst, u8 *sign) | |||
2080 | return NULL; | 2092 | return NULL; |
2081 | 2093 | ||
2082 | sg_init_table(sg, sg_len); | 2094 | sg_init_table(sg, sg_len); |
2083 | sg_set_buf(&sg[0], rqst->rq_iov[0].iov_base + 24, assoc_data_len); | 2095 | smb2_sg_set_buf(&sg[0], rqst->rq_iov[0].iov_base + 24, assoc_data_len); |
2084 | for (i = 1; i < rqst->rq_nvec; i++) | 2096 | for (i = 1; i < rqst->rq_nvec; i++) |
2085 | sg_set_buf(&sg[i], rqst->rq_iov[i].iov_base, | 2097 | smb2_sg_set_buf(&sg[i], rqst->rq_iov[i].iov_base, |
2086 | rqst->rq_iov[i].iov_len); | 2098 | rqst->rq_iov[i].iov_len); |
2087 | for (j = 0; i < sg_len - 1; i++, j++) { | 2099 | for (j = 0; i < sg_len - 1; i++, j++) { |
2088 | unsigned int len = (j < rqst->rq_npages - 1) ? rqst->rq_pagesz | 2100 | unsigned int len = (j < rqst->rq_npages - 1) ? rqst->rq_pagesz |
2089 | : rqst->rq_tailsz; | 2101 | : rqst->rq_tailsz; |
2090 | sg_set_page(&sg[i], rqst->rq_pages[j], len, 0); | 2102 | sg_set_page(&sg[i], rqst->rq_pages[j], len, 0); |
2091 | } | 2103 | } |
2092 | sg_set_buf(&sg[sg_len - 1], sign, SMB2_SIGNATURE_SIZE); | 2104 | smb2_sg_set_buf(&sg[sg_len - 1], sign, SMB2_SIGNATURE_SIZE); |
2093 | return sg; | 2105 | return sg; |
2094 | } | 2106 | } |
2095 | 2107 | ||
@@ -2125,7 +2137,7 @@ crypt_message(struct TCP_Server_Info *server, struct smb_rqst *rqst, int enc) | |||
2125 | { | 2137 | { |
2126 | struct smb2_transform_hdr *tr_hdr = | 2138 | struct smb2_transform_hdr *tr_hdr = |
2127 | (struct smb2_transform_hdr *)rqst->rq_iov[0].iov_base; | 2139 | (struct smb2_transform_hdr *)rqst->rq_iov[0].iov_base; |
2128 | unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24; | 2140 | unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20 - server->vals->header_preamble_size; |
2129 | int rc = 0; | 2141 | int rc = 0; |
2130 | struct scatterlist *sg; | 2142 | struct scatterlist *sg; |
2131 | u8 sign[SMB2_SIGNATURE_SIZE] = {}; | 2143 | u8 sign[SMB2_SIGNATURE_SIZE] = {}; |
@@ -2253,7 +2265,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, struct smb_rqst *new_rq, | |||
2253 | goto err_free_iov; | 2265 | goto err_free_iov; |
2254 | 2266 | ||
2255 | /* fill the 1st iov with a transform header */ | 2267 | /* fill the 1st iov with a transform header */ |
2256 | fill_transform_hdr(tr_hdr, old_rq); | 2268 | fill_transform_hdr(server, tr_hdr, old_rq); |
2257 | new_rq->rq_iov[0].iov_base = tr_hdr; | 2269 | new_rq->rq_iov[0].iov_base = tr_hdr; |
2258 | new_rq->rq_iov[0].iov_len = sizeof(struct smb2_transform_hdr); | 2270 | new_rq->rq_iov[0].iov_len = sizeof(struct smb2_transform_hdr); |
2259 | 2271 | ||
@@ -2335,10 +2347,10 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf, | |||
2335 | if (rc) | 2347 | if (rc) |
2336 | return rc; | 2348 | return rc; |
2337 | 2349 | ||
2338 | memmove(buf + 4, iov[1].iov_base, buf_data_size); | 2350 | memmove(buf + server->vals->header_preamble_size, iov[1].iov_base, buf_data_size); |
2339 | hdr = (struct smb2_hdr *)buf; | 2351 | hdr = (struct smb2_hdr *)buf; |
2340 | hdr->smb2_buf_length = cpu_to_be32(buf_data_size + page_data_size); | 2352 | hdr->smb2_buf_length = cpu_to_be32(buf_data_size + page_data_size); |
2341 | server->total_read = buf_data_size + page_data_size + 4; | 2353 | server->total_read = buf_data_size + page_data_size + server->vals->header_preamble_size; |
2342 | 2354 | ||
2343 | return rc; | 2355 | return rc; |
2344 | } | 2356 | } |
@@ -2442,7 +2454,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, | |||
2442 | return 0; | 2454 | return 0; |
2443 | } | 2455 | } |
2444 | 2456 | ||
2445 | data_offset = server->ops->read_data_offset(buf) + 4; | 2457 | data_offset = server->ops->read_data_offset(buf) + server->vals->header_preamble_size; |
2446 | #ifdef CONFIG_CIFS_SMB_DIRECT | 2458 | #ifdef CONFIG_CIFS_SMB_DIRECT |
2447 | use_rdma_mr = rdata->mr; | 2459 | use_rdma_mr = rdata->mr; |
2448 | #endif | 2460 | #endif |
@@ -2538,11 +2550,12 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid) | |||
2538 | unsigned int npages; | 2550 | unsigned int npages; |
2539 | struct page **pages; | 2551 | struct page **pages; |
2540 | unsigned int len; | 2552 | unsigned int len; |
2541 | unsigned int buflen = get_rfc1002_length(buf) + 4; | 2553 | unsigned int buflen = get_rfc1002_length(buf) + server->vals->header_preamble_size; |
2542 | int rc; | 2554 | int rc; |
2543 | int i = 0; | 2555 | int i = 0; |
2544 | 2556 | ||
2545 | len = min_t(unsigned int, buflen, server->vals->read_rsp_size - 4 + | 2557 | len = min_t(unsigned int, buflen, server->vals->read_rsp_size - |
2558 | server->vals->header_preamble_size + | ||
2546 | sizeof(struct smb2_transform_hdr)) - HEADER_SIZE(server) + 1; | 2559 | sizeof(struct smb2_transform_hdr)) - HEADER_SIZE(server) + 1; |
2547 | 2560 | ||
2548 | rc = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1, len); | 2561 | rc = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1, len); |
@@ -2550,8 +2563,9 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid) | |||
2550 | return rc; | 2563 | return rc; |
2551 | server->total_read += rc; | 2564 | server->total_read += rc; |
2552 | 2565 | ||
2553 | len = le32_to_cpu(tr_hdr->OriginalMessageSize) + 4 - | 2566 | len = le32_to_cpu(tr_hdr->OriginalMessageSize) + |
2554 | server->vals->read_rsp_size; | 2567 | server->vals->header_preamble_size - |
2568 | server->vals->read_rsp_size; | ||
2555 | npages = DIV_ROUND_UP(len, PAGE_SIZE); | 2569 | npages = DIV_ROUND_UP(len, PAGE_SIZE); |
2556 | 2570 | ||
2557 | pages = kmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); | 2571 | pages = kmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); |
@@ -2577,7 +2591,8 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid) | |||
2577 | if (rc) | 2591 | if (rc) |
2578 | goto free_pages; | 2592 | goto free_pages; |
2579 | 2593 | ||
2580 | rc = decrypt_raw_data(server, buf, server->vals->read_rsp_size - 4, | 2594 | rc = decrypt_raw_data(server, buf, server->vals->read_rsp_size - |
2595 | server->vals->header_preamble_size, | ||
2581 | pages, npages, len); | 2596 | pages, npages, len); |
2582 | if (rc) | 2597 | if (rc) |
2583 | goto free_pages; | 2598 | goto free_pages; |
@@ -2614,7 +2629,7 @@ receive_encrypted_standard(struct TCP_Server_Info *server, | |||
2614 | struct mid_q_entry *mid_entry; | 2629 | struct mid_q_entry *mid_entry; |
2615 | 2630 | ||
2616 | /* switch to large buffer if too big for a small one */ | 2631 | /* switch to large buffer if too big for a small one */ |
2617 | if (pdu_length + 4 > MAX_CIFS_SMALL_BUFFER_SIZE) { | 2632 | if (pdu_length + server->vals->header_preamble_size > MAX_CIFS_SMALL_BUFFER_SIZE) { |
2618 | server->large_buf = true; | 2633 | server->large_buf = true; |
2619 | memcpy(server->bigbuf, buf, server->total_read); | 2634 | memcpy(server->bigbuf, buf, server->total_read); |
2620 | buf = server->bigbuf; | 2635 | buf = server->bigbuf; |
@@ -2622,12 +2637,13 @@ receive_encrypted_standard(struct TCP_Server_Info *server, | |||
2622 | 2637 | ||
2623 | /* now read the rest */ | 2638 | /* now read the rest */ |
2624 | length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1, | 2639 | length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1, |
2625 | pdu_length - HEADER_SIZE(server) + 1 + 4); | 2640 | pdu_length - HEADER_SIZE(server) + 1 + |
2641 | server->vals->header_preamble_size); | ||
2626 | if (length < 0) | 2642 | if (length < 0) |
2627 | return length; | 2643 | return length; |
2628 | server->total_read += length; | 2644 | server->total_read += length; |
2629 | 2645 | ||
2630 | buf_size = pdu_length + 4 - sizeof(struct smb2_transform_hdr); | 2646 | buf_size = pdu_length + server->vals->header_preamble_size - sizeof(struct smb2_transform_hdr); |
2631 | length = decrypt_raw_data(server, buf, buf_size, NULL, 0, 0); | 2647 | length = decrypt_raw_data(server, buf, buf_size, NULL, 0, 0); |
2632 | if (length) | 2648 | if (length) |
2633 | return length; | 2649 | return length; |
@@ -2656,7 +2672,7 @@ smb3_receive_transform(struct TCP_Server_Info *server, struct mid_q_entry **mid) | |||
2656 | struct smb2_transform_hdr *tr_hdr = (struct smb2_transform_hdr *)buf; | 2672 | struct smb2_transform_hdr *tr_hdr = (struct smb2_transform_hdr *)buf; |
2657 | unsigned int orig_len = le32_to_cpu(tr_hdr->OriginalMessageSize); | 2673 | unsigned int orig_len = le32_to_cpu(tr_hdr->OriginalMessageSize); |
2658 | 2674 | ||
2659 | if (pdu_length + 4 < sizeof(struct smb2_transform_hdr) + | 2675 | if (pdu_length + server->vals->header_preamble_size < sizeof(struct smb2_transform_hdr) + |
2660 | sizeof(struct smb2_sync_hdr)) { | 2676 | sizeof(struct smb2_sync_hdr)) { |
2661 | cifs_dbg(VFS, "Transform message is too small (%u)\n", | 2677 | cifs_dbg(VFS, "Transform message is too small (%u)\n", |
2662 | pdu_length); | 2678 | pdu_length); |
@@ -2665,14 +2681,14 @@ smb3_receive_transform(struct TCP_Server_Info *server, struct mid_q_entry **mid) | |||
2665 | return -ECONNABORTED; | 2681 | return -ECONNABORTED; |
2666 | } | 2682 | } |
2667 | 2683 | ||
2668 | if (pdu_length + 4 < orig_len + sizeof(struct smb2_transform_hdr)) { | 2684 | if (pdu_length + server->vals->header_preamble_size < orig_len + sizeof(struct smb2_transform_hdr)) { |
2669 | cifs_dbg(VFS, "Transform message is broken\n"); | 2685 | cifs_dbg(VFS, "Transform message is broken\n"); |
2670 | cifs_reconnect(server); | 2686 | cifs_reconnect(server); |
2671 | wake_up(&server->response_q); | 2687 | wake_up(&server->response_q); |
2672 | return -ECONNABORTED; | 2688 | return -ECONNABORTED; |
2673 | } | 2689 | } |
2674 | 2690 | ||
2675 | if (pdu_length + 4 > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) | 2691 | if (pdu_length + server->vals->header_preamble_size > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) |
2676 | return receive_encrypted_read(server, mid); | 2692 | return receive_encrypted_read(server, mid); |
2677 | 2693 | ||
2678 | return receive_encrypted_standard(server, mid); | 2694 | return receive_encrypted_standard(server, mid); |
@@ -2683,7 +2699,8 @@ smb3_handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid) | |||
2683 | { | 2699 | { |
2684 | char *buf = server->large_buf ? server->bigbuf : server->smallbuf; | 2700 | char *buf = server->large_buf ? server->bigbuf : server->smallbuf; |
2685 | 2701 | ||
2686 | return handle_read_data(server, mid, buf, get_rfc1002_length(buf) + 4, | 2702 | return handle_read_data(server, mid, buf, get_rfc1002_length(buf) + |
2703 | server->vals->header_preamble_size, | ||
2687 | NULL, 0, 0); | 2704 | NULL, 0, 0); |
2688 | } | 2705 | } |
2689 | 2706 | ||
@@ -3088,6 +3105,7 @@ struct smb_version_values smb20_values = { | |||
3088 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, | 3105 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, |
3089 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, | 3106 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, |
3090 | .header_size = sizeof(struct smb2_hdr), | 3107 | .header_size = sizeof(struct smb2_hdr), |
3108 | .header_preamble_size = 4, | ||
3091 | .max_header_size = MAX_SMB2_HDR_SIZE, | 3109 | .max_header_size = MAX_SMB2_HDR_SIZE, |
3092 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, | 3110 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, |
3093 | .lock_cmd = SMB2_LOCK, | 3111 | .lock_cmd = SMB2_LOCK, |
@@ -3108,6 +3126,7 @@ struct smb_version_values smb21_values = { | |||
3108 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, | 3126 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, |
3109 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, | 3127 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, |
3110 | .header_size = sizeof(struct smb2_hdr), | 3128 | .header_size = sizeof(struct smb2_hdr), |
3129 | .header_preamble_size = 4, | ||
3111 | .max_header_size = MAX_SMB2_HDR_SIZE, | 3130 | .max_header_size = MAX_SMB2_HDR_SIZE, |
3112 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, | 3131 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, |
3113 | .lock_cmd = SMB2_LOCK, | 3132 | .lock_cmd = SMB2_LOCK, |
@@ -3128,6 +3147,7 @@ struct smb_version_values smb3any_values = { | |||
3128 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, | 3147 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, |
3129 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, | 3148 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, |
3130 | .header_size = sizeof(struct smb2_hdr), | 3149 | .header_size = sizeof(struct smb2_hdr), |
3150 | .header_preamble_size = 4, | ||
3131 | .max_header_size = MAX_SMB2_HDR_SIZE, | 3151 | .max_header_size = MAX_SMB2_HDR_SIZE, |
3132 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, | 3152 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, |
3133 | .lock_cmd = SMB2_LOCK, | 3153 | .lock_cmd = SMB2_LOCK, |
@@ -3148,6 +3168,7 @@ struct smb_version_values smbdefault_values = { | |||
3148 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, | 3168 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, |
3149 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, | 3169 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, |
3150 | .header_size = sizeof(struct smb2_hdr), | 3170 | .header_size = sizeof(struct smb2_hdr), |
3171 | .header_preamble_size = 4, | ||
3151 | .max_header_size = MAX_SMB2_HDR_SIZE, | 3172 | .max_header_size = MAX_SMB2_HDR_SIZE, |
3152 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, | 3173 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, |
3153 | .lock_cmd = SMB2_LOCK, | 3174 | .lock_cmd = SMB2_LOCK, |
@@ -3168,6 +3189,7 @@ struct smb_version_values smb30_values = { | |||
3168 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, | 3189 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, |
3169 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, | 3190 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, |
3170 | .header_size = sizeof(struct smb2_hdr), | 3191 | .header_size = sizeof(struct smb2_hdr), |
3192 | .header_preamble_size = 4, | ||
3171 | .max_header_size = MAX_SMB2_HDR_SIZE, | 3193 | .max_header_size = MAX_SMB2_HDR_SIZE, |
3172 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, | 3194 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, |
3173 | .lock_cmd = SMB2_LOCK, | 3195 | .lock_cmd = SMB2_LOCK, |
@@ -3188,6 +3210,7 @@ struct smb_version_values smb302_values = { | |||
3188 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, | 3210 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, |
3189 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, | 3211 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, |
3190 | .header_size = sizeof(struct smb2_hdr), | 3212 | .header_size = sizeof(struct smb2_hdr), |
3213 | .header_preamble_size = 4, | ||
3191 | .max_header_size = MAX_SMB2_HDR_SIZE, | 3214 | .max_header_size = MAX_SMB2_HDR_SIZE, |
3192 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, | 3215 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, |
3193 | .lock_cmd = SMB2_LOCK, | 3216 | .lock_cmd = SMB2_LOCK, |
@@ -3209,6 +3232,7 @@ struct smb_version_values smb311_values = { | |||
3209 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, | 3232 | .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, |
3210 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, | 3233 | .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, |
3211 | .header_size = sizeof(struct smb2_hdr), | 3234 | .header_size = sizeof(struct smb2_hdr), |
3235 | .header_preamble_size = 4, | ||
3212 | .max_header_size = MAX_SMB2_HDR_SIZE, | 3236 | .max_header_size = MAX_SMB2_HDR_SIZE, |
3213 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, | 3237 | .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, |
3214 | .lock_cmd = SMB2_LOCK, | 3238 | .lock_cmd = SMB2_LOCK, |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 63778ac22fd9..f7741cee2a4c 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -453,6 +453,10 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) | |||
453 | return rc; | 453 | return rc; |
454 | 454 | ||
455 | req->sync_hdr.SessionId = 0; | 455 | req->sync_hdr.SessionId = 0; |
456 | #ifdef CONFIG_CIFS_SMB311 | ||
457 | memset(server->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE); | ||
458 | memset(ses->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE); | ||
459 | #endif | ||
456 | 460 | ||
457 | if (strcmp(ses->server->vals->version_string, | 461 | if (strcmp(ses->server->vals->version_string, |
458 | SMB3ANY_VERSION_STRING) == 0) { | 462 | SMB3ANY_VERSION_STRING) == 0) { |
@@ -564,6 +568,15 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) | |||
564 | 568 | ||
565 | /* BB: add check that dialect was valid given dialect(s) we asked for */ | 569 | /* BB: add check that dialect was valid given dialect(s) we asked for */ |
566 | 570 | ||
571 | #ifdef CONFIG_CIFS_SMB311 | ||
572 | /* | ||
573 | * Keep a copy of the hash after negprot. This hash will be | ||
574 | * the starting hash value for all sessions made from this | ||
575 | * server. | ||
576 | */ | ||
577 | memcpy(server->preauth_sha_hash, ses->preauth_sha_hash, | ||
578 | SMB2_PREAUTH_HASH_SIZE); | ||
579 | #endif | ||
567 | /* SMB2 only has an extended negflavor */ | 580 | /* SMB2 only has an extended negflavor */ |
568 | server->negflavor = CIFS_NEGFLAVOR_EXTENDED; | 581 | server->negflavor = CIFS_NEGFLAVOR_EXTENDED; |
569 | /* set it to the maximum buffer size value we can send with 1 credit */ | 582 | /* set it to the maximum buffer size value we can send with 1 credit */ |
@@ -571,8 +584,10 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) | |||
571 | SMB2_MAX_BUFFER_SIZE); | 584 | SMB2_MAX_BUFFER_SIZE); |
572 | server->max_read = le32_to_cpu(rsp->MaxReadSize); | 585 | server->max_read = le32_to_cpu(rsp->MaxReadSize); |
573 | server->max_write = le32_to_cpu(rsp->MaxWriteSize); | 586 | server->max_write = le32_to_cpu(rsp->MaxWriteSize); |
574 | /* BB Do we need to validate the SecurityMode? */ | ||
575 | server->sec_mode = le16_to_cpu(rsp->SecurityMode); | 587 | server->sec_mode = le16_to_cpu(rsp->SecurityMode); |
588 | if ((server->sec_mode & SMB2_SEC_MODE_FLAGS_ALL) != server->sec_mode) | ||
589 | cifs_dbg(FYI, "Server returned unexpected security mode 0x%x\n", | ||
590 | server->sec_mode); | ||
576 | server->capabilities = le32_to_cpu(rsp->Capabilities); | 591 | server->capabilities = le32_to_cpu(rsp->Capabilities); |
577 | /* Internal types */ | 592 | /* Internal types */ |
578 | server->capabilities |= SMB2_NT_FIND | SMB2_LARGE_FILES; | 593 | server->capabilities |= SMB2_NT_FIND | SMB2_LARGE_FILES; |
@@ -621,6 +636,10 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) | |||
621 | return 0; | 636 | return 0; |
622 | #endif | 637 | #endif |
623 | 638 | ||
639 | /* In SMB3.11 preauth integrity supersedes validate negotiate */ | ||
640 | if (tcon->ses->server->dialect == SMB311_PROT_ID) | ||
641 | return 0; | ||
642 | |||
624 | /* | 643 | /* |
625 | * validation ioctl must be signed, so no point sending this if we | 644 | * validation ioctl must be signed, so no point sending this if we |
626 | * can not sign it (ie are not known user). Even if signing is not | 645 | * can not sign it (ie are not known user). Even if signing is not |
@@ -1148,6 +1167,14 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses, | |||
1148 | sess_data->buf0_type = CIFS_NO_BUFFER; | 1167 | sess_data->buf0_type = CIFS_NO_BUFFER; |
1149 | sess_data->nls_cp = (struct nls_table *) nls_cp; | 1168 | sess_data->nls_cp = (struct nls_table *) nls_cp; |
1150 | 1169 | ||
1170 | #ifdef CONFIG_CIFS_SMB311 | ||
1171 | /* | ||
1172 | * Initialize the session hash with the server one. | ||
1173 | */ | ||
1174 | memcpy(ses->preauth_sha_hash, ses->server->preauth_sha_hash, | ||
1175 | SMB2_PREAUTH_HASH_SIZE); | ||
1176 | #endif | ||
1177 | |||
1151 | while (sess_data->func) | 1178 | while (sess_data->func) |
1152 | sess_data->func(sess_data); | 1179 | sess_data->func(sess_data); |
1153 | 1180 | ||
@@ -1280,6 +1307,11 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, | |||
1280 | iov[1].iov_base = unc_path; | 1307 | iov[1].iov_base = unc_path; |
1281 | iov[1].iov_len = unc_path_len; | 1308 | iov[1].iov_len = unc_path_len; |
1282 | 1309 | ||
1310 | /* 3.11 tcon req must be signed if not encrypted. See MS-SMB2 3.2.4.1.1 */ | ||
1311 | if ((ses->server->dialect == SMB311_PROT_ID) && | ||
1312 | !encryption_required(tcon)) | ||
1313 | req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED; | ||
1314 | |||
1283 | rc = smb2_send_recv(xid, ses, iov, 2, &resp_buftype, flags, &rsp_iov); | 1315 | rc = smb2_send_recv(xid, ses, iov, 2, &resp_buftype, flags, &rsp_iov); |
1284 | cifs_small_buf_release(req); | 1316 | cifs_small_buf_release(req); |
1285 | rsp = (struct smb2_tree_connect_rsp *)rsp_iov.iov_base; | 1317 | rsp = (struct smb2_tree_connect_rsp *)rsp_iov.iov_base; |
@@ -1441,7 +1473,7 @@ parse_lease_state(struct TCP_Server_Info *server, struct smb2_create_rsp *rsp, | |||
1441 | unsigned int remaining; | 1473 | unsigned int remaining; |
1442 | char *name; | 1474 | char *name; |
1443 | 1475 | ||
1444 | data_offset = (char *)rsp + 4 + le32_to_cpu(rsp->CreateContextsOffset); | 1476 | data_offset = (char *)rsp + server->vals->header_preamble_size + le32_to_cpu(rsp->CreateContextsOffset); |
1445 | remaining = le32_to_cpu(rsp->CreateContextsLength); | 1477 | remaining = le32_to_cpu(rsp->CreateContextsLength); |
1446 | cc = (struct create_context *)data_offset; | 1478 | cc = (struct create_context *)data_offset; |
1447 | while (remaining >= sizeof(struct create_context)) { | 1479 | while (remaining >= sizeof(struct create_context)) { |
@@ -1738,8 +1770,10 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, | |||
1738 | rc = alloc_path_with_tree_prefix(©_path, ©_size, | 1770 | rc = alloc_path_with_tree_prefix(©_path, ©_size, |
1739 | &name_len, | 1771 | &name_len, |
1740 | tcon->treeName, path); | 1772 | tcon->treeName, path); |
1741 | if (rc) | 1773 | if (rc) { |
1774 | cifs_small_buf_release(req); | ||
1742 | return rc; | 1775 | return rc; |
1776 | } | ||
1743 | req->NameLength = cpu_to_le16(name_len * 2); | 1777 | req->NameLength = cpu_to_le16(name_len * 2); |
1744 | uni_path_len = copy_size; | 1778 | uni_path_len = copy_size; |
1745 | path = copy_path; | 1779 | path = copy_path; |
@@ -1750,8 +1784,10 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, | |||
1750 | if (uni_path_len % 8 != 0) { | 1784 | if (uni_path_len % 8 != 0) { |
1751 | copy_size = roundup(uni_path_len, 8); | 1785 | copy_size = roundup(uni_path_len, 8); |
1752 | copy_path = kzalloc(copy_size, GFP_KERNEL); | 1786 | copy_path = kzalloc(copy_size, GFP_KERNEL); |
1753 | if (!copy_path) | 1787 | if (!copy_path) { |
1788 | cifs_small_buf_release(req); | ||
1754 | return -ENOMEM; | 1789 | return -ENOMEM; |
1790 | } | ||
1755 | memcpy((char *)copy_path, (const char *)path, | 1791 | memcpy((char *)copy_path, (const char *)path, |
1756 | uni_path_len); | 1792 | uni_path_len); |
1757 | uni_path_len = copy_size; | 1793 | uni_path_len = copy_size; |
@@ -3418,6 +3454,7 @@ static int | |||
3418 | build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level, | 3454 | build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level, |
3419 | int outbuf_len, u64 persistent_fid, u64 volatile_fid) | 3455 | int outbuf_len, u64 persistent_fid, u64 volatile_fid) |
3420 | { | 3456 | { |
3457 | struct TCP_Server_Info *server = tcon->ses->server; | ||
3421 | int rc; | 3458 | int rc; |
3422 | struct smb2_query_info_req *req; | 3459 | struct smb2_query_info_req *req; |
3423 | unsigned int total_len; | 3460 | unsigned int total_len; |
@@ -3440,7 +3477,7 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level, | |||
3440 | req->InputBufferOffset = | 3477 | req->InputBufferOffset = |
3441 | cpu_to_le16(sizeof(struct smb2_query_info_req) - 1); | 3478 | cpu_to_le16(sizeof(struct smb2_query_info_req) - 1); |
3442 | req->OutputBufferLength = cpu_to_le32( | 3479 | req->OutputBufferLength = cpu_to_le32( |
3443 | outbuf_len + sizeof(struct smb2_query_info_rsp) - 1 - 4); | 3480 | outbuf_len + sizeof(struct smb2_query_info_rsp) - 1 - server->vals->header_preamble_size); |
3444 | 3481 | ||
3445 | iov->iov_base = (char *)req; | 3482 | iov->iov_base = (char *)req; |
3446 | iov->iov_len = total_len; | 3483 | iov->iov_len = total_len; |
@@ -3457,6 +3494,7 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, | |||
3457 | int rc = 0; | 3494 | int rc = 0; |
3458 | int resp_buftype; | 3495 | int resp_buftype; |
3459 | struct cifs_ses *ses = tcon->ses; | 3496 | struct cifs_ses *ses = tcon->ses; |
3497 | struct TCP_Server_Info *server = ses->server; | ||
3460 | struct smb2_fs_full_size_info *info = NULL; | 3498 | struct smb2_fs_full_size_info *info = NULL; |
3461 | int flags = 0; | 3499 | int flags = 0; |
3462 | 3500 | ||
@@ -3477,7 +3515,7 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, | |||
3477 | } | 3515 | } |
3478 | rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base; | 3516 | rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base; |
3479 | 3517 | ||
3480 | info = (struct smb2_fs_full_size_info *)(4 /* RFC1001 len */ + | 3518 | info = (struct smb2_fs_full_size_info *)(server->vals->header_preamble_size + |
3481 | le16_to_cpu(rsp->OutputBufferOffset) + (char *)&rsp->hdr); | 3519 | le16_to_cpu(rsp->OutputBufferOffset) + (char *)&rsp->hdr); |
3482 | rc = validate_buf(le16_to_cpu(rsp->OutputBufferOffset), | 3520 | rc = validate_buf(le16_to_cpu(rsp->OutputBufferOffset), |
3483 | le32_to_cpu(rsp->OutputBufferLength), &rsp->hdr, | 3521 | le32_to_cpu(rsp->OutputBufferLength), &rsp->hdr, |
@@ -3500,6 +3538,7 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, | |||
3500 | int rc = 0; | 3538 | int rc = 0; |
3501 | int resp_buftype, max_len, min_len; | 3539 | int resp_buftype, max_len, min_len; |
3502 | struct cifs_ses *ses = tcon->ses; | 3540 | struct cifs_ses *ses = tcon->ses; |
3541 | struct TCP_Server_Info *server = ses->server; | ||
3503 | unsigned int rsp_len, offset; | 3542 | unsigned int rsp_len, offset; |
3504 | int flags = 0; | 3543 | int flags = 0; |
3505 | 3544 | ||
@@ -3540,15 +3579,15 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, | |||
3540 | goto qfsattr_exit; | 3579 | goto qfsattr_exit; |
3541 | 3580 | ||
3542 | if (level == FS_ATTRIBUTE_INFORMATION) | 3581 | if (level == FS_ATTRIBUTE_INFORMATION) |
3543 | memcpy(&tcon->fsAttrInfo, 4 /* RFC1001 len */ + offset | 3582 | memcpy(&tcon->fsAttrInfo, server->vals->header_preamble_size + offset |
3544 | + (char *)&rsp->hdr, min_t(unsigned int, | 3583 | + (char *)&rsp->hdr, min_t(unsigned int, |
3545 | rsp_len, max_len)); | 3584 | rsp_len, max_len)); |
3546 | else if (level == FS_DEVICE_INFORMATION) | 3585 | else if (level == FS_DEVICE_INFORMATION) |
3547 | memcpy(&tcon->fsDevInfo, 4 /* RFC1001 len */ + offset | 3586 | memcpy(&tcon->fsDevInfo, server->vals->header_preamble_size + offset |
3548 | + (char *)&rsp->hdr, sizeof(FILE_SYSTEM_DEVICE_INFO)); | 3587 | + (char *)&rsp->hdr, sizeof(FILE_SYSTEM_DEVICE_INFO)); |
3549 | else if (level == FS_SECTOR_SIZE_INFORMATION) { | 3588 | else if (level == FS_SECTOR_SIZE_INFORMATION) { |
3550 | struct smb3_fs_ss_info *ss_info = (struct smb3_fs_ss_info *) | 3589 | struct smb3_fs_ss_info *ss_info = (struct smb3_fs_ss_info *) |
3551 | (4 /* RFC1001 len */ + offset + (char *)&rsp->hdr); | 3590 | (server->vals->header_preamble_size + offset + (char *)&rsp->hdr); |
3552 | tcon->ss_flags = le32_to_cpu(ss_info->Flags); | 3591 | tcon->ss_flags = le32_to_cpu(ss_info->Flags); |
3553 | tcon->perf_sector_size = | 3592 | tcon->perf_sector_size = |
3554 | le32_to_cpu(ss_info->PhysicalBytesPerSectorForPerf); | 3593 | le32_to_cpu(ss_info->PhysicalBytesPerSectorForPerf); |
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 2a2b34ccaf49..253e2c7c952f 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -249,6 +249,8 @@ struct smb2_negotiate_req { | |||
249 | /* SecurityMode flags */ | 249 | /* SecurityMode flags */ |
250 | #define SMB2_NEGOTIATE_SIGNING_ENABLED 0x0001 | 250 | #define SMB2_NEGOTIATE_SIGNING_ENABLED 0x0001 |
251 | #define SMB2_NEGOTIATE_SIGNING_REQUIRED 0x0002 | 251 | #define SMB2_NEGOTIATE_SIGNING_REQUIRED 0x0002 |
252 | #define SMB2_SEC_MODE_FLAGS_ALL 0x0003 | ||
253 | |||
252 | /* Capabilities flags */ | 254 | /* Capabilities flags */ |
253 | #define SMB2_GLOBAL_CAP_DFS 0x00000001 | 255 | #define SMB2_GLOBAL_CAP_DFS 0x00000001 |
254 | #define SMB2_GLOBAL_CAP_LEASING 0x00000002 /* Resp only New to SMB2.1 */ | 256 | #define SMB2_GLOBAL_CAP_LEASING 0x00000002 /* Resp only New to SMB2.1 */ |
@@ -264,6 +266,7 @@ struct smb2_negotiate_req { | |||
264 | #define SMB311_SALT_SIZE 32 | 266 | #define SMB311_SALT_SIZE 32 |
265 | /* Hash Algorithm Types */ | 267 | /* Hash Algorithm Types */ |
266 | #define SMB2_PREAUTH_INTEGRITY_SHA512 cpu_to_le16(0x0001) | 268 | #define SMB2_PREAUTH_INTEGRITY_SHA512 cpu_to_le16(0x0001) |
269 | #define SMB2_PREAUTH_HASH_SIZE 64 | ||
267 | 270 | ||
268 | struct smb2_preauth_neg_context { | 271 | struct smb2_preauth_neg_context { |
269 | __le16 ContextType; /* 1 */ | 272 | __le16 ContextType; /* 1 */ |
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 05287b01f596..cbcce3f7e86f 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
@@ -202,4 +202,9 @@ extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *); | |||
202 | 202 | ||
203 | extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *, | 203 | extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *, |
204 | enum securityEnum); | 204 | enum securityEnum); |
205 | #ifdef CONFIG_CIFS_SMB311 | ||
206 | extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server); | ||
207 | extern int smb311_update_preauth_hash(struct cifs_ses *ses, | ||
208 | struct kvec *iov, int nvec); | ||
209 | #endif | ||
205 | #endif /* _SMB2PROTO_H */ | 210 | #endif /* _SMB2PROTO_H */ |
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index 99493946e2f9..bf49cb73b9e6 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c | |||
@@ -43,77 +43,62 @@ | |||
43 | static int | 43 | static int |
44 | smb2_crypto_shash_allocate(struct TCP_Server_Info *server) | 44 | smb2_crypto_shash_allocate(struct TCP_Server_Info *server) |
45 | { | 45 | { |
46 | int rc; | 46 | return cifs_alloc_hash("hmac(sha256)", |
47 | unsigned int size; | 47 | &server->secmech.hmacsha256, |
48 | &server->secmech.sdeschmacsha256); | ||
49 | } | ||
48 | 50 | ||
49 | if (server->secmech.sdeschmacsha256 != NULL) | 51 | static int |
50 | return 0; /* already allocated */ | 52 | smb3_crypto_shash_allocate(struct TCP_Server_Info *server) |
53 | { | ||
54 | struct cifs_secmech *p = &server->secmech; | ||
55 | int rc; | ||
51 | 56 | ||
52 | server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0); | 57 | rc = cifs_alloc_hash("hmac(sha256)", |
53 | if (IS_ERR(server->secmech.hmacsha256)) { | 58 | &p->hmacsha256, |
54 | cifs_dbg(VFS, "could not allocate crypto hmacsha256\n"); | 59 | &p->sdeschmacsha256); |
55 | rc = PTR_ERR(server->secmech.hmacsha256); | 60 | if (rc) |
56 | server->secmech.hmacsha256 = NULL; | 61 | goto err; |
57 | return rc; | ||
58 | } | ||
59 | 62 | ||
60 | size = sizeof(struct shash_desc) + | 63 | rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes); |
61 | crypto_shash_descsize(server->secmech.hmacsha256); | 64 | if (rc) |
62 | server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL); | 65 | goto err; |
63 | if (!server->secmech.sdeschmacsha256) { | ||
64 | crypto_free_shash(server->secmech.hmacsha256); | ||
65 | server->secmech.hmacsha256 = NULL; | ||
66 | return -ENOMEM; | ||
67 | } | ||
68 | server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256; | ||
69 | server->secmech.sdeschmacsha256->shash.flags = 0x0; | ||
70 | 66 | ||
71 | return 0; | 67 | return 0; |
68 | err: | ||
69 | cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256); | ||
70 | return rc; | ||
72 | } | 71 | } |
73 | 72 | ||
74 | static int | 73 | #ifdef CONFIG_CIFS_SMB311 |
75 | smb3_crypto_shash_allocate(struct TCP_Server_Info *server) | 74 | int |
75 | smb311_crypto_shash_allocate(struct TCP_Server_Info *server) | ||
76 | { | 76 | { |
77 | unsigned int size; | 77 | struct cifs_secmech *p = &server->secmech; |
78 | int rc; | 78 | int rc = 0; |
79 | |||
80 | if (server->secmech.sdesccmacaes != NULL) | ||
81 | return 0; /* already allocated */ | ||
82 | 79 | ||
83 | rc = smb2_crypto_shash_allocate(server); | 80 | rc = cifs_alloc_hash("hmac(sha256)", |
81 | &p->hmacsha256, | ||
82 | &p->sdeschmacsha256); | ||
84 | if (rc) | 83 | if (rc) |
85 | return rc; | 84 | return rc; |
86 | 85 | ||
87 | server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0); | 86 | rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes); |
88 | if (IS_ERR(server->secmech.cmacaes)) { | 87 | if (rc) |
89 | cifs_dbg(VFS, "could not allocate crypto cmac-aes"); | 88 | goto err; |
90 | kfree(server->secmech.sdeschmacsha256); | ||
91 | server->secmech.sdeschmacsha256 = NULL; | ||
92 | crypto_free_shash(server->secmech.hmacsha256); | ||
93 | server->secmech.hmacsha256 = NULL; | ||
94 | rc = PTR_ERR(server->secmech.cmacaes); | ||
95 | server->secmech.cmacaes = NULL; | ||
96 | return rc; | ||
97 | } | ||
98 | 89 | ||
99 | size = sizeof(struct shash_desc) + | 90 | rc = cifs_alloc_hash("sha512", &p->sha512, &p->sdescsha512); |
100 | crypto_shash_descsize(server->secmech.cmacaes); | 91 | if (rc) |
101 | server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL); | 92 | goto err; |
102 | if (!server->secmech.sdesccmacaes) { | ||
103 | cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__); | ||
104 | kfree(server->secmech.sdeschmacsha256); | ||
105 | server->secmech.sdeschmacsha256 = NULL; | ||
106 | crypto_free_shash(server->secmech.hmacsha256); | ||
107 | crypto_free_shash(server->secmech.cmacaes); | ||
108 | server->secmech.hmacsha256 = NULL; | ||
109 | server->secmech.cmacaes = NULL; | ||
110 | return -ENOMEM; | ||
111 | } | ||
112 | server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes; | ||
113 | server->secmech.sdesccmacaes->shash.flags = 0x0; | ||
114 | 93 | ||
115 | return 0; | 94 | return 0; |
95 | |||
96 | err: | ||
97 | cifs_free_hash(&p->cmacaes, &p->sdesccmacaes); | ||
98 | cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256); | ||
99 | return rc; | ||
116 | } | 100 | } |
101 | #endif | ||
117 | 102 | ||
118 | static struct cifs_ses * | 103 | static struct cifs_ses * |
119 | smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id) | 104 | smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id) |
@@ -457,7 +442,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) | |||
457 | cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__); | 442 | cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__); |
458 | return rc; | 443 | return rc; |
459 | } | 444 | } |
460 | 445 | ||
461 | rc = __cifs_calc_signature(rqst, server, sigptr, | 446 | rc = __cifs_calc_signature(rqst, server, sigptr, |
462 | &server->secmech.sdesccmacaes->shash); | 447 | &server->secmech.sdesccmacaes->shash); |
463 | 448 | ||
diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c index 91710eb571fb..5008af546dd1 100644 --- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c | |||
@@ -862,6 +862,8 @@ static int smbd_post_send_negotiate_req(struct smbd_connection *info) | |||
862 | ib_dma_unmap_single(info->id->device, request->sge[0].addr, | 862 | ib_dma_unmap_single(info->id->device, request->sge[0].addr, |
863 | request->sge[0].length, DMA_TO_DEVICE); | 863 | request->sge[0].length, DMA_TO_DEVICE); |
864 | 864 | ||
865 | smbd_disconnect_rdma_connection(info); | ||
866 | |||
865 | dma_mapping_failed: | 867 | dma_mapping_failed: |
866 | mempool_free(request, info->request_mempool); | 868 | mempool_free(request, info->request_mempool); |
867 | return rc; | 869 | return rc; |
@@ -1025,7 +1027,7 @@ static int smbd_post_send(struct smbd_connection *info, | |||
1025 | 1027 | ||
1026 | for (i = 0; i < request->num_sge; i++) { | 1028 | for (i = 0; i < request->num_sge; i++) { |
1027 | log_rdma_send(INFO, | 1029 | log_rdma_send(INFO, |
1028 | "rdma_request sge[%d] addr=%llu legnth=%u\n", | 1030 | "rdma_request sge[%d] addr=%llu length=%u\n", |
1029 | i, request->sge[0].addr, request->sge[0].length); | 1031 | i, request->sge[0].addr, request->sge[0].length); |
1030 | ib_dma_sync_single_for_device( | 1032 | ib_dma_sync_single_for_device( |
1031 | info->id->device, | 1033 | info->id->device, |
@@ -1061,6 +1063,7 @@ static int smbd_post_send(struct smbd_connection *info, | |||
1061 | if (atomic_dec_and_test(&info->send_pending)) | 1063 | if (atomic_dec_and_test(&info->send_pending)) |
1062 | wake_up(&info->wait_send_pending); | 1064 | wake_up(&info->wait_send_pending); |
1063 | } | 1065 | } |
1066 | smbd_disconnect_rdma_connection(info); | ||
1064 | } else | 1067 | } else |
1065 | /* Reset timer for idle connection after packet is sent */ | 1068 | /* Reset timer for idle connection after packet is sent */ |
1066 | mod_delayed_work(info->workqueue, &info->idle_timer_work, | 1069 | mod_delayed_work(info->workqueue, &info->idle_timer_work, |
@@ -1202,7 +1205,7 @@ static int smbd_post_recv( | |||
1202 | if (rc) { | 1205 | if (rc) { |
1203 | ib_dma_unmap_single(info->id->device, response->sge.addr, | 1206 | ib_dma_unmap_single(info->id->device, response->sge.addr, |
1204 | response->sge.length, DMA_FROM_DEVICE); | 1207 | response->sge.length, DMA_FROM_DEVICE); |
1205 | 1208 | smbd_disconnect_rdma_connection(info); | |
1206 | log_rdma_recv(ERR, "ib_post_recv failed rc=%d\n", rc); | 1209 | log_rdma_recv(ERR, "ib_post_recv failed rc=%d\n", rc); |
1207 | } | 1210 | } |
1208 | 1211 | ||
@@ -1498,8 +1501,8 @@ int smbd_reconnect(struct TCP_Server_Info *server) | |||
1498 | log_rdma_event(INFO, "reconnecting rdma session\n"); | 1501 | log_rdma_event(INFO, "reconnecting rdma session\n"); |
1499 | 1502 | ||
1500 | if (!server->smbd_conn) { | 1503 | if (!server->smbd_conn) { |
1501 | log_rdma_event(ERR, "rdma session already destroyed\n"); | 1504 | log_rdma_event(INFO, "rdma session already destroyed\n"); |
1502 | return -EINVAL; | 1505 | goto create_conn; |
1503 | } | 1506 | } |
1504 | 1507 | ||
1505 | /* | 1508 | /* |
@@ -1512,15 +1515,19 @@ int smbd_reconnect(struct TCP_Server_Info *server) | |||
1512 | } | 1515 | } |
1513 | 1516 | ||
1514 | /* wait until the transport is destroyed */ | 1517 | /* wait until the transport is destroyed */ |
1515 | wait_event(server->smbd_conn->wait_destroy, | 1518 | if (!wait_event_timeout(server->smbd_conn->wait_destroy, |
1516 | server->smbd_conn->transport_status == SMBD_DESTROYED); | 1519 | server->smbd_conn->transport_status == SMBD_DESTROYED, 5*HZ)) |
1520 | return -EAGAIN; | ||
1517 | 1521 | ||
1518 | destroy_workqueue(server->smbd_conn->workqueue); | 1522 | destroy_workqueue(server->smbd_conn->workqueue); |
1519 | kfree(server->smbd_conn); | 1523 | kfree(server->smbd_conn); |
1520 | 1524 | ||
1525 | create_conn: | ||
1521 | log_rdma_event(INFO, "creating rdma session\n"); | 1526 | log_rdma_event(INFO, "creating rdma session\n"); |
1522 | server->smbd_conn = smbd_get_connection( | 1527 | server->smbd_conn = smbd_get_connection( |
1523 | server, (struct sockaddr *) &server->dstaddr); | 1528 | server, (struct sockaddr *) &server->dstaddr); |
1529 | log_rdma_event(INFO, "created rdma session info=%p\n", | ||
1530 | server->smbd_conn); | ||
1524 | 1531 | ||
1525 | return server->smbd_conn ? 0 : -ENOENT; | 1532 | return server->smbd_conn ? 0 : -ENOENT; |
1526 | } | 1533 | } |
@@ -2295,7 +2302,7 @@ static void smbd_mr_recovery_work(struct work_struct *work) | |||
2295 | rc = ib_dereg_mr(smbdirect_mr->mr); | 2302 | rc = ib_dereg_mr(smbdirect_mr->mr); |
2296 | if (rc) { | 2303 | if (rc) { |
2297 | log_rdma_mr(ERR, | 2304 | log_rdma_mr(ERR, |
2298 | "ib_dereg_mr faield rc=%x\n", | 2305 | "ib_dereg_mr failed rc=%x\n", |
2299 | rc); | 2306 | rc); |
2300 | smbd_disconnect_rdma_connection(info); | 2307 | smbd_disconnect_rdma_connection(info); |
2301 | } | 2308 | } |
@@ -2542,6 +2549,8 @@ dma_map_error: | |||
2542 | if (atomic_dec_and_test(&info->mr_used_count)) | 2549 | if (atomic_dec_and_test(&info->mr_used_count)) |
2543 | wake_up(&info->wait_for_mr_cleanup); | 2550 | wake_up(&info->wait_for_mr_cleanup); |
2544 | 2551 | ||
2552 | smbd_disconnect_rdma_connection(info); | ||
2553 | |||
2545 | return NULL; | 2554 | return NULL; |
2546 | } | 2555 | } |
2547 | 2556 | ||
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index c12bffefa3c9..a0b80ac651a6 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c | |||
@@ -121,25 +121,12 @@ int | |||
121 | mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len) | 121 | mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len) |
122 | { | 122 | { |
123 | int rc; | 123 | int rc; |
124 | unsigned int size; | 124 | struct crypto_shash *md4 = NULL; |
125 | struct crypto_shash *md4; | 125 | struct sdesc *sdescmd4 = NULL; |
126 | struct sdesc *sdescmd4; | 126 | |
127 | 127 | rc = cifs_alloc_hash("md4", &md4, &sdescmd4); | |
128 | md4 = crypto_alloc_shash("md4", 0, 0); | 128 | if (rc) |
129 | if (IS_ERR(md4)) { | ||
130 | rc = PTR_ERR(md4); | ||
131 | cifs_dbg(VFS, "%s: Crypto md4 allocation error %d\n", | ||
132 | __func__, rc); | ||
133 | return rc; | ||
134 | } | ||
135 | size = sizeof(struct shash_desc) + crypto_shash_descsize(md4); | ||
136 | sdescmd4 = kmalloc(size, GFP_KERNEL); | ||
137 | if (!sdescmd4) { | ||
138 | rc = -ENOMEM; | ||
139 | goto mdfour_err; | 129 | goto mdfour_err; |
140 | } | ||
141 | sdescmd4->shash.tfm = md4; | ||
142 | sdescmd4->shash.flags = 0x0; | ||
143 | 130 | ||
144 | rc = crypto_shash_init(&sdescmd4->shash); | 131 | rc = crypto_shash_init(&sdescmd4->shash); |
145 | if (rc) { | 132 | if (rc) { |
@@ -156,9 +143,7 @@ mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len) | |||
156 | cifs_dbg(VFS, "%s: Could not generate md4 hash\n", __func__); | 143 | cifs_dbg(VFS, "%s: Could not generate md4 hash\n", __func__); |
157 | 144 | ||
158 | mdfour_err: | 145 | mdfour_err: |
159 | crypto_free_shash(md4); | 146 | cifs_free_hash(&md4, &sdescmd4); |
160 | kfree(sdescmd4); | ||
161 | |||
162 | return rc; | 147 | return rc; |
163 | } | 148 | } |
164 | 149 | ||
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 9779b3292d8e..279718dcb2ed 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "cifsglob.h" | 37 | #include "cifsglob.h" |
38 | #include "cifsproto.h" | 38 | #include "cifsproto.h" |
39 | #include "cifs_debug.h" | 39 | #include "cifs_debug.h" |
40 | #include "smb2proto.h" | ||
40 | #include "smbdirect.h" | 41 | #include "smbdirect.h" |
41 | 42 | ||
42 | /* Max number of iovectors we can use off the stack when sending requests. */ | 43 | /* Max number of iovectors we can use off the stack when sending requests. */ |
@@ -751,6 +752,12 @@ cifs_send_recv(const unsigned int xid, struct cifs_ses *ses, | |||
751 | if (rc < 0) | 752 | if (rc < 0) |
752 | goto out; | 753 | goto out; |
753 | 754 | ||
755 | #ifdef CONFIG_CIFS_SMB311 | ||
756 | if (ses->status == CifsNew) | ||
757 | smb311_update_preauth_hash(ses, rqst->rq_iov+1, | ||
758 | rqst->rq_nvec-1); | ||
759 | #endif | ||
760 | |||
754 | if (timeout == CIFS_ASYNC_OP) | 761 | if (timeout == CIFS_ASYNC_OP) |
755 | goto out; | 762 | goto out; |
756 | 763 | ||
@@ -783,12 +790,23 @@ cifs_send_recv(const unsigned int xid, struct cifs_ses *ses, | |||
783 | 790 | ||
784 | buf = (char *)midQ->resp_buf; | 791 | buf = (char *)midQ->resp_buf; |
785 | resp_iov->iov_base = buf; | 792 | resp_iov->iov_base = buf; |
786 | resp_iov->iov_len = get_rfc1002_length(buf) + 4; | 793 | resp_iov->iov_len = get_rfc1002_length(buf) + |
794 | ses->server->vals->header_preamble_size; | ||
787 | if (midQ->large_buf) | 795 | if (midQ->large_buf) |
788 | *resp_buf_type = CIFS_LARGE_BUFFER; | 796 | *resp_buf_type = CIFS_LARGE_BUFFER; |
789 | else | 797 | else |
790 | *resp_buf_type = CIFS_SMALL_BUFFER; | 798 | *resp_buf_type = CIFS_SMALL_BUFFER; |
791 | 799 | ||
800 | #ifdef CONFIG_CIFS_SMB311 | ||
801 | if (ses->status == CifsNew) { | ||
802 | struct kvec iov = { | ||
803 | .iov_base = buf + 4, | ||
804 | .iov_len = get_rfc1002_length(buf) | ||
805 | }; | ||
806 | smb311_update_preauth_hash(ses, &iov, 1); | ||
807 | } | ||
808 | #endif | ||
809 | |||
792 | credits = ses->server->ops->get_credits(midQ); | 810 | credits = ses->server->ops->get_credits(midQ); |
793 | 811 | ||
794 | rc = ses->server->ops->check_receive(midQ, ses->server, | 812 | rc = ses->server->ops->check_receive(midQ, ses->server, |