aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/smb2misc.c39
-rw-r--r--fs/cifs/smb2pdu.h7
2 files changed, 46 insertions, 0 deletions
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
index 5406e95f5d92..9df9f0b48160 100644
--- a/fs/cifs/smb2misc.c
+++ b/fs/cifs/smb2misc.c
@@ -93,6 +93,41 @@ static const __le16 smb2_rsp_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
93 /* SMB2_OPLOCK_BREAK */ cpu_to_le16(24) 93 /* SMB2_OPLOCK_BREAK */ cpu_to_le16(24)
94}; 94};
95 95
96#ifdef CONFIG_CIFS_SMB311
97static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len, __u32 non_ctxlen)
98{
99 __u16 neg_count;
100 __u32 nc_offset, size_of_pad_before_neg_ctxts;
101 struct smb2_negotiate_rsp *pneg_rsp = (struct smb2_negotiate_rsp *)hdr;
102
103 /* Negotiate contexts are only valid for latest dialect SMB3.11 */
104 neg_count = le16_to_cpu(pneg_rsp->NegotiateContextCount);
105 if ((neg_count == 0) ||
106 (pneg_rsp->DialectRevision != cpu_to_le16(SMB311_PROT_ID)))
107 return 0;
108
109 /* Make sure that negotiate contexts start after gss security blob */
110 nc_offset = le32_to_cpu(pneg_rsp->NegotiateContextOffset);
111 if (nc_offset < non_ctxlen - 4 /* RFC1001 len field */) {
112 printk_once(KERN_WARNING "invalid negotiate context offset\n");
113 return 0;
114 }
115 size_of_pad_before_neg_ctxts = nc_offset - (non_ctxlen - 4);
116
117 /* Verify that at least minimal negotiate contexts fit within frame */
118 if (len < nc_offset + (neg_count * sizeof(struct smb2_neg_context))) {
119 printk_once(KERN_WARNING "negotiate context goes beyond end\n");
120 return 0;
121 }
122
123 cifs_dbg(FYI, "length of negcontexts %d pad %d\n",
124 len - nc_offset, size_of_pad_before_neg_ctxts);
125
126 /* length of negcontexts including pad from end of sec blob to them */
127 return (len - nc_offset) + size_of_pad_before_neg_ctxts;
128}
129#endif /* CIFS_SMB311 */
130
96int 131int
97smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr) 132smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
98{ 133{
@@ -198,6 +233,10 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
198 233
199 clc_len = smb2_calc_size(hdr); 234 clc_len = smb2_calc_size(hdr);
200 235
236#ifdef CONFIG_CIFS_SMB311
237 if (shdr->Command == SMB2_NEGOTIATE)
238 clc_len += get_neg_ctxt_len(hdr, len, clc_len);
239#endif /* SMB311 */
201 if (srvr->vals->header_preamble_size + len != clc_len) { 240 if (srvr->vals->header_preamble_size + len != clc_len) {
202 cifs_dbg(FYI, "Calculated size %u length %zu mismatch mid %llu\n", 241 cifs_dbg(FYI, "Calculated size %u length %zu mismatch mid %llu\n",
203 clc_len, srvr->vals->header_preamble_size + len, mid); 242 clc_len, srvr->vals->header_preamble_size + len, mid);
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index 253e2c7c952f..0e0a0af89e4d 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -263,6 +263,13 @@ struct smb2_negotiate_req {
263#define SMB2_NT_FIND 0x00100000 263#define SMB2_NT_FIND 0x00100000
264#define SMB2_LARGE_FILES 0x00200000 264#define SMB2_LARGE_FILES 0x00200000
265 265
266struct smb2_neg_context {
267 __le16 ContextType;
268 __le16 DataLength;
269 __le32 Reserved;
270 /* Followed by array of data */
271} __packed;
272
266#define SMB311_SALT_SIZE 32 273#define SMB311_SALT_SIZE 32
267/* Hash Algorithm Types */ 274/* Hash Algorithm Types */
268#define SMB2_PREAUTH_INTEGRITY_SHA512 cpu_to_le16(0x0001) 275#define SMB2_PREAUTH_INTEGRITY_SHA512 cpu_to_le16(0x0001)