aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2017-04-04 15:37:43 -0500
committerEric Sandeen <sandeen@redhat.com>2017-04-04 15:37:43 -0500
commit81bf5e85b3f02165be7deed706c7de6a7ca56bf1 (patch)
tree7d388f119169f78f40879cd2cc585f3dcd0dc108
parente2376544b5773619415d9c188b999dab54453686 (diff)
downloadxfsprogs-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.c6
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,