From: Darrick J. Wong Date: Wed, 2 Sep 2015 22:42:50 +0000 (+1000) Subject: xfs_repair: check v5 filesystem attr block header sanity X-Git-Tag: v4.2.0~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1c8e2f033c6862a2aa429e1ed4475540089a9386;p=thirdparty%2Fxfsprogs-dev.git xfs_repair: check v5 filesystem attr block header sanity Check the v5 fields (uuid, blocknr, owner) of attribute blocks for obvious errors while scanning xattr blocks. If the ownership info is incorrect, kill the block. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- diff --git a/repair/attr_repair.c b/repair/attr_repair.c index c2b7c3ad2..8d03161ae 100644 --- a/repair/attr_repair.c +++ b/repair/attr_repair.c @@ -1508,6 +1508,44 @@ process_node_attr( return (process_leaf_attr_level(mp, &da_cursor)); } +/* check v5 metadata */ +static int +__check_attr_header( + struct xfs_mount *mp, + struct xfs_buf *bp, + xfs_ino_t ino) +{ + struct xfs_da3_blkinfo *info = bp->b_addr; + + if (info->hdr.magic != cpu_to_be16(XFS_ATTR3_LEAF_MAGIC) && + info->hdr.magic != cpu_to_be16(XFS_DA3_NODE_MAGIC)) + return 0; + + /* verify owner */ + if (be64_to_cpu(info->owner) != ino) { + do_warn( +_("expected owner inode %" PRIu64 ", got %llu, attr block %" PRIu64 "\n"), + ino, be64_to_cpu(info->owner), bp->b_bn); + return 1; + } + /* verify block number */ + if (be64_to_cpu(info->blkno) != bp->b_bn) { + do_warn( +_("expected block %" PRIu64 ", got %llu, inode %" PRIu64 "attr block\n"), + bp->b_bn, be64_to_cpu(info->blkno), ino); + return 1; + } + /* verify uuid */ + if (platform_uuid_compare(&info->uuid, &mp->m_sb.sb_meta_uuid) != 0) { + do_warn( +_("wrong FS UUID, inode %" PRIu64 " attr block %" PRIu64 "\n"), + ino, bp->b_bn); + return 1; + } + + return 0; +} + /* * Start processing for a leaf or fuller btree. * A leaf directory is one where the attribute fork is too big for @@ -1564,6 +1602,13 @@ process_longform_attr( if (bp->b_error == -EFSBADCRC) (*repair)++; + /* is this block sane? */ + if (__check_attr_header(mp, bp, ino)) { + *repair = 0; + libxfs_putbuf(bp); + return 1; + } + /* verify leaf block */ leaf = (xfs_attr_leafblock_t *)XFS_BUF_PTR(bp); xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);