[PATCH][SMB3]enumerating snapshots was leaving part of the data off end
Steve French
smfrench at gmail.com
Thu Aug 9 06:32:42 UTC 2018
Here is sample output running a userspace tool against the patched kernel
mounted to a Windows volume with two snapshots
(before the second snapshot would be missing a few bytes at the end)
# ~/enum-snapshots /mnt/file
press enter to issue the ioctl to retrieve snapshot information ...
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
On Thu, Aug 9, 2018 at 1:00 AM Steve French <smfrench at gmail.com> wrote:
>
> 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 <stable at vger.kernel.org>
> Signed-off-by: Steve French <stfrench at microsoft.com>
>
> 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;
> (END)
>
>
> --
> Thanks,
>
> Steve
--
Thanks,
Steve
More information about the samba-technical
mailing list