diff --git a/backport-0082-fs-xfs-Add-bigtime-incompat-feature-support.patch b/backport-0082-fs-xfs-Add-bigtime-incompat-feature-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..4f8099b1149dd597ddf16a8fa484e117bf2e0839 --- /dev/null +++ b/backport-0082-fs-xfs-Add-bigtime-incompat-feature-support.patch @@ -0,0 +1,156 @@ +From 8b1e5d1936fffc490510e85c95f93248453586c1 Mon Sep 17 00:00:00 2001 +From: Carlos Maiolino +Date: Mon, 24 May 2021 19:40:06 +0200 +Subject: [PATCH] fs/xfs: Add bigtime incompat feature support + +The XFS filesystem supports a bigtime feature to overcome y2038 problem. +This patch makes the GRUB able to support the XFS filesystems with this +feature enabled. + +The XFS counter for the bigtime enabled timestamps starts at 0, which +translates to GRUB_INT32_MIN (Dec 31 20:45:52 UTC 1901) in the legacy +timestamps. The conversion to Unix timestamps is made before passing the +value to other GRUB functions. + +For this to work properly, GRUB requires an access to flags2 field in the +XFS ondisk inode. So, the grub_xfs_inode structure has been updated to +cover full ondisk inode. + +Signed-off-by: Carlos Maiolino +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/fs/xfs.c | 49 ++++++++++++++++++++++++++++++++++++--------- + include/grub/time.h | 2 ++ + 2 files changed, 42 insertions(+), 9 deletions(-) + +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index 43023e03f..a7f8900bc 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -75,10 +76,15 @@ GRUB_MOD_LICENSE ("GPLv3+"); + XFS_SB_VERSION2_PROJID32BIT | \ + XFS_SB_VERSION2_FTYPE) + ++/* Inode flags2 flags */ ++#define XFS_DIFLAG2_BIGTIME_BIT 3 ++#define XFS_DIFLAG2_BIGTIME (1 << XFS_DIFLAG2_BIGTIME_BIT) ++ + /* incompat feature flags */ + #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ + #define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */ + #define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */ ++#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */ + + /* + * Directory entries with ftype are explicitly handled by GRUB code. +@@ -92,7 +98,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); + #define XFS_SB_FEAT_INCOMPAT_SUPPORTED \ + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_SPINODES | \ +- XFS_SB_FEAT_INCOMPAT_META_UUID) ++ XFS_SB_FEAT_INCOMPAT_META_UUID | \ ++ XFS_SB_FEAT_INCOMPAT_BIGTIME) + + struct grub_xfs_sblock + { +@@ -177,7 +184,7 @@ struct grub_xfs_btree_root + grub_uint64_t keys[1]; + } GRUB_PACKED; + +-struct grub_xfs_time ++struct grub_xfs_time_legacy + { + grub_uint32_t sec; + grub_uint32_t nanosec; +@@ -190,20 +197,23 @@ struct grub_xfs_inode + grub_uint8_t version; + grub_uint8_t format; + grub_uint8_t unused2[26]; +- struct grub_xfs_time atime; +- struct grub_xfs_time mtime; +- struct grub_xfs_time ctime; ++ grub_uint64_t atime; ++ grub_uint64_t mtime; ++ grub_uint64_t ctime; + grub_uint64_t size; + grub_uint64_t nblocks; + grub_uint32_t extsize; + grub_uint32_t nextents; + grub_uint16_t unused3; + grub_uint8_t fork_offset; +- grub_uint8_t unused4[17]; ++ grub_uint8_t unused4[37]; ++ grub_uint64_t flags2; ++ grub_uint8_t unused5[48]; + } GRUB_PACKED; + +-#define XFS_V2_INODE_SIZE sizeof(struct grub_xfs_inode) +-#define XFS_V3_INODE_SIZE (XFS_V2_INODE_SIZE + 76) ++#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) + + struct grub_xfs_dirblock_tail + { +@@ -958,6 +968,27 @@ struct grub_xfs_dir_ctx + void *hook_data; + }; + ++/* Bigtime inodes helpers. */ ++#define XFS_BIGTIME_EPOCH_OFFSET (-(grub_int64_t) GRUB_INT32_MIN) ++ ++static int grub_xfs_inode_has_bigtime (const struct grub_xfs_inode *inode) ++{ ++ return inode->version >= 3 && ++ (inode->flags2 & grub_cpu_to_be64_compile_time (XFS_DIFLAG2_BIGTIME)); ++} ++ ++static grub_int64_t ++grub_xfs_get_inode_time (struct grub_xfs_inode *inode) ++{ ++ struct grub_xfs_time_legacy *lts; ++ ++ if (grub_xfs_inode_has_bigtime (inode)) ++ return grub_divmod64 (grub_be_to_cpu64 (inode->mtime), NSEC_PER_SEC, NULL) - XFS_BIGTIME_EPOCH_OFFSET; ++ ++ lts = (struct grub_xfs_time_legacy *) &inode->mtime; ++ return grub_be_to_cpu32 (lts->sec); ++} ++ + /* Helper for grub_xfs_dir. */ + static int + grub_xfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, +@@ -970,7 +1001,7 @@ grub_xfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, + if (node->inode_read) + { + info.mtimeset = 1; +- info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec); ++ info.mtime = grub_xfs_get_inode_time (&node->inode); + } + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + grub_free (node); +diff --git a/include/grub/time.h b/include/grub/time.h +index c919c1f0b..32f0afaf8 100644 +--- a/include/grub/time.h ++++ b/include/grub/time.h +@@ -30,6 +30,8 @@ grub_cpu_idle(void) + } + #endif + ++#define NSEC_PER_SEC ((grub_int64_t) 1000000000) ++ + void EXPORT_FUNC(grub_millisleep) (grub_uint32_t ms); + grub_uint64_t EXPORT_FUNC(grub_get_time_ms) (void); + +-- +2.20.1 + diff --git a/backport-0083-fs-xfs-Add-needsrepair-incompat-feature-support.patch b/backport-0083-fs-xfs-Add-needsrepair-incompat-feature-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..fc7382e6aa4c5ec8ff01711c87eec642ccac135d --- /dev/null +++ b/backport-0083-fs-xfs-Add-needsrepair-incompat-feature-support.patch @@ -0,0 +1,81 @@ +From 777276063e2ec146d5bd0e379717c199967c65ed Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Mon, 24 May 2021 19:40:07 +0200 +Subject: [PATCH] fs/xfs: Add needsrepair incompat feature support + +The XFS now has an incompat feature flag to indicate that a filesystem +needs to be repaired. The Linux kernel refuses to mount the filesystem +that has it set and only the xfs_repair tool is able to clear that flag. + +The GRUB doesn't have the concept of mounting filesystems and just +attempts to read the files. But it does some sanity checking before +attempting to read from the filesystem. Among the things which are tested, +is if the super block only has set of incompatible features flags that +are supported by GRUB. If it contains any flags that are not listed as +supported, reading the XFS filesystem fails. + +Since the GRUB doesn't attempt to detect if the filesystem is inconsistent +nor replays the journal, the filesystem access is a best effort. For this +reason, ignore if the filesystem needs to be repaired and just print a debug +message. That way, if reading or booting fails later, the user is able to +figure out that the failures can be related to broken XFS filesystem. + +Suggested-by: Eric Sandeen +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/fs/xfs.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index a7f8900bc..0f524c3a8 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -85,6 +85,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); + #define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */ + #define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */ + #define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */ ++#define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */ + + /* + * Directory entries with ftype are explicitly handled by GRUB code. +@@ -99,7 +100,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_SPINODES | \ + XFS_SB_FEAT_INCOMPAT_META_UUID | \ +- XFS_SB_FEAT_INCOMPAT_BIGTIME) ++ XFS_SB_FEAT_INCOMPAT_BIGTIME | \ ++ XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR) + + struct grub_xfs_sblock + { +@@ -310,6 +312,16 @@ static int grub_xfs_sb_valid(struct grub_xfs_data *data) + return 0; + } + ++static int ++grub_xfs_sb_needs_repair (struct grub_xfs_data *data) ++{ ++ return ((data->sblock.version & ++ grub_cpu_to_be16_compile_time (XFS_SB_VERSION_NUMBITS)) == ++ grub_cpu_to_be16_compile_time (XFS_SB_VERSION_5) && ++ (data->sblock.sb_features_incompat & ++ grub_cpu_to_be32_compile_time (XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR))); ++} ++ + /* Filetype information as used in inodes. */ + #define FILETYPE_INO_MASK 0170000 + #define FILETYPE_INO_REG 0100000 +@@ -925,6 +937,9 @@ grub_xfs_mount (grub_disk_t disk) + if (!grub_xfs_sb_valid(data)) + goto fail; + ++ if (grub_xfs_sb_needs_repair (data)) ++ grub_dprintf ("xfs", "XFS filesystem needs repair, boot may fail\n"); ++ + if (grub_add (grub_xfs_inode_size (data), + sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz)) + goto fail; +-- +2.20.1 + diff --git a/grub.patches b/grub.patches index e917dbcac831d2fb7f93cb49e2bea7fbdad76511..33613cef6392d4c457aa09467119ad151f4cad94 100644 --- a/grub.patches +++ b/grub.patches @@ -358,3 +358,5 @@ Patch0357: 0252-LoongArch64-support-boot-parameter-01002-version.patch Patch0358: 0253-LoongArch64-add-fdt-and-efistub-support.patch Patch0359: 0254-LoongArch64-add-clfs-abi-compile.patch Patch0360: 0255-LoongArch64-fix-the-efi-max-usable-address.patch +Patch0361: backport-0082-fs-xfs-Add-bigtime-incompat-feature-support.patch +Patch0362: backport-0083-fs-xfs-Add-needsrepair-incompat-feature-support.patch diff --git a/grub2.spec b/grub2.spec index 4fbbb4bef22cd3995b372bf1bed02a3ae7a22eee..ab4cc29b436b1dfab715ea4bb2a4e21e9d9c1e58 100644 --- a/grub2.spec +++ b/grub2.spec @@ -8,7 +8,7 @@ Name: grub2 Epoch: 1 Version: 2.04 -Release: 27 +Release: 28 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -455,6 +455,12 @@ rm -r /boot/grub2.tmp/ || : %endif %changelog +* Tue Dec 13 2022 mengyingkun - 1:2.04-28 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:backport patches that add incompat features support to xfs + * Fri Oct 28 2022 yangqiming - 2.04-27 - Type:bugfix - CVE:NA