]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Mon, 13 Mar 2023 13:12:27 +0000 (09:12 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 13 Mar 2023 13:12:27 +0000 (09:12 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.1/ext4-fix-deadlock-during-directory-rename.patch [new file with mode: 0644]
queue-6.1/series

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 (file)
index 0000000..db285d0
--- /dev/null
@@ -0,0 +1,86 @@
+From c408596f8fe3ec720da52d5301eb5c7ac24a2f53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Mar 2023 15:10:04 +0100
+Subject: ext4: Fix deadlock during directory rename
+
+From: Jan Kara <jack@suse.cz>
+
+[ 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 <jack@suse.cz>
+Link: https://lore.kernel.org/r/20230301141004.15087-1-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
index 7841e0cd8521d8251b7e837ead539e8c8ce1f699..bb22bfb3629eacb73984e85696db8a804de4f7bf 100644 (file)
@@ -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