diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2017-01-09 10:38:51 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-12 05:39:42 -0500 |
commit | b85f32481d93a23488d208fca4558e84515dc0f4 (patch) | |
tree | 37fc914d5e42c633c1ac82b1db1ebb8a61065f6d /fs | |
parent | 4081d4a79a95252486569b014b9a666ad5bfdbee (diff) |
xfs: forbid AG btrees with level == 0
commit d2a047f31e86941fa896e0e3271536d50aba415e upstream.
There is no such thing as a zero-level AG btree since even a single-node
zero-records btree has one level. Btree cursor constructors read
cur_nlevels straight from disk and then access things like
cur_bufs[cur_nlevels - 1] which is /really/ bad if cur_nlevels is zero!
Therefore, strengthen the verifiers to prevent this possibility.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/libxfs/xfs_alloc.c | 10 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc.c | 9 |
2 files changed, 15 insertions, 4 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index effb64cf714f..5050056a0b06 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c | |||
@@ -2455,12 +2455,15 @@ xfs_agf_verify( | |||
2455 | be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp))) | 2455 | be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp))) |
2456 | return false; | 2456 | return false; |
2457 | 2457 | ||
2458 | if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS || | 2458 | if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 || |
2459 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 || | ||
2460 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS || | ||
2459 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS) | 2461 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS) |
2460 | return false; | 2462 | return false; |
2461 | 2463 | ||
2462 | if (xfs_sb_version_hasrmapbt(&mp->m_sb) && | 2464 | if (xfs_sb_version_hasrmapbt(&mp->m_sb) && |
2463 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS) | 2465 | (be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) < 1 || |
2466 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS)) | ||
2464 | return false; | 2467 | return false; |
2465 | 2468 | ||
2466 | /* | 2469 | /* |
@@ -2477,7 +2480,8 @@ xfs_agf_verify( | |||
2477 | return false; | 2480 | return false; |
2478 | 2481 | ||
2479 | if (xfs_sb_version_hasreflink(&mp->m_sb) && | 2482 | if (xfs_sb_version_hasreflink(&mp->m_sb) && |
2480 | be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS) | 2483 | (be32_to_cpu(agf->agf_refcount_level) < 1 || |
2484 | be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS)) | ||
2481 | return false; | 2485 | return false; |
2482 | 2486 | ||
2483 | return true;; | 2487 | return true;; |
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index c482b9716347..d45c03779dae 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c | |||
@@ -2510,8 +2510,15 @@ xfs_agi_verify( | |||
2510 | if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum))) | 2510 | if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum))) |
2511 | return false; | 2511 | return false; |
2512 | 2512 | ||
2513 | if (be32_to_cpu(agi->agi_level) > XFS_BTREE_MAXLEVELS) | 2513 | if (be32_to_cpu(agi->agi_level) < 1 || |
2514 | be32_to_cpu(agi->agi_level) > XFS_BTREE_MAXLEVELS) | ||
2514 | return false; | 2515 | return false; |
2516 | |||
2517 | if (xfs_sb_version_hasfinobt(&mp->m_sb) && | ||
2518 | (be32_to_cpu(agi->agi_free_level) < 1 || | ||
2519 | be32_to_cpu(agi->agi_free_level) > XFS_BTREE_MAXLEVELS)) | ||
2520 | return false; | ||
2521 | |||
2515 | /* | 2522 | /* |
2516 | * during growfs operations, the perag is not fully initialised, | 2523 | * during growfs operations, the perag is not fully initialised, |
2517 | * so we can't use it for any useful checking. growfs ensures we can't | 2524 | * so we can't use it for any useful checking. growfs ensures we can't |