diff options
| -rw-r--r-- | fs/cifs/cifsglob.h | 2 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 30 | ||||
| -rw-r--r-- | fs/cifs/transport.c | 3 |
3 files changed, 28 insertions, 7 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 1ab33eb71d9..17afb0fbcae 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -654,7 +654,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, | |||
| 654 | #define MID_REQUEST_SUBMITTED 2 | 654 | #define MID_REQUEST_SUBMITTED 2 |
| 655 | #define MID_RESPONSE_RECEIVED 4 | 655 | #define MID_RESPONSE_RECEIVED 4 |
| 656 | #define MID_RETRY_NEEDED 8 /* session closed while this request out */ | 656 | #define MID_RETRY_NEEDED 8 /* session closed while this request out */ |
| 657 | #define MID_NO_RESP_NEEDED 0x10 | 657 | #define MID_RESPONSE_MALFORMED 0x10 |
| 658 | 658 | ||
| 659 | /* Types of response buffer returned from SendReceive2 */ | 659 | /* Types of response buffer returned from SendReceive2 */ |
| 660 | #define CIFS_NO_BUFFER 0 /* Response buffer not returned */ | 660 | #define CIFS_NO_BUFFER 0 /* Response buffer not returned */ |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 161f24ca4f6..8d6c17ab593 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -586,11 +586,20 @@ incomplete_rcv: | |||
| 586 | total_read += 4; /* account for rfc1002 hdr */ | 586 | total_read += 4; /* account for rfc1002 hdr */ |
| 587 | 587 | ||
| 588 | dump_smb(smb_buffer, total_read); | 588 | dump_smb(smb_buffer, total_read); |
| 589 | if (checkSMB(smb_buffer, smb_buffer->Mid, total_read)) { | 589 | |
| 590 | /* | ||
| 591 | * We know that we received enough to get to the MID as we | ||
| 592 | * checked the pdu_length earlier. Now check to see | ||
| 593 | * if the rest of the header is OK. We borrow the length | ||
| 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) | ||
| 590 | cifs_dump_mem("Bad SMB: ", smb_buffer, | 601 | cifs_dump_mem("Bad SMB: ", smb_buffer, |
| 591 | total_read < 48 ? total_read : 48); | 602 | min_t(unsigned int, total_read, 48)); |
| 592 | continue; | ||
| 593 | } | ||
| 594 | 603 | ||
| 595 | mid_entry = NULL; | 604 | mid_entry = NULL; |
| 596 | server->lstrp = jiffies; | 605 | server->lstrp = jiffies; |
| @@ -602,7 +611,8 @@ incomplete_rcv: | |||
| 602 | if ((mid_entry->mid == smb_buffer->Mid) && | 611 | if ((mid_entry->mid == smb_buffer->Mid) && |
| 603 | (mid_entry->midState == MID_REQUEST_SUBMITTED) && | 612 | (mid_entry->midState == MID_REQUEST_SUBMITTED) && |
| 604 | (mid_entry->command == smb_buffer->Command)) { | 613 | (mid_entry->command == smb_buffer->Command)) { |
| 605 | if (check2ndT2(smb_buffer,server->maxBuf) > 0) { | 614 | if (length == 0 && |
| 615 | check2ndT2(smb_buffer, server->maxBuf) > 0) { | ||
| 606 | /* We have a multipart transact2 resp */ | 616 | /* We have a multipart transact2 resp */ |
| 607 | isMultiRsp = true; | 617 | isMultiRsp = true; |
| 608 | if (mid_entry->resp_buf) { | 618 | if (mid_entry->resp_buf) { |
| @@ -637,7 +647,12 @@ incomplete_rcv: | |||
| 637 | mid_entry->resp_buf = smb_buffer; | 647 | mid_entry->resp_buf = smb_buffer; |
| 638 | mid_entry->largeBuf = isLargeBuf; | 648 | mid_entry->largeBuf = isLargeBuf; |
| 639 | multi_t2_fnd: | 649 | multi_t2_fnd: |
| 640 | mid_entry->midState = MID_RESPONSE_RECEIVED; | 650 | if (length == 0) |
| 651 | mid_entry->midState = | ||
| 652 | MID_RESPONSE_RECEIVED; | ||
| 653 | else | ||
| 654 | mid_entry->midState = | ||
| 655 | MID_RESPONSE_MALFORMED; | ||
| 641 | #ifdef CONFIG_CIFS_STATS2 | 656 | #ifdef CONFIG_CIFS_STATS2 |
| 642 | mid_entry->when_received = jiffies; | 657 | mid_entry->when_received = jiffies; |
| 643 | #endif | 658 | #endif |
| @@ -658,6 +673,9 @@ multi_t2_fnd: | |||
| 658 | else | 673 | else |
| 659 | smallbuf = NULL; | 674 | smallbuf = NULL; |
| 660 | } | 675 | } |
| 676 | } else if (length != 0) { | ||
| 677 | /* response sanity checks failed */ | ||
| 678 | continue; | ||
| 661 | } else if (!is_valid_oplock_break(smb_buffer, server) && | 679 | } else if (!is_valid_oplock_break(smb_buffer, server) && |
| 662 | !isMultiRsp) { | 680 | !isMultiRsp) { |
| 663 | cERROR(1, "No task to wake, unknown frame received! " | 681 | cERROR(1, "No task to wake, unknown frame received! " |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index fbc5aace54b..46d8756f2b2 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
| @@ -457,6 +457,9 @@ sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) | |||
| 457 | case MID_RETRY_NEEDED: | 457 | case MID_RETRY_NEEDED: |
| 458 | rc = -EAGAIN; | 458 | rc = -EAGAIN; |
| 459 | break; | 459 | break; |
| 460 | case MID_RESPONSE_MALFORMED: | ||
| 461 | rc = -EIO; | ||
| 462 | break; | ||
| 460 | default: | 463 | default: |
| 461 | cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__, | 464 | cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__, |
| 462 | mid->mid, mid->midState); | 465 | mid->mid, mid->midState); |
