affs_lookup(): close a race with affs_remove_link()
Subsystems (2)
Al Viro
maintainerRFC PATCH 1/1 affs_lookup(): close a race with affs_remove_link()
[#fixes unless somebody yells; -stable fodder and yes, it _is_ that old - all way back to 2001]
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).
fs/affs/namei.c +7 -3
@@ -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 ; }
Quoted 11 lines · Al Viro
[#fixes unless somebody yells; -stable fodder and yes, it _is_ that old - all way back to 2001]
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 [email protected] # 2.4.4+Signed-off-by Al Viro <[email protected]>
Sorry for the delay. As far as my limited knowledge of the AFFS code goes, this change looks ok. You can add my
and please take it through the vfs tree. Thanks.