Re: [PATCH RESEND x3 v9 1/9] iov_iter: add copy_struct_from_iter()
From: Omar Sandoval <osandov@osandov.com>
Date: 2021-06-19 00:43:27
Also in:
linux-btrfs, linux-fsdevel
On Fri, Jun 18, 2021 at 10:32:54PM +0000, Al Viro wrote:
On Fri, Jun 18, 2021 at 03:10:03PM -0700, Omar Sandoval wrote:quoted
Or do the same reverting thing that Al did, but with copy_from_iter() instead of copy_from_iter_full() and being careful with the copied count (which I'm not 100% sure I got correct here): size_t copied = copy_from_iter(&encoded, sizeof(encoded), &i); if (copied < offsetofend(struct encoded_iov, size)) return -EFAULT; if (encoded.size > PAGE_SIZE) return -E2BIG; if (encoded.size < ENCODED_IOV_SIZE_VER0) return -EINVAL; if (encoded.size > sizeof(encoded)) { if (copied < sizeof(encoded) return -EFAULT; if (!iov_iter_check_zeroes(&i, encoded.size - sizeof(encoded)) return -EINVAL; } else if (encoded.size < sizeof(encoded)) { // older than what we expect if (copied < encoded.size) return -EFAULT; iov_iter_revert(&i, copied - encoded.size); memset((void *)&encoded + encoded.size, 0, sizeof(encoded) - encoded.size); }simpler than that, actually - copied = copy_from_iter(&encoded, sizeof(encoded), &i); if (unlikely(copied < sizeof(encoded))) { if (copied < offsetofend(struct encoded_iov, size) || copied < encoded.size) return iov_iter_count(i) ? -EFAULT : -EINVAL; } if (encoded.size > sizeof(encoded)) { if (!iov_iter_check_zeroes(&i, encoded.size - sizeof(encoded)) return -EINVAL; } else if (encoded.size < sizeof(encoded)) { // copied can't be less than encoded.size here - otherwise // we'd have copied < sizeof(encoded) and the check above // would've buggered off iov_iter_revert(&i, copied - encoded.size); memset((void *)&encoded + encoded.size, 0, sizeof(encoded) - encoded.size); } should do it.
Thanks, Al, I'll send an updated version with this approach next week.