From 9e9b890c899c3743bd02f3430a9131761beea751 Mon Sep 17 00:00:00 2001 From: Nicolas Frayer Date: Wed, 26 Feb 2025 18:33:42 +0100 Subject: [PATCH] fs/ext2: Rework out-of-bounds read for inline and external extents Related: RHEL-79857 Signed-off-by: Nicolas Frayer --- ...ut-of-bounds-read-for-inline-and-ext.patch | 65 +++++++++++++++++++ grub.patches | 1 + grub2.spec | 6 +- 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 0454-fs-ext2-Rework-out-of-bounds-read-for-inline-and-ext.patch diff --git a/0454-fs-ext2-Rework-out-of-bounds-read-for-inline-and-ext.patch b/0454-fs-ext2-Rework-out-of-bounds-read-for-inline-and-ext.patch new file mode 100644 index 0000000..3b23dbe --- /dev/null +++ b/0454-fs-ext2-Rework-out-of-bounds-read-for-inline-and-ext.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Michael Chang via Grub-devel +Date: Fri, 21 Feb 2025 09:06:12 +0800 +Subject: [PATCH] fs/ext2: Rework out-of-bounds read for inline and external + extents + +Previously, the number of extent entries was not properly capped based +on the actual available space. This could lead to insufficient reads for +external extents, since the computation was based solely on the inline +extent layout. + +In this patch, when processing the extent header, we determine whether +the header is stored inline (i.e., at inode->blocks.dir_blocks) or in an +external extent block. We then clamp the number of entries accordingly +(using max_inline_ext for inline extents and max_external_ext for +external extent blocks). + +This change ensures that only the valid number of extent entries is +processed, preventing out-of-bound reads and potential filesystem +corruption. + +Fixes: 7e2f750f0a (fs/ext2: Fix out-of-bounds read for inline extents) + +Signed-off-by: Michael Chang +Tested-by: Christian Hesse +Reviewed-by: Daniel Kiper +--- + grub-core/fs/ext2.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c +index 0ee22e675181..ecf4dc0a33f5 100644 +--- a/grub-core/fs/ext2.c ++++ b/grub-core/fs/ext2.c +@@ -482,7 +482,10 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + int i; + grub_disk_addr_t ret; + grub_uint16_t nent; ++ /* maximum number of extent entries in the inode's inline extent area */ + const grub_uint16_t max_inline_ext = sizeof (inode->blocks) / sizeof (*ext) - 1; /* Minus 1 extent header. */ ++ /* maximum number of extent entries in the external extent block */ ++ const grub_uint16_t max_external_ext = EXT2_BLOCK_SIZE(data) / sizeof (*ext) - 1; /* Minus 1 extent header. */ + + leaf = grub_ext4_find_leaf (data, (struct grub_ext4_extent_header *) inode->blocks.dir_blocks, fileblock); + if (! leaf) +@@ -495,8 +498,18 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + + nent = grub_le_to_cpu16 (leaf->entries); + +- if (leaf->depth == 0) ++ /* ++ * Determine the effective number of extent entries (nent) to process: ++ * If the extent header (leaf) is stored inline in the inode’s block ++ * area (i.e. at inode->blocks.dir_blocks), then only max_inline_ext ++ * entries can fit. ++ * Otherwise, if the header was read from an external extent block, use ++ * the larger limit, max_external_ext, based on the full block size. ++ */ ++ if (leaf == (struct grub_ext4_extent_header *) inode->blocks.dir_blocks) + nent = grub_min (nent, max_inline_ext); ++ else ++ nent = grub_min (nent, max_external_ext); + + for (i = 0; i < nent; i++) + { diff --git a/grub.patches b/grub.patches index c25acf8..4720e55 100644 --- a/grub.patches +++ b/grub.patches @@ -451,3 +451,4 @@ Patch0450: 0450-loader-i386-bsd-Use-safe-math-to-avoid-underflow.patch Patch0451: 0451-types-Make-bool-generally-available.patch Patch0452: 0452-include-grub-types.h-Add-PRI-GRUB_OFFSET-and-PRI-GRU.patch Patch0453: 0453-fs-xfs-Fix-issues-found-while-fuzzing-the-XFS-filesy.patch +Patch0454: 0454-fs-ext2-Rework-out-of-bounds-read-for-inline-and-ext.patch diff --git a/grub2.spec b/grub2.spec index b6d2d56..e42bc87 100644 --- a/grub2.spec +++ b/grub2.spec @@ -16,7 +16,7 @@ Name: grub2 Epoch: 1 Version: 2.06 -Release: 96%{?dist} +Release: 97%{?dist} Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -547,6 +547,10 @@ mv ${EFI_HOME}/grub.cfg.stb ${EFI_HOME}/grub.cfg %endif %changelog +* Wed Feb 26 2025 Nicolas Frayer - 2.06-97 +- fs/ext2: Rework out-of-bounds read for inline and external extents +- Related: RHEL-79857 + * Wed Feb 12 2025 Nicolas Frayer - 2.06-96 - Fixes for several CVEs - Resolves: CVE-2024-45779 CVE-2024-45778 CVE-2025-1118