diff options
-rw-r--r-- | sys/compat/svr4/svr4_filio.c | 7 | ||||
-rw-r--r-- | sys/compat/svr4/svr4_misc.c | 11 | ||||
-rw-r--r-- | sys/compat/svr4/svr4_signal.c | 14 | ||||
-rw-r--r-- | sys/compat/svr4/svr4_stream.c | 55 | ||||
-rw-r--r-- | sys/compat/svr4/svr4_sysvec.c | 6 | ||||
-rw-r--r-- | sys/compat/svr4/svr4_util.h | 5 |
6 files changed, 78 insertions, 20 deletions
diff --git a/sys/compat/svr4/svr4_filio.c b/sys/compat/svr4/svr4_filio.c index 3b4467a..79b9bf4 100644 --- a/sys/compat/svr4/svr4_filio.c +++ b/sys/compat/svr4/svr4_filio.c @@ -40,6 +40,8 @@ __FBSDID("$FreeBSD$"); #include <sys/poll.h> #include <sys/malloc.h> #include <sys/mutex.h> +#include <sys/resource.h> +#include <sys/resourcevar.h> #include <sys/sysproto.h> @@ -64,6 +66,11 @@ svr4_sys_poll(td, uap) int idx = 0, cerr; u_long siz; + mtx_assert(&Giant, MA_OWNED); + if (uap->nfds > td->td_proc->p_rlimit[RLIMIT_NOFILE].rlim_cur && + uap->nfds > FD_SETSIZE) + return (EINVAL); + pa.fds = uap->fds; pa.nfds = uap->nfds; pa.timeout = uap->timeout; diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index 4a3b1ed..2bf5df9 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -444,6 +444,9 @@ svr4_sys_getdents(td, uap) u_long *cookiebuf = NULL, *cookie; int ncookies = 0, *retval = td->td_retval; + if (uap->nbytes < 0) + return (EINVAL); + if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) return (error); @@ -1734,6 +1737,7 @@ svr4_sys_resolvepath(td, uap) { struct nameidata nd; int error, *retval = td->td_retval; + unsigned int ncopy; NDINIT(&nd, LOOKUP, NOFOLLOW | SAVENAME, UIO_USERSPACE, uap->path, td); @@ -1741,12 +1745,11 @@ svr4_sys_resolvepath(td, uap) if ((error = namei(&nd)) != 0) return error; - if ((error = copyout(nd.ni_cnd.cn_pnbuf, uap->buf, - uap->bufsiz)) != 0) + ncopy = min(uap->bufsiz, strlen(nd.ni_cnd.cn_pnbuf) + 1); + if ((error = copyout(nd.ni_cnd.cn_pnbuf, uap->buf, ncopy)) != 0) goto bad; - *retval = strlen(nd.ni_cnd.cn_pnbuf) < uap->bufsiz ? - strlen(nd.ni_cnd.cn_pnbuf) + 1 : uap->bufsiz; + *retval = ncopy; bad: NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_vp); diff --git a/sys/compat/svr4/svr4_signal.c b/sys/compat/svr4/svr4_signal.c index f1d2769..dc6af50 100644 --- a/sys/compat/svr4/svr4_signal.c +++ b/sys/compat/svr4/svr4_signal.c @@ -269,6 +269,9 @@ svr4_sys_sigaction(td, uap) struct sigaction *nbsap; int error; + if (uap->signum < 0 || uap->signum >= SVR4_NSIG) + return (EINVAL); + DPRINTF(("@@@ svr4_sys_sigaction(%d, %d, %d)\n", td->td_proc->p_pid, uap->signum, SVR4_SVR42BSD_SIG(uap->signum))); @@ -337,9 +340,14 @@ svr4_sys_signal(td, uap) p = td->td_proc; DPRINTF(("@@@ svr4_sys_signal(%d)\n", p->p_pid)); - signum = SVR4_SVR42BSD_SIG(SVR4_SIGNO(uap->signum)); - if (signum <= 0 || signum > SVR4_NSIG) + signum = SVR4_SIGNO(uap->signum); + if (signum < 0 || signum >= SVR4_NSIG) { + if (SVR4_SIGCALL(uap->signum) == SVR4_SIGNAL_MASK || + SVR4_SIGCALL(uap->signum) == SVR4_SIGDEFER_MASK) + td->td_retval[0] = (int)SVR4_SIG_ERR; return (EINVAL); + } + signum = SVR4_SVR42BSD_SIG(signum); switch (SVR4_SIGCALL(uap->signum)) { case SVR4_SIGDEFER_MASK: @@ -509,6 +517,8 @@ svr4_sys_kill(td, uap) { struct kill_args ka; + if (uap->signum < 0 || uap->signum >= SVR4_NSIG) + return (EINVAL); ka.pid = uap->pid; ka.signum = SVR4_SVR42BSD_SIG(uap->signum); return kill(td, &ka); diff --git a/sys/compat/svr4/svr4_stream.c b/sys/compat/svr4/svr4_stream.c index c9fb65a..6bb4189 100644 --- a/sys/compat/svr4/svr4_stream.c +++ b/sys/compat/svr4/svr4_stream.c @@ -406,22 +406,32 @@ show_ioc(str, ioc) const char *str; struct svr4_strioctl *ioc; { - u_char *ptr = (u_char *) malloc(ioc->len, M_TEMP, M_WAITOK); + u_char *ptr = NULL; + int len; int error; - uprintf("%s cmd = %ld, timeout = %d, len = %d, buf = %p { ", - str, ioc->cmd, ioc->timeout, ioc->len, ioc->buf); + len = ioc->len; + if (len > 1024) + len = 1024; - if ((error = copyin(ioc->buf, ptr, ioc->len)) != 0) { - free((char *) ptr, M_TEMP); - return error; + if (len > 0) { + ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK); + if ((error = copyin(ioc->buf, ptr, len)) != 0) { + free((char *) ptr, M_TEMP); + return error; + } } - bufprint(ptr, ioc->len); + uprintf("%s cmd = %ld, timeout = %d, len = %d, buf = %p { ", + str, ioc->cmd, ioc->timeout, ioc->len, ioc->buf); + + if (ptr != NULL) + bufprint(ptr, len); uprintf("}\n"); - free((char *) ptr, M_TEMP); + if (ptr != NULL) + free((char *) ptr, M_TEMP); return 0; } @@ -435,6 +445,9 @@ show_strbuf(str) int maxlen = str->maxlen; int len = str->len; + if (maxlen > 8192) + maxlen = 8192; + if (maxlen < 0) maxlen = 0; @@ -521,7 +534,8 @@ clean_pipe(td, path) size_t l = strlen(path) + 1; void *tpath; - tpath = stackgap_alloc(&sg, l); + if ((tpath = stackgap_alloc(&sg, l)) == NULL) + return ENAMETOOLONG; la.ub = stackgap_alloc(&sg, sizeof(struct stat)); if ((error = copyout(path, tpath, l)) != 0) @@ -760,6 +774,9 @@ si_listen(fp, fd, ioc, td) if (st == NULL) return EINVAL; + if (ioc->len < 0 || ioc->len > sizeof(lst)) + return EINVAL; + if ((error = copyin(ioc->buf, &lst, ioc->len)) != 0) return error; @@ -961,6 +978,9 @@ ti_getinfo(fp, fd, ioc, td) memset(&info, 0, sizeof(info)); + if (ioc->len < 0 || ioc->len > sizeof(info)) + return EINVAL; + if ((error = copyin(ioc->buf, &info, ioc->len)) != 0) return error; @@ -1009,6 +1029,9 @@ ti_bind(fp, fd, ioc, td) return EINVAL; } + if (ioc->len < 0 || ioc->len > sizeof(bnd)) + return EINVAL; + if ((error = copyin(ioc->buf, &bnd, ioc->len)) != 0) return error; @@ -1137,7 +1160,7 @@ svr4_stream_ti_ioctl(fp, td, retval, fd, cmd, dat) struct sockaddr_in sain; struct sockaddr_un saun; struct svr4_strmcmd sc; - int sasize; + int sasize, oldsasize; caddr_t sg; int *lenp; @@ -1225,11 +1248,16 @@ svr4_stream_ti_ioctl(fp, td, retval, fd, cmd, dat) return error; } + oldsasize = sasize; + if ((error = copyin(lenp, &sasize, sizeof(*lenp))) != 0) { DPRINTF(("ti_ioctl: error copying in socket size\n")); return error; } + if (sasize < 0 || sasize > oldsasize) + return EINVAL; + switch (st->s_family) { case AF_INET: sockaddr_to_netaddr_in(&sc, &sain); @@ -1794,7 +1822,7 @@ svr4_do_putmsg(td, uap, fp) return EINVAL; } - if (ctl.len > sizeof(sc)) { + if (ctl.len < 0 || ctl.len > sizeof(sc)) { DPRINTF(("putmsg: Bad control size %d != %d\n", ctl.len, sizeof(struct svr4_strmcmd))); return EINVAL; @@ -1962,6 +1990,8 @@ svr4_do_getmsg(td, uap, fp) if (uap->ctl != NULL) { if ((error = copyin(uap->ctl, &ctl, sizeof(ctl))) != 0) return error; + if (ctl.len < 0) + return EINVAL; } else { ctl.len = -1; @@ -2147,6 +2177,9 @@ svr4_do_getmsg(td, uap, fp) if (ctl.maxlen > 36 && ctl.len < 36) ctl.len = 36; + if (ctl.len > sizeof(sc)) + ctl.len = sizeof(sc); + if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0) return error; diff --git a/sys/compat/svr4/svr4_sysvec.c b/sys/compat/svr4/svr4_sysvec.c index c488da2..61efd49 100644 --- a/sys/compat/svr4/svr4_sysvec.c +++ b/sys/compat/svr4/svr4_sysvec.c @@ -364,8 +364,10 @@ svr4_emul_find(td, sgp, prefix, path, pbuf, cflag) *pbuf = buf; else { sz = &ptr[len] - buf; - *pbuf = stackgap_alloc(sgp, sz + 1); - error = copyout(buf, *pbuf, sz); + if ((*pbuf = stackgap_alloc(sgp, sz + 1)) != NULL) + error = copyout(buf, *pbuf, sz); + else + error = ENAMETOOLONG; free(buf, M_TEMP); } diff --git a/sys/compat/svr4/svr4_util.h b/sys/compat/svr4/svr4_util.h index 9e5be7f..e0cb54f 100644 --- a/sys/compat/svr4/svr4_util.h +++ b/sys/compat/svr4/svr4_util.h @@ -63,7 +63,10 @@ stackgap_alloc(sgp, sz) size_t sz; { void *p = (void *) *sgp; - *sgp += ALIGN(sz); + sz = ALIGN(sz); + if (*sgp + sz > (caddr_t)(PS_STRINGS - szsigcode)) + return NULL; + *sgp += sz; return p; } |