mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-02 07:04:24 +00:00
affs_lookup(): close a race with affs_remove_link()
commit 30da870ce4
upstream.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2871a70132
commit
1e5edf32e4
1 changed files with 7 additions and 3 deletions
|
@ -206,9 +206,10 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
|||
|
||||
affs_lock_dir(dir);
|
||||
bh = affs_find_entry(dir, dentry);
|
||||
affs_unlock_dir(dir);
|
||||
if (IS_ERR(bh))
|
||||
if (IS_ERR(bh)) {
|
||||
affs_unlock_dir(dir);
|
||||
return ERR_CAST(bh);
|
||||
}
|
||||
if (bh) {
|
||||
u32 ino = bh->b_blocknr;
|
||||
|
||||
|
@ -222,10 +223,13 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
|||
}
|
||||
affs_brelse(bh);
|
||||
inode = affs_iget(sb, ino);
|
||||
if (IS_ERR(inode))
|
||||
if (IS_ERR(inode)) {
|
||||
affs_unlock_dir(dir);
|
||||
return ERR_CAST(inode);
|
||||
}
|
||||
}
|
||||
d_add(dentry, inode);
|
||||
affs_unlock_dir(dir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue