summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-checker.c
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2018-09-27 19:59:34 -0400
committerDavid Sterba <dsterba@suse.com>2018-10-15 11:23:37 -0400
commitf556faa46eb4e96d0d0772e74ecf66781e132f72 (patch)
tree2022f3fe4cc8829472e8f0aef8d5ad362f657c59 /fs/btrfs/tree-checker.c
parent3d0174f78e72301324a5b0ba7d67676474e36fff (diff)
btrfs: tree-checker: Check level for leaves and nodes
Although we have tree level check at tree read runtime, it's completely based on its parent level. We still need to do accurate level check to avoid invalid tree blocks sneak into kernel space. The check itself is simple, for leaf its level should always be 0. For nodes its level should be in range [1, BTRFS_MAX_LEVEL - 1]. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/tree-checker.c')
-rw-r--r--fs/btrfs/tree-checker.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
index db835635372f..cab0b1f1f741 100644
--- a/fs/btrfs/tree-checker.c
+++ b/fs/btrfs/tree-checker.c
@@ -487,6 +487,13 @@ static int check_leaf(struct btrfs_fs_info *fs_info, struct extent_buffer *leaf,
487 u32 nritems = btrfs_header_nritems(leaf); 487 u32 nritems = btrfs_header_nritems(leaf);
488 int slot; 488 int slot;
489 489
490 if (btrfs_header_level(leaf) != 0) {
491 generic_err(fs_info, leaf, 0,
492 "invalid level for leaf, have %d expect 0",
493 btrfs_header_level(leaf));
494 return -EUCLEAN;
495 }
496
490 /* 497 /*
491 * Extent buffers from a relocation tree have a owner field that 498 * Extent buffers from a relocation tree have a owner field that
492 * corresponds to the subvolume tree they are based on. So just from an 499 * corresponds to the subvolume tree they are based on. So just from an
@@ -645,9 +652,16 @@ int btrfs_check_node(struct btrfs_fs_info *fs_info, struct extent_buffer *node)
645 unsigned long nr = btrfs_header_nritems(node); 652 unsigned long nr = btrfs_header_nritems(node);
646 struct btrfs_key key, next_key; 653 struct btrfs_key key, next_key;
647 int slot; 654 int slot;
655 int level = btrfs_header_level(node);
648 u64 bytenr; 656 u64 bytenr;
649 int ret = 0; 657 int ret = 0;
650 658
659 if (level <= 0 || level >= BTRFS_MAX_LEVEL) {
660 generic_err(fs_info, node, 0,
661 "invalid level for node, have %d expect [1, %d]",
662 level, BTRFS_MAX_LEVEL - 1);
663 return -EUCLEAN;
664 }
651 if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(fs_info)) { 665 if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(fs_info)) {
652 btrfs_crit(fs_info, 666 btrfs_crit(fs_info,
653"corrupt node: root=%llu block=%llu, nritems too %s, have %lu expect range [1,%u]", 667"corrupt node: root=%llu block=%llu, nritems too %s, have %lu expect range [1,%u]",