• Qu Wenruo's avatar
    btrfs: free the allocated memory if btrfs_alloc_page_array() fails · 94dbf7c0
    Qu Wenruo authored
    [BUG]
    If btrfs_alloc_page_array() fail to allocate all pages but part of the
    slots, then the partially allocated pages would be leaked in function
    btrfs_submit_compressed_read().
    
    [CAUSE]
    As explicitly stated, if btrfs_alloc_page_array() returned -ENOMEM,
    caller is responsible to free the partially allocated pages.
    
    For the existing call sites, most of them are fine:
    
    - btrfs_raid_bio::stripe_pages
      Handled by free_raid_bio().
    
    - extent_buffer::pages[]
      Handled btrfs_release_extent_buffer_pages().
    
    - scrub_stripe::pages[]
      Handled by release_scrub_stripe().
    
    But there is one exception in btrfs_submit_compressed_read(), if
    btrfs_alloc_page_array() failed, we didn't cleanup the array and freed
    the array pointer directly.
    
    Initially there is still the error handling in commit dd137dd1
    ("btrfs: factor out allocating an array of pages"), but later in commit
    544fe4a9 ("btrfs: embed a btrfs_bio into struct compressed_bio"),
    the error handling is removed, leading to the possible memory leak.
    
    [FIX]
    This patch would add back the error handling first, then to prevent such
    situation from happening again, also
    Make btrfs_alloc_page_array() to free the allocated pages as a extra
    safety net, then we don't need to add the error handling to
    btrfs_submit_compressed_read().
    
    Fixes: 544fe4a9 ("btrfs: embed a btrfs_bio into struct compressed_bio")
    CC: stable@vger.kernel.org # 6.4+
    Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    94dbf7c0
extent_io.c 128 KB