From 51a0d7fade373bf0773e7459139c70e2be17d57c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 28 Jun 2023 21:01:11 +0200 Subject: [PATCH] 4.19-stable patches added patches: gfs2-don-t-deref-jdesc-in-evict.patch series --- .../gfs2-don-t-deref-jdesc-in-evict.patch | 63 +++++++++++++++++++ queue-4.19/series | 1 + 2 files changed, 64 insertions(+) create mode 100644 queue-4.19/gfs2-don-t-deref-jdesc-in-evict.patch create mode 100644 queue-4.19/series diff --git a/queue-4.19/gfs2-don-t-deref-jdesc-in-evict.patch b/queue-4.19/gfs2-don-t-deref-jdesc-in-evict.patch new file mode 100644 index 00000000000..57ffd085898 --- /dev/null +++ b/queue-4.19/gfs2-don-t-deref-jdesc-in-evict.patch @@ -0,0 +1,63 @@ +From 504a10d9e46bc37b23d0a1ae2f28973c8516e636 Mon Sep 17 00:00:00 2001 +From: Bob Peterson +Date: Fri, 28 Apr 2023 12:07:46 -0400 +Subject: gfs2: Don't deref jdesc in evict + +From: Bob Peterson + +commit 504a10d9e46bc37b23d0a1ae2f28973c8516e636 upstream. + +On corrupt gfs2 file systems the evict code can try to reference the +journal descriptor structure, jdesc, after it has been freed and set to +NULL. The sequence of events is: + +init_journal() +... +fail_jindex: + gfs2_jindex_free(sdp); <------frees journals, sets jdesc = NULL + if (gfs2_holder_initialized(&ji_gh)) + gfs2_glock_dq_uninit(&ji_gh); +fail: + iput(sdp->sd_jindex); <--references jdesc in evict_linked_inode + evict() + gfs2_evict_inode() + evict_linked_inode() + ret = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); +<------references the now freed/zeroed sd_jdesc pointer. + +The call to gfs2_trans_begin is done because the truncate_inode_pages +call can cause gfs2 events that require a transaction, such as removing +journaled data (jdata) blocks from the journal. + +This patch fixes the problem by adding a check for sdp->sd_jdesc to +function gfs2_evict_inode. In theory, this should only happen to corrupt +gfs2 file systems, when gfs2 detects the problem, reports it, then tries +to evict all the system inodes it has read in up to that point. + +Reported-by: Yang Lan +Signed-off-by: Bob Peterson +Signed-off-by: Andreas Gruenbacher +[DP: adjusted context] +Signed-off-by: Dragos-Marian Panait +Signed-off-by: Greg Kroah-Hartman +--- + fs/gfs2/super.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/fs/gfs2/super.c ++++ b/fs/gfs2/super.c +@@ -1586,6 +1586,14 @@ static void gfs2_evict_inode(struct inod + if (inode->i_nlink || sb_rdonly(sb)) + goto out; + ++ /* ++ * In case of an incomplete mount, gfs2_evict_inode() may be called for ++ * system files without having an active journal to write to. In that ++ * case, skip the filesystem evict. ++ */ ++ if (!sdp->sd_jdesc) ++ goto out; ++ + if (test_bit(GIF_ALLOC_FAILED, &ip->i_flags)) { + BUG_ON(!gfs2_glock_is_locked_by_me(ip->i_gl)); + gfs2_holder_mark_uninitialized(&gh); diff --git a/queue-4.19/series b/queue-4.19/series new file mode 100644 index 00000000000..2a26bd910b0 --- /dev/null +++ b/queue-4.19/series @@ -0,0 +1 @@ +gfs2-don-t-deref-jdesc-in-evict.patch -- 2.47.3