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