diff options
author | tjr <tjr@FreeBSD.org> | 2003-10-12 04:25:26 +0000 |
---|---|---|
committer | tjr <tjr@FreeBSD.org> | 2003-10-12 04:25:26 +0000 |
commit | b952d3fda36bfd8f96a2152c63ce386caab79def (patch) | |
tree | 2cbe2e22e1145e6680f02fd0c9c0f0bf6b4004d9 /sys/i386/ibcs2/ibcs2_misc.c | |
parent | fef194d740bdc3a139dcc3c56e8cfd55261dc308 (diff) | |
download | FreeBSD-src-b952d3fda36bfd8f96a2152c63ce386caab79def.zip FreeBSD-src-b952d3fda36bfd8f96a2152c63ce386caab79def.tar.gz |
Fix a multitude of security bugs in the iBCS2 emulator:
- Return NULL instead of returning memory outside of the stackgap
in stackgap_alloc() (FreeBSD-SA-00:42.linux)
- Check for stackgap_alloc() returning NULL in ibcs2_emul_find();
other calls to stackgap_alloc() have not been changed since they
are small fixed-size allocations.
- Replace use of strcpy() with strlcpy() in exec_coff_imgact()
to avoid buffer overflow
- Use strlcat() instead of strcat() to avoid a one byte buffer
overflow in ibcs2_setipdomainname()
- Use copyinstr() instead of copyin() in ibcs2_setipdomainname()
to ensure that the string is null-terminated
- Avoid integer overflow in ibcs2_setgroups() and ibcs2_setgroups()
by checking that gidsetsize argument is non-negative and
no larger than NGROUPS_MAX.
- Range-check signal numbers in ibcs2_wait(), ibcs2_sigaction(),
ibcs2_sigsys() and ibcs2_kill() to avoid accessing array past
the end (or before the start)
Diffstat (limited to 'sys/i386/ibcs2/ibcs2_misc.c')
-rw-r--r-- | sys/i386/ibcs2/ibcs2_misc.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c index 8cd3488..2f8a37f 100644 --- a/sys/i386/ibcs2/ibcs2_misc.c +++ b/sys/i386/ibcs2/ibcs2_misc.c @@ -170,12 +170,24 @@ ibcs2_wait(td, uap) if(error) return error; - /* convert status/signal result */ - if(WIFSTOPPED(status)) + /* + * Convert status/signal result. We must validate the + * signal number stored in the exit status in case + * the user changed it between wait4()'s copyout() + * and our copyin(). + */ + if (WIFSTOPPED(status)) { + if (WSTOPSIG(status) <= 0 || + WSTOPSIG(status) > IBCS2_SIGTBLSZ) + return (EINVAL); status = IBCS2_STOPCODE(bsd_to_ibcs2_sig[_SIG_IDX(WSTOPSIG(status))]); - else if(WIFSIGNALED(status)) + } else if (WIFSIGNALED(status)) { + if (WTERMSIG(status) <= 0 || + WTERMSIG(status) > IBCS2_SIGTBLSZ) + return (EINVAL); status = bsd_to_ibcs2_sig[_SIG_IDX(WTERMSIG(status))]; + } /* else exit status -- identical */ /* record result/status */ @@ -647,6 +659,10 @@ ibcs2_getgroups(td, uap) gid_t *gp; caddr_t sg = stackgap_init(); + if (uap->gidsetsize < 0) + return (EINVAL); + if (uap->gidsetsize > NGROUPS_MAX) + uap->gidsetsize = NGROUPS_MAX; sa.gidsetsize = uap->gidsetsize; if (uap->gidsetsize) { sa.gidset = stackgap_alloc(&sg, NGROUPS_MAX * @@ -679,6 +695,8 @@ ibcs2_setgroups(td, uap) gid_t *gp; caddr_t sg = stackgap_init(); + if (uap->gidsetsize < 0 || uap->gidsetsize > NGROUPS_MAX) + return (EINVAL); sa.gidsetsize = uap->gidsetsize; sa.gidset = stackgap_alloc(&sg, sa.gidsetsize * sizeof(gid_t *)); |