On Mon, 2022-10-24 at 14:32 -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <djwong@xxxxxxxxxx> > > 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_cui_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 <djwong@xxxxxxxxxx> Alrighty, looks good Reviewed-by: Allison Henderson <allison.henderson@xxxxxxxxxx> > --- > fs/xfs/xfs_ondisk.h | 4 ++++ > fs/xfs/xfs_refcount_item.c | 45 +++++++++++++++++++++------------- > ---------- > 2 files changed, 25 insertions(+), 24 deletions(-) > > > diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h > index 56917e236370..e20d2844b0c5 100644 > --- a/fs/xfs/xfs_ondisk.h > +++ b/fs/xfs/xfs_ondisk.h > @@ -136,9 +136,13 @@ xfs_check_ondisk_structs(void) > XFS_CHECK_STRUCT_SIZE(struct xfs_attrd_log_format, 16); > XFS_CHECK_STRUCT_SIZE(struct xfs_bui_log_format, 16); > XFS_CHECK_STRUCT_SIZE(struct xfs_bud_log_format, 16); > + XFS_CHECK_STRUCT_SIZE(struct xfs_cui_log_format, 16); > + XFS_CHECK_STRUCT_SIZE(struct xfs_cud_log_format, 16); > XFS_CHECK_STRUCT_SIZE(struct xfs_map_extent, 32); > + XFS_CHECK_STRUCT_SIZE(struct xfs_phys_extent, 16); > > XFS_CHECK_OFFSET(struct xfs_bui_log_format, > bui_extents, 16); > + XFS_CHECK_OFFSET(struct xfs_cui_log_format, > cui_extents, 16); > > /* > * The v5 superblock format extended several v4 header > structures with > diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c > index 7e97bf19793d..24cf4c64ebaa 100644 > --- a/fs/xfs/xfs_refcount_item.c > +++ b/fs/xfs/xfs_refcount_item.c > @@ -622,28 +622,18 @@ static const struct xfs_item_ops > xfs_cui_item_ops = { > .iop_relog = xfs_cui_item_relog, > }; > > -/* > - * Copy an CUI format buffer from the given buf, and into the > destination > - * CUI format structure. The CUI/CUD items were designed not to > need any > - * special alignment handling. > - */ > -static int > +static inline void > xfs_cui_copy_format( > - struct xfs_log_iovec *buf, > - struct xfs_cui_log_format *dst_cui_fmt) > + struct xfs_cui_log_format *dst, > + const struct xfs_cui_log_format *src) > { > - struct xfs_cui_log_format *src_cui_fmt; > - uint len; > + unsigned int i; > > - src_cui_fmt = buf->i_addr; > - len = xfs_cui_log_format_sizeof(src_cui_fmt->cui_nextents); > + memcpy(dst, src, offsetof(struct xfs_cui_log_format, > cui_extents)); > > - if (buf->i_len == len) { > - memcpy(dst_cui_fmt, src_cui_fmt, len); > - return 0; > - } > - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL); > - return -EFSCORRUPTED; > + for (i = 0; i < src->cui_nextents; i++) > + memcpy(&dst->cui_extents[i], &src->cui_extents[i], > + sizeof(struct xfs_phys_extent)); > } > > /* > @@ -660,19 +650,26 @@ xlog_recover_cui_commit_pass2( > struct xlog_recover_item *item, > xfs_lsn_t lsn) > { > - int error; > struct xfs_mount *mp = log->l_mp; > struct xfs_cui_log_item *cuip; > struct xfs_cui_log_format *cui_formatp; > + size_t len; > > cui_formatp = item->ri_buf[0].i_addr; > > + if (item->ri_buf[0].i_len < xfs_cui_log_format_sizeof(0)) { > + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log- > >l_mp); > + return -EFSCORRUPTED; > + } > + > + len = xfs_cui_log_format_sizeof(cui_formatp->cui_nextents); > + if (item->ri_buf[0].i_len != len) { > + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log- > >l_mp); > + return -EFSCORRUPTED; > + } > + > cuip = xfs_cui_init(mp, cui_formatp->cui_nextents); > - error = xfs_cui_copy_format(&item->ri_buf[0], &cuip- > >cui_format); > - if (error) { > - xfs_cui_item_free(cuip); > - return error; > - } > + xfs_cui_copy_format(&cuip->cui_format, cui_formatp); > atomic_set(&cuip->cui_next_extent, cui_formatp- > >cui_nextents); > /* > * Insert the intent into the AIL directly and drop one > reference so >