da8194b45d
- Remove openSUSE Tumbleweed specific handling for default grub distributor (bsc#1191198) - Use /usr/lib/os-release as fallback (bsc#1191196) * grub2-default-distributor.patch * grub2-check-default.sh - VUL-0: grub2: grub2-once uses fixed file name in /var/tmp (bsc#1190474) * grub2-once * grub2-once.service - Fix unknown TPM error on buggy uefi firmware (bsc#1191504) * 0001-tpm-Pass-unknown-error-as-non-fatal-but-debug-print-.patch - Fix error /boot/grub2/locale/POSIX.gmo not found (bsc#1189769) * 0001-Filter-out-POSIX-locale-for-translation.patch - Fix error lvmid disk cannot be found after second disk added to the root volume group (bsc#1189874) (bsc#1071559) * 0001-ieee1275-implement-FCP-methods-for-WWPN-and-LUNs.patch - Fix error in grub installation due to unnecessary requirement to support excessive device for the root logical volume (bsc#1184135) * 0001-disk-diskfilter-Use-nodes-in-logical-volume-s-segmen.patch - Fix regression in reading xfs v4 *0001-fs-xfs-Fix-unreadable-filesystem-with-v4-superblock.patch OBS-URL: https://build.opensuse.org/request/show/928444 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=396
121 lines
4.3 KiB
Diff
121 lines
4.3 KiB
Diff
From 7c11f4f3d71c3fc8acff820b1fd449c94095dab9 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>
|
|
---
|
|
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 0f524c3a8..e3816d1ec 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
|
|
{
|
|
--
|
|
2.31.1
|
|
|