Re: [PATCH RESEND x3 v9 1/9] iov_iter: add copy_struct_from_iter()
From: Al Viro <viro@zeniv.linux.org.uk>
Date: 2021-06-18 22:32:59
Also in:
linux-btrfs, linux-fsdevel
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.