diff options
Diffstat (limited to 'fs/read_write.c')
-rw-r--r-- | fs/read_write.c | 51 |
1 files changed, 19 insertions, 32 deletions
diff --git a/fs/read_write.c b/fs/read_write.c index cf377cf9dfe3..933b53a375b4 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -302,18 +302,6 @@ loff_t vfs_llseek(struct file *file, loff_t offset, int whence) | |||
302 | } | 302 | } |
303 | EXPORT_SYMBOL(vfs_llseek); | 303 | EXPORT_SYMBOL(vfs_llseek); |
304 | 304 | ||
305 | static inline struct fd fdget_pos(int fd) | ||
306 | { | ||
307 | return __to_fd(__fdget_pos(fd)); | ||
308 | } | ||
309 | |||
310 | static inline void fdput_pos(struct fd f) | ||
311 | { | ||
312 | if (f.flags & FDPUT_POS_UNLOCK) | ||
313 | mutex_unlock(&f.file->f_pos_lock); | ||
314 | fdput(f); | ||
315 | } | ||
316 | |||
317 | SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence) | 305 | SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence) |
318 | { | 306 | { |
319 | off_t retval; | 307 | off_t retval; |
@@ -410,11 +398,6 @@ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos) | |||
410 | } | 398 | } |
411 | EXPORT_SYMBOL(vfs_iter_write); | 399 | EXPORT_SYMBOL(vfs_iter_write); |
412 | 400 | ||
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) | 401 | int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count) |
419 | { | 402 | { |
420 | struct inode *inode; | 403 | struct inode *inode; |
@@ -441,11 +424,8 @@ int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t | |||
441 | if (retval < 0) | 424 | if (retval < 0) |
442 | return retval; | 425 | return retval; |
443 | } | 426 | } |
444 | retval = security_file_permission(file, | 427 | return security_file_permission(file, |
445 | read_write == READ ? MAY_READ : MAY_WRITE); | 428 | read_write == READ ? MAY_READ : MAY_WRITE); |
446 | if (retval) | ||
447 | return retval; | ||
448 | return count > MAX_RW_COUNT ? MAX_RW_COUNT : count; | ||
449 | } | 429 | } |
450 | 430 | ||
451 | static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) | 431 | static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) |
@@ -489,8 +469,9 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) | |||
489 | return -EFAULT; | 469 | return -EFAULT; |
490 | 470 | ||
491 | ret = rw_verify_area(READ, file, pos, count); | 471 | ret = rw_verify_area(READ, file, pos, count); |
492 | if (ret >= 0) { | 472 | if (!ret) { |
493 | count = ret; | 473 | if (count > MAX_RW_COUNT) |
474 | count = MAX_RW_COUNT; | ||
494 | ret = __vfs_read(file, buf, count, pos); | 475 | ret = __vfs_read(file, buf, count, pos); |
495 | if (ret > 0) { | 476 | if (ret > 0) { |
496 | fsnotify_access(file); | 477 | fsnotify_access(file); |
@@ -572,8 +553,9 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ | |||
572 | return -EFAULT; | 553 | return -EFAULT; |
573 | 554 | ||
574 | ret = rw_verify_area(WRITE, file, pos, count); | 555 | ret = rw_verify_area(WRITE, file, pos, count); |
575 | if (ret >= 0) { | 556 | if (!ret) { |
576 | count = ret; | 557 | if (count > MAX_RW_COUNT) |
558 | count = MAX_RW_COUNT; | ||
577 | file_start_write(file); | 559 | file_start_write(file); |
578 | ret = __vfs_write(file, buf, count, pos); | 560 | ret = __vfs_write(file, buf, count, pos); |
579 | if (ret > 0) { | 561 | if (ret > 0) { |
@@ -698,12 +680,16 @@ static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, | |||
698 | struct kiocb kiocb; | 680 | struct kiocb kiocb; |
699 | ssize_t ret; | 681 | ssize_t ret; |
700 | 682 | ||
701 | if (flags & ~RWF_HIPRI) | 683 | if (flags & ~(RWF_HIPRI | RWF_DSYNC | RWF_SYNC)) |
702 | return -EOPNOTSUPP; | 684 | return -EOPNOTSUPP; |
703 | 685 | ||
704 | init_sync_kiocb(&kiocb, filp); | 686 | init_sync_kiocb(&kiocb, filp); |
705 | if (flags & RWF_HIPRI) | 687 | if (flags & RWF_HIPRI) |
706 | kiocb.ki_flags |= IOCB_HIPRI; | 688 | kiocb.ki_flags |= IOCB_HIPRI; |
689 | if (flags & RWF_DSYNC) | ||
690 | kiocb.ki_flags |= IOCB_DSYNC; | ||
691 | if (flags & RWF_SYNC) | ||
692 | kiocb.ki_flags |= (IOCB_DSYNC | IOCB_SYNC); | ||
707 | kiocb.ki_pos = *ppos; | 693 | kiocb.ki_pos = *ppos; |
708 | 694 | ||
709 | ret = fn(&kiocb, iter); | 695 | ret = fn(&kiocb, iter); |
@@ -1323,7 +1309,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); | 1309 | retval = rw_verify_area(READ, in.file, &pos, count); |
1324 | if (retval < 0) | 1310 | if (retval < 0) |
1325 | goto fput_in; | 1311 | goto fput_in; |
1326 | count = retval; | 1312 | if (count > MAX_RW_COUNT) |
1313 | count = MAX_RW_COUNT; | ||
1327 | 1314 | ||
1328 | /* | 1315 | /* |
1329 | * Get output file, and verify that it is ok.. | 1316 | * Get output file, and verify that it is ok.. |
@@ -1341,7 +1328,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); | 1328 | retval = rw_verify_area(WRITE, out.file, &out_pos, count); |
1342 | if (retval < 0) | 1329 | if (retval < 0) |
1343 | goto fput_out; | 1330 | goto fput_out; |
1344 | count = retval; | ||
1345 | 1331 | ||
1346 | if (!max) | 1332 | if (!max) |
1347 | 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); |
@@ -1485,11 +1471,12 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in, | |||
1485 | if (flags != 0) | 1471 | if (flags != 0) |
1486 | return -EINVAL; | 1472 | return -EINVAL; |
1487 | 1473 | ||
1488 | /* copy_file_range allows full ssize_t len, ignoring MAX_RW_COUNT */ | ||
1489 | ret = rw_verify_area(READ, file_in, &pos_in, len); | 1474 | ret = rw_verify_area(READ, file_in, &pos_in, len); |
1490 | if (ret >= 0) | 1475 | if (unlikely(ret)) |
1491 | ret = rw_verify_area(WRITE, file_out, &pos_out, len); | 1476 | return ret; |
1492 | if (ret < 0) | 1477 | |
1478 | ret = rw_verify_area(WRITE, file_out, &pos_out, len); | ||
1479 | if (unlikely(ret)) | ||
1493 | return ret; | 1480 | return ret; |
1494 | 1481 | ||
1495 | if (!(file_in->f_mode & FMODE_READ) || | 1482 | if (!(file_in->f_mode & FMODE_READ) || |