From: Dave Chinner <dchinner@xxxxxxxxxx> When scanning a btree format inode, we trust the extent count to be in range. However, values of the range 2^31 <= cnt < 2^32 are invalid and can cause problems with signed range checks. This results in assert failures which validating the extent count such as: xfs_repair: dinode.c:768: process_bmbt_reclist_int: Assertion `i < *numrecs' failed. Validate the extent count is at least within the positive range of a singed 32 bit integer before using it. Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx> --- repair/dinode.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/repair/dinode.c b/repair/dinode.c index 5a2da39..239bb7b 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -1293,7 +1293,7 @@ process_exinode( xfs_bmbt_rec_t *rp; xfs_dfiloff_t first_key; xfs_dfiloff_t last_key; - int numrecs; + int32_t numrecs; int ret; lino = XFS_AGINO_TO_INO(mp, agno, ino); @@ -1302,6 +1302,15 @@ process_exinode( numrecs = XFS_DFORK_NEXTENTS(dip, whichfork); /* + * We've already decided on the maximum number of extents on the inode, + * and numrecs may be corrupt. Hence make sure we only allow numrecs to + * be in the range of valid on-disk numbers, which is: + * 0 < numrecs < 2^31 - 1 + */ + if (numrecs < 0) + numrecs = *nex; + + /* * XXX - if we were going to fix up the btree record, * we'd do it right here. For now, if there's a problem, * we'll bail out and presumably clear the inode. @@ -2038,11 +2047,23 @@ process_inode_data_fork( { xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino); int err = 0; + int nex; + + /* + * extent count on disk is only valid for positive values. The kernel + * uses negative values in memory. hence if we see negative numbers + * here, trash it! + */ + nex = be32_to_cpu(dino->di_nextents); + if (nex < 0) + *nextents = 1; + else + *nextents = nex; - *nextents = be32_to_cpu(dino->di_nextents); if (*nextents > be64_to_cpu(dino->di_nblocks)) *nextents = 1; + if (dino->di_format != XFS_DINODE_FMT_LOCAL && type != XR_INO_RTDATA) *dblkmap = blkmap_alloc(*nextents, XFS_DATA_FORK); *nextents = 0; -- 1.7.10.4 _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs