directory extents The directory extent list does not have to be a continuous list of data blocks. When GRUB tries to read a non-existant member of the list, grub_xfs_read_file() will return a block of zero'ed memory. Checking for a zero'ed magic number is sufficient to skip this non-existant data block. Prior to commit 07318ee7e (fs/xfs: Fix XFS directory extent parsing) this was handled as a subtle side effect of reading the (non-existant) tail data structure. Since the block was zero'ed the computation of the number of directory entries in the block would return 0 as well. (cherry picked from commit e0cd43f8a5486debeba17349abbb088001164d70)
50 lines
1.8 KiB
Diff
50 lines
1.8 KiB
Diff
From 426d43bdf15e3e65c9b2cc80aa4b416750c643c3 Mon Sep 17 00:00:00 2001
|
|
From: openEuler Buildteam <buildteam@openEuler.org>
|
|
Date: Sat, 11 May 2024 10:00:32 +0800
|
|
Subject: [PATCH] Handle non-continuous data blocks in directory extents
|
|
|
|
The directory extent list does not have to be a continuous list of data
|
|
blocks. When GRUB tries to read a non-existant member of the list,
|
|
grub_xfs_read_file() will return a block of zero'ed memory. Checking for
|
|
a zero'ed magic number is sufficient to skip this non-existant data block.
|
|
|
|
Prior to commit 07318ee7e (fs/xfs: Fix XFS directory extent parsing)
|
|
this was handled as a subtle side effect of reading the (non-existant)
|
|
tail data structure. Since the block was zero'ed the computation of the
|
|
number of directory entries in the block would return 0 as well.
|
|
---
|
|
grub-core/fs/xfs.c | 10 ++++++++++
|
|
1 file changed, 10 insertions(+)
|
|
|
|
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
|
index 1ce5fa4..2a22e26 100644
|
|
--- a/grub-core/fs/xfs.c
|
|
+++ b/grub-core/fs/xfs.c
|
|
@@ -904,6 +904,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
|
|
|
int entries = -1;
|
|
char *end = dirblock + dirblk_size;
|
|
+ grub_uint32_t magic;
|
|
|
|
numread = grub_xfs_read_file (dir, 0, 0,
|
|
blk << dirblk_log2,
|
|
@@ -914,6 +915,15 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
|
return 0;
|
|
}
|
|
|
|
+ /*
|
|
+ * If this data block isn't actually part of the extent list then
|
|
+ * grub_xfs_read_file() returns a block of zeros. So, if the magic
|
|
+ * number field is all zeros then this block should be skipped.
|
|
+ */
|
|
+ magic = *(grub_uint32_t *)(void *) dirblock;
|
|
+ if (!magic)
|
|
+ continue;
|
|
+
|
|
/*
|
|
* Leaf and tail information are only in the data block if the number
|
|
* of extents is 1.
|
|
--
|
|
2.33.0
|
|
|