diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-03-31 21:48:20 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-04-03 19:51:39 -0400 |
commit | bc61384dcdd82a6faabafecdcd80040625db5e40 (patch) | |
tree | ac9b46ce9b1d9e24e8158bc9577f061e3aaaaf3a /fs/read_write.c | |
parent | 2958ec177e400be1e26fc37e1759f84fa2c1761c (diff) |
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>
Diffstat (limited to 'fs/read_write.c')
-rw-r--r-- | fs/read_write.c | 33 |
1 files changed, 14 insertions, 19 deletions
diff --git a/fs/read_write.c b/fs/read_write.c index cf377cf9dfe3..b1a0e6ca218f 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -410,11 +410,6 @@ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos) | |||
410 | } | 410 | } |
411 | EXPORT_SYMBOL(vfs_iter_write); | 411 | EXPORT_SYMBOL(vfs_iter_write); |
412 | 412 | ||
413 | /* | ||
414 | * rw_verify_area doesn't like huge counts. We limit | ||
415 | * them to something that fits in "int" so that others | ||
416 | * won't have to do range checks all the time. | ||
417 | */ | ||
418 | int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count) | 413 | int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count) |
419 | { | 414 | { |
420 | struct inode *inode; | 415 | struct inode *inode; |
@@ -441,11 +436,8 @@ int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t | |||
441 | if (retval < 0) | 436 | if (retval < 0) |
442 | return retval; | 437 | return retval; |
443 | } | 438 | } |
444 | retval = security_file_permission(file, | 439 | return security_file_permission(file, |
445 | read_write == READ ? MAY_READ : MAY_WRITE); | 440 | read_write == READ ? MAY_READ : MAY_WRITE); |
446 | if (retval) | ||
447 | return retval; | ||
448 | return count > MAX_RW_COUNT ? MAX_RW_COUNT : count; | ||
449 | } | 441 | } |
450 | 442 | ||
451 | static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) | 443 | 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) | |||
489 | return -EFAULT; | 481 | return -EFAULT; |
490 | 482 | ||
491 | ret = rw_verify_area(READ, file, pos, count); | 483 | ret = rw_verify_area(READ, file, pos, count); |
492 | if (ret >= 0) { | 484 | if (!ret) { |
493 | count = ret; | 485 | if (count > MAX_RW_COUNT) |
486 | count = MAX_RW_COUNT; | ||
494 | ret = __vfs_read(file, buf, count, pos); | 487 | ret = __vfs_read(file, buf, count, pos); |
495 | if (ret > 0) { | 488 | if (ret > 0) { |
496 | fsnotify_access(file); | 489 | fsnotify_access(file); |
@@ -572,8 +565,9 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ | |||
572 | return -EFAULT; | 565 | return -EFAULT; |
573 | 566 | ||
574 | ret = rw_verify_area(WRITE, file, pos, count); | 567 | ret = rw_verify_area(WRITE, file, pos, count); |
575 | if (ret >= 0) { | 568 | if (!ret) { |
576 | count = ret; | 569 | if (count > MAX_RW_COUNT) |
570 | count = MAX_RW_COUNT; | ||
577 | file_start_write(file); | 571 | file_start_write(file); |
578 | ret = __vfs_write(file, buf, count, pos); | 572 | ret = __vfs_write(file, buf, count, pos); |
579 | if (ret > 0) { | 573 | if (ret > 0) { |
@@ -1323,7 +1317,8 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
1323 | retval = rw_verify_area(READ, in.file, &pos, count); | 1317 | retval = rw_verify_area(READ, in.file, &pos, count); |
1324 | if (retval < 0) | 1318 | if (retval < 0) |
1325 | goto fput_in; | 1319 | goto fput_in; |
1326 | count = retval; | 1320 | if (count > MAX_RW_COUNT) |
1321 | count = MAX_RW_COUNT; | ||
1327 | 1322 | ||
1328 | /* | 1323 | /* |
1329 | * Get output file, and verify that it is ok.. | 1324 | * 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, | |||
1341 | retval = rw_verify_area(WRITE, out.file, &out_pos, count); | 1336 | retval = rw_verify_area(WRITE, out.file, &out_pos, count); |
1342 | if (retval < 0) | 1337 | if (retval < 0) |
1343 | goto fput_out; | 1338 | goto fput_out; |
1344 | count = retval; | ||
1345 | 1339 | ||
1346 | if (!max) | 1340 | if (!max) |
1347 | max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes); | 1341 | 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, | |||
1485 | if (flags != 0) | 1479 | if (flags != 0) |
1486 | return -EINVAL; | 1480 | return -EINVAL; |
1487 | 1481 | ||
1488 | /* copy_file_range allows full ssize_t len, ignoring MAX_RW_COUNT */ | ||
1489 | ret = rw_verify_area(READ, file_in, &pos_in, len); | 1482 | ret = rw_verify_area(READ, file_in, &pos_in, len); |
1490 | if (ret >= 0) | 1483 | if (unlikely(ret)) |
1491 | ret = rw_verify_area(WRITE, file_out, &pos_out, len); | 1484 | return ret; |
1492 | if (ret < 0) | 1485 | |
1486 | ret = rw_verify_area(WRITE, file_out, &pos_out, len); | ||
1487 | if (unlikely(ret)) | ||
1493 | return ret; | 1488 | return ret; |
1494 | 1489 | ||
1495 | if (!(file_in->f_mode & FMODE_READ) || | 1490 | if (!(file_in->f_mode & FMODE_READ) || |