diff options
Diffstat (limited to 'net/core/iovec.c')
-rw-r--r-- | net/core/iovec.c | 26 |
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 | ||
38 | long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) | 38 | int 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; |