All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ronnie Sahlberg <lsahlber-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: linux-cifs <linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Cc: Steve French <smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Subject: [PATCH 2/2] cifs: update multiplex loop to handle compounded responses
Date: Mon, 22 Jan 2018 09:06:44 +1100	[thread overview]
Message-ID: <20180121220644.7907-3-lsahlber@redhat.com> (raw)
In-Reply-To: <20180121220644.7907-1-lsahlber-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Signed-off-by: Ronnie Sahlberg <lsahlber-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 fs/cifs/cifsglob.h |  2 +-
 fs/cifs/connect.c  | 18 +++++++++++++++---
 fs/cifs/smb2ops.c  | 26 ++++++++++++++++++++++++--
 3 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 14db722c4b0d..18a961d32e0c 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -449,7 +449,7 @@ struct smb_version_operations {
 				 struct mid_q_entry **);
 	enum securityEnum (*select_sectype)(struct TCP_Server_Info *,
 			    enum securityEnum);
-
+	int (*next_header)(char *);
 };
 
 struct smb_version_values {
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 18a1cb4f2330..9bf79e1f0a05 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -840,6 +840,7 @@ cifs_demultiplex_thread(void *p)
 	int length;
 	struct TCP_Server_Info *server = p;
 	unsigned int pdu_length;
+	unsigned int next_offset;
 	char *buf = NULL;
 	struct task_struct *task_to_wake = NULL;
 	struct mid_q_entry *mid_entry;
@@ -877,17 +878,18 @@ cifs_demultiplex_thread(void *p)
 		 * so we can now interpret the length field.
 		 */
 		pdu_length = get_rfc1002_length(buf);
+next_pdu:
 		server->total_size = pdu_length;
 
-		cifs_dbg(FYI, "RFC1002 header 0x%x\n", pdu_length);
+		cifs_dbg(FYI, "RFC1002 header 0x%x\n", server->total_size);
 		if (!is_smb_response(server, buf[0]))
 			continue;
 
 		/* make sure we have enough to get to the MID */
-		if (pdu_length < HEADER_SIZE(server) - 1 -
+		if (server->total_size < HEADER_SIZE(server) - 1 -
 		    server->vals->header_preamble_size) {
 			cifs_dbg(VFS, "SMB response too short (%u bytes)\n",
-				 pdu_length);
+				 server->total_size);
 			cifs_reconnect(server);
 			wake_up(&server->response_q);
 			continue;
@@ -902,6 +904,12 @@ cifs_demultiplex_thread(void *p)
 			continue;
 		server->total_read += length;
 
+		if (server->ops->next_header) {
+			next_offset = server->ops->next_header(buf);
+			if (next_offset)
+				server->total_size = next_offset;
+		}
+
 		if (server->ops->is_transform_hdr &&
 		    server->ops->receive_transform &&
 		    server->ops->is_transform_hdr(buf))
@@ -947,6 +955,10 @@ cifs_demultiplex_thread(void *p)
 			cifs_dump_mids(server);
 #endif /* CIFS_DEBUG2 */
 
+			if (pdu_length > server->total_size) {
+				pdu_length -= server->total_size;
+				goto next_pdu;
+			}
 		}
 	} /* end while !EXITING */
 
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index fef40876a77a..58b12ed106cd 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -125,8 +125,8 @@ smb2_get_credits(struct mid_q_entry *mid)
 	char *buf = mid->resp_buf;
 	struct smb2_sync_hdr *shdr;
 
-	if ( *(__u32 *)buf == SMB2_PROTO_NUMBER ||
-	     *(__u32 *)buf == SMB2_TRANSFORM_PROTO_NUM)
+	if ( *(__le32 *)buf == SMB2_PROTO_NUMBER ||
+	     *(__le32 *)buf == SMB2_TRANSFORM_PROTO_NUM)
 		shdr = (struct smb2_sync_hdr *)buf;
 	else
 		shdr = (struct smb2_sync_hdr *)(buf + 4);
@@ -2718,6 +2718,24 @@ smb3_handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 				NULL, 0, 0);
 }
 
+static int
+smb2_next_header(char *buf)
+{
+	struct smb2_sync_hdr *hdr = (struct smb2_sync_hdr *)buf;
+	struct smb2_transform_hdr *t_hdr = (struct smb2_transform_hdr *)buf;
+
+	/* FIXME: compounding.
+	 * How does compounding work with smb3 encryption?
+	 * For now, assume that we will have one transform header for each
+	 * smb2 header (and assume that smb2->NextOffset is 0 for all of them.)
+	 */
+	if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM)
+		return sizeof(struct smb2_transform_hdr) +
+		  le32_to_cpu(t_hdr->OriginalMessageSize);
+
+	return le32_to_cpu(hdr->NextCommand);
+}
+
 struct smb_version_operations smb20_operations = {
 	.compare_fids = smb2_compare_fids,
 	.setup_request = smb2_setup_request,
@@ -2809,6 +2827,7 @@ struct smb_version_operations smb20_operations = {
 	.get_acl_by_fid = get_smb2_acl_by_fid,
 	.set_acl = set_smb2_acl,
 #endif /* CIFS_ACL */
+	.next_header = smb2_next_header,
 };
 
 struct smb_version_operations smb21_operations = {
@@ -2903,6 +2922,7 @@ struct smb_version_operations smb21_operations = {
 	.get_acl_by_fid = get_smb2_acl_by_fid,
 	.set_acl = set_smb2_acl,
 #endif /* CIFS_ACL */
+	.next_header = smb2_next_header,
 };
 
 struct smb_version_operations smb30_operations = {
@@ -3007,6 +3027,7 @@ struct smb_version_operations smb30_operations = {
 	.get_acl_by_fid = get_smb2_acl_by_fid,
 	.set_acl = set_smb2_acl,
 #endif /* CIFS_ACL */
+	.next_header = smb2_next_header,
 };
 
 #ifdef CONFIG_CIFS_SMB311
@@ -3107,6 +3128,7 @@ struct smb_version_operations smb311_operations = {
 	.query_all_EAs = smb2_query_eas,
 	.set_EA = smb2_set_ea,
 #endif /* CIFS_XATTR */
+	.next_header = smb2_next_header,
 };
 #endif /* CIFS_SMB311 */
 
-- 
2.13.3

  parent reply	other threads:[~2018-01-21 22:06 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-21 22:06 [PATCH 0/2] cifs: remove rfc1002 length field from all SMB2 response structures Ronnie Sahlberg
     [not found] ` <20180121220644.7907-1-lsahlber-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2018-01-21 22:06   ` [PATCH 1/2] cifs: remove rfc1002 header " Ronnie Sahlberg
2018-01-21 22:06   ` Ronnie Sahlberg [this message]
2018-01-26 16:57   ` [PATCH 0/2] cifs: remove rfc1002 length field " Aurélien Aptel
  -- strict thread matches above, loose matches on Subject: below --
2018-01-02 22:35 [PATCH 0/2] Remove rfc1002 headers from SMB2 responses Ronnie Sahlberg
     [not found] ` <20180102223524.8389-1-lsahlber-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2018-01-02 22:35   ` [PATCH 2/2] cifs: update multiplex loop to handle compounded responses Ronnie Sahlberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180121220644.7907-3-lsahlber@redhat.com \
    --to=lsahlber-h+wxahxf7alqt0dzr+alfa@public.gmane.org \
    --cc=linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.