diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-04-09 00:18:48 +0200 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-04-17 18:52:26 +0200 |
commit | f50298556436ef0f32257b8ea19b112f9028b0a5 (patch) | |
tree | 32c3e7022475150ad1cbfb87f9d29c23f446ee05 /fs/compat.c | |
parent | fhandle: move compat syscalls from compat.c (diff) | |
download | linux-f50298556436ef0f32257b8ea19b112f9028b0a5.tar.xz linux-f50298556436ef0f32257b8ea19b112f9028b0a5.zip |
move compat_rw_copy_check_uvector() over to fs/read_write.c
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/compat.c')
-rw-r--r-- | fs/compat.c | 76 |
1 files changed, 0 insertions, 76 deletions
diff --git a/fs/compat.c b/fs/compat.c index 3e94559c452e..ca2f3ca5dacd 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -54,82 +54,6 @@ #include <asm/ioctls.h> #include "internal.h" -/* A write operation does a read from user space and vice versa */ -#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) - -ssize_t compat_rw_copy_check_uvector(int type, - const struct compat_iovec __user *uvector, unsigned long nr_segs, - unsigned long fast_segs, struct iovec *fast_pointer, - struct iovec **ret_pointer) -{ - compat_ssize_t tot_len; - struct iovec *iov = *ret_pointer = fast_pointer; - ssize_t ret = 0; - int seg; - - /* - * SuS says "The readv() function *may* fail if the iovcnt argument - * was less than or equal to 0, or greater than {IOV_MAX}. Linux has - * traditionally returned zero for zero segments, so... - */ - if (nr_segs == 0) - goto out; - - ret = -EINVAL; - if (nr_segs > UIO_MAXIOV) - goto out; - if (nr_segs > fast_segs) { - ret = -ENOMEM; - iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL); - if (iov == NULL) - goto out; - } - *ret_pointer = iov; - - ret = -EFAULT; - if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector))) - goto out; - - /* - * Single unix specification: - * We should -EINVAL if an element length is not >= 0 and fitting an - * ssize_t. - * - * In Linux, the total length is limited to MAX_RW_COUNT, there is - * no overflow possibility. - */ - tot_len = 0; - ret = -EINVAL; - for (seg = 0; seg < nr_segs; seg++) { - compat_uptr_t buf; - compat_ssize_t len; - - if (__get_user(len, &uvector->iov_len) || - __get_user(buf, &uvector->iov_base)) { - ret = -EFAULT; - goto out; - } - if (len < 0) /* size_t not fitting in compat_ssize_t .. */ - goto out; - if (type >= 0 && - !access_ok(vrfy_dir(type), compat_ptr(buf), len)) { - ret = -EFAULT; - goto out; - } - if (len > MAX_RW_COUNT - tot_len) - len = MAX_RW_COUNT - tot_len; - tot_len += len; - iov->iov_base = compat_ptr(buf); - iov->iov_len = (compat_size_t) len; - uvector++; - iov++; - } - ret = tot_len; - -out: - return ret; -} - struct compat_ncp_mount_data { compat_int_t version; compat_uint_t ncp_fd; |