1
2
3
4
5
6
7
8
9
10#include <linux/ctype.h>
11#include "smb2pdu.h"
12#include "cifsglob.h"
13#include "cifsproto.h"
14#include "smb2proto.h"
15#include "cifs_debug.h"
16#include "cifs_unicode.h"
17#include "smb2status.h"
18#include "smb2glob.h"
19#include "nterr.h"
20
21static int
22check_smb2_hdr(struct smb2_sync_hdr *shdr, __u64 mid)
23{
24 __u64 wire_mid = le64_to_cpu(shdr->MessageId);
25
26
27
28
29
30 if ((shdr->ProtocolId == SMB2_PROTO_NUMBER) &&
31 (mid == wire_mid)) {
32 if (shdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
33 return 0;
34 else {
35
36 if (shdr->Command == SMB2_OPLOCK_BREAK)
37 return 0;
38 else
39 cifs_dbg(VFS, "Received Request not response\n");
40 }
41 } else {
42 if (shdr->ProtocolId != SMB2_PROTO_NUMBER)
43 cifs_dbg(VFS, "Bad protocol string signature header %x\n",
44 le32_to_cpu(shdr->ProtocolId));
45 if (mid != wire_mid)
46 cifs_dbg(VFS, "Mids do not match: %llu and %llu\n",
47 mid, wire_mid);
48 }
49 cifs_dbg(VFS, "Bad SMB detected. The Mid=%llu\n", wire_mid);
50 return 1;
51}
52
53
54
55
56
57
58
59
60static const __le16 smb2_rsp_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
61 cpu_to_le16(65),
62 cpu_to_le16(9),
63 cpu_to_le16(4),
64 cpu_to_le16(16),
65 cpu_to_le16(4),
66 cpu_to_le16(89),
67 cpu_to_le16(60),
68 cpu_to_le16(4),
69 cpu_to_le16(17),
70 cpu_to_le16(17),
71 cpu_to_le16(4),
72 cpu_to_le16(49),
73
74 cpu_to_le16(0),
75 cpu_to_le16(4),
76 cpu_to_le16(9),
77 cpu_to_le16(9),
78 cpu_to_le16(9),
79 cpu_to_le16(2),
80
81 cpu_to_le16(24)
82};
83
84#define SMB311_NEGPROT_BASE_SIZE (sizeof(struct smb2_sync_hdr) + sizeof(struct smb2_negotiate_rsp))
85
86static __u32 get_neg_ctxt_len(struct smb2_sync_hdr *hdr, __u32 len,
87 __u32 non_ctxlen)
88{
89 __u16 neg_count;
90 __u32 nc_offset, size_of_pad_before_neg_ctxts;
91 struct smb2_negotiate_rsp *pneg_rsp = (struct smb2_negotiate_rsp *)hdr;
92
93
94 neg_count = le16_to_cpu(pneg_rsp->NegotiateContextCount);
95 if ((neg_count == 0) ||
96 (pneg_rsp->DialectRevision != cpu_to_le16(SMB311_PROT_ID)))
97 return 0;
98
99
100
101
102
103
104 nc_offset = le32_to_cpu(pneg_rsp->NegotiateContextOffset);
105
106
107
108
109
110 if (nc_offset + 1 < non_ctxlen) {
111 pr_warn_once("Invalid negotiate context offset %d\n", nc_offset);
112 return 0;
113 } else if (nc_offset + 1 == non_ctxlen) {
114 cifs_dbg(FYI, "no SPNEGO security blob in negprot rsp\n");
115 size_of_pad_before_neg_ctxts = 0;
116 } else if (non_ctxlen == SMB311_NEGPROT_BASE_SIZE)
117
118 size_of_pad_before_neg_ctxts = nc_offset - non_ctxlen + 1;
119 else
120 size_of_pad_before_neg_ctxts = nc_offset - non_ctxlen;
121
122
123 if (len < nc_offset + (neg_count * sizeof(struct smb2_neg_context))) {
124 pr_warn_once("negotiate context goes beyond end\n");
125 return 0;
126 }
127
128 cifs_dbg(FYI, "length of negcontexts %d pad %d\n",
129 len - nc_offset, size_of_pad_before_neg_ctxts);
130
131
132 return (len - nc_offset) + size_of_pad_before_neg_ctxts;
133}
134
135int
136smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
137{
138 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
139 struct smb2_sync_pdu *pdu = (struct smb2_sync_pdu *)shdr;
140 __u64 mid;
141 __u32 clc_len;
142 int command;
143 int pdu_size = sizeof(struct smb2_sync_pdu);
144 int hdr_size = sizeof(struct smb2_sync_hdr);
145
146
147
148
149
150 if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
151 struct smb2_transform_hdr *thdr =
152 (struct smb2_transform_hdr *)buf;
153 struct cifs_ses *ses = NULL;
154
155
156 spin_lock(&cifs_tcp_ses_lock);
157 list_for_each_entry(ses, &srvr->smb_ses_list, smb_ses_list) {
158 if (ses->Suid == thdr->SessionId)
159 break;
160 }
161 spin_unlock(&cifs_tcp_ses_lock);
162 if (list_entry_is_head(ses, &srvr->smb_ses_list,
163 smb_ses_list)) {
164 cifs_dbg(VFS, "no decryption - session id not found\n");
165 return 1;
166 }
167 }
168
169 mid = le64_to_cpu(shdr->MessageId);
170 if (len < pdu_size) {
171 if ((len >= hdr_size)
172 && (shdr->Status != 0)) {
173 pdu->StructureSize2 = 0;
174
175
176
177
178 return 0;
179 } else {
180 cifs_dbg(VFS, "Length less than SMB header size\n");
181 }
182 return 1;
183 }
184 if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE) {
185 cifs_dbg(VFS, "SMB length greater than maximum, mid=%llu\n",
186 mid);
187 return 1;
188 }
189
190 if (check_smb2_hdr(shdr, mid))
191 return 1;
192
193 if (shdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
194 cifs_dbg(VFS, "Invalid structure size %u\n",
195 le16_to_cpu(shdr->StructureSize));
196 return 1;
197 }
198
199 command = le16_to_cpu(shdr->Command);
200 if (command >= NUMBER_OF_SMB2_COMMANDS) {
201 cifs_dbg(VFS, "Invalid SMB2 command %d\n", command);
202 return 1;
203 }
204
205 if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) {
206 if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 ||
207 pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2)) {
208
209 cifs_dbg(VFS, "Invalid response size %u for command %d\n",
210 le16_to_cpu(pdu->StructureSize2), command);
211 return 1;
212 } else if (command == SMB2_OPLOCK_BREAK_HE
213 && (shdr->Status == 0)
214 && (le16_to_cpu(pdu->StructureSize2) != 44)
215 && (le16_to_cpu(pdu->StructureSize2) != 36)) {
216
217 cifs_dbg(VFS, "Invalid response size %d for oplock break\n",
218 le16_to_cpu(pdu->StructureSize2));
219 return 1;
220 }
221 }
222
223 clc_len = smb2_calc_size(buf, srvr);
224
225 if (shdr->Command == SMB2_NEGOTIATE)
226 clc_len += get_neg_ctxt_len(shdr, len, clc_len);
227
228 if (len != clc_len) {
229 cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n",
230 clc_len, len, mid);
231
232 if (command == SMB2_CREATE_HE &&
233 shdr->Status == STATUS_STOPPED_ON_SYMLINK)
234 return 0;
235
236 if (clc_len + 24 == len && command == SMB2_OPLOCK_BREAK_HE)
237 return 0;
238
239 if (clc_len == len + 1)
240 return 0;
241
242
243
244
245
246 if (((clc_len + 7) & ~7) == len)
247 return 0;
248
249
250
251
252
253
254
255 if (clc_len < len)
256 return 0;
257
258 pr_warn_once(
259 "srv rsp too short, len %d not %d. cmd:%d mid:%llu\n",
260 len, clc_len, command, mid);
261
262 return 1;
263 }
264 return 0;
265}
266
267
268
269
270
271
272static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = {
273 true,
274 true,
275 false,
276 false,
277 false,
278 true,
279 false,
280 false,
281 true,
282 false,
283 false,
284 true,
285 false,
286 false,
287 true,
288 true,
289 true,
290 false,
291 false
292};
293
294
295
296
297
298char *
299smb2_get_data_area_len(int *off, int *len, struct smb2_sync_hdr *shdr)
300{
301 *off = 0;
302 *len = 0;
303
304
305 if (shdr->Status && shdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
306 (((struct smb2_err_rsp *)shdr)->StructureSize) ==
307 SMB2_ERROR_STRUCTURE_SIZE2)
308 return NULL;
309
310
311
312
313
314
315 switch (shdr->Command) {
316 case SMB2_NEGOTIATE:
317 *off = le16_to_cpu(
318 ((struct smb2_negotiate_rsp *)shdr)->SecurityBufferOffset);
319 *len = le16_to_cpu(
320 ((struct smb2_negotiate_rsp *)shdr)->SecurityBufferLength);
321 break;
322 case SMB2_SESSION_SETUP:
323 *off = le16_to_cpu(
324 ((struct smb2_sess_setup_rsp *)shdr)->SecurityBufferOffset);
325 *len = le16_to_cpu(
326 ((struct smb2_sess_setup_rsp *)shdr)->SecurityBufferLength);
327 break;
328 case SMB2_CREATE:
329 *off = le32_to_cpu(
330 ((struct smb2_create_rsp *)shdr)->CreateContextsOffset);
331 *len = le32_to_cpu(
332 ((struct smb2_create_rsp *)shdr)->CreateContextsLength);
333 break;
334 case SMB2_QUERY_INFO:
335 *off = le16_to_cpu(
336 ((struct smb2_query_info_rsp *)shdr)->OutputBufferOffset);
337 *len = le32_to_cpu(
338 ((struct smb2_query_info_rsp *)shdr)->OutputBufferLength);
339 break;
340 case SMB2_READ:
341
342 *off = ((struct smb2_read_rsp *)shdr)->DataOffset;
343 *len = le32_to_cpu(((struct smb2_read_rsp *)shdr)->DataLength);
344 break;
345 case SMB2_QUERY_DIRECTORY:
346 *off = le16_to_cpu(
347 ((struct smb2_query_directory_rsp *)shdr)->OutputBufferOffset);
348 *len = le32_to_cpu(
349 ((struct smb2_query_directory_rsp *)shdr)->OutputBufferLength);
350 break;
351 case SMB2_IOCTL:
352 *off = le32_to_cpu(
353 ((struct smb2_ioctl_rsp *)shdr)->OutputOffset);
354 *len = le32_to_cpu(
355 ((struct smb2_ioctl_rsp *)shdr)->OutputCount);
356 break;
357 case SMB2_CHANGE_NOTIFY:
358 *off = le16_to_cpu(
359 ((struct smb2_change_notify_rsp *)shdr)->OutputBufferOffset);
360 *len = le32_to_cpu(
361 ((struct smb2_change_notify_rsp *)shdr)->OutputBufferLength);
362 break;
363 default:
364 cifs_dbg(VFS, "no length check for command %d\n", le16_to_cpu(shdr->Command));
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 void
513smb2_queue_pending_open_break(struct tcon_link *tlink, __u8 *lease_key,
514 __le32 new_lease_state)
515{
516 struct smb2_lease_break_work *lw;
517
518 lw = kmalloc(sizeof(struct smb2_lease_break_work), GFP_KERNEL);
519 if (!lw) {
520 cifs_put_tlink(tlink);
521 return;
522 }
523
524 INIT_WORK(&lw->lease_break, cifs_ses_oplock_break);
525 lw->tlink = tlink;
526 lw->lease_state = new_lease_state;
527 memcpy(lw->lease_key, lease_key, SMB2_LEASE_KEY_SIZE);
528 queue_work(cifsiod_wq, &lw->lease_break);
529}
530
531static bool
532smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp)
533{
534 __u8 lease_state;
535 struct cifsFileInfo *cfile;
536 struct cifsInodeInfo *cinode;
537 int ack_req = le32_to_cpu(rsp->Flags &
538 SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED);
539
540 lease_state = le32_to_cpu(rsp->NewLeaseState);
541
542 list_for_each_entry(cfile, &tcon->openFileList, tlist) {
543 cinode = CIFS_I(d_inode(cfile->dentry));
544
545 if (memcmp(cinode->lease_key, rsp->LeaseKey,
546 SMB2_LEASE_KEY_SIZE))
547 continue;
548
549 cifs_dbg(FYI, "found in the open list\n");
550 cifs_dbg(FYI, "lease key match, lease break 0x%x\n",
551 lease_state);
552
553 if (ack_req)
554 cfile->oplock_break_cancelled = false;
555 else
556 cfile->oplock_break_cancelled = true;
557
558 set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags);
559
560 cfile->oplock_epoch = le16_to_cpu(rsp->Epoch);
561 cfile->oplock_level = lease_state;
562
563 cifs_queue_oplock_break(cfile);
564 return true;
565 }
566
567 return false;
568}
569
570static struct cifs_pending_open *
571smb2_tcon_find_pending_open_lease(struct cifs_tcon *tcon,
572 struct smb2_lease_break *rsp)
573{
574 __u8 lease_state = le32_to_cpu(rsp->NewLeaseState);
575 int ack_req = le32_to_cpu(rsp->Flags &
576 SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED);
577 struct cifs_pending_open *open;
578 struct cifs_pending_open *found = NULL;
579
580 list_for_each_entry(open, &tcon->pending_opens, olist) {
581 if (memcmp(open->lease_key, rsp->LeaseKey,
582 SMB2_LEASE_KEY_SIZE))
583 continue;
584
585 if (!found && ack_req) {
586 found = open;
587 }
588
589 cifs_dbg(FYI, "found in the pending open list\n");
590 cifs_dbg(FYI, "lease key match, lease break 0x%x\n",
591 lease_state);
592
593 open->oplock = lease_state;
594 }
595
596 return found;
597}
598
599static bool
600smb2_is_valid_lease_break(char *buffer)
601{
602 struct smb2_lease_break *rsp = (struct smb2_lease_break *)buffer;
603 struct TCP_Server_Info *server;
604 struct cifs_ses *ses;
605 struct cifs_tcon *tcon;
606 struct cifs_pending_open *open;
607
608 cifs_dbg(FYI, "Checking for lease break\n");
609
610
611 spin_lock(&cifs_tcp_ses_lock);
612 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
613 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
614 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
615 spin_lock(&tcon->open_file_lock);
616 cifs_stats_inc(
617 &tcon->stats.cifs_stats.num_oplock_brks);
618 if (smb2_tcon_has_lease(tcon, rsp)) {
619 spin_unlock(&tcon->open_file_lock);
620 spin_unlock(&cifs_tcp_ses_lock);
621 return true;
622 }
623 open = smb2_tcon_find_pending_open_lease(tcon,
624 rsp);
625 if (open) {
626 __u8 lease_key[SMB2_LEASE_KEY_SIZE];
627 struct tcon_link *tlink;
628
629 tlink = cifs_get_tlink(open->tlink);
630 memcpy(lease_key, open->lease_key,
631 SMB2_LEASE_KEY_SIZE);
632 spin_unlock(&tcon->open_file_lock);
633 spin_unlock(&cifs_tcp_ses_lock);
634 smb2_queue_pending_open_break(tlink,
635 lease_key,
636 rsp->NewLeaseState);
637 return true;
638 }
639 spin_unlock(&tcon->open_file_lock);
640
641 if (tcon->crfid.is_valid &&
642 !memcmp(rsp->LeaseKey,
643 tcon->crfid.fid->lease_key,
644 SMB2_LEASE_KEY_SIZE)) {
645 tcon->crfid.time = 0;
646 INIT_WORK(&tcon->crfid.lease_break,
647 smb2_cached_lease_break);
648 queue_work(cifsiod_wq,
649 &tcon->crfid.lease_break);
650 spin_unlock(&cifs_tcp_ses_lock);
651 return true;
652 }
653 }
654 }
655 }
656 spin_unlock(&cifs_tcp_ses_lock);
657 cifs_dbg(FYI, "Can not process lease break - no lease matched\n");
658 return false;
659}
660
661bool
662smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
663{
664 struct smb2_oplock_break *rsp = (struct smb2_oplock_break *)buffer;
665 struct cifs_ses *ses;
666 struct cifs_tcon *tcon;
667 struct cifsInodeInfo *cinode;
668 struct cifsFileInfo *cfile;
669
670 cifs_dbg(FYI, "Checking for oplock break\n");
671
672 if (rsp->sync_hdr.Command != SMB2_OPLOCK_BREAK)
673 return false;
674
675 if (rsp->StructureSize !=
676 smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) {
677 if (le16_to_cpu(rsp->StructureSize) == 44)
678 return smb2_is_valid_lease_break(buffer);
679 else
680 return false;
681 }
682
683 cifs_dbg(FYI, "oplock level 0x%x\n", rsp->OplockLevel);
684
685
686 spin_lock(&cifs_tcp_ses_lock);
687 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
688 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
689
690 spin_lock(&tcon->open_file_lock);
691 list_for_each_entry(cfile, &tcon->openFileList, tlist) {
692 if (rsp->PersistentFid !=
693 cfile->fid.persistent_fid ||
694 rsp->VolatileFid !=
695 cfile->fid.volatile_fid)
696 continue;
697
698 cifs_dbg(FYI, "file id match, oplock break\n");
699 cifs_stats_inc(
700 &tcon->stats.cifs_stats.num_oplock_brks);
701 cinode = CIFS_I(d_inode(cfile->dentry));
702 spin_lock(&cfile->file_info_lock);
703 if (!CIFS_CACHE_WRITE(cinode) &&
704 rsp->OplockLevel == SMB2_OPLOCK_LEVEL_NONE)
705 cfile->oplock_break_cancelled = true;
706 else
707 cfile->oplock_break_cancelled = false;
708
709 set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK,
710 &cinode->flags);
711
712 cfile->oplock_epoch = 0;
713 cfile->oplock_level = rsp->OplockLevel;
714
715 spin_unlock(&cfile->file_info_lock);
716
717 cifs_queue_oplock_break(cfile);
718
719 spin_unlock(&tcon->open_file_lock);
720 spin_unlock(&cifs_tcp_ses_lock);
721 return true;
722 }
723 spin_unlock(&tcon->open_file_lock);
724 }
725 }
726 spin_unlock(&cifs_tcp_ses_lock);
727 cifs_dbg(FYI, "No file id matched, oplock break ignored\n");
728 return true;
729}
730
731void
732smb2_cancelled_close_fid(struct work_struct *work)
733{
734 struct close_cancelled_open *cancelled = container_of(work,
735 struct close_cancelled_open, work);
736 struct cifs_tcon *tcon = cancelled->tcon;
737 int rc;
738
739 if (cancelled->mid)
740 cifs_tcon_dbg(VFS, "Close unmatched open for MID:%llu\n",
741 cancelled->mid);
742 else
743 cifs_tcon_dbg(VFS, "Close interrupted close\n");
744
745 rc = SMB2_close(0, tcon, cancelled->fid.persistent_fid,
746 cancelled->fid.volatile_fid);
747 if (rc)
748 cifs_tcon_dbg(VFS, "Close cancelled mid failed rc:%d\n", rc);
749
750 cifs_put_tcon(tcon);
751 kfree(cancelled);
752}
753
754
755
756
757
758
759
760
761
762static int
763__smb2_handle_cancelled_cmd(struct cifs_tcon *tcon, __u16 cmd, __u64 mid,
764 __u64 persistent_fid, __u64 volatile_fid)
765{
766 struct close_cancelled_open *cancelled;
767
768 cancelled = kzalloc(sizeof(*cancelled), GFP_ATOMIC);
769 if (!cancelled)
770 return -ENOMEM;
771
772 cancelled->fid.persistent_fid = persistent_fid;
773 cancelled->fid.volatile_fid = volatile_fid;
774 cancelled->tcon = tcon;
775 cancelled->cmd = cmd;
776 cancelled->mid = mid;
777 INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
778 WARN_ON(queue_work(cifsiod_wq, &cancelled->work) == false);
779
780 return 0;
781}
782
783int
784smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
785 __u64 volatile_fid)
786{
787 int rc;
788
789 cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count);
790 spin_lock(&cifs_tcp_ses_lock);
791 if (tcon->tc_count <= 0) {
792 struct TCP_Server_Info *server = NULL;
793
794 WARN_ONCE(tcon->tc_count < 0, "tcon refcount is negative");
795 spin_unlock(&cifs_tcp_ses_lock);
796
797 if (tcon->ses)
798 server = tcon->ses->server;
799
800 cifs_server_dbg(FYI, "tid=%u: tcon is closing, skipping async close retry of fid %llu %llu\n",
801 tcon->tid, persistent_fid, volatile_fid);
802
803 return 0;
804 }
805 tcon->tc_count++;
806 spin_unlock(&cifs_tcp_ses_lock);
807
808 rc = __smb2_handle_cancelled_cmd(tcon, SMB2_CLOSE_HE, 0,
809 persistent_fid, volatile_fid);
810 if (rc)
811 cifs_put_tcon(tcon);
812
813 return rc;
814}
815
816int
817smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server)
818{
819 struct smb2_sync_hdr *sync_hdr = mid->resp_buf;
820 struct smb2_create_rsp *rsp = mid->resp_buf;
821 struct cifs_tcon *tcon;
822 int rc;
823
824 if ((mid->optype & CIFS_CP_CREATE_CLOSE_OP) || sync_hdr->Command != SMB2_CREATE ||
825 sync_hdr->Status != STATUS_SUCCESS)
826 return 0;
827
828 tcon = smb2_find_smb_tcon(server, sync_hdr->SessionId,
829 sync_hdr->TreeId);
830 if (!tcon)
831 return -ENOENT;
832
833 rc = __smb2_handle_cancelled_cmd(tcon,
834 le16_to_cpu(sync_hdr->Command),
835 le64_to_cpu(sync_hdr->MessageId),
836 rsp->PersistentFileId,
837 rsp->VolatileFileId);
838 if (rc)
839 cifs_put_tcon(tcon);
840
841 return rc;
842}
843
844
845
846
847
848
849
850
851
852
853
854int
855smb311_update_preauth_hash(struct cifs_ses *ses, struct kvec *iov, int nvec)
856{
857 int i, rc;
858 struct sdesc *d;
859 struct smb2_sync_hdr *hdr;
860 struct TCP_Server_Info *server = cifs_ses_server(ses);
861
862 hdr = (struct smb2_sync_hdr *)iov[0].iov_base;
863
864 if (hdr->Command == SMB2_NEGOTIATE)
865 goto ok;
866
867
868
869
870
871
872 if (server->dialect != SMB311_PROT_ID)
873 return 0;
874
875 if (hdr->Command != SMB2_SESSION_SETUP)
876 return 0;
877
878
879 if ((hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
880 && (hdr->Status == NT_STATUS_OK
881 || (hdr->Status !=
882 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))))
883 return 0;
884
885ok:
886 rc = smb311_crypto_shash_allocate(server);
887 if (rc)
888 return rc;
889
890 d = server->secmech.sdescsha512;
891 rc = crypto_shash_init(&d->shash);
892 if (rc) {
893 cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__);
894 return rc;
895 }
896
897 rc = crypto_shash_update(&d->shash, ses->preauth_sha_hash,
898 SMB2_PREAUTH_HASH_SIZE);
899 if (rc) {
900 cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__);
901 return rc;
902 }
903
904 for (i = 0; i < nvec; i++) {
905 rc = crypto_shash_update(&d->shash,
906 iov[i].iov_base, iov[i].iov_len);
907 if (rc) {
908 cifs_dbg(VFS, "%s: Could not update sha512 shash\n",
909 __func__);
910 return rc;
911 }
912 }
913
914 rc = crypto_shash_final(&d->shash, ses->preauth_sha_hash);
915 if (rc) {
916 cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n",
917 __func__);
918 return rc;
919 }
920
921 return 0;
922}
923