Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3aec46c1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 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
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -188,6 +188,8 @@ struct TCP_Server_Info {
	/* multiplexed reads or writes */
	unsigned int maxBuf;	/* maxBuf specifies the maximum */
	/* 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 */
	/* message size the server can send or receive for */
	/* 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,
#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 */
+28 −9
Original line number Diff line number Diff line
@@ -338,10 +338,11 @@ cifs_echo_request(struct work_struct *work)
					struct TCP_Server_Info, echo.work);

	/*
	 * We cannot send an echo until the NEGOTIATE_PROTOCOL request is done.
	 * Also, no need to ping if we got a response recently
	 * We cannot send an echo until the NEGOTIATE_PROTOCOL request is
	 * 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))
		goto requeue_echo;

@@ -585,11 +586,20 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
		total_read += 4; /* account for rfc1002 hdr */

		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,
					total_read < 48 ? total_read : 48);
			continue;
		}
					min_t(unsigned int, total_read, 48));

		mid_entry = NULL;
		server->lstrp = jiffies;
@@ -601,7 +611,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
			if ((mid_entry->mid == smb_buffer->Mid) &&
			    (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
			    (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 */
					isMultiRsp = true;
					if (mid_entry->resp_buf) {
@@ -636,7 +647,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
				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;
#ifdef CONFIG_CIFS_STATS2
				mid_entry->when_received = jiffies;
#endif
@@ -657,6 +673,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
				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! "
+3 −0
Original line number Diff line number Diff line
@@ -457,6 +457,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);