Hi,
I am sometimes reading some kernel source in my free time, and I think that I
either missed something or something is missing or something is wrong.
Whatever it is, things do not match.
In fs/read_write.c:
> static ssize_t do_readv_writev(blah)
> {
> [...]
>
> /*
> * First get the "struct iovec" from user memory and
> * verify all the pointers
> */
I thought that there would be some calls to verify_area() womewhere below, but
there aren't any. There's just
> [... checks of nr_segs and file->f_op ...]
> ret = -EFAULT;
> if (copy_from_user(iov, vector, nr_segs*sizeof(*vector)))
> goto out;
>
> /*
> * Single unix specification:
> * We should -EINVAL if an element length is not >= 0 and fitting an
> * ssize_t. The total length is fitting an ssize_t
> *
> * Be careful here because iov_len is a size_t not an ssize_t
> */
>
> [... checks like described ...]
>
> inode = file->f_dentry->d_inode;
> /* VERIFY_WRITE actually means a read, as we write to user space */
> ret = locks_verify_area((type == READ
> ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
> inode, file, *pos, tot_len);
The comments look like someone thought of a call to verify_areas() instead of
the function actually called. Or am I just missing something?
Just for the case that I am not, a patch against 2.5.65 for removing the bogus
comments is included. This one also tries to clean up some very small things.
Well, it's my first patch, so handle with care... :-)
Stephan
P.S. I am not 100% sure about this:
for (seg = 0 ; seg < nr_segs; seg++) {
- ssize_t tmp = tot_len;
ssize_t len = (ssize_t)iov[seg].iov_len;
if (len < 0) /* size_t not fitting an ssize_t .. */
goto out;
tot_len += len;
- if (tot_len < tmp) /* maths overflow on the ssize_t */
+ if ((ssize_t)tot_len < 0) /* maths overflow on the ssize_t */
goto out;
}
That should be okay? Or do size_t and ssize_t differ in more than just in
signedness?