diff options
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 47d8ff623683..8d6c17ab593d 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -337,8 +337,13 @@ cifs_echo_request(struct work_struct *work) | |||
337 | struct TCP_Server_Info *server = container_of(work, | 337 | struct TCP_Server_Info *server = container_of(work, |
338 | struct TCP_Server_Info, echo.work); | 338 | struct TCP_Server_Info, echo.work); |
339 | 339 | ||
340 | /* no need to ping if we got a response recently */ | 340 | /* |
341 | if (time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ)) | 341 | * We cannot send an echo until the NEGOTIATE_PROTOCOL request is |
342 | * done, which is indicated by maxBuf != 0. Also, no need to ping if | ||
343 | * we got a response recently | ||
344 | */ | ||
345 | if (server->maxBuf == 0 || | ||
346 | time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ)) | ||
342 | goto requeue_echo; | 347 | goto requeue_echo; |
343 | 348 | ||
344 | rc = CIFSSMBEcho(server); | 349 | rc = CIFSSMBEcho(server); |
@@ -578,14 +583,23 @@ incomplete_rcv: | |||
578 | else if (reconnect == 1) | 583 | else if (reconnect == 1) |
579 | continue; | 584 | continue; |
580 | 585 | ||
581 | length += 4; /* account for rfc1002 hdr */ | 586 | total_read += 4; /* account for rfc1002 hdr */ |
582 | 587 | ||
588 | dump_smb(smb_buffer, total_read); | ||
583 | 589 | ||
584 | dump_smb(smb_buffer, length); | 590 | /* |
585 | if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) { | 591 | * We know that we received enough to get to the MID as we |
586 | cifs_dump_mem("Bad SMB: ", smb_buffer, 48); | 592 | * checked the pdu_length earlier. Now check to see |
587 | continue; | 593 | * if the rest of the header is OK. We borrow the length |
588 | } | 594 | * var for the rest of the loop to avoid a new stack var. |
595 | * | ||
596 | * 48 bytes is enough to display the header and a little bit | ||
597 | * into the payload for debugging purposes. | ||
598 | */ | ||
599 | length = checkSMB(smb_buffer, smb_buffer->Mid, total_read); | ||
600 | if (length != 0) | ||
601 | cifs_dump_mem("Bad SMB: ", smb_buffer, | ||
602 | min_t(unsigned int, total_read, 48)); | ||
589 | 603 | ||
590 | mid_entry = NULL; | 604 | mid_entry = NULL; |
591 | server->lstrp = jiffies; | 605 | server->lstrp = jiffies; |
@@ -597,7 +611,8 @@ incomplete_rcv: | |||
597 | if ((mid_entry->mid == smb_buffer->Mid) && | 611 | if ((mid_entry->mid == smb_buffer->Mid) && |
598 | (mid_entry->midState == MID_REQUEST_SUBMITTED) && | 612 | (mid_entry->midState == MID_REQUEST_SUBMITTED) && |
599 | (mid_entry->command == smb_buffer->Command)) { | 613 | (mid_entry->command == smb_buffer->Command)) { |
600 | if (check2ndT2(smb_buffer,server->maxBuf) > 0) { | 614 | if (length == 0 && |
615 | check2ndT2(smb_buffer, server->maxBuf) > 0) { | ||
601 | /* We have a multipart transact2 resp */ | 616 | /* We have a multipart transact2 resp */ |
602 | isMultiRsp = true; | 617 | isMultiRsp = true; |
603 | if (mid_entry->resp_buf) { | 618 | if (mid_entry->resp_buf) { |
@@ -632,12 +647,17 @@ incomplete_rcv: | |||
632 | mid_entry->resp_buf = smb_buffer; | 647 | mid_entry->resp_buf = smb_buffer; |
633 | mid_entry->largeBuf = isLargeBuf; | 648 | mid_entry->largeBuf = isLargeBuf; |
634 | multi_t2_fnd: | 649 | multi_t2_fnd: |
635 | mid_entry->midState = MID_RESPONSE_RECEIVED; | 650 | if (length == 0) |
636 | list_del_init(&mid_entry->qhead); | 651 | mid_entry->midState = |
637 | mid_entry->callback(mid_entry); | 652 | MID_RESPONSE_RECEIVED; |
653 | else | ||
654 | mid_entry->midState = | ||
655 | MID_RESPONSE_MALFORMED; | ||
638 | #ifdef CONFIG_CIFS_STATS2 | 656 | #ifdef CONFIG_CIFS_STATS2 |
639 | mid_entry->when_received = jiffies; | 657 | mid_entry->when_received = jiffies; |
640 | #endif | 658 | #endif |
659 | list_del_init(&mid_entry->qhead); | ||
660 | mid_entry->callback(mid_entry); | ||
641 | break; | 661 | break; |
642 | } | 662 | } |
643 | mid_entry = NULL; | 663 | mid_entry = NULL; |
@@ -653,6 +673,9 @@ multi_t2_fnd: | |||
653 | else | 673 | else |
654 | smallbuf = NULL; | 674 | smallbuf = NULL; |
655 | } | 675 | } |
676 | } else if (length != 0) { | ||
677 | /* response sanity checks failed */ | ||
678 | continue; | ||
656 | } else if (!is_valid_oplock_break(smb_buffer, server) && | 679 | } else if (!is_valid_oplock_break(smb_buffer, server) && |
657 | !isMultiRsp) { | 680 | !isMultiRsp) { |
658 | cERROR(1, "No task to wake, unknown frame received! " | 681 | cERROR(1, "No task to wake, unknown frame received! " |