diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_inode_buf.c')
| -rw-r--r-- | fs/xfs/libxfs/xfs_inode_buf.c | 16 | 
1 files changed, 12 insertions, 4 deletions
| diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 134424fac434..dd483e2767f7 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -383,7 +383,7 @@ xfs_log_dinode_to_disk(  static bool  xfs_dinode_verify(  	struct xfs_mount	*mp, -	struct xfs_inode	*ip, +	xfs_ino_t		ino,  	struct xfs_dinode	*dip)  {  	uint16_t		flags; @@ -392,6 +392,14 @@ xfs_dinode_verify(  	if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))  		return false; +	/* don't allow invalid i_size */ +	if (be64_to_cpu(dip->di_size) & (1ULL << 63)) +		return false; + +	/* No zero-length symlinks. */ +	if (S_ISLNK(be16_to_cpu(dip->di_mode)) && dip->di_size == 0) +		return false; +  	/* only version 3 or greater inodes are extensively verified here */  	if (dip->di_version < 3)  		return true; @@ -401,7 +409,7 @@ xfs_dinode_verify(  	if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize,  			      XFS_DINODE_CRC_OFF))  		return false; -	if (be64_to_cpu(dip->di_ino) != ip->i_ino) +	if (be64_to_cpu(dip->di_ino) != ino)  		return false;  	if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_meta_uuid))  		return false; @@ -436,7 +444,7 @@ xfs_dinode_calc_crc(  		return;  	ASSERT(xfs_sb_version_hascrc(&mp->m_sb)); -	crc = xfs_start_cksum((char *)dip, mp->m_sb.sb_inodesize, +	crc = xfs_start_cksum_update((char *)dip, mp->m_sb.sb_inodesize,  			      XFS_DINODE_CRC_OFF);  	dip->di_crc = xfs_end_cksum(crc);  } @@ -493,7 +501,7 @@ xfs_iread(  		return error;  	/* even unallocated inodes are verified */ -	if (!xfs_dinode_verify(mp, ip, dip)) { +	if (!xfs_dinode_verify(mp, ip->i_ino, dip)) {  		xfs_alert(mp, "%s: validation failed for inode %lld failed",  				__func__, ip->i_ino); |