diff mbox series

[09/24] xfs: fix memcpy fortify errors in EFI log format copying

Message ID 166795959288.3761583.14358034387087854299.stgit@magnolia (mailing list archive)
State Accepted
Headers show
Series xfsprogs: sync with 6.1 | expand

Commit Message

Darrick J. Wong Nov. 9, 2022, 2:06 a.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

Source kernel commit: b276f256ced3233b74b83d7df4e1b4ba8672ee98

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.

Refactor the xfs_efi_copy_format function to handle the copying of the
head and the flex array members separately, and do the same for the EFI
relogging functions.  While we're at it, fix a minor validation
deficiency in the recovery function.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 libxfs/xfs_log_format.h |   12 ++++++------
 logprint/log_redo.c     |   12 ++++++------
 2 files changed, 12 insertions(+), 12 deletions(-)
diff mbox series

Patch

diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index b351b9dc65..2f41fa8477 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 1974382d2d..12d041da1c 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(struct xfs_efd_log_format);
 
 	/*
 	 * memmove to ensure 8-byte alignment for the long longs in