From patchwork Wed Nov 14 22:40:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ronnie Sahlberg X-Patchwork-Id: 10683263 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5471717F3 for ; Wed, 14 Nov 2018 22:40:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 474852BCF2 for ; Wed, 14 Nov 2018 22:40:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3C1242BD0C; Wed, 14 Nov 2018 22:40:39 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 C3C1D2BCF2 for ; Wed, 14 Nov 2018 22:40:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728048AbeKOIpq (ORCPT ); Thu, 15 Nov 2018 03:45:46 -0500 Received: from mx1.redhat.com ([209.132.183.28]:5058 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726844AbeKOIpq (ORCPT ); Thu, 15 Nov 2018 03:45:46 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9F6C2F815; Wed, 14 Nov 2018 22:40:37 +0000 (UTC) Received: from test1135.test.redhat.com (vpn2-54-34.bne.redhat.com [10.64.54.34]) by smtp.corp.redhat.com (Postfix) with ESMTP id 06B8B5C219; Wed, 14 Nov 2018 22:40:36 +0000 (UTC) From: Ronnie Sahlberg To: Linux CIFS mailing list Cc: Steve French Subject: [PATCH 1/3] cifs: create a helper function for compound query_info Date: Thu, 15 Nov 2018 08:40:18 +1000 Message-Id: <20181114224020.6100-2-lsahlber@redhat.com> In-Reply-To: <20181114224020.6100-1-lsahlber@redhat.com> References: <20181114224020.6100-1-lsahlber@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 14 Nov 2018 22:40:37 +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 and convert statfs to use it. Signed-off-by: Ronnie Sahlberg --- fs/cifs/smb2ops.c | 78 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 24 deletions(-) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 54bedd751e66..5d0d9d618cfa 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -1830,25 +1830,28 @@ smb2_set_next_command(struct TCP_Server_Info *server, struct smb_rqst *rqst) shdr->NextCommand = cpu_to_le32(len); } +/* + * Passes the query info response back to the caller on success. + * Caller need to free this with free_rsp_buf(). + */ static int -smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, - struct kstatfs *buf) +smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, + __le16 *utf16_path, u32 desired_access, + u32 class, u32 type, u32 output_len, + struct kvec *rsp, int *buftype) { - struct smb2_query_info_rsp *rsp; - struct smb2_fs_full_size_info *info = NULL; + struct cifs_ses *ses = tcon->ses; + struct TCP_Server_Info *server = ses->server; + int flags = 0; struct smb_rqst rqst[3]; int resp_buftype[3]; struct kvec rsp_iov[3]; struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; struct kvec qi_iov[1]; struct kvec close_iov[1]; - struct cifs_ses *ses = tcon->ses; - struct TCP_Server_Info *server = ses->server; - __le16 srch_path = 0; /* Null - open root of share */ u8 oplock = SMB2_OPLOCK_LEVEL_NONE; struct cifs_open_parms oparms; struct cifs_fid fid; - int flags = 0; int rc; if (smb3_encryption_required(tcon)) @@ -1863,15 +1866,15 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE; oparms.tcon = tcon; - oparms.desired_access = FILE_READ_ATTRIBUTES; + oparms.desired_access = desired_access; oparms.disposition = FILE_OPEN; oparms.create_options = 0; oparms.fid = &fid; oparms.reconnect = false; - rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, &srch_path); + rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, utf16_path); if (rc) - goto qfs_exit; + goto qic_exit; smb2_set_next_command(server, &rqst[0]); memset(&qi_iov, 0, sizeof(qi_iov)); @@ -1879,12 +1882,11 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, rqst[1].rq_nvec = 1; rc = SMB2_query_info_init(tcon, &rqst[1], COMPOUND_FID, COMPOUND_FID, - FS_FULL_SIZE_INFORMATION, - SMB2_O_INFO_FILESYSTEM, 0, - sizeof(struct smb2_fs_full_size_info), 0, + class, type, 0, + output_len, 0, NULL); if (rc) - goto qfs_exit; + goto qic_exit; smb2_set_next_command(server, &rqst[1]); smb2_set_related(&rqst[1]); @@ -1894,32 +1896,60 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID); if (rc) - goto qfs_exit; + goto qic_exit; smb2_set_related(&rqst[2]); rc = compound_send_recv(xid, ses, flags, 3, rqst, resp_buftype, rsp_iov); if (rc) + goto qic_exit; + + *rsp = rsp_iov[1]; + *buftype = resp_buftype[1]; + + qic_exit: + SMB2_open_free(&rqst[0]); + SMB2_query_info_free(&rqst[1]); + SMB2_close_free(&rqst[2]); + free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); + free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); + return rc; +} + +static int +smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, + struct kstatfs *buf) +{ + struct smb2_query_info_rsp *rsp; + struct smb2_fs_full_size_info *info = NULL; + __le16 utf16_path = 0; /* Null - open root of share */ + struct kvec rsp_iov = {NULL, 0}; + int buftype = CIFS_NO_BUFFER; + int rc; + + + rc = smb2_query_info_compound(xid, tcon, &utf16_path, + FILE_READ_ATTRIBUTES, + FS_FULL_SIZE_INFORMATION, + SMB2_O_INFO_FILESYSTEM, + sizeof(struct smb2_fs_full_size_info), + &rsp_iov, &buftype); + if (rc) goto qfs_exit; - rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base; + rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base; buf->f_type = SMB2_MAGIC_NUMBER; info = (struct smb2_fs_full_size_info *)( le16_to_cpu(rsp->OutputBufferOffset) + (char *)rsp); rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset), le32_to_cpu(rsp->OutputBufferLength), - &rsp_iov[1], + &rsp_iov, sizeof(struct smb2_fs_full_size_info)); if (!rc) smb2_copy_fs_info_to_kstatfs(info, buf); qfs_exit: - SMB2_open_free(&rqst[0]); - SMB2_query_info_free(&rqst[1]); - SMB2_close_free(&rqst[2]); - free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); - free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); - free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); + free_rsp_buf(buftype, rsp_iov.iov_base); return rc; } From patchwork Wed Nov 14 22:40:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ronnie Sahlberg X-Patchwork-Id: 10683261 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5128A3CF1 for ; Wed, 14 Nov 2018 22:40:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 432312BCF2 for ; Wed, 14 Nov 2018 22:40:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 37B412BD0C; Wed, 14 Nov 2018 22:40:37 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 96CAC2BCF2 for ; Wed, 14 Nov 2018 22:40:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728160AbeKOIpo (ORCPT ); Thu, 15 Nov 2018 03:45:44 -0500 Received: from mx1.redhat.com ([209.132.183.28]:59100 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728263AbeKOIpn (ORCPT ); Thu, 15 Nov 2018 03:45:43 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5AAE1A4050; Wed, 14 Nov 2018 22:40:34 +0000 (UTC) Received: from test1135.test.redhat.com (vpn2-54-34.bne.redhat.com [10.64.54.34]) by smtp.corp.redhat.com (Postfix) with ESMTP id A629E1001903; Wed, 14 Nov 2018 22:40:33 +0000 (UTC) From: Ronnie Sahlberg To: Linux CIFS mailing list Cc: Steve French Subject: [PATCH 2/3] cifs: change smb2_query_eas to use the compound query-info helper Date: Thu, 15 Nov 2018 08:40:19 +1000 Message-Id: <20181114224020.6100-3-lsahlber@redhat.com> In-Reply-To: <20181114224020.6100-1-lsahlber@redhat.com> References: <20181114224020.6100-1-lsahlber@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 14 Nov 2018 22:40:34 +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/smb2ops.c | 97 ++++++++++++++++++++++------------------------------- fs/cifs/smb2pdu.c | 12 ------- fs/cifs/smb2pdu.h | 1 - fs/cifs/smb2proto.h | 10 +++--- 4 files changed, 46 insertions(+), 74 deletions(-) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 5d0d9d618cfa..cea942056252 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -831,72 +831,50 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, { int rc; __le16 *utf16_path; - __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; - struct cifs_open_parms oparms; - struct cifs_fid fid; - struct smb2_file_full_ea_info *smb2_data; - int ea_buf_size = SMB2_MIN_EA_BUF; + struct kvec rsp_iov = {NULL, 0}; + int buftype = CIFS_NO_BUFFER; + struct smb2_query_info_rsp *rsp; + struct smb2_file_full_ea_info *info = NULL; utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); if (!utf16_path) return -ENOMEM; - oparms.tcon = tcon; - oparms.desired_access = FILE_READ_EA; - oparms.disposition = FILE_OPEN; - if (backup_cred(cifs_sb)) - oparms.create_options = CREATE_OPEN_BACKUP_INTENT; - else - oparms.create_options = 0; - oparms.fid = &fid; - oparms.reconnect = false; - - rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL); - kfree(utf16_path); + rc = smb2_query_info_compound(xid, tcon, utf16_path, + FILE_READ_EA, + FILE_FULL_EA_INFORMATION, + SMB2_O_INFO_FILE, + SMB2_MAX_EA_BUF, + &rsp_iov, &buftype, cifs_sb); if (rc) { - cifs_dbg(FYI, "open failed rc=%d\n", rc); - return rc; - } - - while (1) { - smb2_data = kzalloc(ea_buf_size, GFP_KERNEL); - if (smb2_data == NULL) { - SMB2_close(xid, tcon, fid.persistent_fid, - fid.volatile_fid); - return -ENOMEM; - } - - rc = SMB2_query_eas(xid, tcon, fid.persistent_fid, - fid.volatile_fid, - ea_buf_size, smb2_data); - - if (rc != -E2BIG) - break; - - kfree(smb2_data); - ea_buf_size <<= 1; - - if (ea_buf_size > SMB2_MAX_EA_BUF) { - cifs_dbg(VFS, "EA size is too large\n"); - SMB2_close(xid, tcon, fid.persistent_fid, - fid.volatile_fid); - return -ENOMEM; - } + if (!ea_name && rc == -ENODATA) + rc = 0; + goto qeas_exit; } - SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); + rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base; + rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset), + le32_to_cpu(rsp->OutputBufferLength), + &rsp_iov, + sizeof(struct smb2_file_full_ea_info)); + if (rc) + goto qeas_exit; /* * If ea_name is NULL (listxattr) and there are no EAs, return 0 as it's * not an error. Otherwise, the specified ea_name was not found. */ - if (!rc) - rc = move_smb2_ea_to_cifs(ea_data, buf_size, smb2_data, - SMB2_MAX_EA_BUF, ea_name); - else if (!ea_name && rc == -ENODATA) + if (!rc) { + info = (struct smb2_file_full_ea_info *)( + le16_to_cpu(rsp->OutputBufferOffset) + (char *)rsp); + rc = move_smb2_ea_to_cifs(ea_data, buf_size, info, + le32_to_cpu(rsp->OutputBufferLength), ea_name); + } else if (!ea_name && rc == -ENODATA) rc = 0; - kfree(smb2_data); + qeas_exit: + kfree(utf16_path); + free_rsp_buf(buftype, rsp_iov.iov_base); return rc; } @@ -1834,11 +1812,12 @@ smb2_set_next_command(struct TCP_Server_Info *server, struct smb_rqst *rqst) * Passes the query info response back to the caller on success. * Caller need to free this with free_rsp_buf(). */ -static int +int smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, __le16 *utf16_path, u32 desired_access, u32 class, u32 type, u32 output_len, - struct kvec *rsp, int *buftype) + struct kvec *rsp, int *buftype, + struct cifs_sb_info *cifs_sb) { struct cifs_ses *ses = tcon->ses; struct TCP_Server_Info *server = ses->server; @@ -1868,7 +1847,10 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, oparms.tcon = tcon; oparms.desired_access = desired_access; oparms.disposition = FILE_OPEN; - oparms.create_options = 0; + if (cifs_sb && backup_cred(cifs_sb)) + oparms.create_options = CREATE_OPEN_BACKUP_INTENT; + else + oparms.create_options = 0; oparms.fid = &fid; oparms.reconnect = false; @@ -1901,9 +1883,10 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, rc = compound_send_recv(xid, ses, flags, 3, rqst, resp_buftype, rsp_iov); - if (rc) + if (rc) { + free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); goto qic_exit; - + } *rsp = rsp_iov[1]; *buftype = resp_buftype[1]; @@ -1933,7 +1916,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, FS_FULL_SIZE_INFORMATION, SMB2_O_INFO_FILESYSTEM, sizeof(struct smb2_fs_full_size_info), - &rsp_iov, &buftype); + &rsp_iov, &buftype, NULL); if (rc) goto qfs_exit; diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 27f86537a5d1..448031898dd4 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2768,18 +2768,6 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, return rc; } -int SMB2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, - u64 persistent_fid, u64 volatile_fid, - int ea_buf_size, struct smb2_file_full_ea_info *data) -{ - return query_info(xid, tcon, persistent_fid, volatile_fid, - FILE_FULL_EA_INFORMATION, SMB2_O_INFO_FILE, 0, - ea_buf_size, - sizeof(struct smb2_file_full_ea_info), - (void **)&data, - NULL); -} - int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, struct smb2_file_all_info *data) { diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 5671d5ee7f58..05dea6750c33 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -1398,7 +1398,6 @@ struct smb2_file_link_info { /* encoding of request for level 11 */ char FileName[0]; /* Name to be assigned to new link */ } __packed; /* level 11 Set */ -#define SMB2_MIN_EA_BUF 2048 #define SMB2_MAX_EA_BUF 65536 struct smb2_file_full_ea_info { /* encoding of response for level 15 */ diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 9f4e9ed9ce53..7f351e5c3ce6 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -153,10 +153,6 @@ extern int SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, extern void SMB2_close_free(struct smb_rqst *rqst); extern int SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_file_id, u64 volatile_file_id); -extern int SMB2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, - u64 persistent_file_id, u64 volatile_file_id, - int ea_buf_size, - struct smb2_file_full_ea_info *data); extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_file_id, u64 volatile_file_id, struct smb2_file_all_info *data); @@ -240,4 +236,10 @@ extern void smb2_copy_fs_info_to_kstatfs( extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server); extern int smb311_update_preauth_hash(struct cifs_ses *ses, struct kvec *iov, int nvec); +extern int smb2_query_info_compound(const unsigned int xid, + struct cifs_tcon *tcon, + __le16 *utf16_path, u32 desired_access, + u32 class, u32 type, u32 output_len, + struct kvec *rsp, int *buftype, + struct cifs_sb_info *cifs_sb); #endif /* _SMB2PROTO_H */ From patchwork Wed Nov 14 22:40:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ronnie Sahlberg X-Patchwork-Id: 10683257 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 197F214E2 for ; Wed, 14 Nov 2018 22:40:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0AEF82BCF2 for ; Wed, 14 Nov 2018 22:40:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F34992BD0C; Wed, 14 Nov 2018 22:40:34 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 9CEF52BCF2 for ; Wed, 14 Nov 2018 22:40:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729062AbeKOIpm (ORCPT ); Thu, 15 Nov 2018 03:45:42 -0500 Received: from mx1.redhat.com ([209.132.183.28]:20317 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728160AbeKOIpl (ORCPT ); Thu, 15 Nov 2018 03:45:41 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 578B129A60; Wed, 14 Nov 2018 22:40:32 +0000 (UTC) Received: from test1135.test.redhat.com (vpn2-54-34.bne.redhat.com [10.64.54.34]) by smtp.corp.redhat.com (Postfix) with ESMTP id B10B3608F3; Wed, 14 Nov 2018 22:40:31 +0000 (UTC) From: Ronnie Sahlberg To: Linux CIFS mailing list Cc: Steve French Subject: [PATCH 3/3] cifs: check how much EA space we already use before adding more EAs Date: Thu, 15 Nov 2018 08:40:20 +1000 Message-Id: <20181114224020.6100-4-lsahlber@redhat.com> In-Reply-To: <20181114224020.6100-1-lsahlber@redhat.com> References: <20181114224020.6100-1-lsahlber@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 14 Nov 2018 22:40:32 +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 When setting/adding an EA, check how much EA space we arelady have on this file and make sure that if we add this new EA that the result will still fit inside a SMB2_MAX_EA_BUF. In the client we limit the maximum buffer to currently 64k. When we store these on the server we have no way of knowing if/what the servers limit for EAs are. They could be, and often are, much larger than 64k. This change is to return an error and not set the EA if we suspect that the result could overflow the buffer. This prevents the very annoying behaviour that we can add EAs well beyond the maximum clientside buffer and thus, at that stage make it is no longer query or list the existing EAs any more. The check for overflow is overly conservative : if (len + rsp_iov[0].iov_len > SMB2_MAX_EA_BUF) { since the actual size of the EAs are a bit less than iov_len but this is simpler to read. The only effect of this is that we will stop allowing adding new EAs ~100 bytes earlier than stricly needed which does not matter much for 64k buffers. Signed-off-by: Ronnie Sahlberg --- fs/cifs/smb2ops.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index cea942056252..65e5d5521a6c 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -915,10 +915,30 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, if (!utf16_path) return -ENOMEM; + len = sizeof(ea) + ea_name_len + ea_value_len + 1; + memset(rqst, 0, sizeof(rqst)); resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; memset(rsp_iov, 0, sizeof(rsp_iov)); + /* + * Make sure we have enough space to store the new EA. + */ + rc = smb2_query_info_compound(xid, tcon, utf16_path, + FILE_READ_EA, + FILE_FULL_EA_INFORMATION, + SMB2_O_INFO_FILE, + SMB2_MAX_EA_BUF, + &rsp_iov[0], &resp_buftype[0], cifs_sb); + free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); + resp_buftype[0] = CIFS_NO_BUFFER; + rsp_iov[0].iov_base = NULL; + if (len + rsp_iov[0].iov_len > SMB2_MAX_EA_BUF) { + rc = -ERANGE; + goto sea_exit; + } + + /* Open */ memset(&open_iov, 0, sizeof(open_iov)); rqst[0].rq_iov = open_iov;