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#include "nterr.h"
33
34static int
35check_smb2_hdr(struct smb2_sync_hdr *shdr, __u64 mid)
36{
37 __u64 wire_mid = le64_to_cpu(shdr->MessageId);
38
39
40
41
42
43 if ((shdr->ProtocolId == SMB2_PROTO_NUMBER) &&
44 (mid == wire_mid)) {
45 if (shdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
46 return 0;
47 else {
48
49 if (shdr->Command == SMB2_OPLOCK_BREAK)
50 return 0;
51 else
52 cifs_dbg(VFS, "Received Request not response\n");
53 }
54 } else {
55 if (shdr->ProtocolId != SMB2_PROTO_NUMBER)
56 cifs_dbg(VFS, "Bad protocol string signature header %x\n",
57 le32_to_cpu(shdr->ProtocolId));
58 if (mid != wire_mid)
59 cifs_dbg(VFS, "Mids do not match: %llu and %llu\n",
60 mid, wire_mid);
61 }
62 cifs_dbg(VFS, "Bad SMB detected. The Mid=%llu\n", wire_mid);
63 return 1;
64}
65
66
67
68
69
70
71
72
73static const __le16 smb2_rsp_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
74 cpu_to_le16(65),
75 cpu_to_le16(9),
76 cpu_to_le16(4),
77 cpu_to_le16(16),
78 cpu_to_le16(4),
79 cpu_to_le16(89),
80 cpu_to_le16(60),
81 cpu_to_le16(4),
82 cpu_to_le16(17),
83 cpu_to_le16(17),
84 cpu_to_le16(4),
85 cpu_to_le16(49),
86
87 cpu_to_le16(0),
88 cpu_to_le16(4),
89 cpu_to_le16(9),
90 cpu_to_le16(9),
91 cpu_to_le16(9),
92 cpu_to_le16(2),
93
94 cpu_to_le16(24)
95};
96
97static __u32 get_neg_ctxt_len(struct smb2_sync_hdr *hdr, __u32 len,
98 __u32 non_ctxlen)
99{
100 __u16 neg_count;
101 __u32 nc_offset, size_of_pad_before_neg_ctxts;
102 struct smb2_negotiate_rsp *pneg_rsp = (struct smb2_negotiate_rsp *)hdr;
103
104
105 neg_count = le16_to_cpu(pneg_rsp->NegotiateContextCount);
106 if ((neg_count == 0) ||
107 (pneg_rsp->DialectRevision != cpu_to_le16(SMB311_PROT_ID)))
108 return 0;
109
110
111 nc_offset = le32_to_cpu(pneg_rsp->NegotiateContextOffset);
112 if (nc_offset < non_ctxlen) {
113 printk_once(KERN_WARNING "invalid negotiate context offset\n");
114 return 0;
115 }
116 size_of_pad_before_neg_ctxts = nc_offset - non_ctxlen;
117
118
119 if (len < nc_offset + (neg_count * sizeof(struct smb2_neg_context))) {
120 printk_once(KERN_WARNING "negotiate context goes beyond end\n");
121 return 0;
122 }
123
124 cifs_dbg(FYI, "length of negcontexts %d pad %d\n",
125 len - nc_offset, size_of_pad_before_neg_ctxts);
126
127
128 return (len - nc_offset) + size_of_pad_before_neg_ctxts;
129}
130
131int
132smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
133{
134 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
135 struct smb2_sync_pdu *pdu = (struct smb2_sync_pdu *)shdr;
136 __u64 mid;
137 __u32 clc_len;
138 int command;
139 int pdu_size = sizeof(struct smb2_sync_pdu);
140 int hdr_size = sizeof(struct smb2_sync_hdr);
141
142
143
144
145
146 if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
147 struct smb2_transform_hdr *thdr =
148 (struct smb2_transform_hdr *)buf;
149 struct cifs_ses *ses = NULL;
150 struct list_head *tmp;
151
152
153 spin_lock(&cifs_tcp_ses_lock);
154 list_for_each(tmp, &srvr->smb_ses_list) {
155 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
156 if (ses->Suid == thdr->SessionId)
157 break;
158
159 ses = NULL;
160 }
161 spin_unlock(&cifs_tcp_ses_lock);
162 if (ses == NULL) {
163 cifs_dbg(VFS, "no decryption - session id not found\n");
164 return 1;
165 }
166 }
167
168 mid = le64_to_cpu(shdr->MessageId);
169 if (len < pdu_size) {
170 if ((len >= hdr_size)
171 && (shdr->Status != 0)) {
172 pdu->StructureSize2 = 0;
173
174
175
176
177 return 0;
178 } else {
179 cifs_dbg(VFS, "Length less than SMB header size\n");
180 }
181 return 1;
182 }
183 if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE) {
184 cifs_dbg(VFS, "SMB length greater than maximum, mid=%llu\n",
185 mid);
186 return 1;
187 }
188
189 if (check_smb2_hdr(shdr, mid))
190 return 1;
191
192 if (shdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
193 cifs_dbg(VFS, "Illegal structure size %u\n",
194 le16_to_cpu(shdr->StructureSize));
195 return 1;
196 }
197
198 command = le16_to_cpu(shdr->Command);
199 if (command >= NUMBER_OF_SMB2_COMMANDS) {
200 cifs_dbg(VFS, "Illegal SMB2 command %d\n", command);
201 return 1;
202 }
203
204 if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) {
205 if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 ||
206 pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2)) {
207
208 cifs_dbg(VFS, "Illegal response size %u for command %d\n",
209 le16_to_cpu(pdu->StructureSize2), command);
210 return 1;
211 } else if (command == SMB2_OPLOCK_BREAK_HE
212 && (shdr->Status == 0)
213 && (le16_to_cpu(pdu->StructureSize2) != 44)
214 && (le16_to_cpu(pdu->StructureSize2) != 36)) {
215
216 cifs_dbg(VFS, "Illegal response size %d for oplock break\n",
217 le16_to_cpu(pdu->StructureSize2));
218 return 1;
219 }
220 }
221
222 clc_len = smb2_calc_size(buf, srvr);
223
224 if (shdr->Command == SMB2_NEGOTIATE)
225 clc_len += get_neg_ctxt_len(shdr, len, clc_len);
226
227 if (len != clc_len) {
228 cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n",
229 clc_len, len, mid);
230
231 if (command == SMB2_CREATE_HE &&
232 shdr->Status == STATUS_STOPPED_ON_SYMLINK)
233 return 0;
234
235 if (clc_len + 24 == len && command == SMB2_OPLOCK_BREAK_HE)
236 return 0;
237
238 if (clc_len == len + 1)
239 return 0;
240
241
242
243
244
245 if (((clc_len + 7) & ~7) == len)
246 return 0;
247
248
249
250
251
252
253
254 if (clc_len < len)
255 return 0;
256
257 pr_warn_once(
258 "srv rsp too short, len %d not %d. cmd:%d mid:%llu\n",
259 len, clc_len, command, mid);
260
261 return 1;
262 }
263 return 0;
264}
265
266
267
268
269
270
271static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = {
272 true,
273 true,
274 false,
275 false,
276 false,
277 true,
278 false,
279 false,
280 true,
281 false,
282 false,
283 true,
284 false,
285 false,
286 true,
287 true,
288 true,
289 false,
290 false
291};
292
293
294
295
296
297char *
298smb2_get_data_area_len(int *off, int *len, struct smb2_sync_hdr *shdr)
299{
300 *off = 0;
301 *len = 0;
302
303
304 if (shdr->Status && shdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
305 (((struct smb2_err_rsp *)shdr)->StructureSize) ==
306 SMB2_ERROR_STRUCTURE_SIZE2)
307 return NULL;
308
309
310
311
312
313
314 switch (shdr->Command) {
315 case SMB2_NEGOTIATE:
316 *off = le16_to_cpu(
317 ((struct smb2_negotiate_rsp *)shdr)->SecurityBufferOffset);
318 *len = le16_to_cpu(
319 ((struct smb2_negotiate_rsp *)shdr)->SecurityBufferLength);
320 break;
321 case SMB2_SESSION_SETUP:
322 *off = le16_to_cpu(
323 ((struct smb2_sess_setup_rsp *)shdr)->SecurityBufferOffset);
324 *len = le16_to_cpu(
325 ((struct smb2_sess_setup_rsp *)shdr)->SecurityBufferLength);
326 break;
327 case SMB2_CREATE:
328 *off = le32_to_cpu(
329 ((struct smb2_create_rsp *)shdr)->CreateContextsOffset);
330 *len = le32_to_cpu(
331 ((struct smb2_create_rsp *)shdr)->CreateContextsLength);
332 break;
333 case SMB2_QUERY_INFO:
334 *off = le16_to_cpu(
335 ((struct smb2_query_info_rsp *)shdr)->OutputBufferOffset);
336 *len = le32_to_cpu(
337 ((struct smb2_query_info_rsp *)shdr)->OutputBufferLength);
338 break;
339 case SMB2_READ:
340
341 *off = ((struct smb2_read_rsp *)shdr)->DataOffset;
342 *len = le32_to_cpu(((struct smb2_read_rsp *)shdr)->DataLength);
343 break;
344 case SMB2_QUERY_DIRECTORY:
345 *off = le16_to_cpu(
346 ((struct smb2_query_directory_rsp *)shdr)->OutputBufferOffset);
347 *len = le32_to_cpu(
348 ((struct smb2_query_directory_rsp *)shdr)->OutputBufferLength);
349 break;
350 case SMB2_IOCTL:
351 *off = le32_to_cpu(
352 ((struct smb2_ioctl_rsp *)shdr)->OutputOffset);
353 *len = le32_to_cpu(
354 ((struct smb2_ioctl_rsp *)shdr)->OutputCount);
355 break;
356 case SMB2_CHANGE_NOTIFY:
357 default:
358
359 cifs_dbg(VFS, "no length check for command\n");
360 break;
361 }
362
363
364
365
366
367 if (*off > 4096) {
368 cifs_dbg(VFS, "offset %d too large, data area ignored\n", *off);
369 *len = 0;
370 *off = 0;
371 } else if (*off < 0) {
372 cifs_dbg(VFS, "negative offset %d to data invalid ignore data area\n",
373 *off);
374 *off = 0;
375 *len = 0;
376 } else if (*len < 0) {
377 cifs_dbg(VFS, "negative data length %d invalid, data area ignored\n",
378 *len);
379 *len = 0;
380 } else if (*len > 128 * 1024) {
381 cifs_dbg(VFS, "data area larger than 128K: %d\n", *len);
382 *len = 0;
383 }
384
385
386 if ((*off != 0) && (*len != 0))
387 return (char *)shdr + *off;
388 else
389 return NULL;
390}
391
392
393
394
395
396unsigned int
397smb2_calc_size(void *buf, struct TCP_Server_Info *srvr)
398{
399 struct smb2_sync_pdu *pdu = (struct smb2_sync_pdu *)buf;
400 struct smb2_sync_hdr *shdr = &pdu->sync_hdr;
401 int offset;
402 int data_length;
403
404 int len = le16_to_cpu(shdr->StructureSize);
405
406
407
408
409
410 len += le16_to_cpu(pdu->StructureSize2);
411
412 if (has_smb2_data_area[le16_to_cpu(shdr->Command)] == false)
413 goto calc_size_exit;
414
415 smb2_get_data_area_len(&offset, &data_length, shdr);
416 cifs_dbg(FYI, "SMB2 data length %d offset %d\n", data_length, offset);
417
418 if (data_length > 0) {
419
420
421
422
423
424
425 if (offset + 1 < len) {
426 cifs_dbg(VFS, "data area offset %d overlaps SMB2 header %d\n",
427 offset + 1, len);
428 data_length = 0;
429 } else {
430 len = offset + data_length;
431 }
432 }
433calc_size_exit:
434 cifs_dbg(FYI, "SMB2 len %d\n", len);
435 return len;
436}
437
438
439__le16 *
440cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
441{
442 int len;
443 const char *start_of_path;
444 __le16 *to;
445 int map_type;
446
447 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR)
448 map_type = SFM_MAP_UNI_RSVD;
449 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
450 map_type = SFU_MAP_UNI_RSVD;
451 else
452 map_type = NO_MAP_UNI_RSVD;
453
454
455 if (from[0] == '\\')
456 start_of_path = from + 1;
457
458
459 else if (cifs_sb_master_tlink(cifs_sb) &&
460 cifs_sb_master_tcon(cifs_sb)->posix_extensions &&
461 (from[0] == '/')) {
462 start_of_path = from + 1;
463 } else
464 start_of_path = from;
465
466 to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len,
467 cifs_sb->local_nls, map_type);
468 return to;
469}
470
471__le32
472smb2_get_lease_state(struct cifsInodeInfo *cinode)
473{
474 __le32 lease = 0;
475
476 if (CIFS_CACHE_WRITE(cinode))
477 lease |= SMB2_LEASE_WRITE_CACHING;
478 if (CIFS_CACHE_HANDLE(cinode))
479 lease |= SMB2_LEASE_HANDLE_CACHING;
480 if (CIFS_CACHE_READ(cinode))
481 lease |= SMB2_LEASE_READ_CACHING;
482 return lease;
483}
484
485struct smb2_lease_break_work {
486 struct work_struct lease_break;
487 struct tcon_link *tlink;
488 __u8 lease_key[16];
489 __le32 lease_state;
490};
491
492static void
493cifs_ses_oplock_break(struct work_struct *work)
494{
495 struct smb2_lease_break_work *lw = container_of(work,
496 struct smb2_lease_break_work, lease_break);
497 int rc = 0;
498
499 rc = SMB2_lease_break(0, tlink_tcon(lw->tlink), lw->lease_key,
500 lw->lease_state);
501
502 cifs_dbg(FYI, "Lease release rc %d\n", rc);
503 cifs_put_tlink(lw->tlink);
504 kfree(lw);
505}
506
507static bool
508smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp,
509 struct smb2_lease_break_work *lw)
510{
511 bool found;
512 __u8 lease_state;
513 struct list_head *tmp;
514 struct cifsFileInfo *cfile;
515 struct cifs_pending_open *open;
516 struct cifsInodeInfo *cinode;
517 int ack_req = le32_to_cpu(rsp->Flags &
518 SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED);
519
520 lease_state = le32_to_cpu(rsp->NewLeaseState);
521
522 list_for_each(tmp, &tcon->openFileList) {
523 cfile = list_entry(tmp, struct cifsFileInfo, tlist);
524 cinode = CIFS_I(d_inode(cfile->dentry));
525
526 if (memcmp(cinode->lease_key, rsp->LeaseKey,
527 SMB2_LEASE_KEY_SIZE))
528 continue;
529
530 cifs_dbg(FYI, "found in the open list\n");
531 cifs_dbg(FYI, "lease key match, lease break 0x%x\n",
532 lease_state);
533
534 if (ack_req)
535 cfile->oplock_break_cancelled = false;
536 else
537 cfile->oplock_break_cancelled = true;
538
539 set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags);
540
541 cfile->oplock_epoch = le16_to_cpu(rsp->Epoch);
542 cfile->oplock_level = lease_state;
543
544 cifs_queue_oplock_break(cfile);
545 kfree(lw);
546 return true;
547 }
548
549 found = false;
550 list_for_each_entry(open, &tcon->pending_opens, olist) {
551 if (memcmp(open->lease_key, rsp->LeaseKey,
552 SMB2_LEASE_KEY_SIZE))
553 continue;
554
555 if (!found && ack_req) {
556 found = true;
557 memcpy(lw->lease_key, open->lease_key,
558 SMB2_LEASE_KEY_SIZE);
559 lw->tlink = cifs_get_tlink(open->tlink);
560 queue_work(cifsiod_wq, &lw->lease_break);
561 }
562
563 cifs_dbg(FYI, "found in the pending open list\n");
564 cifs_dbg(FYI, "lease key match, lease break 0x%x\n",
565 lease_state);
566
567 open->oplock = lease_state;
568 }
569
570 return found;
571}
572
573static bool
574smb2_is_valid_lease_break(char *buffer)
575{
576 struct smb2_lease_break *rsp = (struct smb2_lease_break *)buffer;
577 struct list_head *tmp, *tmp1, *tmp2;
578 struct TCP_Server_Info *server;
579 struct cifs_ses *ses;
580 struct cifs_tcon *tcon;
581 struct smb2_lease_break_work *lw;
582
583 lw = kmalloc(sizeof(struct smb2_lease_break_work), GFP_KERNEL);
584 if (!lw)
585 return false;
586
587 INIT_WORK(&lw->lease_break, cifs_ses_oplock_break);
588 lw->lease_state = rsp->NewLeaseState;
589
590 cifs_dbg(FYI, "Checking for lease break\n");
591
592
593 spin_lock(&cifs_tcp_ses_lock);
594 list_for_each(tmp, &cifs_tcp_ses_list) {
595 server = list_entry(tmp, struct TCP_Server_Info, tcp_ses_list);
596
597 list_for_each(tmp1, &server->smb_ses_list) {
598 ses = list_entry(tmp1, struct cifs_ses, smb_ses_list);
599
600 list_for_each(tmp2, &ses->tcon_list) {
601 tcon = list_entry(tmp2, struct cifs_tcon,
602 tcon_list);
603 spin_lock(&tcon->open_file_lock);
604 cifs_stats_inc(
605 &tcon->stats.cifs_stats.num_oplock_brks);
606 if (smb2_tcon_has_lease(tcon, rsp, lw)) {
607 spin_unlock(&tcon->open_file_lock);
608 spin_unlock(&cifs_tcp_ses_lock);
609 return true;
610 }
611 spin_unlock(&tcon->open_file_lock);
612
613 if (tcon->crfid.is_valid &&
614 !memcmp(rsp->LeaseKey,
615 tcon->crfid.fid->lease_key,
616 SMB2_LEASE_KEY_SIZE)) {
617 INIT_WORK(&tcon->crfid.lease_break,
618 smb2_cached_lease_break);
619 queue_work(cifsiod_wq,
620 &tcon->crfid.lease_break);
621 spin_unlock(&cifs_tcp_ses_lock);
622 return true;
623 }
624 }
625 }
626 }
627 spin_unlock(&cifs_tcp_ses_lock);
628 kfree(lw);
629 cifs_dbg(FYI, "Can not process lease break - no lease matched\n");
630 return false;
631}
632
633bool
634smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
635{
636 struct smb2_oplock_break *rsp = (struct smb2_oplock_break *)buffer;
637 struct list_head *tmp, *tmp1, *tmp2;
638 struct cifs_ses *ses;
639 struct cifs_tcon *tcon;
640 struct cifsInodeInfo *cinode;
641 struct cifsFileInfo *cfile;
642
643 cifs_dbg(FYI, "Checking for oplock break\n");
644
645 if (rsp->sync_hdr.Command != SMB2_OPLOCK_BREAK)
646 return false;
647
648 if (rsp->StructureSize !=
649 smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) {
650 if (le16_to_cpu(rsp->StructureSize) == 44)
651 return smb2_is_valid_lease_break(buffer);
652 else
653 return false;
654 }
655
656 cifs_dbg(FYI, "oplock level 0x%x\n", rsp->OplockLevel);
657
658
659 spin_lock(&cifs_tcp_ses_lock);
660 list_for_each(tmp, &server->smb_ses_list) {
661 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
662
663 list_for_each(tmp1, &ses->tcon_list) {
664 tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
665
666 spin_lock(&tcon->open_file_lock);
667 list_for_each(tmp2, &tcon->openFileList) {
668 cfile = list_entry(tmp2, struct cifsFileInfo,
669 tlist);
670 if (rsp->PersistentFid !=
671 cfile->fid.persistent_fid ||
672 rsp->VolatileFid !=
673 cfile->fid.volatile_fid)
674 continue;
675
676 cifs_dbg(FYI, "file id match, oplock break\n");
677 cifs_stats_inc(
678 &tcon->stats.cifs_stats.num_oplock_brks);
679 cinode = CIFS_I(d_inode(cfile->dentry));
680 spin_lock(&cfile->file_info_lock);
681 if (!CIFS_CACHE_WRITE(cinode) &&
682 rsp->OplockLevel == SMB2_OPLOCK_LEVEL_NONE)
683 cfile->oplock_break_cancelled = true;
684 else
685 cfile->oplock_break_cancelled = false;
686
687 set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK,
688 &cinode->flags);
689
690 cfile->oplock_epoch = 0;
691 cfile->oplock_level = rsp->OplockLevel;
692
693 spin_unlock(&cfile->file_info_lock);
694
695 cifs_queue_oplock_break(cfile);
696
697 spin_unlock(&tcon->open_file_lock);
698 spin_unlock(&cifs_tcp_ses_lock);
699 return true;
700 }
701 spin_unlock(&tcon->open_file_lock);
702 }
703 }
704 spin_unlock(&cifs_tcp_ses_lock);
705 cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n");
706 return false;
707}
708
709void
710smb2_cancelled_close_fid(struct work_struct *work)
711{
712 struct close_cancelled_open *cancelled = container_of(work,
713 struct close_cancelled_open, work);
714 struct cifs_tcon *tcon = cancelled->tcon;
715 int rc;
716
717 if (cancelled->mid)
718 cifs_tcon_dbg(VFS, "Close unmatched open for MID:%llx\n",
719 cancelled->mid);
720 else
721 cifs_tcon_dbg(VFS, "Close interrupted close\n");
722
723 rc = SMB2_close(0, tcon, cancelled->fid.persistent_fid,
724 cancelled->fid.volatile_fid);
725 if (rc)
726 cifs_tcon_dbg(VFS, "Close cancelled mid failed rc:%d\n", rc);
727
728 cifs_put_tcon(tcon);
729 kfree(cancelled);
730}
731
732
733
734
735
736
737
738
739
740static int
741__smb2_handle_cancelled_cmd(struct cifs_tcon *tcon, __u16 cmd, __u64 mid,
742 __u64 persistent_fid, __u64 volatile_fid)
743{
744 struct close_cancelled_open *cancelled;
745
746 cancelled = kzalloc(sizeof(*cancelled), GFP_ATOMIC);
747 if (!cancelled)
748 return -ENOMEM;
749
750 cancelled->fid.persistent_fid = persistent_fid;
751 cancelled->fid.volatile_fid = volatile_fid;
752 cancelled->tcon = tcon;
753 cancelled->cmd = cmd;
754 cancelled->mid = mid;
755 INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
756 WARN_ON(queue_work(cifsiod_wq, &cancelled->work) == false);
757
758 return 0;
759}
760
761int
762smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
763 __u64 volatile_fid)
764{
765 int rc;
766
767 cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count);
768 spin_lock(&cifs_tcp_ses_lock);
769 if (tcon->tc_count <= 0) {
770 struct TCP_Server_Info *server = NULL;
771
772 WARN_ONCE(tcon->tc_count < 0, "tcon refcount is negative");
773 spin_unlock(&cifs_tcp_ses_lock);
774
775 if (tcon->ses)
776 server = tcon->ses->server;
777
778 cifs_server_dbg(FYI, "tid=%u: tcon is closing, skipping async close retry of fid %llu %llu\n",
779 tcon->tid, persistent_fid, volatile_fid);
780
781 return 0;
782 }
783 tcon->tc_count++;
784 spin_unlock(&cifs_tcp_ses_lock);
785
786 rc = __smb2_handle_cancelled_cmd(tcon, SMB2_CLOSE_HE, 0,
787 persistent_fid, volatile_fid);
788 if (rc)
789 cifs_put_tcon(tcon);
790
791 return rc;
792}
793
794int
795smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server)
796{
797 struct smb2_sync_hdr *sync_hdr = (struct smb2_sync_hdr *)buffer;
798 struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer;
799 struct cifs_tcon *tcon;
800 int rc;
801
802 if (sync_hdr->Command != SMB2_CREATE ||
803 sync_hdr->Status != STATUS_SUCCESS)
804 return 0;
805
806 tcon = smb2_find_smb_tcon(server, sync_hdr->SessionId,
807 sync_hdr->TreeId);
808 if (!tcon)
809 return -ENOENT;
810
811 rc = __smb2_handle_cancelled_cmd(tcon,
812 le16_to_cpu(sync_hdr->Command),
813 le64_to_cpu(sync_hdr->MessageId),
814 rsp->PersistentFileId,
815 rsp->VolatileFileId);
816 if (rc)
817 cifs_put_tcon(tcon);
818
819 return rc;
820}
821
822
823
824
825
826
827
828int
829smb311_update_preauth_hash(struct cifs_ses *ses, struct kvec *iov, int nvec)
830{
831 int i, rc;
832 struct sdesc *d;
833 struct smb2_sync_hdr *hdr;
834 struct TCP_Server_Info *server = cifs_ses_server(ses);
835
836 hdr = (struct smb2_sync_hdr *)iov[0].iov_base;
837
838 if (hdr->Command == SMB2_NEGOTIATE)
839 goto ok;
840
841
842
843
844
845
846 if (server->dialect != SMB311_PROT_ID)
847 return 0;
848
849 if (hdr->Command != SMB2_SESSION_SETUP)
850 return 0;
851
852
853 if ((hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
854 && (hdr->Status == NT_STATUS_OK
855 || (hdr->Status !=
856 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))))
857 return 0;
858
859ok:
860 rc = smb311_crypto_shash_allocate(server);
861 if (rc)
862 return rc;
863
864 d = server->secmech.sdescsha512;
865 rc = crypto_shash_init(&d->shash);
866 if (rc) {
867 cifs_dbg(VFS, "%s: could not init sha512 shash\n", __func__);
868 return rc;
869 }
870
871 rc = crypto_shash_update(&d->shash, ses->preauth_sha_hash,
872 SMB2_PREAUTH_HASH_SIZE);
873 if (rc) {
874 cifs_dbg(VFS, "%s: could not update sha512 shash\n", __func__);
875 return rc;
876 }
877
878 for (i = 0; i < nvec; i++) {
879 rc = crypto_shash_update(&d->shash,
880 iov[i].iov_base, iov[i].iov_len);
881 if (rc) {
882 cifs_dbg(VFS, "%s: could not update sha512 shash\n",
883 __func__);
884 return rc;
885 }
886 }
887
888 rc = crypto_shash_final(&d->shash, ses->preauth_sha_hash);
889 if (rc) {
890 cifs_dbg(VFS, "%s: could not finalize sha512 shash\n",
891 __func__);
892 return rc;
893 }
894
895 return 0;
896}
897