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>
This commit is contained in:
parent
d5a91baeb6
commit
b3bf607d58
@ -26,6 +26,7 @@
|
|||||||
#include "xfs_inode.h"
|
#include "xfs_inode.h"
|
||||||
#include "xfs_trans.h"
|
#include "xfs_trans.h"
|
||||||
#include "xfs_inode_item.h"
|
#include "xfs_inode_item.h"
|
||||||
|
#include "xfs_btree.h"
|
||||||
#include "xfs_bmap_btree.h"
|
#include "xfs_bmap_btree.h"
|
||||||
#include "xfs_bmap.h"
|
#include "xfs_bmap.h"
|
||||||
#include "xfs_error.h"
|
#include "xfs_error.h"
|
||||||
@ -429,11 +430,13 @@ xfs_iformat_btree(
|
|||||||
/* REFERENCED */
|
/* REFERENCED */
|
||||||
int nrecs;
|
int nrecs;
|
||||||
int size;
|
int size;
|
||||||
|
int level;
|
||||||
|
|
||||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||||
dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
|
dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
|
||||||
size = XFS_BMAP_BROOT_SPACE(mp, dfp);
|
size = XFS_BMAP_BROOT_SPACE(mp, dfp);
|
||||||
nrecs = be16_to_cpu(dfp->bb_numrecs);
|
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
|
* blow out if -- fork has less extents than can fit in
|
||||||
@ -446,7 +449,8 @@ xfs_iformat_btree(
|
|||||||
XFS_IFORK_MAXEXT(ip, whichfork) ||
|
XFS_IFORK_MAXEXT(ip, whichfork) ||
|
||||||
XFS_BMDR_SPACE_CALC(nrecs) >
|
XFS_BMDR_SPACE_CALC(nrecs) >
|
||||||
XFS_DFORK_SIZE(dip, mp, whichfork) ||
|
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).",
|
xfs_warn(mp, "corrupt inode %Lu (btree).",
|
||||||
(unsigned long long) ip->i_ino);
|
(unsigned long long) ip->i_ino);
|
||||||
XFS_CORRUPTION_ERROR("xfs_iformat_btree", XFS_ERRLEVEL_LOW,
|
XFS_CORRUPTION_ERROR("xfs_iformat_btree", XFS_ERRLEVEL_LOW,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user