aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/iovec.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/iovec.c')
-rw-r--r--net/core/iovec.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/net/core/iovec.c b/net/core/iovec.c
index e6b133b77ccb..c40f27e7d208 100644
--- a/net/core/iovec.c
+++ b/net/core/iovec.c
@@ -35,14 +35,15 @@
35 * in any case. 35 * in any case.
36 */ 36 */
37 37
38long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) 38int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
39{ 39{
40 int size, ct; 40 int size, ct, err;
41 long err;
42 41
43 if (m->msg_namelen) { 42 if (m->msg_namelen) {
44 if (mode == VERIFY_READ) { 43 if (mode == VERIFY_READ) {
45 err = move_addr_to_kernel(m->msg_name, m->msg_namelen, 44 void __user *namep;
45 namep = (void __user __force *) m->msg_name;
46 err = move_addr_to_kernel(namep, m->msg_namelen,
46 address); 47 address);
47 if (err < 0) 48 if (err < 0)
48 return err; 49 return err;
@@ -53,21 +54,20 @@ long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address,
53 } 54 }
54 55
55 size = m->msg_iovlen * sizeof(struct iovec); 56 size = m->msg_iovlen * sizeof(struct iovec);
56 if (copy_from_user(iov, m->msg_iov, size)) 57 if (copy_from_user(iov, (void __user __force *) m->msg_iov, size))
57 return -EFAULT; 58 return -EFAULT;
58 59
59 m->msg_iov = iov; 60 m->msg_iov = iov;
60 err = 0; 61 err = 0;
61 62
62 for (ct = 0; ct < m->msg_iovlen; ct++) { 63 for (ct = 0; ct < m->msg_iovlen; ct++) {
63 err += iov[ct].iov_len; 64 size_t len = iov[ct].iov_len;
64 /* 65
65 * Goal is not to verify user data, but to prevent returning 66 if (len > INT_MAX - err) {
66 * negative value, which is interpreted as errno. 67 len = INT_MAX - err;
67 * Overflow is still possible, but it is harmless. 68 iov[ct].iov_len = len;
68 */ 69 }
69 if (err < 0) 70 err += len;
70 return -EMSGSIZE;
71 } 71 }
72 72
73 return err; 73 return err;