Date: Thu, 15 Mar 2007 22:17:47 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 115948 for review Message-ID: <200703152217.l2FMHld1085360@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=115948 Change 115948 by jhb@jhb_mutex on 2007/03/15 22:17:34 Move the fdrop() after the fdclose() to close the following race: - thread A calls kern_open() and vn_open() fails. - thread B close()'s the fd before thread A returns from kern_open(). - thread A calls fdrop() which free's the file object. - thread B/C creates a new file descriptor which reuses the same file object that was just free'd. It also reuses the same fd since it was just closed and is now available. - thread A calls fdclose() which sees that the file matches the file in the descriptor table, so it clears the file pointer and does an fdrop() - thread B/C returns an fd - later accesses to 'fd' return EBADF I don't think one can get a refcount underflow from this or a panic, just weirdness in userland where a fd returned from open will fail with EBADF when you use it. Affected files ... .. //depot/projects/smpng/sys/kern/vfs_syscalls.c#123 edit Differences ... ==== //depot/projects/smpng/sys/kern/vfs_syscalls.c#123 (text+ko) ==== @@ -997,11 +997,6 @@ } /* - * release our own reference - */ - fdrop(fp, td); - - /* * handle special fdopen() case. bleh. dupfdopen() is * responsible for dropping the old contents of ofiles[indx] * if it succeeds. @@ -1011,6 +1006,7 @@ (error = dupfdopen(td, fdp, indx, td->td_dupfd, flags, error)) == 0) { td->td_retval[0] = indx; + fdrop(fp, td); return (0); } /* @@ -1018,6 +1014,7 @@ * replaced or closed it. */ fdclose(fdp, fp, indx, td); + fdrop(fp, td); if (error == ERESTART) error = EINTR;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200703152217.l2FMHld1085360>