diff mbox series

[6.6,CANDIDATE,03/22] xfs: fix log recovery buffer allocation for the legacy h_size fixup

Message ID 20240906211136.70391-4-catherine.hoang@oracle.com (mailing list archive)
State Not Applicable, archived
Headers show
Series xfs backports for 6.6.y (from 6.10) | expand

Commit Message

Catherine Hoang Sept. 6, 2024, 9:11 p.m. UTC
From: Christoph Hellwig <hch@lst.de>

commit 45cf976008ddef4a9c9a30310c9b4fb2a9a6602a upstream.

[backport: resolve conflict due to kmem_free->kvfree conversion]

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: Catherine Hoang <catherine.hoang@oracle.com>
---
 fs/xfs/xfs_log_recover.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

Comments

Chandan Babu R Sept. 24, 2024, 12:04 p.m. UTC | #1
On Fri, Sep 06, 2024 at 02:11:17 PM -0700, Catherine Hoang wrote:
> From: Christoph Hellwig <hch@lst.de>
>
> commit 45cf976008ddef4a9c9a30310c9b4fb2a9a6602a upstream.
>
> [backport: resolve conflict due to kmem_free->kvfree conversion]
>
> 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.

Looks like this commit has already been backported to 6.6.y. Please refer to
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=c2389c074973aa94e34992e7f66dac0de37595b5
diff mbox series

Patch

diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 57f366c3d355..9f9d3abad2cf 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2965,7 +2965,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);
@@ -3021,14 +3021,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;
 	}