fs/xfs: Fix unreadable filesystem with v4 superblock

While we're here, also: check for the PE magic for the compiled arch

Resolves: rhbz#2008819
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
This commit is contained in:
Robbie Harwood 2021-09-29 16:11:15 +00:00
parent 64dc7670b0
commit 07cf41c169
4 changed files with 189 additions and 1 deletions

View file

@ -0,0 +1,63 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 9 Sep 2021 10:59:28 -0400
Subject: [PATCH] Arm: check for the PE magic for the compiled arch
In "arm64: Fix EFI loader kernel image allocation", Ben fixed the kernel
alignment to match the alignment given in the PE header. In doing so, a
check for valid PE magic was added, which was hard-coded to the value
seen on Aarch64 (GRUB_PE32_PE64_MAGIC).
Unfortunately, this code is shared between 64-bit and 32-bit, and so
that value broke 32-bit Arm systems.
This patch adds a constant definition for GRUB_PE32_PEXX_MAGIC, which is
either GRUB_PE32_PE64_MAGIC or GRUB_PE32_PE32_MAGIC, depending on which
platform is being built, and uses it in the header magic check.
Resolves: rhbz#2000756
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/loader/arm64/linux.c | 2 +-
include/grub/arm/linux.h | 1 +
include/grub/arm64/linux.h | 1 +
3 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 4a252d5e7e9..f18d90bd749 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -322,7 +322,7 @@ parse_pe_header (void *kernel, grub_uint64_t *total_size,
pe = (void *)((unsigned long)kernel + lh->hdr_offset);
- if (pe->opt.magic != GRUB_PE32_PE64_MAGIC)
+ if (pe->opt.magic != GRUB_PE32_PEXX_MAGIC)
return grub_error(GRUB_ERR_BAD_OS, "Invalid PE optional header magic");
*total_size = pe->opt.image_size;
diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
index b582f67f661..966a5074f53 100644
--- a/include/grub/arm/linux.h
+++ b/include/grub/arm/linux.h
@@ -44,6 +44,7 @@ struct grub_arm_linux_pe_header
#if defined(__arm__)
# define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE
+# define GRUB_PE32_PEXX_MAGIC GRUB_PE32_PE32_MAGIC
# define linux_arch_kernel_header linux_arm_kernel_header
# define grub_armxx_linux_pe_header grub_arm_linux_pe_header
#endif
diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h
index ea030312df3..422bf2bf24b 100644
--- a/include/grub/arm64/linux.h
+++ b/include/grub/arm64/linux.h
@@ -48,6 +48,7 @@ struct grub_arm64_linux_pe_header
#if defined(__aarch64__)
# define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE
+# define GRUB_PE32_PEXX_MAGIC GRUB_PE32_PE64_MAGIC
# define linux_arch_kernel_header linux_arm64_kernel_header
# define grub_armxx_linux_pe_header grub_arm64_linux_pe_header
#endif

View file

@ -0,0 +1,118 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Erwan Velu <erwanaliasr1@gmail.com>
Date: Wed, 25 Aug 2021 15:31:52 +0200
Subject: [PATCH] fs/xfs: Fix unreadable filesystem with v4 superblock
The commit 8b1e5d193 (fs/xfs: Add bigtime incompat feature support)
introduced the bigtime support by adding some features in v3 inodes.
This change extended grub_xfs_inode struct by 76 bytes but also changed
the computation of XFS_V2_INODE_SIZE and XFS_V3_INODE_SIZE. Prior this
commit, XFS_V2_INODE_SIZE was 100 bytes. After the commit it's 84 bytes
XFS_V2_INODE_SIZE becomes 16 bytes too small.
As a result, the data structures aren't properly aligned and the GRUB
generates "attempt to read or write outside of partition" errors when
trying to read the XFS filesystem:
GNU GRUB version 2.11
....
grub> set debug=efi,gpt,xfs
grub> insmod part_gpt
grub> ls (hd0,gpt1)/
partmap/gpt.c:93: Read a valid GPT header
partmap/gpt.c:115: GPT entry 0: start=4096, length=1953125
fs/xfs.c:931: Reading sb
fs/xfs.c:270: Validating superblock
fs/xfs.c:295: XFS v4 superblock detected
fs/xfs.c:962: Reading root ino 128
fs/xfs.c:515: Reading inode (128) - 64, 0
fs/xfs.c:515: Reading inode (739521961424144223) - 344365866970255880, 3840
error: attempt to read or write outside of partition.
This commit change the XFS_V2_INODE_SIZE computation by subtracting 76
bytes instead of 92 bytes from the actual size of grub_xfs_inode struct.
This 76 bytes value comes from added members:
20 grub_uint8_t unused5
1 grub_uint64_t flags2
48 grub_uint8_t unused6
This patch explicitly splits the v2 and v3 parts of the structure.
The unused4 is still ending of the v2 structures and the v3 starts
at unused5. Thanks to this we will avoid future corruptions of v2
or v3 inodes.
The XFS_V2_INODE_SIZE is returning to its expected size and the
filesystem is back to a readable state:
GNU GRUB version 2.11
....
grub> set debug=efi,gpt,xfs
grub> insmod part_gpt
grub> ls (hd0,gpt1)/
partmap/gpt.c:93: Read a valid GPT header
partmap/gpt.c:115: GPT entry 0: start=4096, length=1953125
fs/xfs.c:931: Reading sb
fs/xfs.c:270: Validating superblock
fs/xfs.c:295: XFS v4 superblock detected
fs/xfs.c:962: Reading root ino 128
fs/xfs.c:515: Reading inode (128) - 64, 0
fs/xfs.c:515: Reading inode (128) - 64, 0
fs/xfs.c:931: Reading sb
fs/xfs.c:270: Validating superblock
fs/xfs.c:295: XFS v4 superblock detected
fs/xfs.c:962: Reading root ino 128
fs/xfs.c:515: Reading inode (128) - 64, 0
fs/xfs.c:515: Reading inode (128) - 64, 0
fs/xfs.c:515: Reading inode (128) - 64, 0
fs/xfs.c:515: Reading inode (131) - 64, 768
efi/ fs/xfs.c:515: Reading inode (3145856) - 1464904, 0
grub2/ fs/xfs.c:515: Reading inode (132) - 64, 1024
grub/ fs/xfs.c:515: Reading inode (139) - 64, 2816
grub>
Fixes: 8b1e5d193 (fs/xfs: Add bigtime incompat feature support)
Signed-off-by: Erwan Velu <e.velu@criteo.com>
Tested-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
(cherry picked from commit a4b495520e4dc41a896a8b916a64eda9970c50ea)
---
grub-core/fs/xfs.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index 0f524c3a8a6..e3816d1ec4a 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -192,6 +192,11 @@ struct grub_xfs_time_legacy
grub_uint32_t nanosec;
} GRUB_PACKED;
+/*
+ * The struct grub_xfs_inode layout was taken from the
+ * struct xfs_dinode_core which is described here:
+ * https://mirrors.edge.kernel.org/pub/linux/utils/fs/xfs/docs/xfs_filesystem_structure.pdf
+ */
struct grub_xfs_inode
{
grub_uint8_t magic[2];
@@ -208,14 +213,15 @@ struct grub_xfs_inode
grub_uint32_t nextents;
grub_uint16_t unused3;
grub_uint8_t fork_offset;
- grub_uint8_t unused4[37];
+ grub_uint8_t unused4[17]; /* Last member of inode v2. */
+ grub_uint8_t unused5[20]; /* First member of inode v3. */
grub_uint64_t flags2;
- grub_uint8_t unused5[48];
+ grub_uint8_t unused6[48]; /* Last member of inode v3. */
} GRUB_PACKED;
#define XFS_V3_INODE_SIZE sizeof(struct grub_xfs_inode)
-/* Size of struct grub_xfs_inode until fork_offset (included). */
-#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 92)
+/* Size of struct grub_xfs_inode v2, up to unused4 member included. */
+#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 76)
struct grub_xfs_dirblock_tail
{

View file

@ -217,3 +217,5 @@ Patch0216: 0216-arm64-Fix-EFI-loader-kernel-image-allocation.patch
Patch0217: 0217-normal-main-Discover-the-device-to-read-the-config-f.patch Patch0217: 0217-normal-main-Discover-the-device-to-read-the-config-f.patch
Patch0218: 0218-powerpc-adjust-setting-of-prefix-for-signed-binary-c.patch Patch0218: 0218-powerpc-adjust-setting-of-prefix-for-signed-binary-c.patch
Patch0219: 0219-powerpc-fix-prefix-signed-grub-special-case-for-Powe.patch Patch0219: 0219-powerpc-fix-prefix-signed-grub-special-case-for-Powe.patch
Patch0220: 0220-Arm-check-for-the-PE-magic-for-the-compiled-arch.patch
Patch0221: 0221-fs-xfs-Fix-unreadable-filesystem-with-v4-superblock.patch

View file

@ -14,7 +14,7 @@
Name: grub2 Name: grub2
Epoch: 1 Epoch: 1
Version: 2.06 Version: 2.06
Release: 5%{?dist} Release: 6%{?dist}
Summary: Bootloader with support for Linux, Multiboot and more Summary: Bootloader with support for Linux, Multiboot and more
License: GPLv3+ License: GPLv3+
URL: http://www.gnu.org/software/grub/ URL: http://www.gnu.org/software/grub/
@ -523,6 +523,11 @@ mv ${EFI_HOME}/grub.cfg.stb ${EFI_HOME}/grub.cfg
%endif %endif
%changelog %changelog
* Wed Sep 29 2021 Robbie Harwood <rharwood@redhat.com> - 2.06-6
- fs/xfs: Fix unreadable filesystem with v4 superblock
- Arm: check for the PE magic for the compiled arch
- Resolves: rhbz#2008819
* Mon Aug 30 2021 Javier Martinez Canillas <javierm@redhat.com> - 2.06-5 * Mon Aug 30 2021 Javier Martinez Canillas <javierm@redhat.com> - 2.06-5
- A few fixes for ppc64le LPAR Secure Boot support - A few fixes for ppc64le LPAR Secure Boot support