• L
    Btrfs: fix out of bounds array access while reading extent buffer · f716abd5
    Liu Bo 提交于
    There is a corner case that slips through the checkers in functions
    reading extent buffer, ie.
    
    if (start < eb->len) and (start + len > eb->len),
    then
    
    a) map_private_extent_buffer() returns immediately because
    it's thinking the range spans across two pages,
    
    b) and the checkers in read_extent_buffer(), WARN_ON(start > eb->len)
    and WARN_ON(start + len > eb->start + eb->len), both are OK in this
    corner case, but it'd actually try to access the eb->pages out of
    bounds because of (start + len > eb->len).
    
    The case is found by switching extent inline ref type from shared data
    ref to non-shared data ref, which is a kind of metadata corruption.
    
    It'd use the wrong helper to access the eb,
    eg. btrfs_extent_data_ref_root(eb, ref) is used but the %ref passing
    here is "struct btrfs_shared_data_ref".  And if the extent item
    happens to be the first item in the eb, then offset/length will get
    over eb->len which ends up an invalid memory access.
    
    This is adding proper checks in order to avoid invalid memory access,
    ie. 'general protection fault', before it's too late.
    Reviewed-by: NFilipe Manana <fdmanana@suse.com>
    Signed-off-by: NLiu Bo <bo.li.liu@oracle.com>
    Signed-off-by: NChris Mason <clm@fb.com>
    Signed-off-by: NDavid Sterba <dsterba@suse.com>
    f716abd5
extent_io.c 152.1 KB