Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fs: move permission hook out of do_iter_read()

We recently moved fsnotify hook, rw_verify_area() and other checks from
do_iter_write() out to its two callers.

for consistency, do the same thing for do_iter_read() - move the
rw_verify_area() checks and fsnotify hook to the callers vfs_iter_read()
and vfs_readv().

This aligns those vfs helpers with the pattern used in vfs_read() and
vfs_iocb_iter_read() and the vfs write helpers, where all the checks are
in the vfs helpers and the do_* or call_* helpers do the work.

This is needed for fanotify "pre content" events.

Suggested-by: Jan Kara <jack@suse.cz>
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Link: https://lore.kernel.org/r/20231122122715.2561213-13-amir73il@gmail.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Amir Goldstein and committed by
Christian Brauner
b8e1425b 1c8aa833

+49 -37
+49 -37
fs/read_write.c
··· 773 773 return ret; 774 774 } 775 775 776 - static ssize_t do_iter_read(struct file *file, struct iov_iter *iter, 777 - loff_t *pos, rwf_t flags) 778 - { 779 - size_t tot_len; 780 - ssize_t ret = 0; 781 - 782 - if (!(file->f_mode & FMODE_READ)) 783 - return -EBADF; 784 - if (!(file->f_mode & FMODE_CAN_READ)) 785 - return -EINVAL; 786 - 787 - tot_len = iov_iter_count(iter); 788 - if (!tot_len) 789 - goto out; 790 - ret = rw_verify_area(READ, file, pos, tot_len); 791 - if (ret < 0) 792 - return ret; 793 - 794 - if (file->f_op->read_iter) 795 - ret = do_iter_readv_writev(file, iter, pos, READ, flags); 796 - else 797 - ret = do_loop_readv_writev(file, iter, pos, READ, flags); 798 - out: 799 - if (ret >= 0) 800 - fsnotify_access(file); 801 - return ret; 802 - } 803 - 804 776 ssize_t vfs_iocb_iter_read(struct file *file, struct kiocb *iocb, 805 777 struct iov_iter *iter) 806 778 { ··· 802 830 EXPORT_SYMBOL(vfs_iocb_iter_read); 803 831 804 832 ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos, 805 - rwf_t flags) 833 + rwf_t flags) 806 834 { 835 + size_t tot_len; 836 + ssize_t ret = 0; 837 + 807 838 if (!file->f_op->read_iter) 808 839 return -EINVAL; 809 - return do_iter_read(file, iter, ppos, flags); 840 + if (!(file->f_mode & FMODE_READ)) 841 + return -EBADF; 842 + if (!(file->f_mode & FMODE_CAN_READ)) 843 + return -EINVAL; 844 + 845 + tot_len = iov_iter_count(iter); 846 + if (!tot_len) 847 + goto out; 848 + ret = rw_verify_area(READ, file, ppos, tot_len); 849 + if (ret < 0) 850 + return ret; 851 + 852 + ret = do_iter_readv_writev(file, iter, ppos, READ, flags); 853 + out: 854 + if (ret >= 0) 855 + fsnotify_access(file); 856 + return ret; 810 857 } 811 858 EXPORT_SYMBOL(vfs_iter_read); 812 859 ··· 889 898 EXPORT_SYMBOL(vfs_iter_write); 890 899 891 900 static ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, 892 - unsigned long vlen, loff_t *pos, rwf_t flags) 901 + unsigned long vlen, loff_t *pos, rwf_t flags) 893 902 { 894 903 struct iovec iovstack[UIO_FASTIOV]; 895 904 struct iovec *iov = iovstack; 896 905 struct iov_iter iter; 897 - ssize_t ret; 906 + size_t tot_len; 907 + ssize_t ret = 0; 898 908 899 - ret = import_iovec(ITER_DEST, vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter); 900 - if (ret >= 0) { 901 - ret = do_iter_read(file, &iter, pos, flags); 902 - kfree(iov); 903 - } 909 + if (!(file->f_mode & FMODE_READ)) 910 + return -EBADF; 911 + if (!(file->f_mode & FMODE_CAN_READ)) 912 + return -EINVAL; 904 913 914 + ret = import_iovec(ITER_DEST, vec, vlen, ARRAY_SIZE(iovstack), &iov, 915 + &iter); 916 + if (ret < 0) 917 + return ret; 918 + 919 + tot_len = iov_iter_count(&iter); 920 + if (!tot_len) 921 + goto out; 922 + 923 + ret = rw_verify_area(READ, file, pos, tot_len); 924 + if (ret < 0) 925 + goto out; 926 + 927 + if (file->f_op->read_iter) 928 + ret = do_iter_readv_writev(file, &iter, pos, READ, flags); 929 + else 930 + ret = do_loop_readv_writev(file, &iter, pos, READ, flags); 931 + out: 932 + if (ret >= 0) 933 + fsnotify_access(file); 934 + kfree(iov); 905 935 return ret; 906 936 } 907 937