1 |
commit: e30b449f5df55dbb7b036639a39afc17972df03a |
2 |
Author: Mike Gilbert <floppym <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue Sep 7 17:08:24 2021 +0000 |
4 |
Commit: Mike Gilbert <floppym <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue Sep 7 17:27:45 2021 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=e30b449f |
7 |
|
8 |
sys-boot/grub: fix issue with XFS v4 superblocks |
9 |
|
10 |
Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org> |
11 |
|
12 |
sys-boot/grub/files/grub-2.06-xfs-v4.patch | 120 +++++++++++++++++++++ |
13 |
.../grub/{grub-2.06.ebuild => grub-2.06-r1.ebuild} | 1 + |
14 |
2 files changed, 121 insertions(+) |
15 |
|
16 |
diff --git a/sys-boot/grub/files/grub-2.06-xfs-v4.patch b/sys-boot/grub/files/grub-2.06-xfs-v4.patch |
17 |
new file mode 100644 |
18 |
index 00000000000..fe822378038 |
19 |
--- /dev/null |
20 |
+++ b/sys-boot/grub/files/grub-2.06-xfs-v4.patch |
21 |
@@ -0,0 +1,120 @@ |
22 |
+From a4b495520e4dc41a896a8b916a64eda9970c50ea Mon Sep 17 00:00:00 2001 |
23 |
+From: Erwan Velu <erwanaliasr1@×××××.com> |
24 |
+Date: Wed, 25 Aug 2021 15:31:52 +0200 |
25 |
+Subject: fs/xfs: Fix unreadable filesystem with v4 superblock |
26 |
+ |
27 |
+The commit 8b1e5d193 (fs/xfs: Add bigtime incompat feature support) |
28 |
+introduced the bigtime support by adding some features in v3 inodes. |
29 |
+This change extended grub_xfs_inode struct by 76 bytes but also changed |
30 |
+the computation of XFS_V2_INODE_SIZE and XFS_V3_INODE_SIZE. Prior this |
31 |
+commit, XFS_V2_INODE_SIZE was 100 bytes. After the commit it's 84 bytes |
32 |
+XFS_V2_INODE_SIZE becomes 16 bytes too small. |
33 |
+ |
34 |
+As a result, the data structures aren't properly aligned and the GRUB |
35 |
+generates "attempt to read or write outside of partition" errors when |
36 |
+trying to read the XFS filesystem: |
37 |
+ |
38 |
+ GNU GRUB version 2.11 |
39 |
+ .... |
40 |
+ grub> set debug=efi,gpt,xfs |
41 |
+ grub> insmod part_gpt |
42 |
+ grub> ls (hd0,gpt1)/ |
43 |
+ partmap/gpt.c:93: Read a valid GPT header |
44 |
+ partmap/gpt.c:115: GPT entry 0: start=4096, length=1953125 |
45 |
+ fs/xfs.c:931: Reading sb |
46 |
+ fs/xfs.c:270: Validating superblock |
47 |
+ fs/xfs.c:295: XFS v4 superblock detected |
48 |
+ fs/xfs.c:962: Reading root ino 128 |
49 |
+ fs/xfs.c:515: Reading inode (128) - 64, 0 |
50 |
+ fs/xfs.c:515: Reading inode (739521961424144223) - 344365866970255880, 3840 |
51 |
+ error: attempt to read or write outside of partition. |
52 |
+ |
53 |
+This commit change the XFS_V2_INODE_SIZE computation by subtracting 76 |
54 |
+bytes instead of 92 bytes from the actual size of grub_xfs_inode struct. |
55 |
+This 76 bytes value comes from added members: |
56 |
+ 20 grub_uint8_t unused5 |
57 |
+ 1 grub_uint64_t flags2 |
58 |
+ 48 grub_uint8_t unused6 |
59 |
+ |
60 |
+This patch explicitly splits the v2 and v3 parts of the structure. |
61 |
+The unused4 is still ending of the v2 structures and the v3 starts |
62 |
+at unused5. Thanks to this we will avoid future corruptions of v2 |
63 |
+or v3 inodes. |
64 |
+ |
65 |
+The XFS_V2_INODE_SIZE is returning to its expected size and the |
66 |
+filesystem is back to a readable state: |
67 |
+ |
68 |
+ GNU GRUB version 2.11 |
69 |
+ .... |
70 |
+ grub> set debug=efi,gpt,xfs |
71 |
+ grub> insmod part_gpt |
72 |
+ grub> ls (hd0,gpt1)/ |
73 |
+ partmap/gpt.c:93: Read a valid GPT header |
74 |
+ partmap/gpt.c:115: GPT entry 0: start=4096, length=1953125 |
75 |
+ fs/xfs.c:931: Reading sb |
76 |
+ fs/xfs.c:270: Validating superblock |
77 |
+ fs/xfs.c:295: XFS v4 superblock detected |
78 |
+ fs/xfs.c:962: Reading root ino 128 |
79 |
+ fs/xfs.c:515: Reading inode (128) - 64, 0 |
80 |
+ fs/xfs.c:515: Reading inode (128) - 64, 0 |
81 |
+ fs/xfs.c:931: Reading sb |
82 |
+ fs/xfs.c:270: Validating superblock |
83 |
+ fs/xfs.c:295: XFS v4 superblock detected |
84 |
+ fs/xfs.c:962: Reading root ino 128 |
85 |
+ fs/xfs.c:515: Reading inode (128) - 64, 0 |
86 |
+ fs/xfs.c:515: Reading inode (128) - 64, 0 |
87 |
+ fs/xfs.c:515: Reading inode (128) - 64, 0 |
88 |
+ fs/xfs.c:515: Reading inode (131) - 64, 768 |
89 |
+ efi/ fs/xfs.c:515: Reading inode (3145856) - 1464904, 0 |
90 |
+ grub2/ fs/xfs.c:515: Reading inode (132) - 64, 1024 |
91 |
+ grub/ fs/xfs.c:515: Reading inode (139) - 64, 2816 |
92 |
+ grub> |
93 |
+ |
94 |
+Fixes: 8b1e5d193 (fs/xfs: Add bigtime incompat feature support) |
95 |
+ |
96 |
+Signed-off-by: Erwan Velu <e.velu@××××××.com> |
97 |
+Tested-by: Carlos Maiolino <cmaiolino@××××××.com> |
98 |
+Reviewed-by: Daniel Kiper <daniel.kiper@××××××.com> |
99 |
+--- |
100 |
+ grub-core/fs/xfs.c | 14 ++++++++++---- |
101 |
+ 1 file changed, 10 insertions(+), 4 deletions(-) |
102 |
+ |
103 |
+diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c |
104 |
+index 0f524c3a8..e3816d1ec 100644 |
105 |
+--- a/grub-core/fs/xfs.c |
106 |
++++ b/grub-core/fs/xfs.c |
107 |
+@@ -192,6 +192,11 @@ struct grub_xfs_time_legacy |
108 |
+ grub_uint32_t nanosec; |
109 |
+ } GRUB_PACKED; |
110 |
+ |
111 |
++/* |
112 |
++ * The struct grub_xfs_inode layout was taken from the |
113 |
++ * struct xfs_dinode_core which is described here: |
114 |
++ * https://mirrors.edge.kernel.org/pub/linux/utils/fs/xfs/docs/xfs_filesystem_structure.pdf |
115 |
++ */ |
116 |
+ struct grub_xfs_inode |
117 |
+ { |
118 |
+ grub_uint8_t magic[2]; |
119 |
+@@ -208,14 +213,15 @@ struct grub_xfs_inode |
120 |
+ grub_uint32_t nextents; |
121 |
+ grub_uint16_t unused3; |
122 |
+ grub_uint8_t fork_offset; |
123 |
+- grub_uint8_t unused4[37]; |
124 |
++ grub_uint8_t unused4[17]; /* Last member of inode v2. */ |
125 |
++ grub_uint8_t unused5[20]; /* First member of inode v3. */ |
126 |
+ grub_uint64_t flags2; |
127 |
+- grub_uint8_t unused5[48]; |
128 |
++ grub_uint8_t unused6[48]; /* Last member of inode v3. */ |
129 |
+ } GRUB_PACKED; |
130 |
+ |
131 |
+ #define XFS_V3_INODE_SIZE sizeof(struct grub_xfs_inode) |
132 |
+-/* Size of struct grub_xfs_inode until fork_offset (included). */ |
133 |
+-#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 92) |
134 |
++/* Size of struct grub_xfs_inode v2, up to unused4 member included. */ |
135 |
++#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 76) |
136 |
+ |
137 |
+ struct grub_xfs_dirblock_tail |
138 |
+ { |
139 |
+-- |
140 |
+cgit v1.2.1 |
141 |
+ |
142 |
|
143 |
diff --git a/sys-boot/grub/grub-2.06.ebuild b/sys-boot/grub/grub-2.06-r1.ebuild |
144 |
similarity index 99% |
145 |
rename from sys-boot/grub/grub-2.06.ebuild |
146 |
rename to sys-boot/grub/grub-2.06-r1.ebuild |
147 |
index f5286ca3d6b..3c49ad5db1f 100644 |
148 |
--- a/sys-boot/grub/grub-2.06.ebuild |
149 |
+++ b/sys-boot/grub/grub-2.06-r1.ebuild |
150 |
@@ -38,6 +38,7 @@ else |
151 |
fi |
152 |
|
153 |
PATCHES=( |
154 |
+ "${FILESDIR}"/grub-2.06-xfs-v4.patch |
155 |
"${FILESDIR}"/gfxpayload.patch |
156 |
"${FILESDIR}"/grub-2.02_beta2-KERNEL_GLOBS.patch |
157 |
"${FILESDIR}"/grub-2.06-test-words.patch |