diff options
| author | martin <martin@NetBSD.org> | 2022-08-03 11:05:51 +0000 |
|---|---|---|
| committer | martin <martin@NetBSD.org> | 2022-08-03 11:05:51 +0000 |
| commit | 8644187dad7b54af091a9162382bb0b561d53fbc (patch) | |
| tree | 7824b9316c32c8a81784ba35c21556b1de23b735 | |
| parent | 6fe4a01f01d3fb44a5a91090b4d150a3bd1b326a (diff) | |
Pull up following revision(s), all via patch
(requested by riastradh in ticket #1489):
sys/compat/netbsd32/netbsd32_netbsd.c: revision 1.232
sys/compat/netbsd32/netbsd32_socket.c: revision 1.56
sys/compat/netbsd32/netbsd32_conv.h: revision 1.45
sys/compat/netbsd32/netbsd32_fs.c: revision 1.92
sys/compat/netbsd32/netbsd32.h: revision 1.137
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.
| -rw-r--r-- | sys/compat/netbsd32/netbsd32.h | 7 | ||||
| -rw-r--r-- | sys/compat/netbsd32/netbsd32_conv.h | 21 | ||||
| -rw-r--r-- | sys/compat/netbsd32/netbsd32_fs.c | 10 | ||||
| -rw-r--r-- | sys/compat/netbsd32/netbsd32_netbsd.c | 16 | ||||
| -rw-r--r-- | sys/compat/netbsd32/netbsd32_socket.c | 10 |
5 files changed, 51 insertions, 13 deletions
diff --git a/sys/compat/netbsd32/netbsd32.h b/sys/compat/netbsd32/netbsd32.h index 926293d768d..5ac71fd5812 100644 --- a/sys/compat/netbsd32/netbsd32.h +++ b/sys/compat/netbsd32/netbsd32.h @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32.h,v 1.123.4.2 2022/04/24 16:39:00 martin Exp $ */ +/* $NetBSD: netbsd32.h,v 1.123.4.3 2022/08/03 11:05:51 martin Exp $ */ /* * Copyright (c) 1998, 2001, 2008, 2015 Matthew R. Green @@ -57,7 +57,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; @@ -72,6 +72,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 */ /* diff --git a/sys/compat/netbsd32/netbsd32_conv.h b/sys/compat/netbsd32/netbsd32_conv.h index af07787f5f8..56df25aadc0 100644 --- a/sys/compat/netbsd32/netbsd32_conv.h +++ b/sys/compat/netbsd32/netbsd32_conv.h @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_conv.h,v 1.38 2019/02/21 03:37:19 mrg Exp $ */ +/* $NetBSD: netbsd32_conv.h,v 1.38.4.1 2022/08/03 11:05:51 martin Exp $ */ /* * Copyright (c) 1998, 2001 Matthew R. Green @@ -245,14 +245,16 @@ netbsd32_to_iovecin(const struct netbsd32_iovec *iov32p, struct iovec *iovp, int len) { int i, error=0; - u_int32_t iov_base; - u_int32_t iov_len; + uint32_t iov_base; + 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 netbsd32_iovec *iov32p, struct iovec *iovp, 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 --git a/sys/compat/netbsd32/netbsd32_fs.c b/sys/compat/netbsd32/netbsd32_fs.c index c0a97123176..49ede7e0534 100644 --- a/sys/compat/netbsd32/netbsd32_fs.c +++ b/sys/compat/netbsd32/netbsd32_fs.c @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_fs.c,v 1.82.4.2 2022/04/24 16:39:00 martin Exp $ */ +/* $NetBSD: netbsd32_fs.c,v 1.82.4.3 2022/08/03 11:05:51 martin 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.82.4.2 2022/04/24 16:39:00 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.82.4.3 2022/08/03 11:05:51 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -176,7 +176,8 @@ dofilereadv32(int fd, struct file *fp, struct netbsd32_iovec *iovp, int iovcnt, * 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; } @@ -280,7 +281,8 @@ dofilewritev32(int fd, struct file *fp, struct netbsd32_iovec *iovp, int iovcnt, * 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 --git a/sys/compat/netbsd32/netbsd32_netbsd.c b/sys/compat/netbsd32/netbsd32_netbsd.c index 092f56e605d..c84d7d3f7f7 100644 --- a/sys/compat/netbsd32/netbsd32_netbsd.c +++ b/sys/compat/netbsd32/netbsd32_netbsd.c @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_netbsd.c,v 1.228 2019/06/20 03:31:54 kamil Exp $ */ +/* $NetBSD: netbsd32_netbsd.c,v 1.228.2.1 2022/08/03 11:05:51 martin 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.228 2019/06/20 03:31:54 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.228.2.1 2022/08/03 11:05:51 martin Exp $"); /* * below are all the standard NetBSD system calls, in the 32bit @@ -184,6 +184,9 @@ netbsd32_read(struct lwp *l, const struct netbsd32_read_args *uap, register_t *r } */ 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); @@ -200,6 +203,9 @@ netbsd32_write(struct lwp *l, const struct netbsd32_write_args *uap, register_t } */ 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); @@ -1183,6 +1189,9 @@ netbsd32_pread(struct lwp *l, const struct netbsd32_pread_args *uap, register_t } */ 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); @@ -1204,6 +1213,9 @@ netbsd32_pwrite(struct lwp *l, const struct netbsd32_pwrite_args *uap, register_ } */ 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 --git a/sys/compat/netbsd32/netbsd32_socket.c b/sys/compat/netbsd32/netbsd32_socket.c index 6bb472a45e1..cae27646a1d 100644 --- a/sys/compat/netbsd32/netbsd32_socket.c +++ b/sys/compat/netbsd32/netbsd32_socket.c @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_socket.c,v 1.49 2018/11/14 17:51:37 hannken Exp $ */ +/* $NetBSD: netbsd32_socket.c,v 1.49.4.1 2022/08/03 11:05:51 martin 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.49 2018/11/14 17:51:37 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_socket.c,v 1.49.4.1 2022/08/03 11:05:51 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -635,6 +635,9 @@ netbsd32_recvfrom(struct lwp *l, const struct netbsd32_recvfrom_args *uap, 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; @@ -669,6 +672,9 @@ netbsd32_sendto(struct lwp *l, const struct netbsd32_sendto_args *uap, 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; |
