summaryrefslogtreecommitdiffstats
path: root/sys/i386/ibcs2/ibcs2_misc.c
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2003-10-12 04:25:26 +0000
committertjr <tjr@FreeBSD.org>2003-10-12 04:25:26 +0000
commitb952d3fda36bfd8f96a2152c63ce386caab79def (patch)
tree2cbe2e22e1145e6680f02fd0c9c0f0bf6b4004d9 /sys/i386/ibcs2/ibcs2_misc.c
parentfef194d740bdc3a139dcc3c56e8cfd55261dc308 (diff)
downloadFreeBSD-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.c24
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 *));
OpenPOWER on IntegriCloud