]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 28 Jun 2023 19:01:11 +0000 (21:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 28 Jun 2023 19:01:11 +0000 (21:01 +0200)
added patches:
gfs2-don-t-deref-jdesc-in-evict.patch
series

queue-4.19/gfs2-don-t-deref-jdesc-in-evict.patch [new file with mode: 0644]
queue-4.19/series [new file with mode: 0644]

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 (file)
index 0000000..57ffd08
--- /dev/null
@@ -0,0 +1,63 @@
+From 504a10d9e46bc37b23d0a1ae2f28973c8516e636 Mon Sep 17 00:00:00 2001
+From: Bob Peterson <rpeterso@redhat.com>
+Date: Fri, 28 Apr 2023 12:07:46 -0400
+Subject: gfs2: Don't deref jdesc in evict
+
+From: Bob Peterson <rpeterso@redhat.com>
+
+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 <lanyang0908@gmail.com>
+Signed-off-by: Bob Peterson <rpeterso@redhat.com>
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+[DP: adjusted context]
+Signed-off-by: Dragos-Marian Panait <dragos.panait@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..2a26bd9
--- /dev/null
@@ -0,0 +1 @@
+gfs2-don-t-deref-jdesc-in-evict.patch