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#include "smb2glob.h"
32
33static int
34check_smb2_hdr(struct smb2_sync_hdr *shdr, __u64 mid)
35{
36 __u64 wire_mid = le64_to_cpu(shdr->MessageId);
37
38
39
40
41
42 if ((shdr->ProtocolId == SMB2_PROTO_NUMBER) &&
43 (mid == wire_mid)) {
44 if (shdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
45 return 0;
46 else {
47
48 if (shdr->Command == SMB2_OPLOCK_BREAK)
49 return 0;
50 else
51 cifs_dbg(VFS, "Received Request not response\n");
52 }
53 } else {
54 if (shdr->ProtocolId != SMB2_PROTO_NUMBER)
55 cifs_dbg(VFS, "Bad protocol string signature header %x\n",
56 le32_to_cpu(shdr->ProtocolId));
57 if (mid != wire_mid)
58 cifs_dbg(VFS, "Mids do not match: %llu and %llu\n",
59 mid, wire_mid);
60 }
61 cifs_dbg(VFS, "Bad SMB detected. The Mid=%llu\n", wire_mid);
62 return 1;
63}
64
65
66
67
68
69
70
71
72static const __le16 smb2_rsp_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
73 cpu_to_le16(65),
74 cpu_to_le16(9),
75 cpu_to_le16(4),
76 cpu_to_le16(16),
77 cpu_to_le16(4),
78 cpu_to_le16(89),
79 cpu_to_le16(60),
80 cpu_to_le16(4),
81 cpu_to_le16(17),
82 cpu_to_le16(17),
83 cpu_to_le16(4),
84 cpu_to_le16(49),
85
86 cpu_to_le16(0),
87 cpu_to_le16(4),
88 cpu_to_le16(9),
89 cpu_to_le16(9),
90 cpu_to_le16(9),
91 cpu_to_le16(2),
92
93 cpu_to_le16(24)
94};
95
96int
97smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
98{
99 struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
100 struct smb2_hdr *hdr = &pdu->hdr;
101 struct smb2_sync_hdr *shdr = get_sync_hdr(buf);
102 __u64 mid;
103 __u32 len = get_rfc1002_length(buf);
104 __u32 clc_len;
105 int command;
106
107
108 cifs_dbg(FYI, "%s length: 0x%x, smb_buf_length: 0x%x\n",
109 __func__, length, len);
110
111
112
113
114
115
116 if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
117 struct smb2_transform_hdr *thdr =
118 (struct smb2_transform_hdr *)buf;
119 struct cifs_ses *ses = NULL;
120 struct list_head *tmp;
121
122
123 spin_lock(&cifs_tcp_ses_lock);
124 list_for_each(tmp, &srvr->smb_ses_list) {
125 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
126 if (ses->Suid == thdr->SessionId)
127 break;
128
129 ses = NULL;
130 }
131 spin_unlock(&cifs_tcp_ses_lock);
132 if (ses == NULL) {
133 cifs_dbg(VFS, "no decryption - session id not found\n");
134 return 1;
135 }
136 }
137
138 mid = le64_to_cpu(shdr->MessageId);
139 if (length < sizeof(struct smb2_pdu)) {
140 if ((length >= sizeof(struct smb2_hdr))
141 && (shdr->Status != 0)) {
142 pdu->StructureSize2 = 0;
143
144
145
146
147 return 0;
148 } else {
149 cifs_dbg(VFS, "Length less than SMB header size\n");
150 }
151 return 1;
152 }
153 if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE - 4) {
154 cifs_dbg(VFS, "SMB length greater than maximum, mid=%llu\n",
155 mid);
156 return 1;
157 }
158
159 if (check_smb2_hdr(shdr, mid))
160 return 1;
161
162 if (shdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
163 cifs_dbg(VFS, "Illegal structure size %u\n",
164 le16_to_cpu(shdr->StructureSize));
165 return 1;
166 }
167
168 command = le16_to_cpu(shdr->Command);
169 if (command >= NUMBER_OF_SMB2_COMMANDS) {
170 cifs_dbg(VFS, "Illegal SMB2 command %d\n", command);
171 return 1;
172 }
173
174 if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) {
175 if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 ||
176 pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2)) {
177
178 cifs_dbg(VFS, "Illegal response size %u for command %d\n",
179 le16_to_cpu(pdu->StructureSize2), command);
180 return 1;
181 } else if (command == SMB2_OPLOCK_BREAK_HE
182 && (shdr->Status == 0)
183 && (le16_to_cpu(pdu->StructureSize2) != 44)
184 && (le16_to_cpu(pdu->StructureSize2) != 36)) {
185
186 cifs_dbg(VFS, "Illegal response size %d for oplock break\n",
187 le16_to_cpu(pdu->StructureSize2));
188 return 1;
189 }
190 }
191
192 if (4 + len != length) {
193 cifs_dbg(VFS, "Total length %u RFC1002 length %u mismatch mid %llu\n",
194 length, 4 + len, mid);
195 return 1;
196 }
197
198 clc_len = smb2_calc_size(hdr);
199
200 if (4 + len != clc_len) {
201 cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n",
202 clc_len, 4 + len, mid);
203
204 if (command == SMB2_CREATE_HE &&
205 shdr->Status == STATUS_STOPPED_ON_SYMLINK)
206 return 0;
207
208 if (clc_len + 20 == len && command == SMB2_OPLOCK_BREAK_HE)
209 return 0;
210
211 if (clc_len == 4 + len + 1)
212 return 0;
213
214
215
216
217
218
219
220
221 if (clc_len < 4 + len) {
222 printk_once(KERN_WARNING
223 "SMB2 server sent bad RFC1001 len %d not %d\n",
224 len, clc_len - 4);
225 return 0;
226 }
227
228 return 1;
229 }
230 return 0;
231}
232
233
234
235
236
237
238static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = {
239 true,
240 true,
241 false,
242 false,
243 false,
244 true,
245 false,
246 false,
247 true,
248 false,
249 false,
250 true,
251 false,
252 false,
253 true,
254 true,
255 true,
256 false,
257 false
258};
259
260
261
262
263
264char *
265smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
266{
267 struct smb2_sync_hdr *shdr = get_sync_hdr(hdr);
268 *off = 0;
269 *len = 0;
270
271
272 if (shdr->Status && shdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
273 (((struct smb2_err_rsp *)hdr)->StructureSize) ==
274 SMB2_ERROR_STRUCTURE_SIZE2)
275 return NULL;
276
277
278
279
280
281
282 switch (shdr->Command) {
283 case SMB2_NEGOTIATE:
284 *off = le16_to_cpu(
285 ((struct smb2_negotiate_rsp *)hdr)->SecurityBufferOffset);
286 *len = le16_to_cpu(
287 ((struct smb2_negotiate_rsp *)hdr)->SecurityBufferLength);
288 break;
289 case SMB2_SESSION_SETUP:
290 *off = le16_to_cpu(
291 ((struct smb2_sess_setup_rsp *)hdr)->SecurityBufferOffset);
292 *len = le16_to_cpu(
293 ((struct smb2_sess_setup_rsp *)hdr)->SecurityBufferLength);
294 break;
295 case SMB2_CREATE:
296 *off = le32_to_cpu(
297 ((struct smb2_create_rsp *)hdr)->CreateContextsOffset);
298 *len = le32_to_cpu(
299 ((struct smb2_create_rsp *)hdr)->CreateContextsLength);
300 break;
301 case SMB2_QUERY_INFO:
302 *off = le16_to_cpu(
303 ((struct smb2_query_info_rsp *)hdr)->OutputBufferOffset);
304 *len = le32_to_cpu(
305 ((struct smb2_query_info_rsp *)hdr)->OutputBufferLength);
306 break;
307 case SMB2_READ:
308 *off = ((struct smb2_read_rsp *)hdr)->DataOffset;
309 *len = le32_to_cpu(((struct smb2_read_rsp *)hdr)->DataLength);
310 break;
311 case SMB2_QUERY_DIRECTORY:
312 *off = le16_to_cpu(
313 ((struct smb2_query_directory_rsp *)hdr)->OutputBufferOffset);
314 *len = le32_to_cpu(
315 ((struct smb2_query_directory_rsp *)hdr)->OutputBufferLength);
316 break;
317 case SMB2_IOCTL:
318 *off = le32_to_cpu(
319 ((struct smb2_ioctl_rsp *)hdr)->OutputOffset);
320 *len = le32_to_cpu(((struct smb2_ioctl_rsp *)hdr)->OutputCount);
321 break;
322 case SMB2_CHANGE_NOTIFY:
323 default:
324
325 cifs_dbg(VFS, "no length check for command\n");
326 break;
327 }
328
329
330
331
332
333 if (*off > 4096) {
334 cifs_dbg(VFS, "offset %d too large, data area ignored\n", *off);
335 *len = 0;
336 *off = 0;
337 } else if (*off < 0) {
338 cifs_dbg(VFS, "negative offset %d to data invalid ignore data area\n",
339 *off);
340 *off = 0;
341 *len = 0;
342 } else if (*len < 0) {
343 cifs_dbg(VFS, "negative data length %d invalid, data area ignored\n",
344 *len);
345 *len = 0;
346 } else if (*len > 128 * 1024) {
347 cifs_dbg(VFS, "data area larger than 128K: %d\n", *len);
348 *len = 0;
349 }
350
351
352 if ((*off != 0) && (*len != 0))
353 return (char *)shdr + *off;
354 else
355 return NULL;
356}
357
358
359
360
361
362unsigned int
363smb2_calc_size(void *buf)
364{
365 struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
366 struct smb2_hdr *hdr = &pdu->hdr;
367 struct smb2_sync_hdr *shdr = get_sync_hdr(hdr);
368 int offset;
369 int data_length;
370
371 int len = 4 + le16_to_cpu(shdr->StructureSize);
372
373
374
375
376
377 len += le16_to_cpu(pdu->StructureSize2);
378
379 if (has_smb2_data_area[le16_to_cpu(shdr->Command)] == false)
380 goto calc_size_exit;
381
382 smb2_get_data_area_len(&offset, &data_length, hdr);
383 cifs_dbg(FYI, "SMB2 data length %d offset %d\n", data_length, offset);
384
385 if (data_length > 0) {
386
387
388
389
390
391
392
393 if (offset + 4 + 1 < len) {
394 cifs_dbg(VFS, "data area offset %d overlaps SMB2 header %d\n",
395 offset + 4 + 1, len);
396 data_length = 0;
397 } else {
398 len = 4 + offset + data_length;
399 }
400 }
401calc_size_exit:
402 cifs_dbg(FYI, "SMB2 len %d\n", len);
403 return len;
404}
405
406
407__le16 *
408cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
409{
410 int len;
411 const char *start_of_path;
412 __le16 *to;
413 int map_type;
414
415 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR)
416 map_type = SFM_MAP_UNI_RSVD;
417 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
418 map_type = SFU_MAP_UNI_RSVD;
419 else
420 map_type = NO_MAP_UNI_RSVD;
421
422
423 if (from[0] == '\\')
424 start_of_path = from + 1;
425 else
426 start_of_path = from;
427 to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len,
428 cifs_sb->local_nls, map_type);
429 return to;
430}
431
432__le32
433smb2_get_lease_state(struct cifsInodeInfo *cinode)
434{
435 __le32 lease = 0;
436
437 if (CIFS_CACHE_WRITE(cinode))
438 lease |= SMB2_LEASE_WRITE_CACHING;
439 if (CIFS_CACHE_HANDLE(cinode))
440 lease |= SMB2_LEASE_HANDLE_CACHING;
441 if (CIFS_CACHE_READ(cinode))
442 lease |= SMB2_LEASE_READ_CACHING;
443 return lease;
444}
445
446struct smb2_lease_break_work {
447 struct work_struct lease_break;
448 struct tcon_link *tlink;
449 __u8 lease_key[16];
450 __le32 lease_state;
451};
452
453static void
454cifs_ses_oplock_break(struct work_struct *work)
455{
456 struct smb2_lease_break_work *lw = container_of(work,
457 struct smb2_lease_break_work, lease_break);
458 int rc;
459
460 rc = SMB2_lease_break(0, tlink_tcon(lw->tlink), lw->lease_key,
461 lw->lease_state);
462 cifs_dbg(FYI, "Lease release rc %d\n", rc);
463 cifs_put_tlink(lw->tlink);
464 kfree(lw);
465}
466
467static bool
468smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp,
469 struct smb2_lease_break_work *lw)
470{
471 bool found;
472 __u8 lease_state;
473 struct list_head *tmp;
474 struct cifsFileInfo *cfile;
475 struct TCP_Server_Info *server = tcon->ses->server;
476 struct cifs_pending_open *open;
477 struct cifsInodeInfo *cinode;
478 int ack_req = le32_to_cpu(rsp->Flags &
479 SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED);
480
481 lease_state = le32_to_cpu(rsp->NewLeaseState);
482
483 list_for_each(tmp, &tcon->openFileList) {
484 cfile = list_entry(tmp, struct cifsFileInfo, tlist);
485 cinode = CIFS_I(d_inode(cfile->dentry));
486
487 if (memcmp(cinode->lease_key, rsp->LeaseKey,
488 SMB2_LEASE_KEY_SIZE))
489 continue;
490
491 cifs_dbg(FYI, "found in the open list\n");
492 cifs_dbg(FYI, "lease key match, lease break 0x%x\n",
493 le32_to_cpu(rsp->NewLeaseState));
494
495 server->ops->set_oplock_level(cinode, lease_state, 0, NULL);
496
497 if (ack_req)
498 cfile->oplock_break_cancelled = false;
499 else
500 cfile->oplock_break_cancelled = true;
501
502 queue_work(cifsoplockd_wq, &cfile->oplock_break);
503 kfree(lw);
504 return true;
505 }
506
507 found = false;
508 list_for_each_entry(open, &tcon->pending_opens, olist) {
509 if (memcmp(open->lease_key, rsp->LeaseKey,
510 SMB2_LEASE_KEY_SIZE))
511 continue;
512
513 if (!found && ack_req) {
514 found = true;
515 memcpy(lw->lease_key, open->lease_key,
516 SMB2_LEASE_KEY_SIZE);
517 lw->tlink = cifs_get_tlink(open->tlink);
518 queue_work(cifsiod_wq, &lw->lease_break);
519 }
520
521 cifs_dbg(FYI, "found in the pending open list\n");
522 cifs_dbg(FYI, "lease key match, lease break 0x%x\n",
523 le32_to_cpu(rsp->NewLeaseState));
524
525 open->oplock = lease_state;
526 }
527 return found;
528}
529
530static bool
531smb2_is_valid_lease_break(char *buffer)
532{
533 struct smb2_lease_break *rsp = (struct smb2_lease_break *)buffer;
534 struct list_head *tmp, *tmp1, *tmp2;
535 struct TCP_Server_Info *server;
536 struct cifs_ses *ses;
537 struct cifs_tcon *tcon;
538 struct smb2_lease_break_work *lw;
539
540 lw = kmalloc(sizeof(struct smb2_lease_break_work), GFP_KERNEL);
541 if (!lw)
542 return false;
543
544 INIT_WORK(&lw->lease_break, cifs_ses_oplock_break);
545 lw->lease_state = rsp->NewLeaseState;
546
547 cifs_dbg(FYI, "Checking for lease break\n");
548
549
550 spin_lock(&cifs_tcp_ses_lock);
551 list_for_each(tmp, &cifs_tcp_ses_list) {
552 server = list_entry(tmp, struct TCP_Server_Info, tcp_ses_list);
553
554 list_for_each(tmp1, &server->smb_ses_list) {
555 ses = list_entry(tmp1, struct cifs_ses, smb_ses_list);
556
557 list_for_each(tmp2, &ses->tcon_list) {
558 tcon = list_entry(tmp2, struct cifs_tcon,
559 tcon_list);
560 spin_lock(&tcon->open_file_lock);
561 cifs_stats_inc(
562 &tcon->stats.cifs_stats.num_oplock_brks);
563 if (smb2_tcon_has_lease(tcon, rsp, lw)) {
564 spin_unlock(&tcon->open_file_lock);
565 spin_unlock(&cifs_tcp_ses_lock);
566 return true;
567 }
568 spin_unlock(&tcon->open_file_lock);
569 }
570 }
571 }
572 spin_unlock(&cifs_tcp_ses_lock);
573 kfree(lw);
574 cifs_dbg(FYI, "Can not process lease break - no lease matched\n");
575 return false;
576}
577
578bool
579smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
580{
581 struct smb2_oplock_break_rsp *rsp = (struct smb2_oplock_break_rsp *)buffer;
582 struct list_head *tmp, *tmp1, *tmp2;
583 struct cifs_ses *ses;
584 struct cifs_tcon *tcon;
585 struct cifsInodeInfo *cinode;
586 struct cifsFileInfo *cfile;
587
588 cifs_dbg(FYI, "Checking for oplock break\n");
589
590 if (rsp->hdr.sync_hdr.Command != SMB2_OPLOCK_BREAK)
591 return false;
592
593 if (rsp->StructureSize !=
594 smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) {
595 if (le16_to_cpu(rsp->StructureSize) == 44)
596 return smb2_is_valid_lease_break(buffer);
597 else
598 return false;
599 }
600
601 cifs_dbg(FYI, "oplock level 0x%x\n", rsp->OplockLevel);
602
603
604 spin_lock(&cifs_tcp_ses_lock);
605 list_for_each(tmp, &server->smb_ses_list) {
606 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
607 list_for_each(tmp1, &ses->tcon_list) {
608 tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
609
610 cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
611 spin_lock(&tcon->open_file_lock);
612 list_for_each(tmp2, &tcon->openFileList) {
613 cfile = list_entry(tmp2, struct cifsFileInfo,
614 tlist);
615 if (rsp->PersistentFid !=
616 cfile->fid.persistent_fid ||
617 rsp->VolatileFid !=
618 cfile->fid.volatile_fid)
619 continue;
620
621 cifs_dbg(FYI, "file id match, oplock break\n");
622 cinode = CIFS_I(d_inode(cfile->dentry));
623 spin_lock(&cfile->file_info_lock);
624 if (!CIFS_CACHE_WRITE(cinode) &&
625 rsp->OplockLevel == SMB2_OPLOCK_LEVEL_NONE)
626 cfile->oplock_break_cancelled = true;
627 else
628 cfile->oplock_break_cancelled = false;
629
630 set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK,
631 &cinode->flags);
632
633
634
635
636
637 if (rsp->OplockLevel)
638 set_bit(
639 CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
640 &cinode->flags);
641 else
642 clear_bit(
643 CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
644 &cinode->flags);
645 spin_unlock(&cfile->file_info_lock);
646 queue_work(cifsoplockd_wq,
647 &cfile->oplock_break);
648
649 spin_unlock(&tcon->open_file_lock);
650 spin_unlock(&cifs_tcp_ses_lock);
651 return true;
652 }
653 spin_unlock(&tcon->open_file_lock);
654 spin_unlock(&cifs_tcp_ses_lock);
655 cifs_dbg(FYI, "No matching file for oplock break\n");
656 return true;
657 }
658 }
659 spin_unlock(&cifs_tcp_ses_lock);
660 cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n");
661 return false;
662}
663
664void
665smb2_cancelled_close_fid(struct work_struct *work)
666{
667 struct close_cancelled_open *cancelled = container_of(work,
668 struct close_cancelled_open, work);
669
670 cifs_dbg(VFS, "Close unmatched open\n");
671
672 SMB2_close(0, cancelled->tcon, cancelled->fid.persistent_fid,
673 cancelled->fid.volatile_fid);
674 cifs_put_tcon(cancelled->tcon);
675 kfree(cancelled);
676}
677
678int
679smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server)
680{
681 struct smb2_sync_hdr *sync_hdr = get_sync_hdr(buffer);
682 struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer;
683 struct cifs_tcon *tcon;
684 struct close_cancelled_open *cancelled;
685
686 if (sync_hdr->Command != SMB2_CREATE ||
687 sync_hdr->Status != STATUS_SUCCESS)
688 return 0;
689
690 cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
691 if (!cancelled)
692 return -ENOMEM;
693
694 tcon = smb2_find_smb_tcon(server, sync_hdr->SessionId,
695 sync_hdr->TreeId);
696 if (!tcon) {
697 kfree(cancelled);
698 return -ENOENT;
699 }
700
701 cancelled->fid.persistent_fid = rsp->PersistentFileId;
702 cancelled->fid.volatile_fid = rsp->VolatileFileId;
703 cancelled->tcon = tcon;
704 INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
705 queue_work(cifsiod_wq, &cancelled->work);
706
707 return 0;
708}
709