From: "Darrick J. Wong" <djwong@xxxxxxxxxx> The directory/xattr code uses xfs_bmap_first_unused to find a contiguous chunk of file range that can hold a particular value. Unfortunately, file offsets are 64-bit quantities, whereas the dir/attr block number type (xfs_dablk_t) is a 32-bit quantity. If an integer truncation occurs here, we will corrupt the file. Therefore, check for a file offset that would truncate and return EFBIG in that case. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_attr_remote.c | 3 +++ fs/xfs/libxfs/xfs_da_btree.c | 3 +++ fs/xfs/libxfs/xfs_da_format.h | 3 +++ 3 files changed, 9 insertions(+) diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index e90a62c61f28..2bd225b1772c 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -529,6 +529,9 @@ xfs_attr_rmt_find_hole( if (error) return error; + if (lfileoff > XFS_MAX_DABLK) + return -EFBIG; + args->rmtblkno = (xfs_dablk_t)lfileoff; args->rmtblkcnt = blkcnt; diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 17d9e6154f19..6c6c7bab87fb 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -2308,6 +2308,9 @@ xfs_da_grow_inode_int( if (error) return error; + if (*bno > XFS_MAX_DABLK) + return -EFBIG; + /* * Try mapping it in one filesystem block. */ diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h index 48bebcd1e226..ee9635c04197 100644 --- a/fs/xfs/libxfs/xfs_da_format.h +++ b/fs/xfs/libxfs/xfs_da_format.h @@ -748,6 +748,9 @@ struct xfs_attr3_leafblock { */ #define XFS_ATTR_LEAF_NAME_ALIGN ((uint)sizeof(xfs_dablk_t)) +/* Maximum file block offset of a directory or an xattr. */ +#define XFS_MAX_DABLK ((xfs_dablk_t)-1U) + static inline int xfs_attr3_leaf_hdr_size(struct xfs_attr_leafblock *leafp) { -- 2.47.0