mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-15 15:15:47 +00:00
ext4: Fix possible corruption when moving a directory
[ Upstream commit0813299c58
] When we are renaming a directory to a different directory, we need to update '..' entry in the moved directory. However nothing prevents moved directory from being modified and even converted from the inline format to the normal format. When such race happens the rename code gets confused and we crash. Fix the problem by locking the moved directory. CC: stable@vger.kernel.org Fixes:32f7f22c0b
("ext4: let ext4_rename handle inline dir") Signed-off-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/r/20230126112221.11866-1-jack@suse.cz Signed-off-by: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
891a3cba42
commit
8dac5a63cf
1 changed files with 10 additions and 1 deletions
|
@ -3855,10 +3855,17 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|||
if (new.dir != old.dir && EXT4_DIR_LINK_MAX(new.dir))
|
||||
goto end_rename;
|
||||
}
|
||||
/*
|
||||
* We need to protect against old.inode directory getting
|
||||
* converted from inline directory format into a normal one.
|
||||
*/
|
||||
inode_lock_nested(old.inode, I_MUTEX_NONDIR2);
|
||||
retval = ext4_rename_dir_prepare(handle, &old);
|
||||
if (retval)
|
||||
if (retval) {
|
||||
inode_unlock(old.inode);
|
||||
goto end_rename;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If we're renaming a file within an inline_data dir and adding or
|
||||
* setting the new dirent causes a conversion from inline_data to
|
||||
|
@ -3953,6 +3960,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|||
} else {
|
||||
ext4_journal_stop(handle);
|
||||
}
|
||||
if (old.dir_bh)
|
||||
inode_unlock(old.inode);
|
||||
release_bh:
|
||||
brelse(old.dir_bh);
|
||||
brelse(old.bh);
|
||||
|
|
Loading…
Reference in a new issue