Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/compat/netbsd32 The read/write/send/recv system calls re...



details:   https://anonhg.NetBSD.org/src/rev/36c95595545b
branches:  trunk
changeset: 950177:36c95595545b
user:      simonb <simonb%NetBSD.org@localhost>
date:      Tue Jan 19 03:41:22 2021 +0000

description:
The read/write/send/recv system calls return ssize_t because -1 is
returned on error.  Therefore we must restrict the lengths of any
buffers to NETBSD32_SSIZE_MAX with compat32 to avoid garbage return
values.

Fixes ATF lib/libc/sys/t_write:write_err.

diffstat:

 sys/compat/netbsd32/netbsd32.h        |   7 +++++--
 sys/compat/netbsd32/netbsd32_conv.h   |  19 +++++++++++++++++--
 sys/compat/netbsd32/netbsd32_fs.c     |  10 ++++++----
 sys/compat/netbsd32/netbsd32_netbsd.c |  16 ++++++++++++++--
 sys/compat/netbsd32/netbsd32_socket.c |  10 ++++++++--
 5 files changed, 50 insertions(+), 12 deletions(-)

diffs (208 lines):

diff -r 0bf00e80a521 -r 36c95595545b sys/compat/netbsd32/netbsd32.h
--- a/sys/compat/netbsd32/netbsd32.h    Tue Jan 19 03:25:50 2021 +0000
+++ b/sys/compat/netbsd32/netbsd32.h    Tue Jan 19 03:41:22 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd32.h,v 1.136 2021/01/18 23:14:22 simonb Exp $    */
+/*     $NetBSD: netbsd32.h,v 1.137 2021/01/19 03:41:22 simonb Exp $    */
 
 /*
  * Copyright (c) 1998, 2001, 2008, 2015 Matthew R. Green
@@ -58,7 +58,7 @@
 #include <nfs/rpcv2.h>
 
 /*
- * first, define the basic types we need.
+ * first define the basic types we need, and any applicable limits.
  */
 
 typedef int32_t netbsd32_long;
@@ -73,6 +73,9 @@
 typedef int32_t netbsd32_intptr_t;
 typedef uint32_t netbsd32_uintptr_t;
 
+/* Note: 32-bit sparc defines ssize_t as long but still has same size as int. */
+#define        NETBSD32_SSIZE_MAX      INT32_MAX
+
 /* netbsd32_[u]int64 are machine dependent and defined below */
 
 /*
diff -r 0bf00e80a521 -r 36c95595545b sys/compat/netbsd32/netbsd32_conv.h
--- a/sys/compat/netbsd32/netbsd32_conv.h       Tue Jan 19 03:25:50 2021 +0000
+++ b/sys/compat/netbsd32/netbsd32_conv.h       Tue Jan 19 03:41:22 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd32_conv.h,v 1.44 2021/01/19 03:20:13 simonb Exp $        */
+/*     $NetBSD: netbsd32_conv.h,v 1.45 2021/01/19 03:41:22 simonb Exp $        */
 
 /*
  * Copyright (c) 1998, 2001 Matthew R. Green
@@ -246,13 +246,15 @@
 {
        int i, error=0;
        uint32_t iov_base;
-       uint32_t iov_len;
+       uint32_t iov_len, total_iov_len;
+
        /*
         * We could allocate an iov32p, do a copyin, and translate
         * each field and then free it all up, or we could copyin
         * each field separately.  I'm doing the latter to reduce
         * the number of MALLOC()s.
         */
+       total_iov_len = 0;
        for (i = 0; i < len; i++, iovp++, iov32p++) {
                if ((error = copyin(&iov32p->iov_base, &iov_base, sizeof(iov_base))))
                    return error;
@@ -260,6 +262,19 @@
                    return error;
                iovp->iov_base = (void *)(u_long)iov_base;
                iovp->iov_len = (size_t)iov_len;
+
+               /*
+                * System calls return ssize_t because -1 is returned
+                * on error.  Therefore we must restrict the length to
+                * SSIZE_MAX (NETBSD32_SSIZE_MAX with compat32) to
+                * avoid garbage return values.
+                */
+               total_iov_len += iov_len;
+               if (iov_len > NETBSD32_SSIZE_MAX ||
+                   total_iov_len > NETBSD32_SSIZE_MAX) {
+                       return EINVAL;
+                       break;
+               }
        }
        return error;
 }
diff -r 0bf00e80a521 -r 36c95595545b sys/compat/netbsd32/netbsd32_fs.c
--- a/sys/compat/netbsd32/netbsd32_fs.c Tue Jan 19 03:25:50 2021 +0000
+++ b/sys/compat/netbsd32/netbsd32_fs.c Tue Jan 19 03:41:22 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd32_fs.c,v 1.91 2021/01/19 03:20:13 simonb Exp $  */
+/*     $NetBSD: netbsd32_fs.c,v 1.92 2021/01/19 03:41:22 simonb Exp $  */
 
 /*
  * Copyright (c) 1998, 2001 Matthew R. Green
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.91 2021/01/19 03:20:13 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.92 2021/01/19 03:41:22 simonb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -176,7 +176,8 @@
                 * Therefore we must restrict the length to SSIZE_MAX to
                 * avoid garbage return values.
                 */
-               if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
+               if (iov->iov_len > NETBSD32_SSIZE_MAX ||
+                   auio.uio_resid > NETBSD32_SSIZE_MAX) {
                        error = EINVAL;
                        goto done;
                }
@@ -281,7 +282,8 @@
                 * Therefore we must restrict the length to SSIZE_MAX to
                 * avoid garbage return values.
                 */
-               if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
+               if (iov->iov_len > NETBSD32_SSIZE_MAX ||
+                   auio.uio_resid > NETBSD32_SSIZE_MAX) {
                        error = EINVAL;
                        goto done;
                }
diff -r 0bf00e80a521 -r 36c95595545b sys/compat/netbsd32/netbsd32_netbsd.c
--- a/sys/compat/netbsd32/netbsd32_netbsd.c     Tue Jan 19 03:25:50 2021 +0000
+++ b/sys/compat/netbsd32/netbsd32_netbsd.c     Tue Jan 19 03:41:22 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd32_netbsd.c,v 1.231 2021/01/15 03:51:41 simonb Exp $     */
+/*     $NetBSD: netbsd32_netbsd.c,v 1.232 2021/01/19 03:41:22 simonb Exp $     */
 
 /*
  * Copyright (c) 1998, 2001, 2008, 2018 Matthew R. Green
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.231 2021/01/15 03:51:41 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.232 2021/01/19 03:41:22 simonb Exp $");
 
 /*
  * below are all the standard NetBSD system calls, in the 32bit
@@ -182,6 +182,9 @@
        } */
        struct sys_read_args ua;
 
+       if (SCARG(uap, nbyte) > NETBSD32_SSIZE_MAX)
+               return EINVAL;
+
        NETBSD32TO64_UAP(fd);
        NETBSD32TOP_UAP(buf, void *);
        NETBSD32TOX_UAP(nbyte, size_t);
@@ -198,6 +201,9 @@
        } */
        struct sys_write_args ua;
 
+       if (SCARG(uap, nbyte) > NETBSD32_SSIZE_MAX)
+               return EINVAL;
+
        NETBSD32TO64_UAP(fd);
        NETBSD32TOP_UAP(buf, void *);
        NETBSD32TOX_UAP(nbyte, size_t);
@@ -1181,6 +1187,9 @@
        } */
        struct sys_pread_args ua;
 
+       if (SCARG(uap, nbyte) > NETBSD32_SSIZE_MAX)
+               return EINVAL;
+
        NETBSD32TO64_UAP(fd);
        NETBSD32TOP_UAP(buf, void);
        NETBSD32TOX_UAP(nbyte, size_t);
@@ -1202,6 +1211,9 @@
        } */
        struct sys_pwrite_args ua;
 
+       if (SCARG(uap, nbyte) > NETBSD32_SSIZE_MAX)
+               return EINVAL;
+
        NETBSD32TO64_UAP(fd);
        NETBSD32TOP_UAP(buf, void);
        NETBSD32TOX_UAP(nbyte, size_t);
diff -r 0bf00e80a521 -r 36c95595545b sys/compat/netbsd32/netbsd32_socket.c
--- a/sys/compat/netbsd32/netbsd32_socket.c     Tue Jan 19 03:25:50 2021 +0000
+++ b/sys/compat/netbsd32/netbsd32_socket.c     Tue Jan 19 03:41:22 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd32_socket.c,v 1.55 2021/01/19 03:20:13 simonb Exp $      */
+/*     $NetBSD: netbsd32_socket.c,v 1.56 2021/01/19 03:41:22 simonb Exp $      */
 
 /*
  * Copyright (c) 1998, 2001 Matthew R. Green
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_socket.c,v 1.55 2021/01/19 03:20:13 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_socket.c,v 1.56 2021/01/19 03:41:22 simonb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -637,6 +637,9 @@
        int             error;
        struct mbuf     *from;
 
+       if (SCARG(uap, len) > NETBSD32_SSIZE_MAX)
+               return EINVAL;
+
        msg.msg_name = NULL;
        msg.msg_iov = &aiov;
        msg.msg_iovlen = 1;
@@ -671,6 +674,9 @@
        struct msghdr msg;
        struct iovec aiov;
 
+       if (SCARG(uap, len) > NETBSD32_SSIZE_MAX)
+               return EINVAL;
+
        msg.msg_name = SCARG_P32(uap, to); /* XXX kills const */
        msg.msg_namelen = SCARG(uap, tolen);
        msg.msg_iov = &aiov;



Home | Main Index | Thread Index | Old Index