mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 18:39:59 +00:00
Btrfs: improve check_node to avoid reading corrupted nodes
We need to check items in a node to make sure that we're reading a valid one, otherwise we could get various crashes while processing delayed_refs. 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>
This commit is contained in:
parent
a42cbec9c6
commit
6b722c1747
1 changed files with 28 additions and 4 deletions
|
@ -546,9 +546,10 @@ static int check_tree_block_fsid(struct btrfs_fs_info *fs_info,
|
|||
}
|
||||
|
||||
#define CORRUPT(reason, eb, root, slot) \
|
||||
btrfs_crit(root->fs_info, "corrupt leaf, %s: block=%llu," \
|
||||
"root=%llu, slot=%d", reason, \
|
||||
btrfs_header_bytenr(eb), root->objectid, slot)
|
||||
btrfs_crit(root->fs_info, "corrupt %s, %s: block=%llu," \
|
||||
" root=%llu, slot=%d", \
|
||||
btrfs_header_level(eb) == 0 ? "leaf" : "node",\
|
||||
reason, btrfs_header_bytenr(eb), root->objectid, slot)
|
||||
|
||||
static noinline int check_leaf(struct btrfs_root *root,
|
||||
struct extent_buffer *leaf)
|
||||
|
@ -635,6 +636,10 @@ static noinline int check_leaf(struct btrfs_root *root,
|
|||
static int check_node(struct btrfs_root *root, struct extent_buffer *node)
|
||||
{
|
||||
unsigned long nr = btrfs_header_nritems(node);
|
||||
struct btrfs_key key, next_key;
|
||||
int slot;
|
||||
u64 bytenr;
|
||||
int ret = 0;
|
||||
|
||||
if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(root)) {
|
||||
btrfs_crit(root->fs_info,
|
||||
|
@ -642,7 +647,26 @@ static int check_node(struct btrfs_root *root, struct extent_buffer *node)
|
|||
node->start, root->objectid, nr);
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
|
||||
for (slot = 0; slot < nr - 1; slot++) {
|
||||
bytenr = btrfs_node_blockptr(node, slot);
|
||||
btrfs_node_key_to_cpu(node, &key, slot);
|
||||
btrfs_node_key_to_cpu(node, &next_key, slot + 1);
|
||||
|
||||
if (!bytenr) {
|
||||
CORRUPT("invalid item slot", node, root, slot);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (btrfs_comp_cpu_keys(&key, &next_key) >= 0) {
|
||||
CORRUPT("bad key order", node, root, slot);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
|
||||
|
|
Loading…
Reference in a new issue