Skip to content

Commit 0813299

Browse files
jankaratytso
authored andcommitted
ext4: Fix possible corruption when moving a directory
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: [email protected] Fixes: 32f7f22 ("ext4: let ext4_rename handle inline dir") Signed-off-by: Jan Kara <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 172e344 commit 0813299

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

fs/ext4/namei.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3872,9 +3872,16 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
38723872
if (new.dir != old.dir && EXT4_DIR_LINK_MAX(new.dir))
38733873
goto end_rename;
38743874
}
3875+
/*
3876+
* We need to protect against old.inode directory getting
3877+
* converted from inline directory format into a normal one.
3878+
*/
3879+
inode_lock_nested(old.inode, I_MUTEX_NONDIR2);
38753880
retval = ext4_rename_dir_prepare(handle, &old);
3876-
if (retval)
3881+
if (retval) {
3882+
inode_unlock(old.inode);
38773883
goto end_rename;
3884+
}
38783885
}
38793886
/*
38803887
* If we're renaming a file within an inline_data dir and adding or
@@ -4006,6 +4013,8 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
40064013
} else {
40074014
ext4_journal_stop(handle);
40084015
}
4016+
if (old.dir_bh)
4017+
inode_unlock(old.inode);
40094018
release_bh:
40104019
brelse(old.dir_bh);
40114020
brelse(old.bh);

0 commit comments

Comments
 (0)