Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Feb 2009 15:22:01 +0000 (UTC)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r188485 - head/sys/kern
Message-ID:  <200902111522.n1BFM1H2029226@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rwatson
Date: Wed Feb 11 15:22:01 2009
New Revision: 188485
URL: http://svn.freebsd.org/changeset/base/188485

Log:
  Modify fdcopy() so that, during fork(2), it won't copy file descriptors
  from the parent to the child process if they have an operation vector
  of &badfileops.  This narrows a set of races involving system calls that
  allocate a new file descriptor, potentially block for some extended
  period, and then return the file descriptor, when invoked by a threaded
  program that concurrently invokes fork(2).  Similar approches are used
  in both Solaris and Linux, and the wideness of this race was introduced
  in FreeBSD when we moved to a more optimistic implementation of
  accept(2) in order to simplify locking.
  
  A small race necessarily remains because the fork(2) might occur after
  the finit() in accept(2) but before the system call has returned, but
  that appears unavoidable using current APIs.  However, this race is
  vastly narrower.
  
  The fix can be validated using the newfileops_on_fork regression test.
  
  PR:		kern/130348
  Reported by:	Ivan Shcheklein <shcheklein at gmail dot com>
  Reviewed by:	jhb, kib
  MFC after:	1 week

Modified:
  head/sys/kern/kern_descrip.c

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c	Wed Feb 11 14:25:09 2009	(r188484)
+++ head/sys/kern/kern_descrip.c	Wed Feb 11 15:22:01 2009	(r188485)
@@ -1583,7 +1583,8 @@ fdcopy(struct filedesc *fdp)
 	newfdp->fd_freefile = -1;
 	for (i = 0; i <= fdp->fd_lastfile; ++i) {
 		if (fdisused(fdp, i) &&
-		    fdp->fd_ofiles[i]->f_type != DTYPE_KQUEUE) {
+		    fdp->fd_ofiles[i]->f_type != DTYPE_KQUEUE &&
+		    fdp->fd_ofiles[i]->f_ops != &badfileops) {
 			newfdp->fd_ofiles[i] = fdp->fd_ofiles[i];
 			newfdp->fd_ofileflags[i] = fdp->fd_ofileflags[i];
 			fhold(newfdp->fd_ofiles[i]);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902111522.n1BFM1H2029226>