summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/compat/svr4/svr4_filio.c7
-rw-r--r--sys/compat/svr4/svr4_misc.c11
-rw-r--r--sys/compat/svr4/svr4_signal.c14
-rw-r--r--sys/compat/svr4/svr4_stream.c55
-rw-r--r--sys/compat/svr4/svr4_sysvec.c6
-rw-r--r--sys/compat/svr4/svr4_util.h5
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;
}
OpenPOWER on IntegriCloud