]> git.baikalelectronics.ru Git - kernel.git/commit
Fix 32-bit regression in block device read(2)
authorAl Viro <viro@ZenIV.linux.org.uk>
Mon, 23 Jun 2014 07:44:40 +0000 (08:44 +0100)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 26 Jun 2014 20:02:28 +0000 (13:02 -0700)
commit4242ab5b4c18a15acdf234aa0ffb26e39ae6a875
treea135b6259c00d624188e83c1324404e21a433f64
parent6d7e9d1d59dd2edbd7f7844e5d8df63b0ebe23bb
Fix 32-bit regression in block device read(2)

blkdev_read_iter() wants to cap the iov_iter by the amount of data
remaining to the end of device.  That's what iov_iter_truncate() is for
(trim iter->count if it's above the given limit).  So far, so good, but
the argument of iov_iter_truncate() is size_t, so on 32bit boxen (in
case of a large device) we end up with that upper limit truncated down
to 32 bits *before* comparing it with iter->count.

Easily fixed by making iov_iter_truncate() take 64bit argument - it does
the right thing after such change (we only reach the assignment in there
when the current value of iter->count is greater than the limit, i.e.
for anything that would get truncated we don't reach the assignment at
all) and that argument is not the new value of iter->count - it's an
upper limit for such.

The overhead of passing u64 is not an issue - the thing is inlined, so
callers passing size_t won't pay any penalty.

Reported-and-tested-by: Theodore Tso <tytso@mit.edu>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Tested-by: Alan Cox <gnomes@lxorguk.ukuu.org.uk>
Tested-by: Bruno Wolff III <bruno@wolff.to>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/uio.h