diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2017-04-04 15:37:43 -0500 |
---|---|---|
committer | Eric Sandeen <sandeen@redhat.com> | 2017-04-04 15:37:43 -0500 |
commit | 81bf5e85b3f02165be7deed706c7de6a7ca56bf1 (patch) | |
tree | 7d388f119169f78f40879cd2cc585f3dcd0dc108 | |
parent | e2376544b5773619415d9c188b999dab54453686 (diff) | |
download | xfsprogs-dev-81bf5e85b3f02165be7deed706c7de6a7ca56bf1.tar.gz |
xfs: check for obviously bad level values in the bmbt root
Source kernel commit: b3bf607d58520ea8c0666aeb4be60dbb724cd3a2
We can't handle a bmbt that's taller than BTREE_MAXLEVELS, and there's
no such thing as a zero-level bmbt (for that we have extents format),
so if we see this, send back an error code.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
-rw-r--r-- | libxfs/xfs_inode_fork.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c index d117405391..8df1d337b8 100644 --- a/libxfs/xfs_inode_fork.c +++ b/libxfs/xfs_inode_fork.c @@ -23,6 +23,7 @@ #include "xfs_mount.h" #include "xfs_inode.h" #include "xfs_trans.h" +#include "xfs_btree.h" #include "xfs_bmap_btree.h" #include "xfs_bmap.h" #include "xfs_trace.h" @@ -426,11 +427,13 @@ xfs_iformat_btree( /* REFERENCED */ int nrecs; int size; + int level; ifp = XFS_IFORK_PTR(ip, whichfork); dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); size = XFS_BMAP_BROOT_SPACE(mp, dfp); nrecs = be16_to_cpu(dfp->bb_numrecs); + level = be16_to_cpu(dfp->bb_level); /* * blow out if -- fork has less extents than can fit in @@ -443,7 +446,8 @@ xfs_iformat_btree( XFS_IFORK_MAXEXT(ip, whichfork) || XFS_BMDR_SPACE_CALC(nrecs) > XFS_DFORK_SIZE(dip, mp, whichfork) || - XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) { + XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks) || + level == 0 || level > XFS_BTREE_MAXLEVELS) { xfs_warn(mp, "corrupt inode %Lu (btree).", (unsigned long long) ip->i_ino); XFS_CORRUPTION_ERROR("xfs_iformat_btree", XFS_ERRLEVEL_LOW, |