Module Name:    src
Committed By:   simonb
Date:           Tue Jan 19 03:41:22 UTC 2021

Modified Files:
        src/sys/compat/netbsd32: netbsd32.h netbsd32_conv.h netbsd32_fs.c
            netbsd32_netbsd.c netbsd32_socket.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.136 -r1.137 src/sys/compat/netbsd32/netbsd32.h
cvs rdiff -u -r1.44 -r1.45 src/sys/compat/netbsd32/netbsd32_conv.h
cvs rdiff -u -r1.91 -r1.92 src/sys/compat/netbsd32/netbsd32_fs.c
cvs rdiff -u -r1.231 -r1.232 src/sys/compat/netbsd32/netbsd32_netbsd.c
cvs rdiff -u -r1.55 -r1.56 src/sys/compat/netbsd32/netbsd32_socket.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/compat/netbsd32/netbsd32.h
diff -u src/sys/compat/netbsd32/netbsd32.h:1.136 src/sys/compat/netbsd32/netbsd32.h:1.137
--- src/sys/compat/netbsd32/netbsd32.h:1.136	Mon Jan 18 23:14:22 2021
+++ src/sys/compat/netbsd32/netbsd32.h	Tue Jan 19 03:41:22 2021
@@ -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_key_t;
 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 */
 
 /*

Index: src/sys/compat/netbsd32/netbsd32_conv.h
diff -u src/sys/compat/netbsd32/netbsd32_conv.h:1.44 src/sys/compat/netbsd32/netbsd32_conv.h:1.45
--- src/sys/compat/netbsd32/netbsd32_conv.h:1.44	Tue Jan 19 03:20:13 2021
+++ src/sys/compat/netbsd32/netbsd32_conv.h	Tue Jan 19 03:41:22 2021
@@ -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 @@ netbsd32_to_iovecin(const struct netbsd3
 {
 	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 @@ netbsd32_to_iovecin(const struct netbsd3
 		    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;
 }

Index: src/sys/compat/netbsd32/netbsd32_fs.c
diff -u src/sys/compat/netbsd32/netbsd32_fs.c:1.91 src/sys/compat/netbsd32/netbsd32_fs.c:1.92
--- src/sys/compat/netbsd32/netbsd32_fs.c:1.91	Tue Jan 19 03:20:13 2021
+++ src/sys/compat/netbsd32/netbsd32_fs.c	Tue Jan 19 03:41:22 2021
@@ -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 @@ dofilereadv32(int fd, struct file *fp, s
 		 * 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 @@ dofilewritev32(int fd, struct file *fp, 
 		 * 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;
 		}

Index: src/sys/compat/netbsd32/netbsd32_netbsd.c
diff -u src/sys/compat/netbsd32/netbsd32_netbsd.c:1.231 src/sys/compat/netbsd32/netbsd32_netbsd.c:1.232
--- src/sys/compat/netbsd32/netbsd32_netbsd.c:1.231	Fri Jan 15 03:51:41 2021
+++ src/sys/compat/netbsd32/netbsd32_netbsd.c	Tue Jan 19 03:41:22 2021
@@ -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 @@ netbsd32_read(struct lwp *l, const struc
 	} */
 	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 @@ netbsd32_write(struct lwp *l, const stru
 	} */
 	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 @@ netbsd32_pread(struct lwp *l, const stru
 	} */
 	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 @@ netbsd32_pwrite(struct lwp *l, const str
 	} */
 	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);

Index: src/sys/compat/netbsd32/netbsd32_socket.c
diff -u src/sys/compat/netbsd32/netbsd32_socket.c:1.55 src/sys/compat/netbsd32/netbsd32_socket.c:1.56
--- src/sys/compat/netbsd32/netbsd32_socket.c:1.55	Tue Jan 19 03:20:13 2021
+++ src/sys/compat/netbsd32/netbsd32_socket.c	Tue Jan 19 03:41:22 2021
@@ -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 @@ netbsd32_recvfrom(struct lwp *l, const s
 	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 @@ netbsd32_sendto(struct lwp *l, const str
 	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;

Reply via email to