On Tue, May 21, 2019 at 07:28:08PM +0800, Qu Wenruo wrote: > [BUG] > When mounting a fs with reloc tree and has qgroup enabled, it can cause > NULL pointer dereference at mount time: > BUG: kernel NULL pointer dereference, address: 00000000000000a8 > #PF: supervisor read access in kernel mode > #PF: error_code(0x0000) - not-present page > PGD 0 P4D 0 > Oops: 0000 [#1] PREEMPT SMP NOPTI > RIP: 0010:btrfs_qgroup_add_swapped_blocks+0x186/0x300 [btrfs] > Call Trace: > replace_path.isra.23+0x685/0x900 [btrfs] > merge_reloc_root+0x26e/0x5f0 [btrfs] > merge_reloc_roots+0x10a/0x1a0 [btrfs] > btrfs_recover_relocation+0x3cd/0x420 [btrfs] > open_ctree+0x1bc8/0x1ed0 [btrfs] > btrfs_mount_root+0x544/0x680 [btrfs] > legacy_get_tree+0x34/0x60 > vfs_get_tree+0x2d/0xf0 > fc_mount+0x12/0x40 > vfs_kern_mount.part.12+0x61/0xa0 > vfs_kern_mount+0x13/0x20 > btrfs_mount+0x16f/0x860 [btrfs] > legacy_get_tree+0x34/0x60 > vfs_get_tree+0x2d/0xf0 > do_mount+0x81f/0xac0 > ksys_mount+0xbf/0xe0 > __x64_sys_mount+0x25/0x30 > do_syscall_64+0x65/0x240 > entry_SYSCALL_64_after_hwframe+0x49/0xbe > > [CAUSE] > In btrfs_recover_relocation(), we don't have enough info to determine > which block group we're relocating, but only to merge existing reloc > trees. > > Thus in btrfs_recover_relocation(), rc->block_group is NULL. > btrfs_qgroup_add_swapped_blocks() hasn't take this into consideration, > and causes NULL pointer dereference. > > The bug is introduced by commit 3d0174f78e72 ("btrfs: qgroup: Only trace > data extents in leaves if we're relocating data block group"), and > later qgroup refactor still keeps this optimization. > > [FIX] > Thankfully in the context of btrfs_recover_relocation(), there is no > other progress can modify tree blocks, thus those swapped tree blocks > pair will never affect qgroup numbers, no matter whatever we set for > block->trace_leaf. > > So we only need to check if @bg is NULL before accessing @bg->flags. > > Reported-by: Juan Erbes <jer...@gmail.com> > Link: https://bugzilla.opensuse.org/show_bug.cgi?id=1134806 > Fixes: 3d0174f78e72 ("btrfs: qgroup: Only trace data extents in leaves if > we're relocating data block group") > Signed-off-by: Qu Wenruo <w...@suse.com>
I've changed the subject to "btrfs: qgroup: Check bg while resuming relocation to avoid NULL pointer dereference", patch is going to 5.2-rc and will be tagged for stable.