Hi folks, in order to fix CVE-2024-39472 in kernels 5.15, 6.1, and 6.6, I have adapted the mainline patch 45cf976008dd (xfs: fix log recovery buffer allocation for the legacy h_size fixup) to resolve conflicts with those kernels. Specifically, the mainline patch uses kvfree, but the amended patch uses kmem_free since kmem_free was used in xfs until patch 49292576136f (xfs: convert kmem_free() for kvmalloc users to kvfree()).
I tested the patch by applying it to the above kernels and recompiling them. I also ran xfstests on the 6.6.43 kernel with the patch applied. In my initial xfstests run, all xfs and generic tests passed except for generic/082, generic/269, generic/627, and xfs/155, but those tests all passed on a second run. I'm assuming those initial failures were unrelated to this patch, unless someone more familiar with those tests thinks otherwise.
I'd be more than happy to do any more verification or tests if they're required. Thanks!
Christoph Hellwig (1): xfs: fix log recovery buffer allocation for the legacy h_size fixup
fs/xfs/xfs_log_recover.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
base-commit: 58b0425ff5df680d0b67f64ae1f3f1ebdf1c4de9
From: Christoph Hellwig hch@lst.de
[ Upstream commit 45cf976008ddef4a9c9a30310c9b4fb2a9a6602a ]
Note: The upstream commit was adjusted to use kmem_free instead of kvfree since kmem_free was used in xfs_log_recover.c until commit 49292576136f (xfs: convert kmem_free() for kvmalloc users to kvfree()), and the remainder of the file still uses kmem_free.
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 --- fs/xfs/xfs_log_recover.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
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; }
On Sat, Aug 10, 2024 at 01:16:45AM +0000, Kevin Berry wrote:
Hi folks, in order to fix CVE-2024-39472 in kernels 5.15, 6.1, and 6.6, I have adapted the mainline patch 45cf976008dd (xfs: fix log recovery buffer allocation for the legacy h_size fixup) to resolve conflicts with those kernels. Specifically, the mainline patch uses kvfree, but the amended patch uses kmem_free since kmem_free was used in xfs until patch 49292576136f (xfs: convert kmem_free() for kvmalloc users to kvfree()).
I tested the patch by applying it to the above kernels and recompiling them. I also ran xfstests on the 6.6.43 kernel with the patch applied. In my initial xfstests run, all xfs and generic tests passed except for generic/082, generic/269, generic/627, and xfs/155, but those tests all passed on a second run. I'm assuming those initial failures were unrelated to this patch, unless someone more familiar with those tests thinks otherwise.
I'd be more than happy to do any more verification or tests if they're required. Thanks!
Note, for xfs changes, you do need to actually cc: the xfs developers :(
Please do so in the future...
thanks,
greg k-h
linux-stable-mirror@lists.linaro.org