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