From: Sasha Levin Date: Mon, 13 Mar 2023 13:12:27 +0000 (-0400) Subject: Fixes for 6.1 X-Git-Tag: v4.14.310~82 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=868241f75a8c75c73a6e2cbb1374e5101e6c993b;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.1 Signed-off-by: Sasha Levin --- diff --git a/queue-6.1/ext4-fix-deadlock-during-directory-rename.patch b/queue-6.1/ext4-fix-deadlock-during-directory-rename.patch new file mode 100644 index 00000000000..db285d0b478 --- /dev/null +++ b/queue-6.1/ext4-fix-deadlock-during-directory-rename.patch @@ -0,0 +1,86 @@ +From c408596f8fe3ec720da52d5301eb5c7ac24a2f53 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Mar 2023 15:10:04 +0100 +Subject: ext4: Fix deadlock during directory rename + +From: Jan Kara + +[ Upstream commit 3c92792da8506a295afb6d032b4476e46f979725 ] + +As lockdep properly warns, we should not be locking i_rwsem while having +transactions started as the proper lock ordering used by all directory +handling operations is i_rwsem -> transaction start. Fix the lock +ordering by moving the locking of the directory earlier in +ext4_rename(). + +Reported-by: syzbot+9d16c39efb5fade84574@syzkaller.appspotmail.com +Fixes: 0813299c586b ("ext4: Fix possible corruption when moving a directory") +Link: https://syzkaller.appspot.com/bug?extid=9d16c39efb5fade84574 +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20230301141004.15087-1-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/namei.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index dc8f8a435a7ea..800d631c920b4 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -3813,10 +3813,20 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + return retval; + } + ++ /* ++ * We need to protect against old.inode directory getting converted ++ * from inline directory format into a normal one. ++ */ ++ if (S_ISDIR(old.inode->i_mode)) ++ inode_lock_nested(old.inode, I_MUTEX_NONDIR2); ++ + old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, + &old.inlined); +- if (IS_ERR(old.bh)) +- return PTR_ERR(old.bh); ++ if (IS_ERR(old.bh)) { ++ retval = PTR_ERR(old.bh); ++ goto unlock_moved_dir; ++ } ++ + /* + * Check for inode number is _not_ due to possible IO errors. + * We might rmdir the source, keep it as pwd of some process +@@ -3873,11 +3883,6 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + 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) { + inode_unlock(old.inode); +@@ -4014,12 +4019,15 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir, + } else { + ext4_journal_stop(handle); + } +- if (old.dir_bh) +- inode_unlock(old.inode); + release_bh: + brelse(old.dir_bh); + brelse(old.bh); + brelse(new.bh); ++ ++unlock_moved_dir: ++ if (S_ISDIR(old.inode->i_mode)) ++ inode_unlock(old.inode); ++ + return retval; + } + +-- +2.39.2 + diff --git a/queue-6.1/series b/queue-6.1/series index 7841e0cd852..bb22bfb3629 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -112,3 +112,4 @@ erofs-revert-erofs-fix-kvcalloc-misuse-with-__gfp_no.patch riscv-use-read_once_nocheck-in-imprecise-unwinding-s.patch risc-v-don-t-check-text_mutex-during-stop_machine.patch drm-amdgpu-fix-return-value-check-in-kfd.patch +ext4-fix-deadlock-during-directory-rename.patch