From patchwork Sun Jan 21 22:06:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ronnie Sahlberg X-Patchwork-Id: 10177147 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 1B482600F5 for ; Sun, 21 Jan 2018 22:07:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0B78620499 for ; Sun, 21 Jan 2018 22:07:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 001E626E74; Sun, 21 Jan 2018 22:07:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 61CA020499 for ; Sun, 21 Jan 2018 22:07:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751038AbeAUWHB (ORCPT ); Sun, 21 Jan 2018 17:07:01 -0500 Received: from mx1.redhat.com ([209.132.183.28]:44788 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751098AbeAUWHA (ORCPT ); Sun, 21 Jan 2018 17:07:00 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 20DAF7EA98; Sun, 21 Jan 2018 22:07:00 +0000 (UTC) Received: from test1190.test.redhat.com (vpn2-54-18.bne.redhat.com [10.64.54.18]) by smtp.corp.redhat.com (Postfix) with ESMTP id DA3605D70A; Sun, 21 Jan 2018 22:06:58 +0000 (UTC) From: Ronnie Sahlberg To: linux-cifs Cc: Steve French Subject: [PATCH 2/2] cifs: update multiplex loop to handle compounded responses Date: Mon, 22 Jan 2018 09:06:44 +1100 Message-Id: <20180121220644.7907-3-lsahlber@redhat.com> In-Reply-To: <20180121220644.7907-1-lsahlber@redhat.com> References: <20180121220644.7907-1-lsahlber@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Sun, 21 Jan 2018 22:07:00 +0000 (UTC) Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Ronnie Sahlberg --- 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 */