Module Name:    src
Committed By:   snj
Date:           Sat Aug 12 03:59:55 UTC 2017

Modified Files:
        src/sys/compat/svr4 [netbsd-7-1]: svr4_lwp.c svr4_signal.c
            svr4_stream.c
        src/sys/compat/svr4_32 [netbsd-7-1]: svr4_32_signal.c

Log Message:
Pull up following revision(s) (requested by mrg in ticket #1475):
        sys/compat/svr4/svr4_lwp.c: revision 1.20
        sys/compat/svr4/svr4_signal.c: revision 1.67
        sys/compat/svr4/svr4_stream.c: revision 1.89-1.91 via patch
        sys/compat/svr4_32/svr4_32_signal.c: revision 1.29
Fix some of the multitudinous holes in svr4 streams.
We should never have enabled this by default; it is a minefield.
>From Ilja Van Sprundel.
--
Zero stack data before copyout.
>From Ilja Van Sprundel.
--
Fix indexing of svr4 signals.
>From Ilja Van Sprundel.
--
Feebly attempt to get this reference counting less bad.
This svr4 streams code is bad and it should feel bad.
>From Ilja Van Sprundel.
--
Check bounds in svr4_sys_putmsg.  Check more svr4_strmcmd bounds.
svr4 streams code is still a disaster.
>From Ilja Van Sprundel.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.19.50.1 src/sys/compat/svr4/svr4_lwp.c
cvs rdiff -u -r1.65.30.1 -r1.65.30.1.6.1 src/sys/compat/svr4/svr4_signal.c
cvs rdiff -u -r1.80 -r1.80.8.1 src/sys/compat/svr4/svr4_stream.c
cvs rdiff -u -r1.26 -r1.26.70.1 src/sys/compat/svr4_32/svr4_32_signal.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/svr4/svr4_lwp.c
diff -u src/sys/compat/svr4/svr4_lwp.c:1.19 src/sys/compat/svr4/svr4_lwp.c:1.19.50.1
--- src/sys/compat/svr4/svr4_lwp.c:1.19	Mon Nov 23 00:46:07 2009
+++ src/sys/compat/svr4/svr4_lwp.c	Sat Aug 12 03:59:55 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: svr4_lwp.c,v 1.19 2009/11/23 00:46:07 rmind Exp $	*/
+/*	$NetBSD: svr4_lwp.c,v 1.19.50.1 2017/08/12 03:59:55 snj Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: svr4_lwp.c,v 1.19 2009/11/23 00:46:07 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: svr4_lwp.c,v 1.19.50.1 2017/08/12 03:59:55 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -108,6 +108,8 @@ svr4_sys__lwp_info(struct lwp *l, const 
 	struct svr4_lwpinfo lwpinfo;
 	int error;
 
+	memset(&lwpinfo, 0, sizeof(lwpinfo));
+
 	/* XXX NJWLWP */
 	TIMEVAL_TO_TIMESPEC(&l->l_proc->p_stats->p_ru.ru_stime, &lwpinfo.lwp_stime);
 	TIMEVAL_TO_TIMESPEC(&l->l_proc->p_stats->p_ru.ru_utime, &lwpinfo.lwp_utime);

Index: src/sys/compat/svr4/svr4_signal.c
diff -u src/sys/compat/svr4/svr4_signal.c:1.65.30.1 src/sys/compat/svr4/svr4_signal.c:1.65.30.1.6.1
--- src/sys/compat/svr4/svr4_signal.c:1.65.30.1	Sat Jan 17 12:10:53 2015
+++ src/sys/compat/svr4/svr4_signal.c	Sat Aug 12 03:59:55 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: svr4_signal.c,v 1.65.30.1 2015/01/17 12:10:53 martin Exp $	 */
+/*	$NetBSD: svr4_signal.c,v 1.65.30.1.6.1 2017/08/12 03:59:55 snj Exp $	 */
 
 /*-
  * Copyright (c) 1994, 1998 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: svr4_signal.c,v 1.65.30.1 2015/01/17 12:10:53 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: svr4_signal.c,v 1.65.30.1.6.1 2017/08/12 03:59:55 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -72,6 +72,21 @@ void native_to_svr4_sigaction(const stru
 extern const int native_to_svr4_signo[];
 extern const int svr4_to_native_signo[];
 
+static int
+svr4_decode_signum(int signum, int *native_signo, int *sigcall)
+{
+
+	if (SVR4_SIGNO(signum) >= SVR4_NSIG)
+		return EINVAL;
+
+	if (native_signo)
+		*native_signo = svr4_to_native_signo[SVR4_SIGNO(signum)];
+	if (sigcall)
+		*sigcall = SVR4_SIGCALL(signum);
+
+	return 0;
+}
+
 static inline void
 svr4_sigfillset(svr4_sigset_t *s)
 {
@@ -173,6 +188,7 @@ svr4_sys_sigaction(struct lwp *l, const 
 	} */
 	struct svr4_sigaction nssa, ossa;
 	struct sigaction nbsa, obsa;
+	int native_signo;
 	int error;
 
 	if (SCARG(uap, nsa)) {
@@ -181,7 +197,12 @@ svr4_sys_sigaction(struct lwp *l, const 
 			return (error);
 		svr4_to_native_sigaction(&nssa, &nbsa);
 	}
-	error = sigaction1(l, svr4_to_native_signo[SVR4_SIGNO(SCARG(uap, signum))],
+
+	error = svr4_decode_signum(SCARG(uap, signum), &native_signo, NULL);
+	if (error)
+		return error;
+
+	error = sigaction1(l, native_signo,
 	    SCARG(uap, nsa) ? &nbsa : 0, SCARG(uap, osa) ? &obsa : 0,
 	    NULL, 0);
 	if (error)
@@ -216,16 +237,18 @@ svr4_sys_signal(struct lwp *l, const str
 		syscallarg(int) signum;
 		syscallarg(svr4_sig_t) handler;
 	} */
-	int signum = svr4_to_native_signo[SVR4_SIGNO(SCARG(uap, signum))];
+	int native_signo, sigcall;
 	struct proc *p = l->l_proc;
 	struct sigaction nbsa, obsa;
 	sigset_t ss;
 	int error;
 
-	if (signum <= 0 || signum >= SVR4_NSIG)
-		return (EINVAL);
+	error = svr4_decode_signum(SCARG(uap, signum), &native_signo,
+	    &sigcall);
+	if (error)
+		return error;
 
-	switch (SVR4_SIGCALL(SCARG(uap, signum))) {
+	switch (sigcall) {
 	case SVR4_SIGDEFER_MASK:
 		if (SCARG(uap, handler) == SVR4_SIG_HOLD)
 			goto sighold;
@@ -235,7 +258,7 @@ svr4_sys_signal(struct lwp *l, const str
 		nbsa.sa_handler = (sig_t)SCARG(uap, handler);
 		sigemptyset(&nbsa.sa_mask);
 		nbsa.sa_flags = 0;
-		error = sigaction1(l, signum, &nbsa, &obsa, NULL, 0);
+		error = sigaction1(l, native_signo, &nbsa, &obsa, NULL, 0);
 		if (error)
 			return (error);
 		*retval = (u_int)(u_long)obsa.sa_handler;
@@ -244,7 +267,7 @@ svr4_sys_signal(struct lwp *l, const str
 	case SVR4_SIGHOLD_MASK:
 	sighold:
 		sigemptyset(&ss);
-		sigaddset(&ss, signum);
+		sigaddset(&ss, native_signo);
 		mutex_enter(p->p_lock);
 		error = sigprocmask1(l, SIG_BLOCK, &ss, 0);
 		mutex_exit(p->p_lock);
@@ -252,7 +275,7 @@ svr4_sys_signal(struct lwp *l, const str
 
 	case SVR4_SIGRELSE_MASK:
 		sigemptyset(&ss);
-		sigaddset(&ss, signum);
+		sigaddset(&ss, native_signo);
 		mutex_enter(p->p_lock);
 		error = sigprocmask1(l, SIG_UNBLOCK, &ss, 0);
 		mutex_exit(p->p_lock);
@@ -262,11 +285,11 @@ svr4_sys_signal(struct lwp *l, const str
 		nbsa.sa_handler = SIG_IGN;
 		sigemptyset(&nbsa.sa_mask);
 		nbsa.sa_flags = 0;
-		return (sigaction1(l, signum, &nbsa, 0, NULL, 0));
+		return (sigaction1(l, native_signo, &nbsa, 0, NULL, 0));
 
 	case SVR4_SIGPAUSE_MASK:
 		ss = l->l_sigmask;	/* XXXAD locking */
-		sigdelset(&ss, signum);
+		sigdelset(&ss, native_signo);
 		return (sigsuspend1(l, &ss));
 
 	default:
@@ -392,9 +415,15 @@ svr4_sys_kill(struct lwp *l, const struc
 		syscallarg(int) signum;
 	} */
 	struct sys_kill_args ka;
+	int native_signo;
+	int error;
+
+	error = svr4_decode_signum(SCARG(uap, signum), &native_signo, NULL);
+	if (error)
+		return error;
 
 	SCARG(&ka, pid) = SCARG(uap, pid);
-	SCARG(&ka, signum) = svr4_to_native_signo[SVR4_SIGNO(SCARG(uap, signum))];
+	SCARG(&ka, signum) = native_signo;
 	return sys_kill(l, &ka, retval);
 }
 

Index: src/sys/compat/svr4/svr4_stream.c
diff -u src/sys/compat/svr4/svr4_stream.c:1.80 src/sys/compat/svr4/svr4_stream.c:1.80.8.1
--- src/sys/compat/svr4/svr4_stream.c:1.80	Wed Jul  9 04:54:03 2014
+++ src/sys/compat/svr4/svr4_stream.c	Sat Aug 12 03:59:55 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: svr4_stream.c,v 1.80 2014/07/09 04:54:03 rtr Exp $	 */
+/*	$NetBSD: svr4_stream.c,v 1.80.8.1 2017/08/12 03:59:55 snj Exp $	 */
 
 /*-
  * Copyright (c) 1994, 2008 The NetBSD Foundation, Inc.
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: svr4_stream.c,v 1.80 2014/07/09 04:54:03 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: svr4_stream.c,v 1.80.8.1 2017/08/12 03:59:55 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -526,11 +526,17 @@ si_listen(file_t *fp, int fd, struct svr
 	if (st == NULL)
 		return EINVAL;
 
-	if (ioc->len > sizeof(lst))
+	if (ioc->len < offsetof(struct svr4_strmcmd, pad) ||
+	    ioc->len > sizeof(lst))
 		return EINVAL;
 
 	if ((error = copyin(NETBSD32PTR(ioc->buf), &lst, ioc->len)) != 0)
 		return error;
+	if (lst.offs < 0 ||
+	    lst.len < 0 ||
+	    lst.len > ioc->len ||
+	    ioc->len - lst.len < lst.offs)
+		return EINVAL;
 
 	if (lst.cmd != SVR4_TI_OLD_BIND_REQUEST) {
 		DPRINTF(("si_listen: bad request %ld\n", lst.cmd));
@@ -716,7 +722,9 @@ ti_getinfo(file_t *fp, int fd, struct sv
 
 	memset(&info, 0, sizeof(info));
 
-	if (ioc->len > sizeof(info))
+	/* tsdu is next after cmd, the only field we read */
+	if (ioc->len < offsetof(struct svr4_infocmd, tsdu) ||
+	    ioc->len > sizeof(info))
 		return EINVAL;
 
 	if ((error = copyin(NETBSD32PTR(ioc->buf), &info, ioc->len)) != 0)
@@ -762,7 +770,8 @@ ti_bind(file_t *fp, int fd, struct svr4_
 		return EINVAL;
 	}
 
-	if (ioc->len > sizeof(bnd))
+	if (ioc->len < offsetof(struct svr4_strmcmd, pad) ||
+	    ioc->len > sizeof(bnd))
 		return EINVAL;
 
 	if ((error = copyin(NETBSD32PTR(ioc->buf), &bnd, ioc->len)) != 0)
@@ -772,6 +781,11 @@ ti_bind(file_t *fp, int fd, struct svr4_
 		DPRINTF(("ti_bind: bad request %ld\n", bnd.cmd));
 		return EINVAL;
 	}
+	if (bnd.offs < 0 ||
+	    bnd.len < 0 ||
+	    bnd.len > ioc->len ||
+	    ioc->len - bnd.len < bnd.offs)
+		return EINVAL;
 
 	switch (st->s_family) {
 	case AF_INET:
@@ -781,6 +795,9 @@ ti_bind(file_t *fp, int fd, struct svr4_
 		if (bnd.offs == 0)
 			goto reply;
 
+		if (ioc->len < sizeof(struct svr4_netaddr_in) ||
+		    bnd.offs > ioc->len - sizeof(struct svr4_netaddr_in))
+			return EINVAL;
 		netaddr_to_sockaddr_in(&sain, &bnd);
 
 		DPRINTF(("TI_BIND: fam %d, port %d, addr %x\n",
@@ -794,6 +811,9 @@ ti_bind(file_t *fp, int fd, struct svr4_
 		if (bnd.offs == 0)
 			goto reply;
 
+		if (ioc->len < sizeof(struct svr4_netaddr_un) ||
+		    bnd.offs > ioc->len - sizeof(struct svr4_netaddr_un))
+			return EINVAL;
 		netaddr_to_sockaddr_un(&saun, &bnd);
 
 		if (saun.sun_path[0] == '\0')
@@ -1420,7 +1440,8 @@ svr4_sys_putmsg(struct lwp *l, const str
 		goto out;
 	}
 
-	if (ctl.len > sizeof(sc)) {
+	if (ctl.len < offsetof(struct svr4_strmcmd, pad) ||
+	    ctl.len > sizeof(sc)) {
 		DPRINTF(("putmsg: Bad control size %ld != %d\n",
 		    (unsigned long)sizeof(struct svr4_strmcmd), ctl.len));
 		error = EINVAL;
@@ -1429,6 +1450,13 @@ svr4_sys_putmsg(struct lwp *l, const str
 
 	if ((error = copyin(NETBSD32PTR(ctl.buf), &sc, ctl.len)) != 0)
 		goto out;
+	if (sc.offs < 0 ||
+	    sc.len < 0 ||
+	    sc.len > ctl.len ||
+	    sc.offs > ctl.len - sc.len) {
+		error = EINVAL;
+		goto out;
+	}
 
 	switch (st->s_family) {
 	case AF_INET:
@@ -1473,8 +1501,11 @@ svr4_sys_putmsg(struct lwp *l, const str
 			*retval = 0;
 			error = 0;
 			goto out;
-		}
-		else {
+		} else if (sc.len < sizeof(dev_t[2])) {
+			*retval = 0;
+			error = EINVAL;
+			goto out;
+		} else {
 			/* Maybe we've been given a device/inode pair */
 			dev_t *dev = SVR4_ADDROF(&sc);
 			svr4_ino_t *ino = (svr4_ino_t *) &dev[1];
@@ -1502,10 +1533,12 @@ svr4_sys_putmsg(struct lwp *l, const str
  	switch (st->s_cmd = sc.cmd) {
 	case SVR4_TI_CONNECT_REQUEST:	/* connect 	*/
 	 	KERNEL_UNLOCK_ONE(NULL);
+		fd_putfile(SCARG(uap, fd));
 		return do_sys_connect(l, SCARG(uap, fd), nam);
 
 	case SVR4_TI_SENDTO_REQUEST:	/* sendto 	*/
 	 	KERNEL_UNLOCK_ONE(NULL);
+		fd_putfile(SCARG(uap, fd));
 		msg.msg_name = nam;
 		msg.msg_namelen = sasize;
 		msg.msg_iov = &aiov;
@@ -1735,8 +1768,16 @@ svr4_sys_getmsg(struct lwp *l, const str
 		if (ctl.len > sizeof(sc))
 			ctl.len = sizeof(sc);
 
+		if (ctl.len < offsetof(struct svr4_strmcmd, pad)) {
+			error = EINVAL;
+			goto out;
+		}
 		if ((error = copyin(NETBSD32PTR(ctl.buf), &sc, ctl.len)) != 0)
 			goto out;
+		if (sc.offs < 0) {
+			error = EINVAL;
+			goto out;
+		}
 
 		msg.msg_name = NULL;
 		msg.msg_namelen = 0;

Index: src/sys/compat/svr4_32/svr4_32_signal.c
diff -u src/sys/compat/svr4_32/svr4_32_signal.c:1.26 src/sys/compat/svr4_32/svr4_32_signal.c:1.26.70.1
--- src/sys/compat/svr4_32/svr4_32_signal.c:1.26	Mon Apr 28 20:23:46 2008
+++ src/sys/compat/svr4_32/svr4_32_signal.c	Sat Aug 12 03:59:55 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: svr4_32_signal.c,v 1.26 2008/04/28 20:23:46 martin Exp $	 */
+/*	$NetBSD: svr4_32_signal.c,v 1.26.70.1 2017/08/12 03:59:55 snj Exp $	 */
 
 /*-
  * Copyright (c) 1994, 1998 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: svr4_32_signal.c,v 1.26 2008/04/28 20:23:46 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: svr4_32_signal.c,v 1.26.70.1 2017/08/12 03:59:55 snj Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_svr4.h"
@@ -208,6 +208,21 @@ const int svr4_to_native_signo[SVR4_NSIG
 };
 #endif
 
+static int
+svr4_32_decode_signum(int signum, int *native_signo, int *sigcall)
+{
+
+	if (SVR4_SIGNO(signum) >= SVR4_NSIG)
+		return EINVAL;
+
+	if (native_signo)
+		*native_signo = svr4_to_native_signo[SVR4_SIGNO(signum)];
+	if (sigcall)
+		*sigcall = SVR4_SIGCALL(signum);
+
+	return 0;
+}
+
 static inline void
 svr4_32_sigfillset(svr4_32_sigset_t *s)
 {
@@ -310,6 +325,7 @@ svr4_32_sys_sigaction(struct lwp *l, con
 	} */
 	struct svr4_32_sigaction nssa, ossa;
 	struct sigaction nbsa, obsa;
+	int native_signo;
 	int error;
 
 	if (SCARG_P32(uap, nsa)) {
@@ -319,8 +335,12 @@ svr4_32_sys_sigaction(struct lwp *l, con
 			return (error);
 		svr4_32_to_native_sigaction(&nssa, &nbsa);
 	}
-	error = sigaction1(l,
-			   svr4_to_native_signo[SVR4_SIGNO(SCARG(uap, signum))],
+
+	error = svr4_32_decode_signum(SCARG(uap, signum), &native_signo, NULL);
+	if (error)
+		return error;
+
+	error = sigaction1(l, native_signo,
 	    SCARG_P32(uap, nsa) ? &nbsa : 0, SCARG_P32(uap, osa) ? &obsa : 0,
 	    NULL, 0);
 	if (error)
@@ -357,15 +377,17 @@ svr4_32_sys_signal(struct lwp *l, const 
 		syscallarg(svr4_32_sig_t) handler;
 	} */
 	struct proc *p = l->l_proc;
-	int signum = svr4_to_native_signo[SVR4_SIGNO(SCARG(uap, signum))];
+	int native_signo, sigcall;
 	struct sigaction nbsa, obsa;
 	sigset_t ss;
 	int error;
 
-	if (signum <= 0 || signum >= SVR4_NSIG)
-		return (EINVAL);
+	error = svr4_32_decode_signum(SCARG(uap, signum), &native_signo,
+	    &sigcall);
+	if (error)
+		return error;
 
-	switch (SVR4_SIGCALL(SCARG(uap, signum))) {
+	switch (sigcall) {
 	case SVR4_SIGDEFER_MASK:
 		if (SCARG(uap, handler) == SVR4_SIG_HOLD)
 			goto sighold;
@@ -536,9 +558,15 @@ svr4_32_sys_kill(struct lwp *l, const st
 		syscallarg(int) signum;
 	} */
 	struct sys_kill_args ka;
+	int native_signo;
+	int error;
+
+	error = svr4_32_decode_signum(SCARG(uap, signum), &native_signo, NULL);
+	if (error)
+		return error;
 
 	SCARG(&ka, pid) = SCARG(uap, pid);
-	SCARG(&ka, signum) = svr4_to_native_signo[SVR4_SIGNO(SCARG(uap, signum))];
+	SCARG(&ka, signum) = native_signo;
 	return sys_kill(l, &ka, retval);
 }
 

Reply via email to