lkml.org 
[lkml]   [2020]   [Apr]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 051/245] btrfs: Check that each block group has corresponding chunk at mount time
    3.16.83-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Qu Wenruo <wqu@suse.com>

    commit 514c7dca85a0bf40be984dab0b477403a6db901f upstream.

    A crafted btrfs image with incorrect chunk<->block group mapping will
    trigger a lot of unexpected things as the mapping is essential.

    Although the problem can be caught by block group item checker
    added in "btrfs: tree-checker: Verify block_group_item", it's still not
    sufficient. A sufficiently valid block group item can pass the check
    added by the mentioned patch but could fail to match the existing chunk.

    This patch will add extra block group -> chunk mapping check, to ensure
    we have a completely matching (start, len, flags) chunk for each block
    group at mount time.

    Here we reuse the original helper find_first_block_group(), which is
    already doing the basic bg -> chunk checks, adding further checks of the
    start/len and type flags.

    Link: https://bugzilla.kernel.org/show_bug.cgi?id=199837
    Reported-by: Xu Wen <wen.xu@gatech.edu>
    Signed-off-by: Qu Wenruo <wqu@suse.com>
    Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
    Reviewed-by: David Sterba <dsterba@suse.com>
    Signed-off-by: David Sterba <dsterba@suse.com>
    [bwh: Backported to 4.4: Use root->fs_info instead of fs_info]
    Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    fs/btrfs/extent-tree.c | 28 +++++++++++++++++++++++++++-
    1 file changed, 27 insertions(+), 1 deletion(-)

    --- a/fs/btrfs/extent-tree.c
    +++ b/fs/btrfs/extent-tree.c
    @@ -8556,6 +8556,8 @@ static int find_first_block_group(struct
    int ret = 0;
    struct btrfs_key found_key;
    struct extent_buffer *leaf;
    + struct btrfs_block_group_item bg;
    + u64 flags;
    int slot;

    ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
    @@ -8590,8 +8592,32 @@ static int find_first_block_group(struct
    "logical %llu len %llu found bg but no related chunk",
    found_key.objectid, found_key.offset);
    ret = -ENOENT;
    + } else if (em->start != found_key.objectid ||
    + em->len != found_key.offset) {
    + btrfs_err(root->fs_info,
    + "block group %llu len %llu mismatch with chunk %llu len %llu",
    + found_key.objectid, found_key.offset,
    + em->start, em->len);
    + ret = -EUCLEAN;
    } else {
    - ret = 0;
    + read_extent_buffer(leaf, &bg,
    + btrfs_item_ptr_offset(leaf, slot),
    + sizeof(bg));
    + flags = btrfs_block_group_flags(&bg) &
    + BTRFS_BLOCK_GROUP_TYPE_MASK;
    +
    + if (flags != (em->map_lookup->type &
    + BTRFS_BLOCK_GROUP_TYPE_MASK)) {
    + btrfs_err(root->fs_info,
    +"block group %llu len %llu type flags 0x%llx mismatch with chunk type flags 0x%llx",
    + found_key.objectid,
    + found_key.offset, flags,
    + (BTRFS_BLOCK_GROUP_TYPE_MASK &
    + em->map_lookup->type));
    + ret = -EUCLEAN;
    + } else {
    + ret = 0;
    + }
    }
    free_extent_map(em);
    goto out;
    \
     
     \ /
      Last update: 2020-04-24 01:21    [W:4.097 / U:0.000 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site