]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 Nov 2022 12:27:04 +0000 (13:27 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 Nov 2022 12:27:04 +0000 (13:27 +0100)
added patches:
nilfs2-fix-nilfs_sufile_mark_dirty-not-set-segment-usage-as-dirty.patch

queue-4.9/nilfs2-fix-nilfs_sufile_mark_dirty-not-set-segment-usage-as-dirty.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/nilfs2-fix-nilfs_sufile_mark_dirty-not-set-segment-usage-as-dirty.patch b/queue-4.9/nilfs2-fix-nilfs_sufile_mark_dirty-not-set-segment-usage-as-dirty.patch
new file mode 100644 (file)
index 0000000..2138c21
--- /dev/null
@@ -0,0 +1,77 @@
+From 512c5ca01a3610ab14ff6309db363de51f1c13a6 Mon Sep 17 00:00:00 2001
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+Date: Fri, 18 Nov 2022 14:33:04 +0800
+Subject: nilfs2: fix nilfs_sufile_mark_dirty() not set segment usage as dirty
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+commit 512c5ca01a3610ab14ff6309db363de51f1c13a6 upstream.
+
+When extending segments, nilfs_sufile_alloc() is called to get an
+unassigned segment, then mark it as dirty to avoid accidentally allocating
+the same segment in the future.
+
+But for some special cases such as a corrupted image it can be unreliable.
+If such corruption of the dirty state of the segment occurs, nilfs2 may
+reallocate a segment that is in use and pick the same segment for writing
+twice at the same time.
+
+This will cause the problem reported by syzkaller:
+https://syzkaller.appspot.com/bug?id=c7c4748e11ffcc367cef04f76e02e931833cbd24
+
+This case started with segbuf1.segnum = 3, nextnum = 4 when constructed.
+It supposed segment 4 has already been allocated and marked as dirty.
+
+However the dirty state was corrupted and segment 4 usage was not dirty.
+For the first time nilfs_segctor_extend_segments() segment 4 was allocated
+again, which made segbuf2 and next segbuf3 had same segment 4.
+
+sb_getblk() will get same bh for segbuf2 and segbuf3, and this bh is added
+to both buffer lists of two segbuf.  It makes the lists broken which
+causes NULL pointer dereference.
+
+Fix the problem by setting usage as dirty every time in
+nilfs_sufile_mark_dirty(), which is called during constructing current
+segment to be written out and before allocating next segment.
+
+[chenzhongjin@huawei.com: add lock protection per Ryusuke]
+  Link: https://lkml.kernel.org/r/20221121091141.214703-1-chenzhongjin@huawei.com
+Link: https://lkml.kernel.org/r/20221118063304.140187-1-chenzhongjin@huawei.com
+Fixes: 9ff05123e3bf ("nilfs2: segment constructor")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Reported-by: <syzbot+77e4f0...@syzkaller.appspotmail.com>
+Reported-by: Liu Shixin <liushixin2@huawei.com>
+Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nilfs2/sufile.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/fs/nilfs2/sufile.c
++++ b/fs/nilfs2/sufile.c
+@@ -507,14 +507,22 @@ void nilfs_sufile_do_free(struct inode *
+ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
+ {
+       struct buffer_head *bh;
++      void *kaddr;
++      struct nilfs_segment_usage *su;
+       int ret;
++      down_write(&NILFS_MDT(sufile)->mi_sem);
+       ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh);
+       if (!ret) {
+               mark_buffer_dirty(bh);
+               nilfs_mdt_mark_dirty(sufile);
++              kaddr = kmap_atomic(bh->b_page);
++              su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
++              nilfs_segment_usage_set_dirty(su);
++              kunmap_atomic(kaddr);
+               brelse(bh);
+       }
++      up_write(&NILFS_MDT(sufile)->mi_sem);
+       return ret;
+ }
index 3027f5da155e310ef608cbcf677b87e0de2dcd1b..cc829788e528f41e794160d63a1c151012332c86 100644 (file)
@@ -22,3 +22,4 @@ iio-light-apds9960-fix-wrong-register-for-gesture-gain.patch
 iio-core-fix-entry-not-deleted-when-iio_register_sw_trigger_type-fails.patch
 kconfig-display-recursive-dependency-resolution-hint-just-once.patch
 nios2-add-force-for-vmlinuz.gz.patch
+nilfs2-fix-nilfs_sufile_mark_dirty-not-set-segment-usage-as-dirty.patch