aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLiu Bo <bo.li.liu@oracle.com>2016-06-23 19:32:45 -0400
committerDavid Sterba <dsterba@suse.com>2016-07-26 07:52:25 -0400
commit5e24e9af01abcb151173bb133f1a72b94239c670 (patch)
treeacaaca007c5763a9f6309de02fa4459946132e67 /fs
parent6fb37b756acce6d6e045f79c3764206033f617b4 (diff)
Btrfs: error out if generic_bin_search get invalid arguments
With btrfs-corrupt-block, one can set btree node/leaf's field, if we assign a negative value to node/leaf, we can get various hangs, eg. if extent_root's nritems is -2ULL, then we get stuck in btrfs_read_block_groups() because it has a while loop and btrfs_search_slot() on extent_root will always return the first child. This lets us know what's happening and returns a EINVAL to callers instead of returning the first item. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index a85cf7d23309..362879da4f0d 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1771,6 +1771,14 @@ static noinline int generic_bin_search(struct extent_buffer *eb,
1771 unsigned long map_len = 0; 1771 unsigned long map_len = 0;
1772 int err; 1772 int err;
1773 1773
1774 if (low > high) {
1775 btrfs_err(eb->fs_info,
1776 "%s: low (%d) > high (%d) eb %llu owner %llu level %d",
1777 __func__, low, high, eb->start,
1778 btrfs_header_owner(eb), btrfs_header_level(eb));
1779 return -EINVAL;
1780 }
1781
1774 while (low < high) { 1782 while (low < high) {
1775 mid = (low + high) / 2; 1783 mid = (low + high) / 2;
1776 offset = p + mid * item_size; 1784 offset = p + mid * item_size;