From 1c8e2f033c6862a2aa429e1ed4475540089a9386 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 3 Sep 2015 08:42:50 +1000 Subject: [PATCH] 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 --- repair/attr_repair.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) 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); -- 2.47.2