All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] fs/xfs: Avoid unreadble filesystem if V4 superblock
@ 2021-08-25 13:31 Erwan Velu
  2021-08-26  7:54 ` Erwan Velu
  2021-09-06 12:20 ` [PATCH] fs/xfs: Avoid unreadble filesystem if V4 superblock Daniel Kiper
  0 siblings, 2 replies; 23+ messages in thread
From: Erwan Velu @ 2021-08-25 13:31 UTC (permalink / raw)
  To: grub-devel; +Cc: a.rougemont, Erwan Velu

Commit 8b1e5d1936fffc490510e85c95f93248453586c1 introduced the support
of bigtime by adding the some features in inodes V3.

This change extended grub_xfs_inode struct by 76 bytes but also changed the
computation of XFS_V3_INODE_SIZE & XFS_V2_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 structure aren't properly aligned and generates
"attempt to read or write outside of partition" errors when trying to
read the 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 substracting 76
instead of 92 from the actual size of grub_xfs_inode.
This 76 value is coming from the added :
	20 uint8   unused5
	 1 uint64  flags2
        48 uint8   unused6

This patch explicit the split between the v2 and v3 parts of structure.
The unused4 is still ending to the v2 structures and the v3 starts at unused5.
This will avoid future corruption of v2 or v3.

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>

Signed-off-by: Erwan Velu <e.velu@criteo.com>
---
 grub-core/fs/xfs.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index 0f524c3a8a61..becea5bcdf61 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -192,6 +192,7 @@ struct grub_xfs_time_legacy
   grub_uint32_t nanosec;
 } GRUB_PACKED;
 
+// From https://mirrors.edge.kernel.org/pub/linux/utils/fs/xfs/docs/xfs_filesystem_structure.pdf about 'struct xfs_dinode_core'
 struct grub_xfs_inode
 {
   grub_uint8_t magic[2];
@@ -208,14 +209,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 included */
+#define XFS_V2_INODE_SIZE	(XFS_V3_INODE_SIZE - 76)
 
 struct grub_xfs_dirblock_tail
 {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2021-09-14 12:24 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-25 13:31 [PATCH] fs/xfs: Avoid unreadble filesystem if V4 superblock Erwan Velu
2021-08-26  7:54 ` Erwan Velu
2021-08-26 13:26   ` Carlos Maiolino
2021-08-26 13:30     ` Erwan Velu
2021-08-30  9:18     ` Erwan Velu
2021-08-30 11:48       ` Carlos Maiolino
2021-09-01 12:40         ` Daniel Kiper
2021-09-01 13:05           ` Carlos Maiolino
2021-09-02  8:56           ` Carlos Maiolino
2021-09-02 11:33             ` Daniel Kiper
2021-09-02 11:39               ` Erwan Velu
2021-09-02 12:49                 ` Daniel Kiper
2021-09-02 13:05                   ` Erwan Velu
2021-09-02 13:31                     ` Daniel Kiper
2021-09-02 13:34                       ` Erwan Velu
2021-09-08  1:22             ` Where is the testing? (was: Re: [PATCH] fs/xfs: Avoid unreadble filesystem if V4 superblock) Glenn Washburn
2021-09-08  9:20               ` Erwan Velu
2021-09-08 16:19                 ` Daniel Kiper
2021-09-08 16:21                   ` Erwan Velu
2021-09-08 16:03               ` Daniel Kiper
2021-09-08 19:57                 ` Glenn Washburn
2021-09-14 12:24                   ` Daniel Kiper
2021-09-06 12:20 ` [PATCH] fs/xfs: Avoid unreadble filesystem if V4 superblock Daniel Kiper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.