From: Jeffrey Hutzelman Date: Wed, 12 Jun 2013 20:22:36 +0000 (-0400) Subject: libafs/LINUX: avoid leaks due to corrupt dir X-Git-Tag: upstream/1.8.0_pre1^2~1071 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=a2bfa0e853fb4954fd06a00ea6fbc55c39e76b8a;p=packages%2Fo%2Fopenafs.git libafs/LINUX: avoid leaks due to corrupt dir When a corrupt directory is discovered, scanning stops immediately and readdir returns ENOENT. Currently, the vcache lock is unlocked and the dcache containing the directory is released, but that's not enough. It's also necessary to unlock the dcache, on which we hold a read lock, and to clear the vcache state which records an in-progress readdir. Change-Id: I408e8bc8b1f4a0ebc1740410da5d760f30b4c875 Reviewed-on: http://gerrit.openafs.org/9971 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 25cbac205..ce59f6ec6 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -368,10 +368,8 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) if (code) { afs_warn("Corrupt directory (inode %lx, dirpos %d)", (unsigned long)&tdc->f.inode, dirpos); - ReleaseSharedLock(&avc->lock); - afs_PutDCache(tdc); code = -ENOENT; - goto out; + goto unlock_out; } de = (struct DirEntry *)entry.data; @@ -438,7 +436,9 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) #else fp->f_pos = (loff_t) offset; #endif + code = 0; +unlock_out: ReleaseReadLock(&tdc->lock); afs_PutDCache(tdc); UpgradeSToWLock(&avc->lock, 813); @@ -446,7 +446,6 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) avc->dcreaddir = 0; avc->readdir_pid = 0; ReleaseSharedLock(&avc->lock); - code = 0; out: afs_PutFakeStat(&fakestat);