Commit 4056a74a authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Greg Kroah-Hartman

xfs: check for obviously bad level values in the bmbt root

commit b3bf607d upstream.

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: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent efab3ae2
...@@ -26,6 +26,7 @@ ...@@ -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( ...@@ -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( ...@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment