summaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2017-04-08 18:18:48 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2017-04-17 12:52:26 -0400
commitf50298556436ef0f32257b8ea19b112f9028b0a5 (patch)
tree32c3e7022475150ad1cbfb87f9d29c23f446ee05 /fs/compat.c
parent2b8910264a7fec4599b620e5206eb877a207f40a (diff)
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.c76
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 @@
54#include <asm/ioctls.h> 54#include <asm/ioctls.h>
55#include "internal.h" 55#include "internal.h"
56 56
57/* A write operation does a read from user space and vice versa */
58#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
59
60ssize_t compat_rw_copy_check_uvector(int type,
61 const struct compat_iovec __user *uvector, unsigned long nr_segs,
62 unsigned long fast_segs, struct iovec *fast_pointer,
63 struct iovec **ret_pointer)
64{
65 compat_ssize_t tot_len;
66 struct iovec *iov = *ret_pointer = fast_pointer;
67 ssize_t ret = 0;
68 int seg;
69
70 /*
71 * SuS says "The readv() function *may* fail if the iovcnt argument
72 * was less than or equal to 0, or greater than {IOV_MAX}. Linux has
73 * traditionally returned zero for zero segments, so...
74 */
75 if (nr_segs == 0)
76 goto out;
77
78 ret = -EINVAL;
79 if (nr_segs > UIO_MAXIOV)
80 goto out;
81 if (nr_segs > fast_segs) {
82 ret = -ENOMEM;
83 iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL);
84 if (iov == NULL)
85 goto out;
86 }
87 *ret_pointer = iov;
88
89 ret = -EFAULT;
90 if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
91 goto out;
92
93 /*
94 * Single unix specification:
95 * We should -EINVAL if an element length is not >= 0 and fitting an
96 * ssize_t.
97 *
98 * In Linux, the total length is limited to MAX_RW_COUNT, there is
99 * no overflow possibility.
100 */
101 tot_len = 0;
102 ret = -EINVAL;
103 for (seg = 0; seg < nr_segs; seg++) {
104 compat_uptr_t buf;
105 compat_ssize_t len;
106
107 if (__get_user(len, &uvector->iov_len) ||
108 __get_user(buf, &uvector->iov_base)) {
109 ret = -EFAULT;
110 goto out;
111 }
112 if (len < 0) /* size_t not fitting in compat_ssize_t .. */
113 goto out;
114 if (type >= 0 &&
115 !access_ok(vrfy_dir(type), compat_ptr(buf), len)) {
116 ret = -EFAULT;
117 goto out;
118 }
119 if (len > MAX_RW_COUNT - tot_len)
120 len = MAX_RW_COUNT - tot_len;
121 tot_len += len;
122 iov->iov_base = compat_ptr(buf);
123 iov->iov_len = (compat_size_t) len;
124 uvector++;
125 iov++;
126 }
127 ret = tot_len;
128
129out:
130 return ret;
131}
132
133struct compat_ncp_mount_data { 57struct compat_ncp_mount_data {
134 compat_int_t version; 58 compat_int_t version;
135 compat_uint_t ncp_fd; 59 compat_uint_t ncp_fd;