diff options
author | green <green@FreeBSD.org> | 1999-10-14 05:37:52 +0000 |
---|---|---|
committer | green <green@FreeBSD.org> | 1999-10-14 05:37:52 +0000 |
commit | b5080e1313db57b3ff6521e897b5338d7533367d (patch) | |
tree | 7f7118b577e4903d6b34998437bb07c30d3a43bf /sys/kern/sys_generic.c | |
parent | e8104eadd50cf65dc2f77a7ab173f5a737a4cba5 (diff) | |
download | FreeBSD-src-b5080e1313db57b3ff6521e897b5338d7533367d.zip FreeBSD-src-b5080e1313db57b3ff6521e897b5338d7533367d.tar.gz |
Fix a race condition with shared fd tables and writev(). It's
still not safe to consider file table sharing secure.
Submitted by: Ville-Pertti Keinonen <will@iki.fi>
Diffstat (limited to 'sys/kern/sys_generic.c')
-rw-r--r-- | sys/kern/sys_generic.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 8eb0efe..88c7d7f 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -405,11 +405,15 @@ writev(p, uap) if ((fp = getfp(fdp, uap->fd, FWRITE)) == NULL) return (EBADF); + fhold(fp); /* note: can't use iovlen until iovcnt is validated */ iovlen = uap->iovcnt * sizeof (struct iovec); if (uap->iovcnt > UIO_SMALLIOV) { - if (uap->iovcnt > UIO_MAXIOV) - return (EINVAL); + if (uap->iovcnt > UIO_MAXIOV) { + needfree = NULL; + error = EINVAL; + goto done; + } MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); needfree = iov; } else { @@ -461,6 +465,7 @@ writev(p, uap) #endif p->p_retval[0] = cnt; done: + fdrop(fp); if (needfree) FREE(needfree, M_IOV); return (error); |