--- /dev/null
+From stable+bounces-216866-greg=kroah.com@vger.kernel.org Tue Feb 17 18:30:23 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 12:30:16 -0500
+Subject: f2fs: fix to do sanity check on node footer in __write_node_folio()
+To: stable@vger.kernel.org
+Cc: Chao Yu <chao@kernel.org>, Jaegeuk Kim <jaegeuk@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260217173017.3790988-1-sashal@kernel.org>
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 0a736109c9d29de0c26567e42cb99b27861aa8ba ]
+
+Add node footer sanity check during node folio's writeback, if sanity
+check fails, let's shutdown filesystem to avoid looping to redirty
+and writeback in .writepages.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/node.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -1751,7 +1751,11 @@ static bool __write_node_folio(struct fo
+
+ /* get old block addr of this node page */
+ nid = nid_of_node(folio);
+- f2fs_bug_on(sbi, folio->index != nid);
++
++ if (sanity_check_node_footer(sbi, folio, nid, NODE_TYPE_REGULAR)) {
++ f2fs_handle_critical_error(sbi, STOP_CP_REASON_CORRUPTED_NID);
++ goto redirty_out;
++ }
+
+ if (f2fs_get_node_info(sbi, nid, &ni, !do_balance))
+ goto redirty_out;
--- /dev/null
+From stable+bounces-216867-greg=kroah.com@vger.kernel.org Tue Feb 17 18:30:25 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 12:30:17 -0500
+Subject: f2fs: fix to do sanity check on node footer in {read,write}_end_io
+To: stable@vger.kernel.org
+Cc: Chao Yu <chao@kernel.org>, stable@kernel.org, syzbot+803dd716c4310d16ff3a@syzkaller.appspotmail.com, Jaegeuk Kim <jaegeuk@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260217173017.3790988-2-sashal@kernel.org>
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 50ac3ecd8e05b6bcc350c71a4307d40c030ec7e4 ]
+
+-----------[ cut here ]------------
+kernel BUG at fs/f2fs/data.c:358!
+Call Trace:
+ <IRQ>
+ blk_update_request+0x5eb/0xe70 block/blk-mq.c:987
+ blk_mq_end_request+0x3e/0x70 block/blk-mq.c:1149
+ blk_complete_reqs block/blk-mq.c:1224 [inline]
+ blk_done_softirq+0x107/0x160 block/blk-mq.c:1229
+ handle_softirqs+0x283/0x870 kernel/softirq.c:579
+ __do_softirq kernel/softirq.c:613 [inline]
+ invoke_softirq kernel/softirq.c:453 [inline]
+ __irq_exit_rcu+0xca/0x1f0 kernel/softirq.c:680
+ irq_exit_rcu+0x9/0x30 kernel/softirq.c:696
+ instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1050 [inline]
+ sysvec_apic_timer_interrupt+0xa6/0xc0 arch/x86/kernel/apic/apic.c:1050
+ </IRQ>
+
+In f2fs_write_end_io(), it detects there is inconsistency in between
+node page index (nid) and footer.nid of node page.
+
+If footer of node page is corrupted in fuzzed image, then we load corrupted
+node page w/ async method, e.g. f2fs_ra_node_pages() or f2fs_ra_node_page(),
+in where we won't do sanity check on node footer, once node page becomes
+dirty, we will encounter this bug after node page writeback.
+
+Cc: stable@kernel.org
+Reported-by: syzbot+803dd716c4310d16ff3a@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=803dd716c4310d16ff3a
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+[ Context ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/data.c | 13 +++++++++++--
+ fs/f2fs/f2fs.h | 12 ++++++++++++
+ fs/f2fs/node.c | 20 +++++++++++---------
+ fs/f2fs/node.h | 8 --------
+ 4 files changed, 34 insertions(+), 19 deletions(-)
+
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -151,6 +151,12 @@ static void f2fs_finish_read_bio(struct
+ }
+
+ dec_page_count(F2FS_F_SB(folio), __read_io_type(folio));
++
++ if (F2FS_F_SB(folio)->node_inode && is_node_folio(folio) &&
++ f2fs_sanity_check_node_footer(F2FS_F_SB(folio),
++ folio, folio->index, NODE_TYPE_REGULAR, true))
++ bio->bi_status = BLK_STS_IOERR;
++
+ folio_end_read(folio, bio->bi_status == BLK_STS_OK);
+ }
+
+@@ -352,8 +358,11 @@ static void f2fs_write_end_io(struct bio
+ STOP_CP_REASON_WRITE_FAIL);
+ }
+
+- f2fs_bug_on(sbi, is_node_folio(folio) &&
+- folio->index != nid_of_node(folio));
++ if (is_node_folio(folio)) {
++ f2fs_sanity_check_node_footer(sbi, folio,
++ folio->index, NODE_TYPE_REGULAR, true);
++ f2fs_bug_on(sbi, folio->index != nid_of_node(folio));
++ }
+
+ dec_page_count(sbi, type);
+
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -1529,6 +1529,15 @@ enum f2fs_lookup_mode {
+ LOOKUP_AUTO,
+ };
+
++/* For node type in __get_node_folio() */
++enum node_type {
++ NODE_TYPE_REGULAR,
++ NODE_TYPE_INODE,
++ NODE_TYPE_XATTR,
++ NODE_TYPE_NON_INODE,
++};
++
++
+ static inline int f2fs_test_bit(unsigned int nr, char *addr);
+ static inline void f2fs_set_bit(unsigned int nr, char *addr);
+ static inline void f2fs_clear_bit(unsigned int nr, char *addr);
+@@ -3877,6 +3886,9 @@ struct folio *f2fs_new_node_folio(struct
+ void f2fs_ra_node_page(struct f2fs_sb_info *sbi, nid_t nid);
+ struct folio *f2fs_get_node_folio(struct f2fs_sb_info *sbi, pgoff_t nid,
+ enum node_type node_type);
++int f2fs_sanity_check_node_footer(struct f2fs_sb_info *sbi,
++ struct folio *folio, pgoff_t nid,
++ enum node_type ntype, bool in_irq);
+ struct folio *f2fs_get_inode_folio(struct f2fs_sb_info *sbi, pgoff_t ino);
+ struct folio *f2fs_get_xnode_folio(struct f2fs_sb_info *sbi, pgoff_t xnid);
+ int f2fs_move_node_folio(struct folio *node_folio, int gc_type);
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -1500,9 +1500,9 @@ void f2fs_ra_node_page(struct f2fs_sb_in
+ f2fs_folio_put(afolio, err ? true : false);
+ }
+
+-static int sanity_check_node_footer(struct f2fs_sb_info *sbi,
++int f2fs_sanity_check_node_footer(struct f2fs_sb_info *sbi,
+ struct folio *folio, pgoff_t nid,
+- enum node_type ntype)
++ enum node_type ntype, bool in_irq)
+ {
+ if (unlikely(nid != nid_of_node(folio)))
+ goto out_err;
+@@ -1527,12 +1527,13 @@ static int sanity_check_node_footer(stru
+ goto out_err;
+ return 0;
+ out_err:
+- f2fs_warn(sbi, "inconsistent node block, node_type:%d, nid:%lu, "
+- "node_footer[nid:%u,ino:%u,ofs:%u,cpver:%llu,blkaddr:%u]",
+- ntype, nid, nid_of_node(folio), ino_of_node(folio),
+- ofs_of_node(folio), cpver_of_node(folio),
+- next_blkaddr_of_node(folio));
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
++ f2fs_warn_ratelimited(sbi, "inconsistent node block, node_type:%d, nid:%lu, "
++ "node_footer[nid:%u,ino:%u,ofs:%u,cpver:%llu,blkaddr:%u]",
++ ntype, nid, nid_of_node(folio), ino_of_node(folio),
++ ofs_of_node(folio), cpver_of_node(folio),
++ next_blkaddr_of_node(folio));
++
+ f2fs_handle_error(sbi, ERROR_INCONSISTENT_FOOTER);
+ return -EFSCORRUPTED;
+ }
+@@ -1578,7 +1579,7 @@ repeat:
+ goto out_err;
+ }
+ page_hit:
+- err = sanity_check_node_footer(sbi, folio, nid, ntype);
++ err = f2fs_sanity_check_node_footer(sbi, folio, nid, ntype, false);
+ if (!err)
+ return folio;
+ out_err:
+@@ -1752,7 +1753,8 @@ static bool __write_node_folio(struct fo
+ /* get old block addr of this node page */
+ nid = nid_of_node(folio);
+
+- if (sanity_check_node_footer(sbi, folio, nid, NODE_TYPE_REGULAR)) {
++ if (f2fs_sanity_check_node_footer(sbi, folio, nid,
++ NODE_TYPE_REGULAR, false)) {
+ f2fs_handle_critical_error(sbi, STOP_CP_REASON_CORRUPTED_NID);
+ goto redirty_out;
+ }
+--- a/fs/f2fs/node.h
++++ b/fs/f2fs/node.h
+@@ -52,14 +52,6 @@ enum {
+ IS_PREALLOC, /* nat entry is preallocated */
+ };
+
+-/* For node type in __get_node_folio() */
+-enum node_type {
+- NODE_TYPE_REGULAR,
+- NODE_TYPE_INODE,
+- NODE_TYPE_XATTR,
+- NODE_TYPE_NON_INODE,
+-};
+-
+ /*
+ * For node information
+ */