Sat Aug 19 03:40:48 2017 UTC ()
Pull up following revision(s) (requested by mrg in ticket #1479):
sys/compat/svr4/svr4_lwp.c: 1.20
sys/compat/svr4/svr4_signal.c: 1.67
sys/compat/svr4/svr4_stream.c: 1.89-1.91 via patch
sys/compat/svr4_32/svr4_32_signal.c: 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.
(snj)
diff -r1.19 -r1.19.32.1 src/sys/compat/svr4/svr4_lwp.c
diff -r1.65 -r1.65.24.1 src/sys/compat/svr4/svr4_signal.c
diff -r1.79 -r1.79.22.1 src/sys/compat/svr4/svr4_stream.c
diff -r1.26 -r1.26.56.1 src/sys/compat/svr4_32/svr4_32_signal.c
--- src/sys/compat/svr4/Attic/svr4_lwp.c 2009/11/23 00:46:07 1.19
+++ src/sys/compat/svr4/Attic/svr4_lwp.c 2017/08/19 03:40:48 1.19.32.1
@@ -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.32.1 2017/08/19 03:40:48 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.32.1 2017/08/19 03:40:48 snj Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -107,6 +107,8 @@
{
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);
--- src/sys/compat/svr4/Attic/svr4_signal.c 2011/02/03 21:45:31 1.65
+++ src/sys/compat/svr4/Attic/svr4_signal.c 2017/08/19 03:40:48 1.65.24.1
@@ -1,4 +1,4 @@
-/* $NetBSD: svr4_signal.c,v 1.65 2011/02/03 21:45:31 joerg Exp $ */
+/* $NetBSD: svr4_signal.c,v 1.65.24.1 2017/08/19 03:40:48 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 2011/02/03 21:45:31 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: svr4_signal.c,v 1.65.24.1 2017/08/19 03:40:48 snj Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -73,6 +73,21 @@
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)
{
@@ -174,6 +189,7 @@
} */
struct svr4_sigaction nssa, ossa;
struct sigaction nbsa, obsa;
+ int native_signo;
int error;
if (SCARG(uap, nsa)) {
@@ -182,7 +198,12 @@
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)
@@ -217,16 +238,18 @@
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;
@@ -236,7 +259,7 @@
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;
@@ -245,7 +268,7 @@
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);
@@ -253,7 +276,7 @@
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);
@@ -263,11 +286,11 @@
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:
@@ -393,9 +416,15 @@
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);
}
--- src/sys/compat/svr4/Attic/svr4_stream.c 2011/06/26 16:42:41 1.79
+++ src/sys/compat/svr4/Attic/svr4_stream.c 2017/08/19 03:40:48 1.79.22.1
@@ -1,4 +1,4 @@
-/* $NetBSD: svr4_stream.c,v 1.79 2011/06/26 16:42:41 christos Exp $ */
+/* $NetBSD: svr4_stream.c,v 1.79.22.1 2017/08/19 03:40:48 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.79 2011/06/26 16:42:41 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: svr4_stream.c,v 1.79.22.1 2017/08/19 03:40:48 snj Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -526,11 +526,17 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
*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 @@
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;
@@ -1736,8 +1769,16 @@
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;
--- src/sys/compat/svr4_32/Attic/svr4_32_signal.c 2008/04/28 20:23:46 1.26
+++ src/sys/compat/svr4_32/Attic/svr4_32_signal.c 2017/08/19 03:40:48 1.26.56.1
@@ -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.56.1 2017/08/19 03:40:48 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.56.1 2017/08/19 03:40:48 snj Exp $");
#if defined(_KERNEL_OPT)
#include "opt_compat_svr4.h"
@@ -208,6 +208,21 @@
};
#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 @@
} */
struct svr4_32_sigaction nssa, ossa;
struct sigaction nbsa, obsa;
+ int native_signo;
int error;
if (SCARG_P32(uap, nsa)) {
@@ -319,8 +335,12 @@
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 @@
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 @@
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);
}