]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Aug 2024 14:42:05 +0000 (16:42 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Aug 2024 14:42:05 +0000 (16:42 +0200)
added patches:
xfs-fix-log-recovery-buffer-allocation-for-the-legacy-h_size-fixup.patch

queue-5.15/series
queue-5.15/xfs-fix-log-recovery-buffer-allocation-for-the-legacy-h_size-fixup.patch [new file with mode: 0644]

index cb83b4e8d798eda1d605fbf94793b27a5cd2ad02..a7b140eb8d991dcae1349af2cd18bc2475366883 100644 (file)
@@ -484,3 +484,4 @@ selftests-mptcp-join-validate-backup-in-mpj.patch
 selftests-mptcp-join-check-backup-support-in-signal-endp.patch
 btrfs-fix-corruption-after-buffer-fault-in-during-direct-io-append-write.patch
 ipv6-fix-source-address-selection-with-route-leak.patch
+xfs-fix-log-recovery-buffer-allocation-for-the-legacy-h_size-fixup.patch
diff --git a/queue-5.15/xfs-fix-log-recovery-buffer-allocation-for-the-legacy-h_size-fixup.patch b/queue-5.15/xfs-fix-log-recovery-buffer-allocation-for-the-legacy-h_size-fixup.patch
new file mode 100644 (file)
index 0000000..fe0f157
--- /dev/null
@@ -0,0 +1,72 @@
+From 45cf976008ddef4a9c9a30310c9b4fb2a9a6602a Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Tue, 30 Apr 2024 06:07:55 +0200
+Subject: xfs: fix log recovery buffer allocation for the legacy h_size fixup
+
+From: Christoph Hellwig <hch@lst.de>
+
+commit 45cf976008ddef4a9c9a30310c9b4fb2a9a6602a upstream.
+
+Commit a70f9fe52daa ("xfs: detect and handle invalid iclog size set by
+mkfs") added a fixup for incorrect h_size values used for the initial
+umount record in old xfsprogs versions.  Later commit 0c771b99d6c9
+("xfs: clean up calculation of LR header blocks") cleaned up the log
+reover buffer calculation, but stoped using the fixed up h_size value
+to size the log recovery buffer, which can lead to an out of bounds
+access when the incorrect h_size does not come from the old mkfs
+tool, but a fuzzer.
+
+Fix this by open coding xlog_logrec_hblks and taking the fixed h_size
+into account for this calculation.
+
+Fixes: 0c771b99d6c9 ("xfs: clean up calculation of LR header blocks")
+Reported-by: Sam Sun <samsun1006219@gmail.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
+Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
+Signed-off-by: Kevin Berry <kpberry@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_log_recover.c |   20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+--- a/fs/xfs/xfs_log_recover.c
++++ b/fs/xfs/xfs_log_recover.c
+@@ -2972,7 +2972,7 @@ xlog_do_recovery_pass(
+       int                     error = 0, h_size, h_len;
+       int                     error2 = 0;
+       int                     bblks, split_bblks;
+-      int                     hblks, split_hblks, wrapped_hblks;
++      int                     hblks = 1, split_hblks, wrapped_hblks;
+       int                     i;
+       struct hlist_head       rhash[XLOG_RHASH_SIZE];
+       LIST_HEAD               (buffer_list);
+@@ -3028,14 +3028,22 @@ xlog_do_recovery_pass(
+               if (error)
+                       goto bread_err1;
+-              hblks = xlog_logrec_hblks(log, rhead);
+-              if (hblks != 1) {
+-                      kmem_free(hbp);
+-                      hbp = xlog_alloc_buffer(log, hblks);
++              /*
++               * This open codes xlog_logrec_hblks so that we can reuse the
++               * fixed up h_size value calculated above.  Without that we'd
++               * still allocate the buffer based on the incorrect on-disk
++               * size.
++               */
++              if (h_size > XLOG_HEADER_CYCLE_SIZE &&
++                  (rhead->h_version & cpu_to_be32(XLOG_VERSION_2))) {
++                      hblks = DIV_ROUND_UP(h_size, XLOG_HEADER_CYCLE_SIZE);
++                      if (hblks > 1) {
++                              kmem_free(hbp);
++                              hbp = xlog_alloc_buffer(log, hblks);
++                      }
+               }
+       } else {
+               ASSERT(log->l_sectBBsize == 1);
+-              hblks = 1;
+               hbp = xlog_alloc_buffer(log, 1);
+               h_size = XLOG_BIG_RECORD_BSIZE;
+       }