@@ -652,7 +652,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
#define MID_REQUEST_SUBMITTED 2
#define MID_RESPONSE_RECEIVED 4
#define MID_RETRY_NEEDED 8 /* session closed while this request out */
-#define MID_NO_RESP_NEEDED 0x10
+#define MID_RESPONSE_MALFORMED 0x10
/* Types of response buffer returned from SendReceive2 */
#define CIFS_NO_BUFFER 0 /* Response buffer not returned */
@@ -584,11 +584,21 @@ incomplete_rcv:
total_read += 4; /* account for rfc1002 hdr */
dump_smb(smb_buffer, total_read);
- if (checkSMB(smb_buffer, smb_buffer->Mid, total_read)) {
- cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
+
+ /* did we read enough to get to the Mid? */
+ if (total_read < (sizeof(struct smb_hdr) - 1)) {
+ cERROR(1, "Received packet too short to reach MID: "
+ "%u bytes\n", total_read);
+ cifs_dump_mem("Bad SMB: ", smb_buffer, total_read);
continue;
}
+ /*
+ * we received enough to get to the MID, now check to see
+ * if the rest of the header checks out.
+ */
+ length = checkSMB(smb_buffer, smb_buffer->Mid, total_read);
+
mid_entry = NULL;
server->lstrp = jiffies;
@@ -634,7 +644,12 @@ incomplete_rcv:
mid_entry->resp_buf = smb_buffer;
mid_entry->largeBuf = isLargeBuf;
multi_t2_fnd:
- mid_entry->midState = MID_RESPONSE_RECEIVED;
+ if (length == 0)
+ mid_entry->midState =
+ MID_RESPONSE_RECEIVED;
+ else
+ mid_entry->midState =
+ MID_RESPONSE_MALFORMED;
list_del_init(&mid_entry->qhead);
mid_entry->callback(mid_entry);
#ifdef CONFIG_CIFS_STATS2
@@ -655,6 +670,9 @@ multi_t2_fnd:
else
smallbuf = NULL;
}
+ } else if (length != 0) {
+ /* response sanity checks failed */
+ continue;
} else if (!is_valid_oplock_break(smb_buffer, server) &&
!isMultiRsp) {
cERROR(1, "No task to wake, unknown frame received! "
@@ -453,6 +453,9 @@ sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
case MID_RETRY_NEEDED:
rc = -EAGAIN;
break;
+ case MID_RESPONSE_MALFORMED:
+ rc = -EIO;
+ break;
default:
cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__,
mid->mid, mid->midState);