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: > > > 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.