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 e6b133b77ccb..58eb9999f89d 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) { |
@@ -60,14 +59,13 @@ long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, | |||
60 | err = 0; | 59 | err = 0; |
61 | 60 | ||
62 | for (ct = 0; ct < m->msg_iovlen; ct++) { | 61 | for (ct = 0; ct < m->msg_iovlen; ct++) { |
63 | err += iov[ct].iov_len; | 62 | size_t len = iov[ct].iov_len; |
64 | /* | 63 | |
65 | * Goal is not to verify user data, but to prevent returning | 64 | if (len > INT_MAX - err) { |
66 | * negative value, which is interpreted as errno. | 65 | len = INT_MAX - err; |
67 | * Overflow is still possible, but it is harmless. | 66 | iov[ct].iov_len = len; |
68 | */ | 67 | } |
69 | if (err < 0) | 68 | err += len; |
70 | return -EMSGSIZE; | ||
71 | } | 69 | } |
72 | 70 | ||
73 | return err; | 71 | return err; |