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