--- /dev/null
+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;
+ }