@@ -706,6 +706,7 @@ btrfs_check_leaf(struct btrfs_fs_info *fs_info,
*/
for (slot = 0; slot < nritems; slot++) {
u32 item_end_expected;
+ u64 item_data_end;
btrfs_item_key_to_cpu(leaf, &key, slot);
@@ -720,6 +721,8 @@ btrfs_check_leaf(struct btrfs_fs_info *fs_info,
goto fail;
}
+ item_data_end = (u64)btrfs_item_offset_nr(leaf, slot) +
+ btrfs_item_size_nr(leaf, slot);
/*
* Make sure the offset and ends are right, remember that the
* item data starts at the end of the leaf and grows towards the
@@ -730,11 +733,10 @@ btrfs_check_leaf(struct btrfs_fs_info *fs_info,
else
item_end_expected = btrfs_item_offset_nr(leaf,
slot - 1);
- if (btrfs_item_end_nr(leaf, slot) != item_end_expected) {
+ if (item_data_end != item_end_expected) {
generic_err(leaf, slot,
- "unexpected item end, have %u expect %u",
- btrfs_item_end_nr(leaf, slot),
- item_end_expected);
+ "unexpected item end, have %llu expect %u",
+ item_data_end, item_end_expected);
ret = BTRFS_TREE_BLOCK_INVALID_OFFSETS;
goto fail;
}
@@ -744,12 +746,10 @@ btrfs_check_leaf(struct btrfs_fs_info *fs_info,
* just in case all the items are consistent to each other, but
* all point outside of the leaf.
*/
- if (btrfs_item_end_nr(leaf, slot) >
- BTRFS_LEAF_DATA_SIZE(fs_info)) {
+ if (item_data_end > BTRFS_LEAF_DATA_SIZE(fs_info)) {
generic_err(leaf, slot,
- "slot end outside of leaf, have %u expect range [0, %u]",
- btrfs_item_end_nr(leaf, slot),
- BTRFS_LEAF_DATA_SIZE(fs_info));
+ "slot end outside of leaf, have %llu expect range [0, %u]",
+ item_data_end, BTRFS_LEAF_DATA_SIZE(fs_info));
ret = BTRFS_TREE_BLOCK_INVALID_OFFSETS;
goto fail;
}
Similar to kernel check_leaf(), calling btrfs_item_end_nr() may get a reasonable value even an item has invalid offset/size due to u32 overflow. Fix it by use u64 variable to store item data end in btrfs_check_leaf() to avoid u32 overflow. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=215299 Reported-by: Wenqing Liu <wenqingliu0120@gmail.com> Signed-off-by: Su Yue <l@damenly.su> --- kernel-shared/ctree.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)