summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_descrip.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2002-07-17 02:48:43 +0000
committerjhb <jhb@FreeBSD.org>2002-07-17 02:48:43 +0000
commit3af47b505779529ef058e22b9ae31366e60ffa70 (patch)
tree1eebff95653ad26595d2e12ca7b5bfdcdf4d355e /sys/kern/kern_descrip.c
parent0ae44e9908e1c97278867390b837a5157e346ccd (diff)
downloadFreeBSD-src-3af47b505779529ef058e22b9ae31366e60ffa70.zip
FreeBSD-src-3af47b505779529ef058e22b9ae31366e60ffa70.tar.gz
Preallocate a struct file as the first thing in falloc() before we lock
the filelist_lock and check nfiles. This closes a race where we had to unlock the filedesc to re-lock the filelist_lock. Reported by: David Xu Reviewed by: bde (mostly)
Diffstat (limited to 'sys/kern/kern_descrip.c')
-rw-r--r--sys/kern/kern_descrip.c21
1 files changed, 5 insertions, 16 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index f030284..43a7e44 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1107,32 +1107,24 @@ falloc(td, resultfp, resultfd)
register struct file *fp, *fq;
int error, i;
+ fp = uma_zalloc(file_zone, M_WAITOK | M_ZERO);
sx_xlock(&filelist_lock);
if (nfiles >= maxfiles) {
sx_xunlock(&filelist_lock);
+ uma_zfree(file_zone, fp);
tablefull("file");
return (ENFILE);
}
nfiles++;
- sx_xunlock(&filelist_lock);
- /*
- * Allocate a new file descriptor.
- * If the process has file descriptor zero open, add to the list
- * of open files at that point, otherwise put it at the front of
- * the list of open files.
- */
- fp = uma_zalloc(file_zone, M_WAITOK);
- bzero(fp, sizeof(*fp));
/*
- * wait until after malloc (which may have blocked) returns before
- * allocating the slot, else a race might have shrunk it if we had
- * allocated it before the malloc.
+ * If the process has file descriptor zero open, add the new file
+ * descriptor to the list of open files at that point, otherwise
+ * put it at the front of the list of open files.
*/
FILEDESC_LOCK(p->p_fd);
if ((error = fdalloc(td, 0, &i))) {
FILEDESC_UNLOCK(p->p_fd);
- sx_xlock(&filelist_lock);
nfiles--;
sx_xunlock(&filelist_lock);
uma_zfree(file_zone, fp);
@@ -1144,9 +1136,6 @@ falloc(td, resultfp, resultfd)
fp->f_cred = crhold(td->td_ucred);
fp->f_ops = &badfileops;
fp->f_seqcount = 1;
- FILEDESC_UNLOCK(p->p_fd);
- sx_xlock(&filelist_lock);
- FILEDESC_LOCK(p->p_fd);
if ((fq = p->p_fd->fd_ofiles[0])) {
LIST_INSERT_AFTER(fq, fp, f_list);
} else {
OpenPOWER on IntegriCloud