From ab7f9b938f8f0008fe71e8c790afb7f86a267e1c Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Fri, 30 Aug 2002 15:47:10 +0000 Subject: * miscfuncs.cc (check_iovec_for_read): Don't check buffer when zero length iov_len. (check_iovec_for_write): Ditto. * fhandler.h (fhandler_base::readv): New method. (fhandler_base::writev): Ditto. * fhandler.cc (fhandler_base::readv): New method. (fhandler_base::writev): Ditto. * syscalls.cc (_read): Delegate to readv(2). (_write): Ditto, mutatis mutandi. (readv): Rewrite, based on the old _read code, to use the new fhandler_base::readv method. Improve access mode handling and ensure all calls reach the final strace statement. (writev): Ditto, mutatis mutandi. * include/sys/uio.h (struct iovec): Change field types to match SUSv3. * winsup.h (check_iovec_for_read): New function. (check_iovec_for_write): Ditto. * miscfuncs.cc (check_iovec_for_read): Ditto. (check_iovec_for_write): Ditto. --- winsup/cygwin/miscfuncs.cc | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'winsup/cygwin/miscfuncs.cc') diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index 0849da51c..a6fec0ddc 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -11,6 +11,9 @@ details. */ #include "winsup.h" #include "cygerrno.h" #include +#include +#include +#include #include #include @@ -179,6 +182,76 @@ __check_invalid_read_ptr_errno (const void *s, unsigned sz) return set_errno (EFAULT); } +ssize_t +check_iovec_for_read (const struct iovec *iov, int iovcnt) +{ + if (iovcnt <= 0 || iovcnt > IOV_MAX) + { + set_errno (EINVAL); + return -1; + } + + if (__check_invalid_read_ptr_errno (iov, iovcnt * sizeof (*iov))) + return -1; + + size_t tot = 0; + + while (iovcnt != 0) + { + if (iov->iov_len > SSIZE_MAX || (tot += iov->iov_len) > SSIZE_MAX) + { + set_errno (EINVAL); + return -1; + } + + if (iov->iov_len + && __check_null_invalid_struct_errno (iov->iov_base, iov->iov_len)) + return -1; + + iov += 1; + iovcnt -= 1; + } + + assert (tot <= SSIZE_MAX); + + return (ssize_t) tot; +} + +ssize_t +check_iovec_for_write (const struct iovec *iov, int iovcnt) +{ + if (iovcnt <= 0 || iovcnt > IOV_MAX) + { + set_errno (EINVAL); + return -1; + } + + if (__check_invalid_read_ptr_errno (iov, iovcnt * sizeof (*iov))) + return -1; + + size_t tot = 0; + + while (iovcnt != 0) + { + if (iov->iov_len > SSIZE_MAX || (tot += iov->iov_len) > SSIZE_MAX) + { + set_errno (EINVAL); + return -1; + } + + if (iov->iov_len + && __check_invalid_read_ptr_errno (iov->iov_base, iov->iov_len)) + return -1; + + iov += 1; + iovcnt -= 1; + } + + assert (tot <= SSIZE_MAX); + + return (ssize_t) tot; +} + UINT get_cp () { -- cgit v1.2.3