Add several more validations to xfs_dinode_verify: - For LOCAL data fork formats, di_nextents must be 0. - For LOCAL attr fork formats, di_anextents must be 0. - For inodes with no attr fork offset, - format must be XFS_DINODE_FMT_EXTENTS if set at all - di_anextents must be 0. Thanks to dchinner for pointing out a couple related checks I had forgotten to add. Signed-off-by: Eric Sandeen <sandeen@xxxxxxxxxx> --- V2: due credit :) diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 4fe17b368316..72ab4d2df8cf 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -458,6 +458,8 @@ xfs_dinode_verify( return __this_address; if (di_size > XFS_DFORK_DSIZE(dip, mp)) return __this_address; + if (dip->di_nextents) + return __this_address; /* fall through */ case XFS_DINODE_FMT_EXTENTS: case XFS_DINODE_FMT_BTREE: @@ -476,12 +478,25 @@ xfs_dinode_verify( if (XFS_DFORK_Q(dip)) { switch (dip->di_aformat) { case XFS_DINODE_FMT_LOCAL: + if (dip->di_anextents) + return __this_address; + /* fall through */ case XFS_DINODE_FMT_EXTENTS: case XFS_DINODE_FMT_BTREE: break; default: return __this_address; } + } else { /* No attr fork */ + switch (dip->di_aformat) { + case 0: /* Uninitialized OK */ + case XFS_DINODE_FMT_EXTENTS: + break; + default: + return __this_address; + } + if (dip->di_anextents) + return __this_address; } /* only version 3 or greater inodes are extensively verified here */ -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html