rw_verify_area(): saner calling conventions
Lift length capping into the few callers that care about it. Most of
them treat all non-negatives as "success" and ignore the capped value,
and with good reasons.
Make rw_verify_area() return 0 on success.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/fs/read_write.c b/fs/read_write.c
index cf377cf..b1a0e6c 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -410,11 +410,6 @@
}
EXPORT_SYMBOL(vfs_iter_write);
-/*
- * rw_verify_area doesn't like huge counts. We limit
- * them to something that fits in "int" so that others
- * won't have to do range checks all the time.
- */
int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count)
{
struct inode *inode;
@@ -441,11 +436,8 @@
if (retval < 0)
return retval;
}
- retval = security_file_permission(file,
+ return security_file_permission(file,
read_write == READ ? MAY_READ : MAY_WRITE);
- if (retval)
- return retval;
- return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
}
static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
@@ -489,8 +481,9 @@
return -EFAULT;
ret = rw_verify_area(READ, file, pos, count);
- if (ret >= 0) {
- count = ret;
+ if (!ret) {
+ if (count > MAX_RW_COUNT)
+ count = MAX_RW_COUNT;
ret = __vfs_read(file, buf, count, pos);
if (ret > 0) {
fsnotify_access(file);
@@ -572,8 +565,9 @@
return -EFAULT;
ret = rw_verify_area(WRITE, file, pos, count);
- if (ret >= 0) {
- count = ret;
+ if (!ret) {
+ if (count > MAX_RW_COUNT)
+ count = MAX_RW_COUNT;
file_start_write(file);
ret = __vfs_write(file, buf, count, pos);
if (ret > 0) {
@@ -1323,7 +1317,8 @@
retval = rw_verify_area(READ, in.file, &pos, count);
if (retval < 0)
goto fput_in;
- count = retval;
+ if (count > MAX_RW_COUNT)
+ count = MAX_RW_COUNT;
/*
* Get output file, and verify that it is ok..
@@ -1341,7 +1336,6 @@
retval = rw_verify_area(WRITE, out.file, &out_pos, count);
if (retval < 0)
goto fput_out;
- count = retval;
if (!max)
max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
@@ -1485,11 +1479,12 @@
if (flags != 0)
return -EINVAL;
- /* copy_file_range allows full ssize_t len, ignoring MAX_RW_COUNT */
ret = rw_verify_area(READ, file_in, &pos_in, len);
- if (ret >= 0)
- ret = rw_verify_area(WRITE, file_out, &pos_out, len);
- if (ret < 0)
+ if (unlikely(ret))
+ return ret;
+
+ ret = rw_verify_area(WRITE, file_out, &pos_out, len);
+ if (unlikely(ret))
return ret;
if (!(file_in->f_mode & FMODE_READ) ||