]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 Aug 2018 09:11:26 +0000 (11:11 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 Aug 2018 09:11:26 +0000 (11:11 +0200)
added patches:
f2fs-return-error-during-fill_super.patch
f2fs-sanity-check-for-total-valid-node-blocks.patch
kvm-irqfd-fix-race-between-epollhup-and-irq_bypass_register_consumer.patch

queue-4.14/f2fs-return-error-during-fill_super.patch [new file with mode: 0644]
queue-4.14/f2fs-sanity-check-for-total-valid-node-blocks.patch [new file with mode: 0644]
queue-4.14/kvm-irqfd-fix-race-between-epollhup-and-irq_bypass_register_consumer.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/f2fs-return-error-during-fill_super.patch b/queue-4.14/f2fs-return-error-during-fill_super.patch
new file mode 100644 (file)
index 0000000..611253a
--- /dev/null
@@ -0,0 +1,120 @@
+From c39a1b348c4fe172729eff77c533dabc3c7cdaa7 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+Date: Tue, 19 Dec 2017 19:16:34 -0800
+Subject: f2fs: return error during fill_super
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+commit c39a1b348c4fe172729eff77c533dabc3c7cdaa7 upstream.
+
+Let's avoid BUG_ON during fill_super, when on-disk was totall corrupted.
+
+Reviewed-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/segment.c |   16 ++++++++++++----
+ fs/f2fs/segment.h |   22 ++++++++++++++++++----
+ 2 files changed, 30 insertions(+), 8 deletions(-)
+
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -3240,7 +3240,7 @@ static int build_curseg(struct f2fs_sb_i
+       return restore_curseg_summaries(sbi);
+ }
+-static void build_sit_entries(struct f2fs_sb_info *sbi)
++static int build_sit_entries(struct f2fs_sb_info *sbi)
+ {
+       struct sit_info *sit_i = SIT_I(sbi);
+       struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
+@@ -3250,6 +3250,7 @@ static void build_sit_entries(struct f2f
+       int sit_blk_cnt = SIT_BLK_CNT(sbi);
+       unsigned int i, start, end;
+       unsigned int readed, start_blk = 0;
++      int err = 0;
+       do {
+               readed = ra_meta_pages(sbi, start_blk, BIO_MAX_PAGES,
+@@ -3268,7 +3269,9 @@ static void build_sit_entries(struct f2f
+                       sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)];
+                       f2fs_put_page(page, 1);
+-                      check_block_count(sbi, start, &sit);
++                      err = check_block_count(sbi, start, &sit);
++                      if (err)
++                              return err;
+                       seg_info_from_raw_sit(se, &sit);
+                       /* build discard map only one time */
+@@ -3303,7 +3306,9 @@ static void build_sit_entries(struct f2f
+               old_valid_blocks = se->valid_blocks;
+-              check_block_count(sbi, start, &sit);
++              err = check_block_count(sbi, start, &sit);
++              if (err)
++                      break;
+               seg_info_from_raw_sit(se, &sit);
+               if (f2fs_discard_en(sbi)) {
+@@ -3323,6 +3328,7 @@ static void build_sit_entries(struct f2f
+                               se->valid_blocks - old_valid_blocks;
+       }
+       up_read(&curseg->journal_rwsem);
++      return err;
+ }
+ static void init_free_segmap(struct f2fs_sb_info *sbi)
+@@ -3492,7 +3498,9 @@ int build_segment_manager(struct f2fs_sb
+               return err;
+       /* reinit free segmap based on SIT */
+-      build_sit_entries(sbi);
++      err = build_sit_entries(sbi);
++      if (err)
++              return err;
+       init_free_segmap(sbi);
+       err = build_dirty_segmap(sbi);
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -625,7 +625,7 @@ static inline void verify_block_addr(str
+ /*
+  * Summary block is always treated as an invalid block
+  */
+-static inline void check_block_count(struct f2fs_sb_info *sbi,
++static inline int check_block_count(struct f2fs_sb_info *sbi,
+               int segno, struct f2fs_sit_entry *raw_sit)
+ {
+ #ifdef CONFIG_F2FS_CHECK_FS
+@@ -647,11 +647,25 @@ static inline void check_block_count(str
+               cur_pos = next_pos;
+               is_valid = !is_valid;
+       } while (cur_pos < sbi->blocks_per_seg);
+-      BUG_ON(GET_SIT_VBLOCKS(raw_sit) != valid_blocks);
++
++      if (unlikely(GET_SIT_VBLOCKS(raw_sit) != valid_blocks)) {
++              f2fs_msg(sbi->sb, KERN_ERR,
++                              "Mismatch valid blocks %d vs. %d",
++                                      GET_SIT_VBLOCKS(raw_sit), valid_blocks);
++              set_sbi_flag(sbi, SBI_NEED_FSCK);
++              return -EINVAL;
++      }
+ #endif
+       /* check segment usage, and check boundary of a given segment number */
+-      f2fs_bug_on(sbi, GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg
+-                                      || segno > TOTAL_SEGS(sbi) - 1);
++      if (unlikely(GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg
++                                      || segno > TOTAL_SEGS(sbi) - 1)) {
++              f2fs_msg(sbi->sb, KERN_ERR,
++                              "Wrong valid blocks %d or segno %u",
++                                      GET_SIT_VBLOCKS(raw_sit), segno);
++              set_sbi_flag(sbi, SBI_NEED_FSCK);
++              return -EINVAL;
++      }
++      return 0;
+ }
+ static inline pgoff_t current_sit_addr(struct f2fs_sb_info *sbi,
diff --git a/queue-4.14/f2fs-sanity-check-for-total-valid-node-blocks.patch b/queue-4.14/f2fs-sanity-check-for-total-valid-node-blocks.patch
new file mode 100644 (file)
index 0000000..a49d6d3
--- /dev/null
@@ -0,0 +1,147 @@
+From 8a29c1260e24e7c9c6ab138aa0017558d8b28208 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+Date: Tue, 24 Apr 2018 21:34:05 -0600
+Subject: f2fs: sanity check for total valid node blocks
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+commit 8a29c1260e24e7c9c6ab138aa0017558d8b28208 upstream.
+
+This patch enhances sanity check for SIT entries.
+
+syzbot hit the following crash on upstream commit
+83beed7b2b26f232d782127792dd0cd4362fdc41 (Fri Apr 20 17:56:32 2018 +0000)
+Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal
+syzbot dashboard link: https://syzkaller.appspot.com/bug?extid=bf9253040425feb155ad
+
+syzkaller reproducer: https://syzkaller.appspot.com/x/repro.syz?id=5692130282438656
+Raw console output: https://syzkaller.appspot.com/x/log.txt?id=5095924598571008
+Kernel config: https://syzkaller.appspot.com/x/.config?id=1808800213120130118
+compiler: gcc (GCC) 8.0.1 20180413 (experimental)
+
+IMPORTANT: if you fix the bug, please add the following tag to the commit:
+Reported-by: syzbot+bf9253040425feb155ad@syzkaller.appspotmail.com
+It will help syzbot understand when the bug is fixed. See footer for details.
+If you forward the report, please keep this part and the footer.
+
+F2FS-fs (loop0): invalid crc value
+F2FS-fs (loop0): Try to recover 1th superblock, ret: 0
+F2FS-fs (loop0): Mounted with checkpoint version = d
+F2FS-fs (loop0): Bitmap was wrongly cleared, blk:9740
+------------[ cut here ]------------
+kernel BUG at fs/f2fs/segment.c:1884!
+invalid opcode: 0000 [#1] SMP KASAN
+Dumping ftrace buffer:
+   (ftrace buffer empty)
+Modules linked in:
+CPU: 1 PID: 4508 Comm: syz-executor0 Not tainted 4.17.0-rc1+ #10
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+RIP: 0010:update_sit_entry+0x1215/0x1590 fs/f2fs/segment.c:1882
+RSP: 0018:ffff8801af526708 EFLAGS: 00010282
+RAX: ffffed0035ea4cc0 RBX: ffff8801ad454f90 RCX: 0000000000000000
+RDX: 0000000000000000 RSI: ffffffff82eeb87e RDI: ffffed0035ea4cb6
+RBP: ffff8801af526760 R08: ffff8801ad4a2480 R09: ffffed003b5e4f90
+R10: ffffed003b5e4f90 R11: ffff8801daf27c87 R12: ffff8801adb8d380
+R13: 0000000000000001 R14: 0000000000000008 R15: 00000000ffffffff
+FS:  00000000014af940(0000) GS:ffff8801daf00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f06bc223000 CR3: 00000001adb02000 CR4: 00000000001406e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ allocate_data_block+0x66f/0x2050 fs/f2fs/segment.c:2663
+ do_write_page+0x105/0x1b0 fs/f2fs/segment.c:2727
+ write_node_page+0x129/0x350 fs/f2fs/segment.c:2770
+ __write_node_page+0x7da/0x1370 fs/f2fs/node.c:1398
+ sync_node_pages+0x18cf/0x1eb0 fs/f2fs/node.c:1652
+ block_operations+0x429/0xa60 fs/f2fs/checkpoint.c:1088
+ write_checkpoint+0x3ba/0x5380 fs/f2fs/checkpoint.c:1405
+ f2fs_sync_fs+0x2fb/0x6a0 fs/f2fs/super.c:1077
+ __sync_filesystem fs/sync.c:39 [inline]
+ sync_filesystem+0x265/0x310 fs/sync.c:67
+ generic_shutdown_super+0xd7/0x520 fs/super.c:429
+ kill_block_super+0xa4/0x100 fs/super.c:1191
+ kill_f2fs_super+0x9f/0xd0 fs/f2fs/super.c:3030
+ deactivate_locked_super+0x97/0x100 fs/super.c:316
+ deactivate_super+0x188/0x1b0 fs/super.c:347
+ cleanup_mnt+0xbf/0x160 fs/namespace.c:1174
+ __cleanup_mnt+0x16/0x20 fs/namespace.c:1181
+ task_work_run+0x1e4/0x290 kernel/task_work.c:113
+ tracehook_notify_resume include/linux/tracehook.h:191 [inline]
+ exit_to_usermode_loop+0x2bd/0x310 arch/x86/entry/common.c:166
+ prepare_exit_to_usermode arch/x86/entry/common.c:196 [inline]
+ syscall_return_slowpath arch/x86/entry/common.c:265 [inline]
+ do_syscall_64+0x6ac/0x800 arch/x86/entry/common.c:290
+ entry_SYSCALL_64_after_hwframe+0x49/0xbe
+RIP: 0033:0x457d97
+RSP: 002b:00007ffd46f9c8e8 EFLAGS: 00000246 ORIG_RAX: 00000000000000a6
+RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000457d97
+RDX: 00000000014b09a3 RSI: 0000000000000002 RDI: 00007ffd46f9da50
+RBP: 00007ffd46f9da50 R08: 0000000000000000 R09: 0000000000000009
+R10: 0000000000000005 R11: 0000000000000246 R12: 00000000014b0940
+R13: 0000000000000000 R14: 0000000000000002 R15: 000000000000658e
+RIP: update_sit_entry+0x1215/0x1590 fs/f2fs/segment.c:1882 RSP: ffff8801af526708
+---[ end trace f498328bb02610a2 ]---
+
+Reported-and-tested-by: syzbot+bf9253040425feb155ad@syzkaller.appspotmail.com
+Reported-and-tested-by: syzbot+7d6d31d3bc702f566ce3@syzkaller.appspotmail.com
+Reported-and-tested-by: syzbot+0a725420475916460f12@syzkaller.appspotmail.com
+Reviewed-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/segment.c |   16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -3251,6 +3251,7 @@ static int build_sit_entries(struct f2fs
+       unsigned int i, start, end;
+       unsigned int readed, start_blk = 0;
+       int err = 0;
++      block_t total_node_blocks = 0;
+       do {
+               readed = ra_meta_pages(sbi, start_blk, BIO_MAX_PAGES,
+@@ -3273,6 +3274,8 @@ static int build_sit_entries(struct f2fs
+                       if (err)
+                               return err;
+                       seg_info_from_raw_sit(se, &sit);
++                      if (IS_NODESEG(se->type))
++                              total_node_blocks += se->valid_blocks;
+                       /* build discard map only one time */
+                       if (f2fs_discard_en(sbi)) {
+@@ -3305,11 +3308,15 @@ static int build_sit_entries(struct f2fs
+               sit = sit_in_journal(journal, i);
+               old_valid_blocks = se->valid_blocks;
++              if (IS_NODESEG(se->type))
++                      total_node_blocks -= old_valid_blocks;
+               err = check_block_count(sbi, start, &sit);
+               if (err)
+                       break;
+               seg_info_from_raw_sit(se, &sit);
++              if (IS_NODESEG(se->type))
++                      total_node_blocks += se->valid_blocks;
+               if (f2fs_discard_en(sbi)) {
+                       if (is_set_ckpt_flags(sbi, CP_TRIMMED_FLAG)) {
+@@ -3328,6 +3335,15 @@ static int build_sit_entries(struct f2fs
+                               se->valid_blocks - old_valid_blocks;
+       }
+       up_read(&curseg->journal_rwsem);
++
++      if (!err && total_node_blocks != valid_node_count(sbi)) {
++              f2fs_msg(sbi->sb, KERN_ERR,
++                      "SIT is corrupted node# %u vs %u",
++                      total_node_blocks, valid_node_count(sbi));
++              set_sbi_flag(sbi, SBI_NEED_FSCK);
++              err = -EINVAL;
++      }
++
+       return err;
+ }
diff --git a/queue-4.14/kvm-irqfd-fix-race-between-epollhup-and-irq_bypass_register_consumer.patch b/queue-4.14/kvm-irqfd-fix-race-between-epollhup-and-irq_bypass_register_consumer.patch
new file mode 100644 (file)
index 0000000..e1d0e92
--- /dev/null
@@ -0,0 +1,51 @@
+From 9432a3175770e06cb83eada2d91fac90c977cb99 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Mon, 28 May 2018 13:31:13 +0200
+Subject: KVM: irqfd: fix race between EPOLLHUP and irq_bypass_register_consumer
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+commit 9432a3175770e06cb83eada2d91fac90c977cb99 upstream.
+
+A comment warning against this bug is there, but the code is not doing what
+the comment says.  Therefore it is possible that an EPOLLHUP races against
+irq_bypass_register_consumer.  The EPOLLHUP handler schedules irqfd_shutdown,
+and if that runs soon enough, you get a use-after-free.
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ virt/kvm/eventfd.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/virt/kvm/eventfd.c
++++ b/virt/kvm/eventfd.c
+@@ -405,11 +405,6 @@ kvm_irqfd_assign(struct kvm *kvm, struct
+       if (events & POLLIN)
+               schedule_work(&irqfd->inject);
+-      /*
+-       * do not drop the file until the irqfd is fully initialized, otherwise
+-       * we might race against the POLLHUP
+-       */
+-      fdput(f);
+ #ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
+       if (kvm_arch_has_irq_bypass()) {
+               irqfd->consumer.token = (void *)irqfd->eventfd;
+@@ -425,6 +420,12 @@ kvm_irqfd_assign(struct kvm *kvm, struct
+ #endif
+       srcu_read_unlock(&kvm->irq_srcu, idx);
++
++      /*
++       * do not drop the file until the irqfd is fully initialized, otherwise
++       * we might race against the POLLHUP
++       */
++      fdput(f);
+       return 0;
+ fail:
index 74b65a9e946a0a277cbadb99dc25ab51c9b9526c..ca2b5027a2ce5c4b7b4fa50c8aaa5a8e506ce994 100644 (file)
@@ -198,3 +198,6 @@ soc-imx-gpc-restrict-register-range-for-regmap-access.patch
 acpi-ec-use-ec_no_wakeup-on-more-thinkpad-x1-carbon-6th-systems.patch
 arm-dts-imx6-rdu2-fix-irq-type-for-mv88e6xxx-switch.patch
 nvme-fix-handling-of-metadata_len-for-nvme_ioctl_io_cmd.patch
+kvm-irqfd-fix-race-between-epollhup-and-irq_bypass_register_consumer.patch
+f2fs-return-error-during-fill_super.patch
+f2fs-sanity-check-for-total-valid-node-blocks.patch