|
@@ -35,10 +35,9 @@
|
|
|
* in any case.
|
|
|
*/
|
|
|
|
|
|
-long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
|
|
|
+int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
|
|
|
{
|
|
|
- int size, ct;
|
|
|
- long err;
|
|
|
+ int size, ct, err;
|
|
|
|
|
|
if (m->msg_namelen) {
|
|
|
if (mode == VERIFY_READ) {
|
|
@@ -62,14 +61,13 @@ long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address,
|
|
|
err = 0;
|
|
|
|
|
|
for (ct = 0; ct < m->msg_iovlen; ct++) {
|
|
|
- err += iov[ct].iov_len;
|
|
|
- /*
|
|
|
- * Goal is not to verify user data, but to prevent returning
|
|
|
- * negative value, which is interpreted as errno.
|
|
|
- * Overflow is still possible, but it is harmless.
|
|
|
- */
|
|
|
- if (err < 0)
|
|
|
- return -EMSGSIZE;
|
|
|
+ size_t len = iov[ct].iov_len;
|
|
|
+
|
|
|
+ if (len > INT_MAX - err) {
|
|
|
+ len = INT_MAX - err;
|
|
|
+ iov[ct].iov_len = len;
|
|
|
+ }
|
|
|
+ err += len;
|
|
|
}
|
|
|
|
|
|
return err;
|