diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2017-02-02 18:13:59 -0500 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2017-02-02 18:13:59 -0500 |
commit | b3bf607d58520ea8c0666aeb4be60dbb724cd3a2 (patch) | |
tree | 56e86f190cb9513c8e23d670e9637f87217b10f3 | |
parent | d5a91baeb6033c3392121e4d5c011cdc08dfa9f7 (diff) |
xfs: check for obviously bad level values in the bmbt root
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>
-rw-r--r-- | fs/xfs/libxfs/xfs_inode_fork.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 421341f93bea..25c1e078aef6 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "xfs_inode.h" | 26 | #include "xfs_inode.h" |
27 | #include "xfs_trans.h" | 27 | #include "xfs_trans.h" |
28 | #include "xfs_inode_item.h" | 28 | #include "xfs_inode_item.h" |
29 | #include "xfs_btree.h" | ||
29 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
30 | #include "xfs_bmap.h" | 31 | #include "xfs_bmap.h" |
31 | #include "xfs_error.h" | 32 | #include "xfs_error.h" |
@@ -429,11 +430,13 @@ xfs_iformat_btree( | |||
429 | /* REFERENCED */ | 430 | /* REFERENCED */ |
430 | int nrecs; | 431 | int nrecs; |
431 | int size; | 432 | int size; |
433 | int level; | ||
432 | 434 | ||
433 | ifp = XFS_IFORK_PTR(ip, whichfork); | 435 | ifp = XFS_IFORK_PTR(ip, whichfork); |
434 | dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); | 436 | dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); |
435 | size = XFS_BMAP_BROOT_SPACE(mp, dfp); | 437 | size = XFS_BMAP_BROOT_SPACE(mp, dfp); |
436 | nrecs = be16_to_cpu(dfp->bb_numrecs); | 438 | nrecs = be16_to_cpu(dfp->bb_numrecs); |
439 | level = be16_to_cpu(dfp->bb_level); | ||
437 | 440 | ||
438 | /* | 441 | /* |
439 | * blow out if -- fork has less extents than can fit in | 442 | * blow out if -- fork has less extents than can fit in |
@@ -446,7 +449,8 @@ xfs_iformat_btree( | |||
446 | XFS_IFORK_MAXEXT(ip, whichfork) || | 449 | XFS_IFORK_MAXEXT(ip, whichfork) || |
447 | XFS_BMDR_SPACE_CALC(nrecs) > | 450 | XFS_BMDR_SPACE_CALC(nrecs) > |
448 | XFS_DFORK_SIZE(dip, mp, whichfork) || | 451 | XFS_DFORK_SIZE(dip, mp, whichfork) || |
449 | XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) { | 452 | XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks) || |
453 | level == 0 || level > XFS_BTREE_MAXLEVELS) { | ||
450 | xfs_warn(mp, "corrupt inode %Lu (btree).", | 454 | xfs_warn(mp, "corrupt inode %Lu (btree).", |
451 | (unsigned long long) ip->i_ino); | 455 | (unsigned long long) ip->i_ino); |
452 | XFS_CORRUPTION_ERROR("xfs_iformat_btree", XFS_ERRLEVEL_LOW, | 456 | XFS_CORRUPTION_ERROR("xfs_iformat_btree", XFS_ERRLEVEL_LOW, |