Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2002-08-30 19:47:10 +0400
committerChristopher Faylor <me@cgf.cx>2002-08-30 19:47:10 +0400
commitab7f9b938f8f0008fe71e8c790afb7f86a267e1c (patch)
treef8149696d46c25222099b0d51dab157e891e3037 /winsup/cygwin/miscfuncs.cc
parent70c306d781b881d7142d2d99f481b0aace248270 (diff)
* 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.
Diffstat (limited to 'winsup/cygwin/miscfuncs.cc')
-rw-r--r--winsup/cygwin/miscfuncs.cc73
1 files changed, 73 insertions, 0 deletions
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 <sys/errno.h>
+#include <sys/uio.h>
+#include <assert.h>
+#include <limits.h>
#include <winbase.h>
#include <winnls.h>
@@ -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 ()
{