diff options
Diffstat (limited to 'net/core/iovec.c')
-rw-r--r-- | net/core/iovec.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/net/core/iovec.c b/net/core/iovec.c index 72aceb1fe4fa..c40f27e7d208 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c | |||
@@ -35,10 +35,9 @@ | |||
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) { |
@@ -62,14 +61,13 @@ long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, | |||
62 | err = 0; | 61 | err = 0; |
63 | 62 | ||
64 | for (ct = 0; ct < m->msg_iovlen; ct++) { | 63 | for (ct = 0; ct < m->msg_iovlen; ct++) { |
65 | err += iov[ct].iov_len; | 64 | size_t len = iov[ct].iov_len; |
66 | /* | 65 | |
67 | * Goal is not to verify user data, but to prevent returning | 66 | if (len > INT_MAX - err) { |
68 | * negative value, which is interpreted as errno. | 67 | len = INT_MAX - err; |
69 | * Overflow is still possible, but it is harmless. | 68 | iov[ct].iov_len = len; |
70 | */ | 69 | } |
71 | if (err < 0) | 70 | err += len; |
72 | return -EMSGSIZE; | ||
73 | } | 71 | } |
74 | 72 | ||
75 | return err; | 73 | return err; |