Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp1825504imm; Mon, 3 Sep 2018 10:24:53 -0700 (PDT) X-Google-Smtp-Source: ANB0VdbuBwxKeCQ3je8Lf08cIFFFsaf2yodAmizWBKQBkHqRM6m/Bd0qirfbdZg00scs8ZhD0yT8 X-Received: by 2002:a17:902:24e1:: with SMTP id l30-v6mr29669684plg.315.1535995493363; Mon, 03 Sep 2018 10:24:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535995493; cv=none; d=google.com; s=arc-20160816; b=eUWPrRnGAepbsVUBAY/Yvg6pcVjrQT7G4dGXgYbxcjGMI3s4NyFQDfHOj20NoCRbpm 8qXdGBWOImHtXDJoErVt1tqBfaPrt5BS9cgtZ4UC+4Vb1Rv7+yZ6U6J1UpOSA9WQPWmX HCQrgQdkljQ6GEz1eYp7HkYJIGkfz1+ZsoFKBKeNZofZZ2Sm93lXUwwoGUZZTZjEWuMY LPXfEcb1OFYa04WXrC1rEqcj0KKUMeXfKO4kEu8r2rN7ptPHoTfbZJxpIeSwtKet0kZr b/5egtPkWQ4e0ch6gKoV8Jsp/F2lHAvRCnn1KyiYpcXyNFwNoZ74yjfngK7VXsZw45fy 69rg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=ec2zmsvu0ubA/yWQ5YUY0/Wdvugkorsi+y+kT9u015A=; b=E28/hSIGxY1u06oE9plOvO0Wkmpz/2Xctutaq8zI/sFXFLv9vLqMhVBn+DlnuFkBwg QpGvCpVVt3SxpYe9G0+kzT3mcc2hqGpEWWzWkgM3+tylsdAkP9ruS08aSGJXNes3tnej ZuqbhjjRXpbHv/Elf/lm5Tbg+h9iYwquKMZRKSTXPLtLweG6CFbkQfzSPT1zX0qDgFnY 8bUwqWZ2KcODVXDlO0nS6mFwvHiZyPazD+8K+j6m8cgYYsE0iOenbVy76FUENHhpnCNh lnbd6y1w5kYR7m5GWddCr2bUqm/HPBXAZSNwvTMYgrPi6iq6e+L19etJAXYIvFtUTgCJ N8VA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u186-v6si18895410pfu.263.2018.09.03.10.24.38; Mon, 03 Sep 2018 10:24:53 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730409AbeICVno (ORCPT + 99 others); Mon, 3 Sep 2018 17:43:44 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:45332 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727873AbeICVnn (ORCPT ); Mon, 3 Sep 2018 17:43:43 -0400 Received: from localhost (ip-213-127-74-90.ip.prioritytelecom.net [213.127.74.90]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id D0419D00; Mon, 3 Sep 2018 17:22:36 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Steve French , Pavel Shilovsky Subject: [PATCH 4.14 086/165] smb3: enumerating snapshots was leaving part of the data off end Date: Mon, 3 Sep 2018 18:56:12 +0200 Message-Id: <20180903165659.521790778@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165655.003605184@linuxfoundation.org> References: <20180903165655.003605184@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Steve French commit e02789a53d71334b067ad72eee5d4e88a0158083 upstream. When enumerating snapshots, the last few bytes of the final snapshot could be left off since we were miscalculating the length returned (leaving off the sizeof struct SRV_SNAPSHOT_ARRAY) See MS-SMB2 section 2.2.32.2. In addition fixup the length used to allow smaller buffer to be passed in, in order to allow returning the size of the whole snapshot array more easily. Sample userspace output with a kernel patched with this (mounted to a Windows volume with two snapshots). Before this patch, the second snapshot would be missing a few bytes at the end. ~/cifs-2.6# ~/enum-snapshots /mnt/file press enter to issue the ioctl to retrieve snapshot information ... size of snapshot array = 102 Num snapshots: 2 Num returned: 2 Array Size: 102 Snapshot 0:@GMT-2018.06.30-19.34.17 Snapshot 1:@GMT-2018.06.30-19.33.37 CC: Stable Signed-off-by: Steve French Reviewed-by: Pavel Shilovsky Signed-off-by: Greg Kroah-Hartman --- fs/cifs/smb2ops.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -1129,6 +1129,13 @@ smb3_set_integrity(const unsigned int xi } +/* GMT Token is @GMT-YYYY.MM.DD-HH.MM.SS Unicode which is 48 bytes + null */ +#define GMT_TOKEN_SIZE 50 + +/* + * Input buffer contains (empty) struct smb_snapshot array with size filled in + * For output see struct SRV_SNAPSHOT_ARRAY in MS-SMB2 section 2.2.32.2 + */ static int smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon, struct cifsFileInfo *cfile, void __user *ioc_buf) @@ -1158,14 +1165,27 @@ smb3_enum_snapshots(const unsigned int x kfree(retbuf); return rc; } - if (snapshot_in.snapshot_array_size < sizeof(struct smb_snapshot_array)) { - rc = -ERANGE; - kfree(retbuf); - return rc; - } - if (ret_data_len > snapshot_in.snapshot_array_size) - ret_data_len = snapshot_in.snapshot_array_size; + /* + * Check for min size, ie not large enough to fit even one GMT + * token (snapshot). On the first ioctl some users may pass in + * smaller size (or zero) to simply get the size of the array + * so the user space caller can allocate sufficient memory + * and retry the ioctl again with larger array size sufficient + * to hold all of the snapshot GMT tokens on the second try. + */ + if (snapshot_in.snapshot_array_size < GMT_TOKEN_SIZE) + ret_data_len = sizeof(struct smb_snapshot_array); + + /* + * We return struct SRV_SNAPSHOT_ARRAY, followed by + * the snapshot array (of 50 byte GMT tokens) each + * representing an available previous version of the data + */ + if (ret_data_len > (snapshot_in.snapshot_array_size + + sizeof(struct smb_snapshot_array))) + ret_data_len = snapshot_in.snapshot_array_size + + sizeof(struct smb_snapshot_array); if (copy_to_user(ioc_buf, retbuf, ret_data_len)) rc = -EFAULT;