On 2018年05月07日 15:46, Qu Wenruo wrote: > 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 restrict 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 <ka...@wit.edu.pl>
Mail changed to <hub...@kario.pl> (Github version already updated.) Thanks, Qu > Signed-off-by: Qu Wenruo <w...@suse.com> > --- > print-tree.c | 18 ++++++++++++++++++ > 1 file changed, 18 insertions(+) > > diff --git a/print-tree.c b/print-tree.c > index a1a7954abdae..aaff0f618b7e 100644 > --- a/print-tree.c > +++ b/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 restrict 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 */ >
signature.asc
Description: OpenPGP digital signature