aboutsummaryrefslogtreecommitdiffstats
path: root/fs/affs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2018-05-06 12:15:20 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2018-05-21 14:27:45 -0400
commit30da870ce4a4e007c901858a96e9e394a1daa74a (patch)
treed75869642ea5ce962ed9aa442db2784d3779ca2e /fs/affs/namei.c
parentb127125d9db23e4856156a7c909a3c8e18b69f99 (diff)
affs_lookup(): close a race with affs_remove_link()
we unlock the directory hash too early - if we are looking at secondary link and primary (in another directory) gets removed just as we unlock, we could have the old primary moved in place of the secondary, leaving us to look into freed entry (and leaving our dentry with ->d_fsdata pointing to a freed entry). Cc: stable@vger.kernel.org # 2.4.4+ Acked-by: David Sterba <dsterba@suse.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/affs/namei.c')
-rw-r--r--fs/affs/namei.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index d8aa0ae3d037..1ed0fa4c4d48 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -206,9 +206,10 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
206 206
207 affs_lock_dir(dir); 207 affs_lock_dir(dir);
208 bh = affs_find_entry(dir, dentry); 208 bh = affs_find_entry(dir, dentry);
209 affs_unlock_dir(dir); 209 if (IS_ERR(bh)) {
210 if (IS_ERR(bh)) 210 affs_unlock_dir(dir);
211 return ERR_CAST(bh); 211 return ERR_CAST(bh);
212 }
212 if (bh) { 213 if (bh) {
213 u32 ino = bh->b_blocknr; 214 u32 ino = bh->b_blocknr;
214 215
@@ -222,10 +223,13 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
222 } 223 }
223 affs_brelse(bh); 224 affs_brelse(bh);
224 inode = affs_iget(sb, ino); 225 inode = affs_iget(sb, ino);
225 if (IS_ERR(inode)) 226 if (IS_ERR(inode)) {
227 affs_unlock_dir(dir);
226 return ERR_CAST(inode); 228 return ERR_CAST(inode);
229 }
227 } 230 }
228 d_add(dentry, inode); 231 d_add(dentry, inode);
232 affs_unlock_dir(dir);
229 return NULL; 233 return NULL;
230} 234}
231 235