• Qu Wenruo's avatar
    btrfs: reloc: Fix NULL pointer dereference due to expanded reloc_root lifespan · a28d37d7
    Qu Wenruo authored
    commit 10995c04 upstream.
    
    Commit d2311e69 ("btrfs: relocation: Delay reloc tree deletion after
    merge_reloc_roots()") expands the life span of root->reloc_root.
    
    This breaks certain checs of fs_info->reloc_ctl.  Before that commit, if
    we have a root with valid reloc_root, then it's ensured to have
    fs_info->reloc_ctl.
    
    But now since reloc_root doesn't always mean a valid fs_info->reloc_ctl,
    such check is unreliable and can cause the following NULL pointer
    dereference:
    
      BUG: unable to handle kernel NULL pointer dereference at 00000000000005c1
      IP: btrfs_reloc_pre_snapshot+0x20/0x50 [btrfs]
      PGD 0 P4D 0
      Oops: 0000 [#1] SMP PTI
      CPU: 0 PID: 10379 Comm: snapperd Not tainted
      Call Trace:
       create_pending_snapshot+0xd7/0xfc0 [btrfs]
       create_pending_snapshots+0x8e/0xb0 [btrfs]
       btrfs_commit_transaction+0x2ac/0x8f0 [btrfs]
       btrfs_mksubvol+0x561/0x570 [btrfs]
       btrfs_ioctl_snap_create_transid+0x189/0x190 [btrfs]
       btrfs_ioctl_snap_create_v2+0x102/0x150 [btrfs]
       btrfs_ioctl+0x5c9/0x1e60 [btrfs]
       do_vfs_ioctl+0x90/0x5f0
       SyS_ioctl+0x74/0x80
       do_syscall_64+0x7b/0x150
       entry_SYSCALL_64_after_hwframe+0x3d/0xa2
      RIP: 0033:0x7fd7cdab8467
    
    Fix it by explicitly checking fs_info->reloc_ctl other than using the
    implied root->reloc_root.
    
    Fixes: d2311e69 ("btrfs: relocation: Delay reloc tree deletion after merge_reloc_roots")
    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>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    a28d37d7
relocation.c 113 KB