PERFORCE change 115948 for review
John Baldwin
jhb at FreeBSD.org
Thu Mar 15 22:17:47 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=115948
Change 115948 by jhb at 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;
More information about the p4-projects
mailing list