diff options
author | kib <kib@FreeBSD.org> | 2013-12-17 17:31:16 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2013-12-17 17:31:16 +0000 |
commit | b6824d8c7799a0ffcbcf6ca4e1ef83d54b85e6b3 (patch) | |
tree | 8394341f6c7c7600c311f728fd22d282508ad568 /sys/kern/vfs_vnops.c | |
parent | 6ef68a42084eb753005a5251593d103fd5ee98a1 (diff) | |
download | FreeBSD-src-b6824d8c7799a0ffcbcf6ca4e1ef83d54b85e6b3.zip FreeBSD-src-b6824d8c7799a0ffcbcf6ca4e1ef83d54b85e6b3.tar.gz |
If vn_open_vnode() succeeded in opening the vnode, but subsequent
advisory lock cannot be obtained, prevent double-close of the vnode in
vn_close() called from the fdrop(), by resetting file' f_ops methods.
Reported and tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Diffstat (limited to 'sys/kern/vfs_vnops.c')
-rw-r--r-- | sys/kern/vfs_vnops.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index da4a914..ec995c7 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -313,6 +313,9 @@ vn_open_vnode(struct vnode *vp, int fmode, struct ucred *cred, vn_lock(vp, lock_flags | LK_RETRY); (void)VOP_CLOSE(vp, fmode, cred, td); vn_finished_write(mp); + /* Prevent second close from fdrop()->vn_close(). */ + if (fp != NULL) + fp->f_ops= &badfileops; return (error); } fp->f_flag |= FHASLOCK; |