mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-13 14:24:11 +08:00
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>
This commit is contained in:
parent
2958ec177e
commit
bc61384dcd
@ -410,11 +410,6 @@ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vfs_iter_write);
|
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)
|
int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count)
|
||||||
{
|
{
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
@ -441,11 +436,8 @@ int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t
|
|||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
retval = security_file_permission(file,
|
return security_file_permission(file,
|
||||||
read_write == READ ? MAY_READ : MAY_WRITE);
|
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)
|
static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
|
||||||
@ -489,8 +481,9 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
ret = rw_verify_area(READ, file, pos, count);
|
ret = rw_verify_area(READ, file, pos, count);
|
||||||
if (ret >= 0) {
|
if (!ret) {
|
||||||
count = ret;
|
if (count > MAX_RW_COUNT)
|
||||||
|
count = MAX_RW_COUNT;
|
||||||
ret = __vfs_read(file, buf, count, pos);
|
ret = __vfs_read(file, buf, count, pos);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
fsnotify_access(file);
|
fsnotify_access(file);
|
||||||
@ -572,8 +565,9 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
ret = rw_verify_area(WRITE, file, pos, count);
|
ret = rw_verify_area(WRITE, file, pos, count);
|
||||||
if (ret >= 0) {
|
if (!ret) {
|
||||||
count = ret;
|
if (count > MAX_RW_COUNT)
|
||||||
|
count = MAX_RW_COUNT;
|
||||||
file_start_write(file);
|
file_start_write(file);
|
||||||
ret = __vfs_write(file, buf, count, pos);
|
ret = __vfs_write(file, buf, count, pos);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
@ -1323,7 +1317,8 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
|
|||||||
retval = rw_verify_area(READ, in.file, &pos, count);
|
retval = rw_verify_area(READ, in.file, &pos, count);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto fput_in;
|
goto fput_in;
|
||||||
count = retval;
|
if (count > MAX_RW_COUNT)
|
||||||
|
count = MAX_RW_COUNT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get output file, and verify that it is ok..
|
* Get output file, and verify that it is ok..
|
||||||
@ -1341,7 +1336,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
|
|||||||
retval = rw_verify_area(WRITE, out.file, &out_pos, count);
|
retval = rw_verify_area(WRITE, out.file, &out_pos, count);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto fput_out;
|
goto fput_out;
|
||||||
count = retval;
|
|
||||||
|
|
||||||
if (!max)
|
if (!max)
|
||||||
max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
|
max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
|
||||||
@ -1485,11 +1479,12 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
|
|||||||
if (flags != 0)
|
if (flags != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* copy_file_range allows full ssize_t len, ignoring MAX_RW_COUNT */
|
|
||||||
ret = rw_verify_area(READ, file_in, &pos_in, len);
|
ret = rw_verify_area(READ, file_in, &pos_in, len);
|
||||||
if (ret >= 0)
|
if (unlikely(ret))
|
||||||
ret = rw_verify_area(WRITE, file_out, &pos_out, len);
|
return ret;
|
||||||
if (ret < 0)
|
|
||||||
|
ret = rw_verify_area(WRITE, file_out, &pos_out, len);
|
||||||
|
if (unlikely(ret))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (!(file_in->f_mode & FMODE_READ) ||
|
if (!(file_in->f_mode & FMODE_READ) ||
|
||||||
|
Loading…
Reference in New Issue
Block a user