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