On Fri, Jun 18, 2021 at 02:40:51PM -0700, Linus Torvalds wrote: > On Fri, Jun 18, 2021 at 2:32 PM Al Viro <viro@xxxxxxxxxxxxxxxxxx> wrote: > > > > Huh? All corner cases are already taken care of by copy_from_iter{,_full}(). > > What I'm proposing is to have the size as a field in 'encoded' and > > do this > > Hmm. Making it part of the structure does make it easier (also for the > sending userspace side, that doesn't now have to create yet another > iov or copy the structure or whatever). > > Except your code doesn't actually handle the "smaller than expected" > case correctly, since by the time it even checks for that, it will > possibly already have failed. So you actually had a bug there - you > can't use the "xyz_full()" version and get it right. Right you are - should be something along the lines of #define MIN_ENCODED_SIZE minimal size, e.g. offsetof of the next field after .size size = copy_from_iter(&encoded, sizeof(encoded), &i); if (unlikely(size < sizeof(encoded))) { // the total length is less than expected // must be at least encoded.size, though, and it would better // cover the .size field itself. if (size < MIN_ENCODED_SIZE || size < encoded.size) sod off } if (sizeof(encoded) < encoded.size) { // newer than expected same as in previous variant } else if (size > encoded.size) { // older than expected iov_iter_revert(size - encoded.size); memset(....) as in previous variant }