btrfs-progs: print-tree: Avoid segfault for heavily corrupted item pointers
Normally corrupted leaf should be caught by csum check, but sometimes corrupted item pointers (out of leaf range) can still pass csum check. In fact, our fsck/005 test case image has such corrupted item pointer and btrfs check can surprisingly fix it. Anyway, make print-tree to skip such item and remaining slots to avoid segfault. Please note that, in btrfs-progs we can't put such check into check_tree_block() nor do kernel level comprehensive check as under certain case, btrfs-progs can handle or even repair it. A strict check_tree_block() or backporting kernel btrfs_check_leaf() could break such test cases and reduce the utility of btrfs-progs. Issue: #128 Reported-by: Hubert Kario <hubert@kario.pl> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
8a7b9c9b47
commit
9e061cae19
18
print-tree.c
18
print-tree.c
|
@ -1179,6 +1179,7 @@ void btrfs_print_leaf(struct extent_buffer *eb)
|
|||
struct btrfs_item *item;
|
||||
struct btrfs_disk_key disk_key;
|
||||
char flags_str[128];
|
||||
u32 leaf_data_size = BTRFS_LEAF_DATA_SIZE(fs_info);
|
||||
u32 i;
|
||||
u32 nr;
|
||||
u64 flags;
|
||||
|
@ -1207,6 +1208,23 @@ void btrfs_print_leaf(struct extent_buffer *eb)
|
|||
u32 type;
|
||||
u64 offset;
|
||||
|
||||
/*
|
||||
* Extra check on item pointers
|
||||
* Here we don't need to be as strict as kernel leaf check.
|
||||
* Only need to ensure all pointers are pointing range inside
|
||||
* the leaf, thus no segfault.
|
||||
*/
|
||||
if (btrfs_item_offset_nr(eb, i) > leaf_data_size ||
|
||||
btrfs_item_size_nr(eb, i) + btrfs_item_offset_nr(eb, i) >
|
||||
leaf_data_size) {
|
||||
error(
|
||||
"leaf %llu slot %u pointer invalid, offset %u size %u leaf data limit %u",
|
||||
btrfs_header_bytenr(eb), i,
|
||||
btrfs_item_offset_nr(eb, i),
|
||||
btrfs_item_size_nr(eb, i), leaf_data_size);
|
||||
error("skip remaining slots");
|
||||
break;
|
||||
}
|
||||
item = btrfs_item_nr(i);
|
||||
item_size = btrfs_item_size(eb, item);
|
||||
/* Untyped extraction of slot from btrfs_item_ptr */
|
||||
|
|
Loading…
Reference in New Issue