summaryrefslogtreecommitdiffstats
path: root/fs/read_write.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-18 14:46:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-18 14:46:23 -0400
commit69370471d0b2fc3020c60f5473b1eef5977d165a (patch)
treee0ba8b51204779afb17b5749657e9709e8a1ea3e /fs/read_write.c
parente34df3344d7b6f284e958147d7225faa340a1f39 (diff)
parentdd254f5a382cc7879db7a07ed266b12d38fe3ab6 (diff)
Merge branch 'work.iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull iov_iter cleanups from Al Viro. * 'work.iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: fold checks into iterate_and_advance() rw_verify_area(): saner calling conventions aio: remove a pointless assignment
Diffstat (limited to 'fs/read_write.c')
-rw-r--r--fs/read_write.c33
1 files changed, 14 insertions, 19 deletions
diff --git a/fs/read_write.c b/fs/read_write.c
index 56425cd5c9e7..933b53a375b4 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -398,11 +398,6 @@ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos)
398} 398}
399EXPORT_SYMBOL(vfs_iter_write); 399EXPORT_SYMBOL(vfs_iter_write);
400 400
401/*
402 * rw_verify_area doesn't like huge counts. We limit
403 * them to something that fits in "int" so that others
404 * won't have to do range checks all the time.
405 */
406int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count) 401int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count)
407{ 402{
408 struct inode *inode; 403 struct inode *inode;
@@ -429,11 +424,8 @@ int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t
429 if (retval < 0) 424 if (retval < 0)
430 return retval; 425 return retval;
431 } 426 }
432 retval = security_file_permission(file, 427 return security_file_permission(file,
433 read_write == READ ? MAY_READ : MAY_WRITE); 428 read_write == READ ? MAY_READ : MAY_WRITE);
434 if (retval)
435 return retval;
436 return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
437} 429}
438 430
439static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) 431static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
@@ -477,8 +469,9 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
477 return -EFAULT; 469 return -EFAULT;
478 470
479 ret = rw_verify_area(READ, file, pos, count); 471 ret = rw_verify_area(READ, file, pos, count);
480 if (ret >= 0) { 472 if (!ret) {
481 count = ret; 473 if (count > MAX_RW_COUNT)
474 count = MAX_RW_COUNT;
482 ret = __vfs_read(file, buf, count, pos); 475 ret = __vfs_read(file, buf, count, pos);
483 if (ret > 0) { 476 if (ret > 0) {
484 fsnotify_access(file); 477 fsnotify_access(file);
@@ -560,8 +553,9 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
560 return -EFAULT; 553 return -EFAULT;
561 554
562 ret = rw_verify_area(WRITE, file, pos, count); 555 ret = rw_verify_area(WRITE, file, pos, count);
563 if (ret >= 0) { 556 if (!ret) {
564 count = ret; 557 if (count > MAX_RW_COUNT)
558 count = MAX_RW_COUNT;
565 file_start_write(file); 559 file_start_write(file);
566 ret = __vfs_write(file, buf, count, pos); 560 ret = __vfs_write(file, buf, count, pos);
567 if (ret > 0) { 561 if (ret > 0) {
@@ -1315,7 +1309,8 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
1315 retval = rw_verify_area(READ, in.file, &pos, count); 1309 retval = rw_verify_area(READ, in.file, &pos, count);
1316 if (retval < 0) 1310 if (retval < 0)
1317 goto fput_in; 1311 goto fput_in;
1318 count = retval; 1312 if (count > MAX_RW_COUNT)
1313 count = MAX_RW_COUNT;
1319 1314
1320 /* 1315 /*
1321 * Get output file, and verify that it is ok.. 1316 * Get output file, and verify that it is ok..
@@ -1333,7 +1328,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
1333 retval = rw_verify_area(WRITE, out.file, &out_pos, count); 1328 retval = rw_verify_area(WRITE, out.file, &out_pos, count);
1334 if (retval < 0) 1329 if (retval < 0)
1335 goto fput_out; 1330 goto fput_out;
1336 count = retval;
1337 1331
1338 if (!max) 1332 if (!max)
1339 max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes); 1333 max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
@@ -1477,11 +1471,12 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
1477 if (flags != 0) 1471 if (flags != 0)
1478 return -EINVAL; 1472 return -EINVAL;
1479 1473
1480 /* copy_file_range allows full ssize_t len, ignoring MAX_RW_COUNT */
1481 ret = rw_verify_area(READ, file_in, &pos_in, len); 1474 ret = rw_verify_area(READ, file_in, &pos_in, len);
1482 if (ret >= 0) 1475 if (unlikely(ret))
1483 ret = rw_verify_area(WRITE, file_out, &pos_out, len); 1476 return ret;
1484 if (ret < 0) 1477
1478 ret = rw_verify_area(WRITE, file_out, &pos_out, len);
1479 if (unlikely(ret))
1485 return ret; 1480 return ret;
1486 1481
1487 if (!(file_in->f_mode & FMODE_READ) || 1482 if (!(file_in->f_mode & FMODE_READ) ||