xfs_sb_read_verify() uses the sector size in the superblock as input to the CRC calculations - but if the value is corrupted, we can have a catastrophic failure - a value of 0 for length in: length - (cksum_offset + sizeof(__be32)) passes a very large (unsigned) value to crc32c, which will cause an oops, today. (Hardening crc32c is above my pay grade). Doing a quick validation of sectorsize before the crc calculation solves this problem. Signed-off-by: Eric Sandeen <sandeen@xxxxxxxxxx> --- diff --git a/fs/xfs/xfs_sb.c b/fs/xfs/xfs_sb.c index 6d81ece..4b62ad2 100644 --- a/fs/xfs/xfs_sb.c +++ b/fs/xfs/xfs_sb.c @@ -599,9 +600,19 @@ xfs_sb_read_verify( { struct xfs_mount *mp = bp->b_target->bt_mount; struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp); + __uint16_t sectsize = be16_to_cpu(dsb->sb_sectsize); int error; /* + * We use the sb sectorsize in crc calculations before general sb + * validation, so check that value first. + */ + if (sectsize < XFS_MIN_SECTORSIZE || sectsize > XFS_MAX_SECTORSIZE) { + error = EFSCORRUPTED; + goto out_error; + } + + /* * open code the version check to avoid needing to convert the entire * superblock from disk order just to check the version number */ @@ -610,8 +621,7 @@ xfs_sb_read_verify( XFS_SB_VERSION_5) || dsb->sb_crc != 0)) { - if (!xfs_verify_cksum(bp->b_addr, be16_to_cpu(dsb->sb_sectsize), - XFS_SB_CRC_OFF)) { + if (!xfs_verify_cksum(bp->b_addr, sectsize, XFS_SB_CRC_OFF)) { /* Only fail bad secondaries on a known V5 filesystem */ if (bp->b_bn == XFS_SB_DADDR || xfs_sb_version_hascrc(&mp->m_sb)) { _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs