From patchwork Thu Aug 9 06:00:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 955363 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="mxL4UFt4"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41mHg25qWPz9ryt for ; Thu, 9 Aug 2018 16:00:46 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727670AbeHIIX6 (ORCPT ); Thu, 9 Aug 2018 04:23:58 -0400 Received: from mail-pl0-f66.google.com ([209.85.160.66]:38040 "EHLO mail-pl0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727614AbeHIIX5 (ORCPT ); Thu, 9 Aug 2018 04:23:57 -0400 Received: by mail-pl0-f66.google.com with SMTP id u11-v6so2085283plq.5 for ; Wed, 08 Aug 2018 23:00:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=Ib9+27EOJlWvVQ3xFTaAqox58exV3Woz+FYKBoYYZ4E=; b=mxL4UFt4D4YJGn++j+pYIKCcPXrTCQPfQbd7y5GNp/SkgOl1sBaPhJKCvDxrQ/+FK7 30xffw5V8YCrD+nriA0RHEb3tJ5f2Oztv6M3lYbql07XACz/6l+F4zUvTOqpSp+2mEBj hoXMRsxy4tpLyfNTm1gHQH3SnuBsEsFGg/iC5mXmHWYl2ij3nEpeB2VSmiAPYICbYcO4 Gqjc3a2VYrEQBFPFOMsZUIr4fV1/WfVnpD5/jfcrkEKg9FgsDCbumEIIsQepNjMYmIxB qX53r32x9uZSbBGwXGsMtqHH4NeTnlOhUseyHUK3Cyk0ULpmTQdPy2IP3uoxe6qzRmGj H0Jw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=Ib9+27EOJlWvVQ3xFTaAqox58exV3Woz+FYKBoYYZ4E=; b=gHmd7msjGayDtg9wcYLw0cpTPWnGHJ5aCsJPoEo5oDSLla2Asyfo0WAklzp2ijl1Ex pOqFINMVTz2X1sS+Md7Rg/8icla7UJqx6C/NbcKGV22+agb0F0DpwkoFVB5KvZR6B8pn lxmYefUFkOvvFyazIDzefQVs6DOcEIMx6WiyqOf502Dr8SOgmZZcGH7idHGGo41s+GlV wuJ1fDTBxmDXxOB2swXwxC4e1YFkbiVPBpjgluqqqGNgVCD8U8WSs9vSD1zIr7rpS3vm J8Ervdu37rWA++j4clL6EsWPzlAD6xHGGPIjDu4qAFD2vOIyxkHJHFFTBeCbOBRa8UIo 0TVw== X-Gm-Message-State: AOUpUlHLoAfugwAXiV+LIhgrNl76W2P8LLEgDMQEpQdRlHYo9Z9y+qAv DUUtSV2BAV+NZjewdrFjyAcJDl4q/PBa+caubTMK0rAt X-Google-Smtp-Source: AA+uWPx1Zq6XHZOBT5pjtY5wXtgVYoESqJatGM2kYOaBAUUq9EWcK7FjjdAhJ0ugkyBHLfleq+ykfVLaqtCZFSH30Qc= X-Received: by 2002:a17:902:9302:: with SMTP id bc2-v6mr751934plb.280.1533794444552; Wed, 08 Aug 2018 23:00:44 -0700 (PDT) MIME-Version: 1.0 From: Steve French Date: Thu, 9 Aug 2018 01:00:32 -0500 Message-ID: Subject: [PATCH][SMB3]enumerating snapshots was leaving part of the data off end To: CIFS Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org 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. CC: Stable Signed-off-by: Steve French struct cifsFileInfo *cfile, void __user *ioc_buf) @@ -1398,14 +1400,25 @@ smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon, 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; (END) Acked-by: Pavel Shilovsky From b505088cfa0c22b4cc1bbed08b72c9bdf16c8522 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 9 Aug 2018 00:51:34 -0500 Subject: [PATCH] smb3: enumerating snapshots was leaving part of the data off end 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. CC: Stable Signed-off-by: Steve French --- fs/cifs/smb2ops.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 15c7cbde2f39..abd6142e1b4a 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -1369,6 +1369,8 @@ smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon, } +/* GMT Token is @GMT-YYYY.MM.DD-HH.MM.SS Unicode which is 48 bytes + null */ +#define GMT_TOKEN_SIZE 50 static int smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon, struct cifsFileInfo *cfile, void __user *ioc_buf) @@ -1398,14 +1400,25 @@ smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon, 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; -- 2.17.1