From 39ca1315e23a31c6794b9fcb2bded1d9147c3253 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: May 17 2023 19:16:08 +0000 Subject: ext4: fix deadlock when converting an inline directory in nojournal mode (bsc#1012628). --- diff --git a/patches.kernel.org/6.3.3-233-ext4-fix-deadlock-when-converting-an-inline-dir.patch b/patches.kernel.org/6.3.3-233-ext4-fix-deadlock-when-converting-an-inline-dir.patch new file mode 100644 index 0000000..9a369af --- /dev/null +++ b/patches.kernel.org/6.3.3-233-ext4-fix-deadlock-when-converting-an-inline-dir.patch @@ -0,0 +1,70 @@ +From: Theodore Ts'o +Date: Sat, 6 May 2023 21:04:01 -0400 +Subject: [PATCH] ext4: fix deadlock when converting an inline directory in + nojournal mode +References: bsc#1012628 +Patch-mainline: 6.3.3 +Git-commit: f4ce24f54d9cca4f09a395f3eecce20d6bec4663 + +commit f4ce24f54d9cca4f09a395f3eecce20d6bec4663 upstream. + +In no journal mode, ext4_finish_convert_inline_dir() can self-deadlock +by calling ext4_handle_dirty_dirblock() when it already has taken the +directory lock. There is a similar self-deadlock in +ext4_incvert_inline_data_nolock() for data files which we'll fix at +the same time. + +A simple reproducer demonstrating the problem: + + mke2fs -Fq -t ext2 -O inline_data -b 4k /dev/vdc 64 + mount -t ext4 -o dirsync /dev/vdc /vdc + cd /vdc + mkdir file0 + cd file0 + touch file0 + touch file1 + attr -s BurnSpaceInEA -V abcde . + touch supercalifragilisticexpialidocious + +Cc: stable@kernel.org +Link: https://lore.kernel.org/r/20230507021608.1290720-1-tytso@mit.edu +Reported-by: syzbot+91dccab7c64e2850a4e5@syzkaller.appspotmail.com +Link: https://syzkaller.appspot.com/bug?id=ba84cc80a9491d65416bc7877e1650c87530fe8a +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Jiri Slaby +--- + fs/ext4/inline.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c +index 1602d74b..db6304c0 100644 +--- a/fs/ext4/inline.c ++++ b/fs/ext4/inline.c +@@ -1177,6 +1177,7 @@ static int ext4_finish_convert_inline_dir(handle_t *handle, + ext4_initialize_dirent_tail(dir_block, + inode->i_sb->s_blocksize); + set_buffer_uptodate(dir_block); ++ unlock_buffer(dir_block); + err = ext4_handle_dirty_dirblock(handle, inode, dir_block); + if (err) + return err; +@@ -1251,6 +1252,7 @@ static int ext4_convert_inline_data_nolock(handle_t *handle, + if (!S_ISDIR(inode->i_mode)) { + memcpy(data_bh->b_data, buf, inline_size); + set_buffer_uptodate(data_bh); ++ unlock_buffer(data_bh); + error = ext4_handle_dirty_metadata(handle, + inode, data_bh); + } else { +@@ -1258,7 +1260,6 @@ static int ext4_convert_inline_data_nolock(handle_t *handle, + buf, inline_size); + } + +- unlock_buffer(data_bh); + out_restore: + if (error) + ext4_restore_inline_data(handle, inode, iloc, buf, inline_size); +-- +2.35.3 + diff --git a/series.conf b/series.conf index bb6c841..e33d5f9 100644 --- a/series.conf +++ b/series.conf @@ -966,6 +966,7 @@ patches.kernel.org/6.3.3-230-ext4-check-iomap-type-only-if-ext4_iomap_begin-.patch patches.kernel.org/6.3.3-231-ext4-improve-error-recovery-code-paths-in-__ext.patch patches.kernel.org/6.3.3-232-ext4-improve-error-handling-from-ext4_dirhash.patch + patches.kernel.org/6.3.3-233-ext4-fix-deadlock-when-converting-an-inline-dir.patch ######################################################## # Build fixes that apply to the vanilla kernel too.