]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: check for bogus values in btree block headers
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 10 Jan 2017 02:18:49 +0000 (20:18 -0600)
committerEric Sandeen <sandeen@redhat.com>
Tue, 10 Jan 2017 02:18:49 +0000 (20:18 -0600)
Source kernel commit: bb3be7e7c1c18e1b141d4cadeb98cc89ecf78099

When we're reading a btree block, make sure that what we retrieved
matches the owner and level; and has a plausible number of records.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/xfs_btree.c

index 3dea6bd31f8b1058296e620d3c491ddf6ded3f23..258b4dd2d68277803808aed68122ad9b98fac4e3 100644 (file)
@@ -1765,8 +1765,28 @@ xfs_btree_lookup_get_block(
        if (error)
                return error;
 
+       /* Check the inode owner since the verifiers don't. */
+       if (xfs_sb_version_hascrc(&cur->bc_mp->m_sb) &&
+           (cur->bc_flags & XFS_BTREE_LONG_PTRS) &&
+           be64_to_cpu((*blkp)->bb_u.l.bb_owner) !=
+                       cur->bc_private.b.ip->i_ino)
+               goto out_bad;
+
+       /* Did we get the level we were looking for? */
+       if (be16_to_cpu((*blkp)->bb_level) != level)
+               goto out_bad;
+
+       /* Check that internal nodes have at least one record. */
+       if (level != 0 && be16_to_cpu((*blkp)->bb_numrecs) == 0)
+               goto out_bad;
+
        xfs_btree_setbuf(cur, level, bp);
        return 0;
+
+out_bad:
+       *blkp = NULL;
+       xfs_trans_brelse(cur->bc_tp, bp);
+       return -EFSCORRUPTED;
 }
 
 /*