diff --git a/0003-xfs-fix-memcpy-fortify-errors-in-EFI-log-format-copy.patch b/0003-xfs-fix-memcpy-fortify-errors-in-EFI-log-format-copy.patch new file mode 100644 index 0000000000000000000000000000000000000000..ec080085d5a1cb7dad528428e5c5420b1e8131b8 --- /dev/null +++ b/0003-xfs-fix-memcpy-fortify-errors-in-EFI-log-format-copy.patch @@ -0,0 +1,140 @@ +From d267ac6a00cd57bf6015e34af565f4bdcb4d7e34 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Fri, 18 Nov 2022 10:54:10 +0100 +Subject: [PATCH] xfs: fix memcpy fortify errors in EFI log format copying + +Source kernel commit: 03a7485cd701e1c08baadcf39d9592d83715e224 + +Starting in 6.1, CONFIG_FORTIFY_SOURCE checks the length parameter of +memcpy. Since we're already fixing problems with BUI item copying, we +should fix it everything else. + +An extra difficulty here is that the ef[id]_extents arrays are declared +as single-element arrays. This is not the convention for flex arrays in +the modern kernel, and it causes all manner of problems with static +checking tools, since they often cannot tell the difference between a +single element array and a flex array. + +So for starters, change those array[1] declarations to array[] +declarations to signal that they are proper flex arrays and adjust all +the "size-1" expressions to fit the new declaration style. + +Next, refactor the xfs_efi_copy_format function to handle the copying of +the head and the flex array members separately. While we're at it, fix +a minor validation deficiency in the recovery function. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Kees Cook +Reviewed-by: Allison Henderson +Reviewed-by: Dave Chinner +Signed-off-by: Carlos Maiolino +--- + libxfs/xfs_log_format.h | 12 ++++++------ + logprint/log_redo.c | 12 ++++++------ + 2 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h +index b351b9dc..2f41fa84 100644 +--- a/libxfs/xfs_log_format.h ++++ b/libxfs/xfs_log_format.h +@@ -613,7 +613,7 @@ typedef struct xfs_efi_log_format { + uint16_t efi_size; /* size of this item */ + uint32_t efi_nextents; /* # extents to free */ + uint64_t efi_id; /* efi identifier */ +- xfs_extent_t efi_extents[1]; /* array of extents to free */ ++ xfs_extent_t efi_extents[]; /* array of extents to free */ + } xfs_efi_log_format_t; + + typedef struct xfs_efi_log_format_32 { +@@ -621,7 +621,7 @@ typedef struct xfs_efi_log_format_32 { + uint16_t efi_size; /* size of this item */ + uint32_t efi_nextents; /* # extents to free */ + uint64_t efi_id; /* efi identifier */ +- xfs_extent_32_t efi_extents[1]; /* array of extents to free */ ++ xfs_extent_32_t efi_extents[]; /* array of extents to free */ + } __attribute__((packed)) xfs_efi_log_format_32_t; + + typedef struct xfs_efi_log_format_64 { +@@ -629,7 +629,7 @@ typedef struct xfs_efi_log_format_64 { + uint16_t efi_size; /* size of this item */ + uint32_t efi_nextents; /* # extents to free */ + uint64_t efi_id; /* efi identifier */ +- xfs_extent_64_t efi_extents[1]; /* array of extents to free */ ++ xfs_extent_64_t efi_extents[]; /* array of extents to free */ + } xfs_efi_log_format_64_t; + + /* +@@ -642,7 +642,7 @@ typedef struct xfs_efd_log_format { + uint16_t efd_size; /* size of this item */ + uint32_t efd_nextents; /* # of extents freed */ + uint64_t efd_efi_id; /* id of corresponding efi */ +- xfs_extent_t efd_extents[1]; /* array of extents freed */ ++ xfs_extent_t efd_extents[]; /* array of extents freed */ + } xfs_efd_log_format_t; + + typedef struct xfs_efd_log_format_32 { +@@ -650,7 +650,7 @@ typedef struct xfs_efd_log_format_32 { + uint16_t efd_size; /* size of this item */ + uint32_t efd_nextents; /* # of extents freed */ + uint64_t efd_efi_id; /* id of corresponding efi */ +- xfs_extent_32_t efd_extents[1]; /* array of extents freed */ ++ xfs_extent_32_t efd_extents[]; /* array of extents freed */ + } __attribute__((packed)) xfs_efd_log_format_32_t; + + typedef struct xfs_efd_log_format_64 { +@@ -658,7 +658,7 @@ typedef struct xfs_efd_log_format_64 { + uint16_t efd_size; /* size of this item */ + uint32_t efd_nextents; /* # of extents freed */ + uint64_t efd_efi_id; /* id of corresponding efi */ +- xfs_extent_64_t efd_extents[1]; /* array of extents freed */ ++ xfs_extent_64_t efd_extents[]; /* array of extents freed */ + } xfs_efd_log_format_64_t; + + /* +diff --git a/logprint/log_redo.c b/logprint/log_redo.c +index 1974382d..226bc30a 100644 +--- a/logprint/log_redo.c ++++ b/logprint/log_redo.c +@@ -20,9 +20,9 @@ xfs_efi_copy_format( + { + uint i; + uint nextents = ((xfs_efi_log_format_t *)buf)->efi_nextents; +- uint dst_len = sizeof(xfs_efi_log_format_t) + (nextents - 1) * sizeof(xfs_extent_t); +- uint len32 = sizeof(xfs_efi_log_format_32_t) + (nextents - 1) * sizeof(xfs_extent_32_t); +- uint len64 = sizeof(xfs_efi_log_format_64_t) + (nextents - 1) * sizeof(xfs_extent_64_t); ++ uint dst_len = sizeof(xfs_efi_log_format_t) + (nextents) * sizeof(xfs_extent_t); ++ uint len32 = sizeof(xfs_efi_log_format_32_t) + (nextents) * sizeof(xfs_extent_32_t); ++ uint len64 = sizeof(xfs_efi_log_format_64_t) + (nextents) * sizeof(xfs_extent_64_t); + + if (len == dst_len || continued) { + memcpy((char *)dst_efi_fmt, buf, len); +@@ -86,7 +86,7 @@ xlog_print_trans_efi( + *ptr += src_len; + + /* convert to native format */ +- dst_len = sizeof(xfs_efi_log_format_t) + (src_f->efi_nextents - 1) * sizeof(xfs_extent_t); ++ dst_len = sizeof(xfs_efi_log_format_t) + (src_f->efi_nextents) * sizeof(xfs_extent_t); + + if (continued && src_len < core_size) { + printf(_("EFI: Not enough data to decode further\n")); +@@ -144,7 +144,7 @@ xlog_recover_print_efi( + * Need to convert to native format. + */ + dst_len = sizeof(xfs_efi_log_format_t) + +- (src_f->efi_nextents - 1) * sizeof(xfs_extent_t); ++ (src_f->efi_nextents) * sizeof(xfs_extent_t); + if ((f = (xfs_efi_log_format_t *)malloc(dst_len)) == NULL) { + fprintf(stderr, _("%s: xlog_recover_print_efi: malloc failed\n"), + progname); +@@ -177,7 +177,7 @@ xlog_print_trans_efd(char **ptr, uint len) + xfs_efd_log_format_t *f; + xfs_efd_log_format_t lbuf; + /* size without extents at end */ +- uint core_size = sizeof(xfs_efd_log_format_t) - sizeof(xfs_extent_t); ++ uint core_size = sizeof(xfs_efd_log_format_t); + + /* + * memmove to ensure 8-byte alignment for the long longs in +-- +2.33.0 + diff --git a/xfsprogs.spec b/xfsprogs.spec index 546403c964974d5ce3430bd2f0fce3339c2ab9d2..8e1000ca03e0ccfbe0989bbfa6c27f23499f5581 100644 --- a/xfsprogs.spec +++ b/xfsprogs.spec @@ -1,6 +1,6 @@ Name: xfsprogs Version: 6.6.0 -Release: 2 +Release: 3 Summary: Administration and debugging tools for the XFS file system License: GPL+ and LGPLv2+ URL: https://xfs.wiki.kernel.org @@ -21,6 +21,7 @@ Conflicts: xfsdump < 3.0.1 Patch0: xfsprogs-5.12.0-default-bigtime-inobtcnt-on.patch Patch1: 0001-xfsprogs-Add-sw64-architecture.patch Patch2: 0002-xfs-fix-internal-error-from-AGFL-exhaustion.patch +Patch3: 0003-xfs-fix-memcpy-fortify-errors-in-EFI-log-format-copy.patch %description xfsprogs are the userspace utilities that manage XFS filesystems. @@ -102,6 +103,9 @@ rm -rf %{buildroot}%{_datadir}/doc/xfsprogs/ %changelog +* Thu Apr 18 2024 wuguanghao - 6.6.0-3 +- fix memcpy fortify errors in EFI log format copying + * Fri Mar 29 2024 liuh - 6.6.0-2 - sync patch from community