• Qu Wenruo's avatar
    btrfs: subpage: fix wild pointer access during metadata read failure · d9bb77d5
    Qu Wenruo authored
    [BUG]
    When running fstests for btrfs subpage read-write test, it has a very
    high chance to crash at generic/475 with the following stack:
    
     BTRFS warning (device dm-8): direct IO failed ino 510 rw 1,34817 sector 0xcdf0 len 94208 err no 10
     Unable to handle kernel paging request at virtual address ffff80001157e7c0
     CPU: 2 PID: 687125 Comm: kworker/u12:4 Tainted: G        WC        5.12.0-rc2-custom+ #5
     Hardware name: Khadas VIM3 (DT)
     Workqueue: btrfs-endio-meta btrfs_work_helper [btrfs]
     pc : queued_spin_lock_slowpath+0x1a0/0x390
     lr : do_raw_spin_lock+0xc4/0x11c
     Call trace:
      queued_spin_lock_slowpath+0x1a0/0x390
      _raw_spin_lock+0x68/0x84
      btree_readahead_hook+0x38/0xc0 [btrfs]
      end_bio_extent_readpage+0x504/0x5f4 [btrfs]
      bio_endio+0x170/0x1a4
      end_workqueue_fn+0x3c/0x60 [btrfs]
      btrfs_work_helper+0x1b0/0x1b4 [btrfs]
      process_one_work+0x22c/0x430
      worker_thread+0x70/0x3a0
      kthread+0x13c/0x140
      ret_from_fork+0x10/0x30
     Code: 910020e0 8b0200c2 f861d884 aa0203e1 (f8246827)
    
    [CAUSE]
    In end_bio_extent_readpage(), if we hit an error during read, we will
    handle the error differently for data and metadata.
    For data we queue a repair, while for metadata, we record the error and
    let the caller choose what to do.
    
    But the code is still using page->private to grab extent buffer, which
    no longer points to extent buffer for subpage metadata pages.
    
    Thus this wild pointer access leads to above crash.
    
    [FIX]
    Introduce a helper, find_extent_buffer_readpage(), to grab extent
    buffer.
    
    The difference against find_extent_buffer_nospinlock() is:
    
    - Also handles regular sectorsize == PAGE_SIZE case
    - No extent buffer refs increase/decrease
      As extent buffer under IO must have non-zero refs, so this is safe
    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>
    d9bb77d5
extent_io.c 176 KB