Module Name: src Committed By: martin Date: Tue Aug 8 16:05:37 UTC 2017
Modified Files: src/sys/compat/svr4 [netbsd-8]: svr4_lwp.c svr4_signal.c svr4_stream.c src/sys/compat/svr4_32 [netbsd-8]: svr4_32_signal.c Log Message: Pull up following revision(s) (requested by spz in ticket #189): sys/compat/svr4/svr4_stream.c: revision 1.89 sys/compat/svr4/svr4_signal.c: revision 1.67 sys/compat/svr4/svr4_stream.c: revision 1.90 sys/compat/svr4/svr4_stream.c: revision 1.91 sys/compat/svr4_32/svr4_32_signal.c: revision 1.29 sys/compat/svr4/svr4_lwp.c: revision 1.20 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.56.1 src/sys/compat/svr4/svr4_lwp.c cvs rdiff -u -r1.66 -r1.66.12.1 src/sys/compat/svr4/svr4_signal.c cvs rdiff -u -r1.88 -r1.88.4.1 src/sys/compat/svr4/svr4_stream.c cvs rdiff -u -r1.28 -r1.28.10.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.56.1 --- src/sys/compat/svr4/svr4_lwp.c:1.19 Mon Nov 23 00:46:07 2009 +++ src/sys/compat/svr4/svr4_lwp.c Tue Aug 8 16:05:37 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.56.1 2017/08/08 16:05:37 martin 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.56.1 2017/08/08 16:05:37 martin 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.66 src/sys/compat/svr4/svr4_signal.c:1.66.12.1 --- src/sys/compat/svr4/svr4_signal.c:1.66 Sun Nov 9 18:16:55 2014 +++ src/sys/compat/svr4/svr4_signal.c Tue Aug 8 16:05:37 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: svr4_signal.c,v 1.66 2014/11/09 18:16:55 maxv Exp $ */ +/* $NetBSD: svr4_signal.c,v 1.66.12.1 2017/08/08 16:05:37 martin 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.66 2014/11/09 18:16:55 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: svr4_signal.c,v 1.66.12.1 2017/08/08 16:05:37 martin 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.88 src/sys/compat/svr4/svr4_stream.c:1.88.4.1 --- src/sys/compat/svr4/svr4_stream.c:1.88 Wed Apr 26 03:02:48 2017 +++ src/sys/compat/svr4/svr4_stream.c Tue Aug 8 16:05:37 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: svr4_stream.c,v 1.88 2017/04/26 03:02:48 riastradh Exp $ */ +/* $NetBSD: svr4_stream.c,v 1.88.4.1 2017/08/08 16:05:37 martin 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.88 2017/04/26 03:02:48 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: svr4_stream.c,v 1.88.4.1 2017/08/08 16:05:37 martin Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -527,11 +527,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)); @@ -717,7 +723,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) @@ -763,7 +771,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) @@ -773,6 +782,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: @@ -782,6 +796,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", @@ -795,6 +812,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') @@ -1412,7 +1432,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; @@ -1421,6 +1442,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: @@ -1464,8 +1492,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]; @@ -1490,10 +1521,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), skp); case SVR4_TI_SENDTO_REQUEST: /* sendto */ KERNEL_UNLOCK_ONE(NULL); + fd_putfile(SCARG(uap, fd)); msg.msg_name = skp; msg.msg_namelen = skp->sa_len; msg.msg_iov = &aiov; @@ -1723,8 +1756,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.28 src/sys/compat/svr4_32/svr4_32_signal.c:1.28.10.1 --- src/sys/compat/svr4_32/svr4_32_signal.c:1.28 Mon Apr 4 23:07:06 2016 +++ src/sys/compat/svr4_32/svr4_32_signal.c Tue Aug 8 16:05:37 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: svr4_32_signal.c,v 1.28 2016/04/04 23:07:06 christos Exp $ */ +/* $NetBSD: svr4_32_signal.c,v 1.28.10.1 2017/08/08 16:05:37 martin 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.28 2016/04/04 23:07:06 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: svr4_32_signal.c,v 1.28.10.1 2017/08/08 16:05:37 martin 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); }