1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/ctype.h>
24#include "smb2pdu.h"
25#include "cifsglob.h"
26#include "cifsproto.h"
27#include "smb2proto.h"
28#include "cifs_debug.h"
29#include "cifs_unicode.h"
30#include "smb2status.h"
31
32static int
33check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid)
34{
35
36
37
38
39 if ((*(__le32 *)hdr->ProtocolId == SMB2_PROTO_NUMBER) &&
40 (mid == hdr->MessageId)) {
41 if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
42 return 0;
43 else {
44
45 if (hdr->Command == SMB2_OPLOCK_BREAK)
46 return 0;
47 else
48 cERROR(1, "Received Request not response");
49 }
50 } else {
51 if (*(__le32 *)hdr->ProtocolId != SMB2_PROTO_NUMBER)
52 cERROR(1, "Bad protocol string signature header %x",
53 *(unsigned int *) hdr->ProtocolId);
54 if (mid != hdr->MessageId)
55 cERROR(1, "Mids do not match: %llu and %llu", mid,
56 hdr->MessageId);
57 }
58 cERROR(1, "Bad SMB detected. The Mid=%llu", hdr->MessageId);
59 return 1;
60}
61
62
63
64
65
66
67
68
69static const __le16 smb2_rsp_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
70 __constant_cpu_to_le16(65),
71 __constant_cpu_to_le16(9),
72 __constant_cpu_to_le16(4),
73 __constant_cpu_to_le16(16),
74 __constant_cpu_to_le16(4),
75 __constant_cpu_to_le16(89),
76 __constant_cpu_to_le16(60),
77 __constant_cpu_to_le16(4),
78 __constant_cpu_to_le16(17),
79 __constant_cpu_to_le16(17),
80 __constant_cpu_to_le16(4),
81 __constant_cpu_to_le16(49),
82
83 __constant_cpu_to_le16(0),
84 __constant_cpu_to_le16(4),
85 __constant_cpu_to_le16(9),
86 __constant_cpu_to_le16(9),
87 __constant_cpu_to_le16(9),
88 __constant_cpu_to_le16(2),
89
90 __constant_cpu_to_le16(24)
91};
92
93int
94smb2_check_message(char *buf, unsigned int length)
95{
96 struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
97 struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
98 __u64 mid = hdr->MessageId;
99 __u32 len = get_rfc1002_length(buf);
100 __u32 clc_len;
101 int command;
102
103
104 cFYI(1, "%s length: 0x%x, smb_buf_length: 0x%x", __func__, length, len);
105
106
107
108
109
110
111 if (length < sizeof(struct smb2_pdu)) {
112 if ((length >= sizeof(struct smb2_hdr)) && (hdr->Status != 0)) {
113 pdu->StructureSize2 = 0;
114
115
116
117
118 return 0;
119 } else {
120 cERROR(1, "Length less than SMB header size");
121 }
122 return 1;
123 }
124 if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE - 4) {
125 cERROR(1, "SMB length greater than maximum, mid=%llu", mid);
126 return 1;
127 }
128
129 if (check_smb2_hdr(hdr, mid))
130 return 1;
131
132 if (hdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
133 cERROR(1, "Illegal structure size %u",
134 le16_to_cpu(hdr->StructureSize));
135 return 1;
136 }
137
138 command = le16_to_cpu(hdr->Command);
139 if (command >= NUMBER_OF_SMB2_COMMANDS) {
140 cERROR(1, "Illegal SMB2 command %d", command);
141 return 1;
142 }
143
144 if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) {
145 if (command != SMB2_OPLOCK_BREAK_HE && (hdr->Status == 0 ||
146 pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2)) {
147
148 cERROR(1, "Illegal response size %u for command %d",
149 le16_to_cpu(pdu->StructureSize2), command);
150 return 1;
151 } else if (command == SMB2_OPLOCK_BREAK_HE && (hdr->Status == 0)
152 && (le16_to_cpu(pdu->StructureSize2) != 44)
153 && (le16_to_cpu(pdu->StructureSize2) != 36)) {
154
155 cERROR(1, "Illegal response size %d for oplock break",
156 le16_to_cpu(pdu->StructureSize2));
157 return 1;
158 }
159 }
160
161 if (4 + len != length) {
162 cERROR(1, "Total length %u RFC1002 length %u mismatch mid %llu",
163 length, 4 + len, mid);
164 return 1;
165 }
166
167 clc_len = smb2_calc_size(hdr);
168
169 if (4 + len != clc_len) {
170 cFYI(1, "Calculated size %u length %u mismatch mid %llu",
171 clc_len, 4 + len, mid);
172
173 if (clc_len + 20 == len && command == SMB2_OPLOCK_BREAK_HE)
174 return 0;
175
176 if (clc_len == 4 + len + 1)
177 return 0;
178 return 1;
179 }
180 return 0;
181}
182
183
184
185
186
187
188static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = {
189 true,
190 true,
191 false,
192 false,
193 false,
194 true,
195 false,
196 false,
197 true,
198 false,
199 false,
200 true,
201 false,
202 false,
203 true,
204 true,
205 true,
206 false,
207 false
208};
209
210
211
212
213
214char *
215smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
216{
217 *off = 0;
218 *len = 0;
219
220
221 if (hdr->Status && hdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
222 (((struct smb2_err_rsp *)hdr)->StructureSize) ==
223 SMB2_ERROR_STRUCTURE_SIZE2)
224 return NULL;
225
226
227
228
229
230
231 switch (hdr->Command) {
232 case SMB2_NEGOTIATE:
233 *off = le16_to_cpu(
234 ((struct smb2_negotiate_rsp *)hdr)->SecurityBufferOffset);
235 *len = le16_to_cpu(
236 ((struct smb2_negotiate_rsp *)hdr)->SecurityBufferLength);
237 break;
238 case SMB2_SESSION_SETUP:
239 *off = le16_to_cpu(
240 ((struct smb2_sess_setup_rsp *)hdr)->SecurityBufferOffset);
241 *len = le16_to_cpu(
242 ((struct smb2_sess_setup_rsp *)hdr)->SecurityBufferLength);
243 break;
244 case SMB2_CREATE:
245 *off = le32_to_cpu(
246 ((struct smb2_create_rsp *)hdr)->CreateContextsOffset);
247 *len = le32_to_cpu(
248 ((struct smb2_create_rsp *)hdr)->CreateContextsLength);
249 break;
250 case SMB2_QUERY_INFO:
251 *off = le16_to_cpu(
252 ((struct smb2_query_info_rsp *)hdr)->OutputBufferOffset);
253 *len = le32_to_cpu(
254 ((struct smb2_query_info_rsp *)hdr)->OutputBufferLength);
255 break;
256 case SMB2_READ:
257 *off = ((struct smb2_read_rsp *)hdr)->DataOffset;
258 *len = le32_to_cpu(((struct smb2_read_rsp *)hdr)->DataLength);
259 break;
260 case SMB2_QUERY_DIRECTORY:
261 *off = le16_to_cpu(
262 ((struct smb2_query_directory_rsp *)hdr)->OutputBufferOffset);
263 *len = le32_to_cpu(
264 ((struct smb2_query_directory_rsp *)hdr)->OutputBufferLength);
265 break;
266 case SMB2_IOCTL:
267 case SMB2_CHANGE_NOTIFY:
268 default:
269
270 cERROR(1, "no length check for command");
271 break;
272 }
273
274
275
276
277
278 if (*off > 4096) {
279 cERROR(1, "offset %d too large, data area ignored", *off);
280 *len = 0;
281 *off = 0;
282 } else if (*off < 0) {
283 cERROR(1, "negative offset %d to data invalid ignore data area",
284 *off);
285 *off = 0;
286 *len = 0;
287 } else if (*len < 0) {
288 cERROR(1, "negative data length %d invalid, data area ignored",
289 *len);
290 *len = 0;
291 } else if (*len > 128 * 1024) {
292 cERROR(1, "data area larger than 128K: %d", *len);
293 *len = 0;
294 }
295
296
297 if ((*off != 0) && (*len != 0))
298 return hdr->ProtocolId + *off;
299 else
300 return NULL;
301}
302
303
304
305
306
307unsigned int
308smb2_calc_size(void *buf)
309{
310 struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
311 struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
312 int offset;
313 int data_length;
314
315 int len = 4 + le16_to_cpu(pdu->hdr.StructureSize);
316
317
318
319
320
321 len += le16_to_cpu(pdu->StructureSize2);
322
323 if (has_smb2_data_area[le16_to_cpu(hdr->Command)] == false)
324 goto calc_size_exit;
325
326 smb2_get_data_area_len(&offset, &data_length, hdr);
327 cFYI(1, "SMB2 data length %d offset %d", data_length, offset);
328
329 if (data_length > 0) {
330
331
332
333
334
335
336
337 if (offset + 4 + 1 < len) {
338 cERROR(1, "data area offset %d overlaps SMB2 header %d",
339 offset + 4 + 1, len);
340 data_length = 0;
341 } else {
342 len = 4 + offset + data_length;
343 }
344 }
345calc_size_exit:
346 cFYI(1, "SMB2 len %d", len);
347 return len;
348}
349
350
351__le16 *
352cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
353{
354 int len;
355 const char *start_of_path;
356 __le16 *to;
357
358
359 if (from[0] == '\\')
360 start_of_path = from + 1;
361 else
362 start_of_path = from;
363 to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len,
364 cifs_sb->local_nls,
365 cifs_sb->mnt_cifs_flags &
366 CIFS_MOUNT_MAP_SPECIAL_CHR);
367 return to;
368}
369
370__le32
371smb2_get_lease_state(struct cifsInodeInfo *cinode)
372{
373 if (cinode->clientCanCacheAll)
374 return SMB2_LEASE_WRITE_CACHING | SMB2_LEASE_READ_CACHING;
375 else if (cinode->clientCanCacheRead)
376 return SMB2_LEASE_READ_CACHING;
377 return 0;
378}
379
380__u8 smb2_map_lease_to_oplock(__le32 lease_state)
381{
382 if (lease_state & SMB2_LEASE_WRITE_CACHING) {
383 if (lease_state & SMB2_LEASE_HANDLE_CACHING)
384 return SMB2_OPLOCK_LEVEL_BATCH;
385 else
386 return SMB2_OPLOCK_LEVEL_EXCLUSIVE;
387 } else if (lease_state & SMB2_LEASE_READ_CACHING)
388 return SMB2_OPLOCK_LEVEL_II;
389 return 0;
390}
391
392struct smb2_lease_break_work {
393 struct work_struct lease_break;
394 struct tcon_link *tlink;
395 __u8 lease_key[16];
396 __le32 lease_state;
397};
398
399static void
400cifs_ses_oplock_break(struct work_struct *work)
401{
402 struct smb2_lease_break_work *lw = container_of(work,
403 struct smb2_lease_break_work, lease_break);
404 int rc;
405
406 rc = SMB2_lease_break(0, tlink_tcon(lw->tlink), lw->lease_key,
407 lw->lease_state);
408 cFYI(1, "Lease release rc %d", rc);
409 cifs_put_tlink(lw->tlink);
410 kfree(lw);
411}
412
413static bool
414smb2_is_valid_lease_break(char *buffer, struct TCP_Server_Info *server)
415{
416 struct smb2_lease_break *rsp = (struct smb2_lease_break *)buffer;
417 struct list_head *tmp, *tmp1, *tmp2;
418 struct cifs_ses *ses;
419 struct cifs_tcon *tcon;
420 struct cifsInodeInfo *cinode;
421 struct cifsFileInfo *cfile;
422 struct cifs_pending_open *open;
423 struct smb2_lease_break_work *lw;
424 bool found;
425 int ack_req = le32_to_cpu(rsp->Flags &
426 SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED);
427
428 lw = kmalloc(sizeof(struct smb2_lease_break_work), GFP_KERNEL);
429 if (!lw) {
430 cERROR(1, "Memory allocation failed during lease break check");
431 return false;
432 }
433
434 INIT_WORK(&lw->lease_break, cifs_ses_oplock_break);
435 lw->lease_state = rsp->NewLeaseState;
436
437 cFYI(1, "Checking for lease break");
438
439
440 spin_lock(&cifs_tcp_ses_lock);
441 list_for_each(tmp, &server->smb_ses_list) {
442 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
443
444 spin_lock(&cifs_file_list_lock);
445 list_for_each(tmp1, &ses->tcon_list) {
446 tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
447
448 cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
449 list_for_each(tmp2, &tcon->openFileList) {
450 cfile = list_entry(tmp2, struct cifsFileInfo,
451 tlist);
452 cinode = CIFS_I(cfile->dentry->d_inode);
453
454 if (memcmp(cinode->lease_key, rsp->LeaseKey,
455 SMB2_LEASE_KEY_SIZE))
456 continue;
457
458 cFYI(1, "found in the open list");
459 cFYI(1, "lease key match, lease break 0x%d",
460 le32_to_cpu(rsp->NewLeaseState));
461
462 smb2_set_oplock_level(cinode,
463 smb2_map_lease_to_oplock(rsp->NewLeaseState));
464
465 if (ack_req)
466 cfile->oplock_break_cancelled = false;
467 else
468 cfile->oplock_break_cancelled = true;
469
470 queue_work(cifsiod_wq, &cfile->oplock_break);
471
472 spin_unlock(&cifs_file_list_lock);
473 spin_unlock(&cifs_tcp_ses_lock);
474 return true;
475 }
476
477 found = false;
478 list_for_each_entry(open, &tcon->pending_opens, olist) {
479 if (memcmp(open->lease_key, rsp->LeaseKey,
480 SMB2_LEASE_KEY_SIZE))
481 continue;
482
483 if (!found && ack_req) {
484 found = true;
485 memcpy(lw->lease_key, open->lease_key,
486 SMB2_LEASE_KEY_SIZE);
487 lw->tlink = cifs_get_tlink(open->tlink);
488 queue_work(cifsiod_wq,
489 &lw->lease_break);
490 }
491
492 cFYI(1, "found in the pending open list");
493 cFYI(1, "lease key match, lease break 0x%d",
494 le32_to_cpu(rsp->NewLeaseState));
495
496 open->oplock =
497 smb2_map_lease_to_oplock(rsp->NewLeaseState);
498 }
499 if (found) {
500 spin_unlock(&cifs_file_list_lock);
501 spin_unlock(&cifs_tcp_ses_lock);
502 return true;
503 }
504 }
505 spin_unlock(&cifs_file_list_lock);
506 }
507 spin_unlock(&cifs_tcp_ses_lock);
508 kfree(lw);
509 cFYI(1, "Can not process lease break - no lease matched");
510 return false;
511}
512
513bool
514smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
515{
516 struct smb2_oplock_break *rsp = (struct smb2_oplock_break *)buffer;
517 struct list_head *tmp, *tmp1, *tmp2;
518 struct cifs_ses *ses;
519 struct cifs_tcon *tcon;
520 struct cifsInodeInfo *cinode;
521 struct cifsFileInfo *cfile;
522
523 cFYI(1, "Checking for oplock break");
524
525 if (rsp->hdr.Command != SMB2_OPLOCK_BREAK)
526 return false;
527
528 if (rsp->StructureSize !=
529 smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) {
530 if (le16_to_cpu(rsp->StructureSize) == 44)
531 return smb2_is_valid_lease_break(buffer, server);
532 else
533 return false;
534 }
535
536 cFYI(1, "oplock level 0x%d", rsp->OplockLevel);
537
538
539 spin_lock(&cifs_tcp_ses_lock);
540 list_for_each(tmp, &server->smb_ses_list) {
541 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
542 list_for_each(tmp1, &ses->tcon_list) {
543 tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
544
545 cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
546 spin_lock(&cifs_file_list_lock);
547 list_for_each(tmp2, &tcon->openFileList) {
548 cfile = list_entry(tmp2, struct cifsFileInfo,
549 tlist);
550 if (rsp->PersistentFid !=
551 cfile->fid.persistent_fid ||
552 rsp->VolatileFid !=
553 cfile->fid.volatile_fid)
554 continue;
555
556 cFYI(1, "file id match, oplock break");
557 cinode = CIFS_I(cfile->dentry->d_inode);
558
559 if (!cinode->clientCanCacheAll &&
560 rsp->OplockLevel == SMB2_OPLOCK_LEVEL_NONE)
561 cfile->oplock_break_cancelled = true;
562 else
563 cfile->oplock_break_cancelled = false;
564
565 smb2_set_oplock_level(cinode,
566 rsp->OplockLevel ? SMB2_OPLOCK_LEVEL_II : 0);
567
568 queue_work(cifsiod_wq, &cfile->oplock_break);
569
570 spin_unlock(&cifs_file_list_lock);
571 spin_unlock(&cifs_tcp_ses_lock);
572 return true;
573 }
574 spin_unlock(&cifs_file_list_lock);
575 spin_unlock(&cifs_tcp_ses_lock);
576 cFYI(1, "No matching file for oplock break");
577 return true;
578 }
579 }
580 spin_unlock(&cifs_tcp_ses_lock);
581 cFYI(1, "Can not process oplock break for non-existent connection");
582 return false;
583}
584