Commit 3aec46c1 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  cifs: don't always drop malformed replies on the floor (try #3)
  cifs: clean up checks in cifs_echo_request
  [CIFS] Do not send SMBEcho requests on new sockets until SMBNegotiate
parents 68c3d4b2 71823baf
...@@ -188,6 +188,8 @@ struct TCP_Server_Info { ...@@ -188,6 +188,8 @@ struct TCP_Server_Info {
/* multiplexed reads or writes */ /* multiplexed reads or writes */
unsigned int maxBuf; /* maxBuf specifies the maximum */ unsigned int maxBuf; /* maxBuf specifies the maximum */
/* message size the server can send or receive for non-raw SMBs */ /* message size the server can send or receive for non-raw SMBs */
/* maxBuf is returned by SMB NegotiateProtocol so maxBuf is only 0 */
/* when socket is setup (and during reconnect) before NegProt sent */
unsigned int max_rw; /* maxRw specifies the maximum */ unsigned int max_rw; /* maxRw specifies the maximum */
/* message size the server can send or receive for */ /* message size the server can send or receive for */
/* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */
...@@ -652,7 +654,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, ...@@ -652,7 +654,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
#define MID_REQUEST_SUBMITTED 2 #define MID_REQUEST_SUBMITTED 2
#define MID_RESPONSE_RECEIVED 4 #define MID_RESPONSE_RECEIVED 4
#define MID_RETRY_NEEDED 8 /* session closed while this request out */ #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 */ /* Types of response buffer returned from SendReceive2 */
#define CIFS_NO_BUFFER 0 /* Response buffer not returned */ #define CIFS_NO_BUFFER 0 /* Response buffer not returned */
......
...@@ -338,10 +338,11 @@ cifs_echo_request(struct work_struct *work) ...@@ -338,10 +338,11 @@ cifs_echo_request(struct work_struct *work)
struct TCP_Server_Info, echo.work); struct TCP_Server_Info, echo.work);
/* /*
* We cannot send an echo until the NEGOTIATE_PROTOCOL request is done. * We cannot send an echo until the NEGOTIATE_PROTOCOL request is
* Also, no need to ping if we got a response recently * done, which is indicated by maxBuf != 0. Also, no need to ping if
* we got a response recently
*/ */
if (server->tcpStatus != CifsGood || if (server->maxBuf == 0 ||
time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ)) time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
goto requeue_echo; goto requeue_echo;
...@@ -585,11 +586,20 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -585,11 +586,20 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
total_read += 4; /* account for rfc1002 hdr */ total_read += 4; /* account for rfc1002 hdr */
dump_smb(smb_buffer, total_read); dump_smb(smb_buffer, total_read);
if (checkSMB(smb_buffer, smb_buffer->Mid, total_read)) {
/*
* We know that we received enough to get to the MID as we
* checked the pdu_length earlier. Now check to see
* if the rest of the header is OK. We borrow the length
* var for the rest of the loop to avoid a new stack var.
*
* 48 bytes is enough to display the header and a little bit
* into the payload for debugging purposes.
*/
length = checkSMB(smb_buffer, smb_buffer->Mid, total_read);
if (length != 0)
cifs_dump_mem("Bad SMB: ", smb_buffer, cifs_dump_mem("Bad SMB: ", smb_buffer,
total_read < 48 ? total_read : 48); min_t(unsigned int, total_read, 48));
continue;
}
mid_entry = NULL; mid_entry = NULL;
server->lstrp = jiffies; server->lstrp = jiffies;
...@@ -601,7 +611,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -601,7 +611,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
if ((mid_entry->mid == smb_buffer->Mid) && if ((mid_entry->mid == smb_buffer->Mid) &&
(mid_entry->midState == MID_REQUEST_SUBMITTED) && (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
(mid_entry->command == smb_buffer->Command)) { (mid_entry->command == smb_buffer->Command)) {
if (check2ndT2(smb_buffer,server->maxBuf) > 0) { if (length == 0 &&
check2ndT2(smb_buffer, server->maxBuf) > 0) {
/* We have a multipart transact2 resp */ /* We have a multipart transact2 resp */
isMultiRsp = true; isMultiRsp = true;
if (mid_entry->resp_buf) { if (mid_entry->resp_buf) {
...@@ -636,7 +647,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -636,7 +647,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
mid_entry->resp_buf = smb_buffer; mid_entry->resp_buf = smb_buffer;
mid_entry->largeBuf = isLargeBuf; mid_entry->largeBuf = isLargeBuf;
multi_t2_fnd: 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;
#ifdef CONFIG_CIFS_STATS2 #ifdef CONFIG_CIFS_STATS2
mid_entry->when_received = jiffies; mid_entry->when_received = jiffies;
#endif #endif
...@@ -657,6 +673,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -657,6 +673,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
else else
smallbuf = NULL; smallbuf = NULL;
} }
} else if (length != 0) {
/* response sanity checks failed */
continue;
} else if (!is_valid_oplock_break(smb_buffer, server) && } else if (!is_valid_oplock_break(smb_buffer, server) &&
!isMultiRsp) { !isMultiRsp) {
cERROR(1, "No task to wake, unknown frame received! " cERROR(1, "No task to wake, unknown frame received! "
......
...@@ -457,6 +457,9 @@ sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) ...@@ -457,6 +457,9 @@ sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
case MID_RETRY_NEEDED: case MID_RETRY_NEEDED:
rc = -EAGAIN; rc = -EAGAIN;
break; break;
case MID_RESPONSE_MALFORMED:
rc = -EIO;
break;
default: default:
cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__, cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__,
mid->mid, mid->midState); mid->mid, mid->midState);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment