lib: Introduce iov_buflen
authorVolker Lendecke <vl@samba.org>
Sun, 2 Mar 2014 17:34:53 +0000 (18:34 +0100)
committerJeremy Allison <jra@samba.org>
Wed, 23 Apr 2014 20:33:08 +0000 (22:33 +0200)
.. with overflow protection

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/include/proto.h
source3/lib/util_sock.c

index c8548829770e92924cbe1bade5be03f816f1cb53..983a4d009480e9728758d279e3793445ff382b1d 100644 (file)
@@ -583,6 +583,7 @@ NTSTATUS read_fd_with_timeout(int fd, char *buf,
                                  size_t *size_ret);
 NTSTATUS read_data(int fd, char *buffer, size_t N);
 ssize_t write_data(int fd, const char *buffer, size_t N);
+ssize_t iov_buflen(const struct iovec *iov, int iovlen);
 ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt);
 bool send_keepalive(int client);
 NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf,
index 12e4ccdccefef67aefede4ec791c65aa8faaabc7..b8149cad83845ae54590e98ecad0c21edf85ce3c 100644 (file)
@@ -201,6 +201,24 @@ NTSTATUS read_data(int fd, char *buffer, size_t N)
        return read_fd_with_timeout(fd, buffer, N, N, 0, NULL);
 }
 
+ssize_t iov_buflen(const struct iovec *iov, int iovcnt)
+{
+       size_t buflen = 0;
+       int i;
+
+       for (i=0; i<iovcnt; i++) {
+               size_t thislen = iov[i].iov_len;
+               size_t tmp = buflen + thislen;
+
+               if ((tmp < buflen) || (tmp < thislen)) {
+                       /* overflow */
+                       return -1;
+               }
+               buflen = tmp;
+       }
+       return buflen;
+}
+
 /****************************************************************************
  Write all data from an iov array
  NB. This can be called with a non-socket fd, don't add dependencies
@@ -209,15 +227,15 @@ NTSTATUS read_data(int fd, char *buffer, size_t N)
 
 ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
 {
-       int i;
-       size_t to_send;
+       ssize_t to_send;
        ssize_t thistime;
        size_t sent;
        struct iovec *iov_copy, *iov;
 
-       to_send = 0;
-       for (i=0; i<iovcnt; i++) {
-               to_send += orig_iov[i].iov_len;
+       to_send = iov_buflen(orig_iov, iovcnt);
+       if (to_send == -1) {
+               errno = EINVAL;
+               return -1;
        }
 
        thistime = sys_writev(fd, orig_iov, iovcnt);