Skip to content

Latest commit

 

History

History

CVE-2019-19036

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

CVE-2019-19036

Target

Linux Kernel 5.0.21 btrfs FileSystem

Bug Type

Null-Pointer-Dereference

Abstract

mount crafted image can cause Null-Ptr-Deref

it can be not only local(mount btrfs image in local shell), but also remote(mount corrupted(with crafted btrfs image) USB or other storage)

Reproduce

mkdir ./mount
mount poc_2019_19036.img ./mnt

Details

Debug View

─────────────────────────────────────────────────────────── registers ────
$rax   : 0x1ffff1100d8efd36  →  0x1ffff1100d8efd36
$rbx   : 0xffff88806c77e9b0  →  0x0000000041b58ab3  →  0x0000000041b58ab3
$rcx   : 0x0000000000000000  →  0x0000000000000000
$rdx   : 0xdffffc0000000000  →  0xdffffc0000000000
$rsp   : 0xffff88806c77e968  →  0xffffed100d8efd46  →  0x00000000f2f2f2f8 →  0x00000000f2f2f2f8
$rbp   : 0xffff888069bcc400  →  0x0000000000000000  →  0x0000000000000000
$rsi   : 0x0000000000000004  →  0x0000000000000004
$rdi   : 0x0000000000000024  →  0x0000000000000024
$rip   : 0xffffffff81c8c6a4  →  0x448b48ff9dc357e8  →  0x448b48ff9dc357e8
$r8    : 0x0000000000000000  →  0x0000000000000000
$r9    : 0x0000000000000000  →  0x0000000000000000
$r10   : 0x1ffff1100d8efda0  →  0x1ffff1100d8efda0
$r11   : 0xffffed100d3795bd  →  0x0000000000000000  →  0x0000000000000000
$r12   : 0xffffed100d379880  →  0x0000000000000000  →  0x0000000000000000
$r13   : 0x0000000000000024  →  0x0000000000000024
$r14   : 0xdffffc0000000000  →  0xdffffc0000000000
$r15   : 0x0000000000000000  →  0x0000000000000000
$eflags: [zero carry PARITY adjust sign trap INTERRUPT direction overflowresume virtualx86 identification]
$cs: 0x0010 $ss: 0x0018 $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
─────────────────────────────────────────────────────────────── stack ────
0xffff88806c77e968│+0x0000: 0xffffed100d8efd46  →  0x00000000f2f2f2f8  →0x00000000f2f2f2f8	 ← $rsp
0xffff88806c77e970│+0x0008: 0x1ffff1100d8efd3e  →  0x1ffff1100d8efd3e
0xffff88806c77e978│+0x0010: 0xffff888069bcc400  →  0x0000000000000000  →0x0000000000000000
0xffff88806c77e980│+0x0018: 0x1ffff1100d8efd32  →  0x1ffff1100d8efd32
0xffff88806c77e988│+0x0020: 0xffff88806c77eb75  →  0x0041b58ab3000000  →0x0041b58ab3000000
0xffff88806c77e990│+0x0028: 0x0000000041b58ab3  →  0x0000000041b58ab3
0xffff88806c77e998│+0x0030: 0xffffffff84937b50  →  0x3120342032332033  →0x3120342032332033
0xffff88806c77e9a0│+0x0038: 0xffffffff81c8c590  →  0x0000ba4856415741  →0x0000ba4856415741
───────────────────────────────────────────────────────── code:x86:64 ────
   0xffffffff81c8c698 <btrfs_root_node+264> mov    rax, rbx
   0xffffffff81c8c69b <btrfs_root_node+267> shr    rax, 0x3
   0xffffffff81c8c69f <btrfs_root_node+271> mov    BYTE PTR [rax+r14*1], 0x4
 → 0xffffffff81c8c6a4 <btrfs_root_node+276> call   0xffffffff81668a00 <kasan_check_read>
   ↳  0xffffffff81668a00 <kasan_check_read+0> mov    rcx, QWORD PTR [rsp]
      0xffffffff81668a04 <kasan_check_read+4> mov    esi, esi
      0xffffffff81668a06 <kasan_check_read+6> xor    edx, edx
      0xffffffff81668a08 <kasan_check_read+8> jmp    0xffffffff8166aa50 <check_memory_region>
      0xffffffff81668a0d                  nop    DWORD PTR [rax]
      0xffffffff81668a10 <kasan_check_write+0> mov    rcx, QWORD PTR [rsp]
─────────────────────────────────────────────────────────── arguments ────
kasan_check_read (
   QWORD var_0 = 0x0000000000000024 → 0x0000000000000024,
   unsigned int var_1 = 0x0000000000000004 → 0x0000000000000004
)
──────────────────────────────────── source:./include/asm-g[...].h+21 ────
     16	 #include <linux/build_bug.h>
     17	 #include <linux/kasan-checks.h>
     18
     19	 static __always_inline int atomic_read(const atomic_t *v)
     20	 {
 →   21	 	kasan_check_read(v, sizeof(*v));
     22	 	return arch_atomic_read(v);
     23	 }
     24
     25	 static __always_inline s64 atomic64_read(const atomic64_t *v)
     26	 {
───────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "", stopped, reason: BREAKPOINT
[#1] Id 2, Name: "", stopped, reason: BREAKPOINT
─────────────────────────────────────────────────────────────── trace ────
[#0] 0xffffffff81c8c6a4 → atomic_fetch_add_unless(a=<optimized out>, u=<optimized out>, v=<optimized out>)
[#1] 0xffffffff81c8c6a4 → atomic_add_unless(u=<optimized out>, a=<optimized out>, v=<optimized out>)
[#2] 0xffffffff81c8c6a4 → btrfs_root_node(root=<optimized out>)
[#3] 0xffffffff81c8c925 → btrfs_read_lock_root_node(root=0xffff888069bcc400)
[#4] 0xffffffff81c9be94 → btrfs_search_slot_get_root(write_lock_level=<optimized out>, p=<optimized out>, root=<optimized out>)
[#5] 0xffffffff81c9be94 → btrfs_search_slot(trans=<optimized out>, root=0xffff888069bcc400, key=<optimized out>, p=0xffff888069d91000, ins_len=<optimized out>, cow=<optimized out>)
[#6] 0xffffffff81cf73ae → btrfs_find_root(root=<optimized out>, search_key=0xffff88806c77f040, path=0xffff888069d91000, root_item=<optimized out>, root_key=0xffff888069bcac5f)
[#7] 0xffffffff81d19e54 → btrfs_read_tree_root(tree_root=0xffff888069bcc400, key=0x4 <irq_stack_union+4>)
[#8] 0xffffffff81d1a049 → btrfs_read_fs_root(tree_root=<optimized out>, location=<optimized out>)
[#9] 0xffffffff81d1a338 → btrfs_get_fs_root(fs_info=0x24 <irq_stack_union+36>, location=0x4 <irq_stack_union+4>, check_ref=<optimized out>)
──────────────────────────────────────────────────────────────────────────

Thread 1 hit Breakpoint 2, atomic_fetch_add_unless (a=<optimized out>, u=<optimized out>, v=<optimized out>) at ./include/linux/atomic.h:575
575		int c = atomic_read(v);
gef➤

$r15(struct extent_buffer *eb, return value of rcu_dereference(root->node)) appears to 0.

Bug Causes

struct extent_buffer *btrfs_root_node(struct btrfs_root *root)
{
	struct extent_buffer *eb;

	while (1) {
		rcu_read_lock();
[1]		eb = rcu_dereference(root->node);

		/*
		 * RCU really hurts here, we could free up the root node because
		 * it was COWed but we may not get the new root node yet so do
		 * the inc_not_zero dance and if it doesn't work then
		 * synchronize_rcu and try again.
		 */
[2]		if (atomic_inc_not_zero(&eb->refs)) {
			rcu_read_aunlock();
			break;
		}
		rcu_read_unlock();
		synchronize_rcu();
	}
	return eb;
}

in [1], rcu_dereference(root->node) returns 0.

it used in [2] (eb is 0, so eb->refs equals 0x00 + 0x24)

KASAN logs

[  166.132649] BTRFS: device fsid a62e00e8-e94e-4200-8217-12444de93c2e devid 1 transid 8 /dev/loop0
[  166.186424] BTRFS info (device loop0): disk space caching is enabled
[  166.186980] BTRFS info (device loop0): has skinny extents
[  166.370019] ==================================================================
[  166.370195] BUG: KASAN: null-ptr-deref in btrfs_root_node+0x119/0x300
[  166.370195] Read of size 4 at addr 0000000000000024 by task kworker/u4:4/174
[  166.370195]
[  166.370195] CPU: 0 PID: 174 Comm: kworker/u4:4 Not tainted 5.0.21 #1
[  166.370195] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
[  166.370195] Workqueue: btrfs-endio-meta btrfs_endio_meta_helper
[  166.370195] Call Trace:
[  166.370195]  dump_stack+0xae/0x14b
[  166.370195]  ? show_regs_print_info+0x5/0x5
[  166.370195]  ? __read_once_size_nocheck.constprop.8+0x10/0x10
[  166.370195]  ? btrfs_root_node+0x119/0x300
[  166.370195]  ? btrfs_root_node+0x119/0x300
[  166.370195]  kasan_report+0x171/0x18d
[  166.370195]  ? btrfs_root_node+0x119/0x300
[  166.370195]  btrfs_root_node+0x119/0x300
[  166.370195]  ? btrfs_free_path+0x10/0x10
[  166.370195]  ? deref_stack_reg+0xab/0x110
[  166.370195]  ? __read_once_size_nocheck.constprop.8+0x10/0x10
[  166.370195]  ? ret_from_fork+0x34/0x40
[  166.370195]  ? unwind_next_frame+0x357/0x1ca0
[  166.370195]  btrfs_read_lock_root_node+0x35/0x60
[  166.370195]  btrfs_search_slot+0x10c4/0x2190
[  166.370195]  ? __lock_text_start+0x8/0x8
[  166.370195]  ? split_leaf+0x11e0/0x11e0
[  166.370195]  ? save_stack+0x89/0xb0
[  166.370195]  ? __kasan_kmalloc.constprop.4+0xa0/0xd0
[  166.370195]  ? btrfs_read_tree_root+0x94/0x330
[  166.370195]  ? btrfs_get_fs_root+0x248/0x810
[  166.370195]  ? check_leaf+0x31e/0x17e0
[  166.370195]  ? btree_readpage_end_io_hook+0x5a2/0x7d0
[  166.370195]  ? bio_endio+0x36a/0x680
[  166.370195]  ? normal_work_helper+0x24a/0xf30
[  166.370195]  ? process_one_work+0x90a/0x1690
[  166.370195]  ? kthread+0x2e4/0x3a0
[  166.370195]  ? ret_from_fork+0x35/0x40
[  166.370195]  ? kasan_init_slab_obj+0x20/0x30
[  166.370195]  btrfs_find_root+0xbe/0xb20
[  166.370195]  ? print_extent_data_ref+0x7c/0x7c
[  166.370195]  ? btrfs_read_tree_root+0x49/0x330
[  166.370195]  ? rcu_qs+0x2f0/0x2f0
[  166.370195]  ? kasan_unpoison_shadow+0x30/0x40
[  166.370195]  ? __kasan_kmalloc.constprop.4+0xa0/0xd0
[  166.370195]  ? btrfs_read_tree_root+0x144/0x330
[  166.370195]  btrfs_read_tree_root+0x144/0x330
[  166.370195]  btrfs_read_fs_root+0x9/0xb0
[  166.370195]  btrfs_get_fs_root+0x248/0x810
[  166.370195]  ? btrfs_read_fs_root+0xb0/0xb0
[  166.370195]  ? memcmp_extent_buffer+0x109/0x190
[  166.370195]  ? deref_stack_reg+0xab/0x110
[  166.370195]  ? csum_tree_block+0x289/0x4a0
[  166.370195]  check_leaf+0x31e/0x17e0
[  166.370195]  ? check_dir_item+0x5d0/0x5d0
[  166.370195]  ? ret_from_fork+0x34/0x40
[  166.370195]  ? unwind_next_frame+0x357/0x1ca0
[  166.370195]  ? ret_from_fork+0x35/0x40
[  166.370195]  ? memcpy+0x34/0x50
[  166.370195]  ? read_extent_buffer+0xef/0x180
[  166.370195]  btree_readpage_end_io_hook+0x5a2/0x7d0
[  166.370195]  ? csum_tree_block+0x4a0/0x4a0
[  166.370195]  end_bio_extent_readpage+0x525/0x10e0
[  166.370195]  ? btrfs_create_repair_bio+0x630/0x630
[  166.370195]  ? down_read+0x5f/0x100
[  166.370195]  ? pick_next_entity+0x194/0x400
[  166.370195]  bio_endio+0x36a/0x680
[  166.370195]  ? apic_timer_interrupt+0xa/0x20
[  166.370195]  ? bio_put+0x180/0x180
[  166.370195]  ? __kasan_slab_free+0x143/0x180
[  166.370195]  ? end_workqueue_fn+0x11b/0x1b0
[  166.370195]  ? kmem_cache_free+0x70/0x1a0
[  166.370195]  ? btrfs_create_repair_bio+0x630/0x630
[  166.370195]  normal_work_helper+0x24a/0xf30
[  166.370195]  ? fork_idle+0x2e0/0x2e0
[  166.370195]  ? __btrfs_alloc_workqueue+0x640/0x640
[  166.370195]  ? ldsem_up_read+0xe/0x30
[  166.370195]  ? tty_port_default_receive_buf+0xf2/0x150
[  166.370195]  ? tty_port_tty_set+0xa0/0xa0
[  166.370195]  ? fsnotify_mark_destroy_workfn+0x2e3/0x4a0
[  166.370195]  ? kprobe_flush_task+0x16a/0x590
[  166.370195]  ? do_flush_tlb_all+0x80/0x80
[  166.370195]  ? tty_prepare_flip_string+0x160/0x160
[  166.370195]  ? read_word_at_a_time+0xe/0x20
[  166.370195]  ? strscpy+0x15b/0x470
[  166.370195]  ? read_word_at_a_time+0x20/0x20
[  166.370195]  ? set_load_weight+0x2d0/0x2d0
[  166.370195]  ? __switch_to_asm+0x41/0x70
[  166.370195]  ? __switch_to_asm+0x35/0x70
[  166.370195]  ? __switch_to_asm+0x41/0x70
[  166.370195]  ? __switch_to_asm+0x35/0x70
[  166.370195]  ? __switch_to_asm+0x41/0x70
[  166.370195]  process_one_work+0x90a/0x1690
[  166.370195]  ? __switch_to_asm+0x41/0x70
[  166.370195]  ? __switch_to_asm+0x35/0x70
[  166.370195]  ? cancel_delayed_work_sync+0x10/0x10
[  166.370195]  ? __schedule+0x738/0x1af0
[  166.370195]  ? pick_next_task_fair+0x1287/0x18d0
[  166.370195]  ? pci_mmcfg_check_reserved+0x100/0x100
[  166.370195]  ? run_rebalance_domains+0x3e0/0x3e0
[  166.370195]  ? native_calibrate_cpu_early+0x7b0/0x7b0
[  166.370195]  ? rcu_qs+0x2f0/0x2f0
[  166.370195]  ? schedule+0xd2/0x2f0
[  166.370195]  ? __schedule+0x1af0/0x1af0
[  166.370195]  ? _raw_spin_lock_irq+0x9a/0x130
[  166.370195]  ? _raw_write_unlock_irqrestore+0x110/0x110
[  166.370195]  worker_thread+0x191/0x1200
[  166.370195]  ? __switch_to_asm+0x41/0x70
[  166.370195]  ? process_one_work+0x1690/0x1690
[  166.370195]  ? __switch_to_asm+0x35/0x70
[  166.370195]  ? __switch_to_asm+0x41/0x70
[  166.370195]  ? __switch_to_asm+0x35/0x70
[  166.370195]  ? __switch_to_asm+0x41/0x70
[  166.370195]  ? __switch_to_asm+0x41/0x70
[  166.370195]  ? __switch_to_asm+0x35/0x70
[  166.370195]  ? __switch_to_asm+0x41/0x70
[  166.370195]  ? __switch_to_asm+0x35/0x70
[  166.370195]  ? syscall_return_via_sysret+0xf/0x7f
[  166.370195]  ? __switch_to_asm+0x35/0x70
[  166.370195]  ? __schedule+0x738/0x1af0
[  166.370195]  ? pci_mmcfg_check_reserved+0x100/0x100
[  166.370195]  ? ret_from_fork+0x35/0x40
[  166.370195]  ? save_stack+0x89/0xb0
[  166.370195]  ? __kasan_kmalloc.constprop.4+0xa0/0xd0
[  166.370195]  ? kthread+0x93/0x3a0
[  166.370195]  ? __wake_up_common+0x178/0x650
[  166.370195]  ? _raw_spin_lock_irqsave+0x9f/0x130
[  166.370195]  ? __lock_text_start+0x8/0x8
[  166.370195]  ? _raw_write_lock_irqsave+0x60/0x130
[  166.370195]  ? __lock_text_start+0x8/0x8
[  166.370195]  ? process_one_work+0x1690/0x1690
[  166.370195]  kthread+0x2e4/0x3a0
[  166.370195]  ? kthread_park+0x120/0x120
[  166.370195]  ret_from_fork+0x35/0x40
[  166.370195] ==================================================================
[  166.370195] Disabling lock debugging due to kernel taint
[  166.408519] kasan: CONFIG_KASAN_INLINE enabled
[  166.408727] kasan: GPF could be caused by NULL-ptr deref or user memory access
[  166.413672] general protection fault: 0000 [#1] SMP KASAN NOPTI
[  166.414228] CPU: 0 PID: 174 Comm: kworker/u4:4 Tainted: G    B             5.0.21 #1
[  166.414228] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
[  166.414228] Workqueue: btrfs-endio-meta btrfs_endio_meta_helper
[  166.414228] RIP: 0010:btrfs_root_node+0x12a/0x300
[  166.414228] Code: 00 00 4c 89 ef c6 00 f8 48 89 d8 48 c1 e8 03 42 c6 04 30 04 e8 57 c3 9d ff 48 8b 44 24 08 42 c6 04 30 04 4c 89 e8 48 c1 e8 03 <42> 0f b6 34 30 4c 89 e8 83 e0 07 83 c0 03 40 38 f0 7c 09 40 84 f6
[  166.414228] RSP: 0018:ffff88806c1ee968 EFLAGS: 00000203
[  166.414228] RAX: 0000000000000004 RBX: ffff88806c1ee9b0 RCX: 0000000000000000
[  166.414228] RDX: 0000000000000000 RSI: 0000000000000246 RDI: ffffffff85b15ef8
[  166.414228] RBP: ffff888064034400 R08: ffffed100da0609b R09: ffffed100da0609b
[  166.414228] R10: 0000000000000001 R11: ffffed100da0609a R12: ffffed100c806880
[  166.414228] R13: 0000000000000024 R14: dffffc0000000000 R15: 0000000000000000
[  166.414228] FS:  0000000000000000(0000) GS:ffff88806d000000(0000) knlGS:0000000000000000
[  166.414228] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  166.414228] CR2: 00007f0b8db9b000 CR3: 00000000692c0000 CR4: 00000000000006f0
[  166.414228] Call Trace:
[  166.414228]  ? btrfs_free_path+0x10/0x10
[  166.414228]  ? deref_stack_reg+0xab/0x110
[  166.414228]  ? __read_once_size_nocheck.constprop.8+0x10/0x10
[  166.414228]  ? ret_from_fork+0x34/0x40
[  166.414228]  ? unwind_next_frame+0x357/0x1ca0
[  166.414228]  btrfs_read_lock_root_node+0x35/0x60
[  166.414228]  btrfs_search_slot+0x10c4/0x2190
[  166.414228]  ? __lock_text_start+0x8/0x8
[  166.414228]  ? split_leaf+0x11e0/0x11e0
[  166.414228]  ? save_stack+0x89/0xb0
[  166.414228]  ? __kasan_kmalloc.constprop.4+0xa0/0xd0
[  166.414228]  ? btrfs_read_tree_root+0x94/0x330
[  166.414228]  ? btrfs_get_fs_root+0x248/0x810
[  166.414228]  ? check_leaf+0x31e/0x17e0
[  166.414228]  ? btree_readpage_end_io_hook+0x5a2/0x7d0
[  166.414228]  ? bio_endio+0x36a/0x680
[  166.414228]  ? normal_work_helper+0x24a/0xf30
[  166.414228]  ? process_one_work+0x90a/0x1690
[  166.414228]  ? kthread+0x2e4/0x3a0
[  166.414228]  ? ret_from_fork+0x35/0x40
[  166.414228]  ? kasan_init_slab_obj+0x20/0x30
[  166.414228]  btrfs_find_root+0xbe/0xb20
[  166.414228]  ? print_extent_data_ref+0x7c/0x7c
[  166.414228]  ? btrfs_read_tree_root+0x49/0x330
[  166.414228]  ? rcu_qs+0x2f0/0x2f0
[  166.414228]  ? kasan_unpoison_shadow+0x30/0x40
[  166.414228]  ? __kasan_kmalloc.constprop.4+0xa0/0xd0
[  166.414228]  ? btrfs_read_tree_root+0x144/0x330
[  166.414228]  btrfs_read_tree_root+0x144/0x330
[  166.414228]  btrfs_read_fs_root+0x9/0xb0
[  166.414228]  btrfs_get_fs_root+0x248/0x810
[  166.414228]  ? btrfs_read_fs_root+0xb0/0xb0
[  166.414228]  ? memcmp_extent_buffer+0x109/0x190
[  166.414228]  ? deref_stack_reg+0xab/0x110
[  166.414228]  ? csum_tree_block+0x289/0x4a0
[  166.414228]  check_leaf+0x31e/0x17e0
[  166.414228]  ? check_dir_item+0x5d0/0x5d0
[  166.414228]  ? ret_from_fork+0x34/0x40
[  166.414228]  ? unwind_next_frame+0x357/0x1ca0
[  166.414228]  ? ret_from_fork+0x35/0x40
[  166.414228]  ? memcpy+0x34/0x50
[  166.414228]  ? read_extent_buffer+0xef/0x180
[  166.414228]  btree_readpage_end_io_hook+0x5a2/0x7d0
[  166.414228]  ? csum_tree_block+0x4a0/0x4a0
[  166.414228]  end_bio_extent_readpage+0x525/0x10e0
[  166.414228]  ? btrfs_create_repair_bio+0x630/0x630
[  166.414228]  ? down_read+0x5f/0x100
[  166.414228]  ? pick_next_entity+0x194/0x400
[  166.414228]  bio_endio+0x36a/0x680
[  166.414228]  ? apic_timer_interrupt+0xa/0x20
[  166.414228]  ? bio_put+0x180/0x180
[  166.414228]  ? __kasan_slab_free+0x143/0x180
[  166.414228]  ? end_workqueue_fn+0x11b/0x1b0
[  166.414228]  ? kmem_cache_free+0x70/0x1a0
[  166.414228]  ? btrfs_create_repair_bio+0x630/0x630
[  166.414228]  normal_work_helper+0x24a/0xf30
[  166.414228]  ? fork_idle+0x2e0/0x2e0
[  166.414228]  ? __btrfs_alloc_workqueue+0x640/0x640
[  166.414228]  ? ldsem_up_read+0xe/0x30
[  166.414228]  ? tty_port_default_receive_buf+0xf2/0x150
[  166.414228]  ? tty_port_tty_set+0xa0/0xa0
[  166.414228]  ? fsnotify_mark_destroy_workfn+0x2e3/0x4a0
[  166.414228]  ? kprobe_flush_task+0x16a/0x590
[  166.414228]  ? do_flush_tlb_all+0x80/0x80
[  166.414228]  ? tty_prepare_flip_string+0x160/0x160
[  166.414228]  ? read_word_at_a_time+0xe/0x20
[  166.414228]  ? strscpy+0x15b/0x470
[  166.414228]  ? read_word_at_a_time+0x20/0x20
[  166.414228]  ? set_load_weight+0x2d0/0x2d0
[  166.414228]  ? __switch_to_asm+0x41/0x70
[  166.414228]  ? __switch_to_asm+0x35/0x70
[  166.414228]  ? __switch_to_asm+0x41/0x70
[  166.414228]  ? __switch_to_asm+0x35/0x70
[  166.414228]  ? __switch_to_asm+0x41/0x70
[  166.414228]  process_one_work+0x90a/0x1690
[  166.414228]  ? __switch_to_asm+0x41/0x70
[  166.414228]  ? __switch_to_asm+0x35/0x70
[  166.414228]  ? cancel_delayed_work_sync+0x10/0x10
[  166.414228]  ? __schedule+0x738/0x1af0
[  166.414228]  ? pick_next_task_fair+0x1287/0x18d0
[  166.414228]  ? pci_mmcfg_check_reserved+0x100/0x100
[  166.414228]  ? run_rebalance_domains+0x3e0/0x3e0
[  166.414228]  ? native_calibrate_cpu_early+0x7b0/0x7b0
[  166.414228]  ? rcu_qs+0x2f0/0x2f0
[  166.414228]  ? schedule+0xd2/0x2f0
[  166.414228]  ? __schedule+0x1af0/0x1af0
[  166.414228]  ? _raw_spin_lock_irq+0x9a/0x130
[  166.414228]  ? _raw_write_unlock_irqrestore+0x110/0x110
[  166.414228]  worker_thread+0x191/0x1200
[  166.414228]  ? __switch_to_asm+0x41/0x70
[  166.414228]  ? process_one_work+0x1690/0x1690
[  166.414228]  ? __switch_to_asm+0x35/0x70
[  166.414228]  ? __switch_to_asm+0x41/0x70
[  166.414228]  ? __switch_to_asm+0x35/0x70
[  166.414228]  ? __switch_to_asm+0x41/0x70
[  166.414228]  ? __switch_to_asm+0x41/0x70
[  166.414228]  ? __switch_to_asm+0x35/0x70
[  166.414228]  ? __switch_to_asm+0x41/0x70
[  166.414228]  ? __switch_to_asm+0x35/0x70
[  166.414228]  ? syscall_return_via_sysret+0xf/0x7f
[  166.414228]  ? __switch_to_asm+0x35/0x70
[  166.414228]  ? __schedule+0x738/0x1af0
[  166.414228]  ? pci_mmcfg_check_reserved+0x100/0x100
[  166.414228]  ? ret_from_fork+0x35/0x40
[  166.414228]  ? save_stack+0x89/0xb0
[  166.414228]  ? __kasan_kmalloc.constprop.4+0xa0/0xd0
[  166.414228]  ? kthread+0x93/0x3a0
[  166.414228]  ? __wake_up_common+0x178/0x650
[  166.414228]  ? _raw_spin_lock_irqsave+0x9f/0x130
[  166.414228]  ? __lock_text_start+0x8/0x8
[  166.414228]  ? _raw_write_lock_irqsave+0x60/0x130
[  166.414228]  ? __lock_text_start+0x8/0x8
[  166.414228]  ? process_one_work+0x1690/0x1690
[  166.414228]  kthread+0x2e4/0x3a0
[  166.414228]  ? kthread_park+0x120/0x120
[  166.414228]  ret_from_fork+0x35/0x40
[  166.414228] Modules linked in:
[  166.453905] ---[ end trace 43259c89f26aad18 ]---
[  166.455459] RIP: 0010:btrfs_root_node+0x12a/0x300
[  166.455713] Code: 00 00 4c 89 ef c6 00 f8 48 89 d8 48 c1 e8 03 42 c6 04 30 04 e8 57 c3 9d ff 48 8b 44 24 08 42 c6 04 30 04 4c 89 e8 48 c1 e8 03 <42> 0f b6 34 30 4c 89 e8 83 e0 07 83 c0 03 40 38 f0 7c 09 40 84 f6
[  166.458661] RSP: 0018:ffff88806c1ee968 EFLAGS: 00000203
[  166.458919] RAX: 0000000000000004 RBX: ffff88806c1ee9b0 RCX: 0000000000000000
[  166.459804] RDX: 0000000000000000 RSI: 0000000000000246 RDI: ffffffff85b15ef8
[  166.461553] RBP: ffff888064034400 R08: ffffed100da0609b R09: ffffed100da0609b
[  166.461675] R10: 0000000000000001 R11: ffffed100da0609a R12: ffffed100c806880
[  166.461776] R13: 0000000000000024 R14: dffffc0000000000 R15: 0000000000000000
[  166.461897] FS:  0000000000000000(0000) GS:ffff88806d000000(0000) knlGS:0000000000000000
[  166.462089] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  166.462167] CR2: 00007f0b8db9b000 CR3: 00000000692c0000 CR4: 00000000000006f0
[  166.467859] kworker/u4:4 (174) used greatest stack depth: 41672 bytes left

Conclusion

crafted image can handle rcu_dereference(root->node) return value to 0.

it can be danger in other functions.

it can be not only local(mount btrfs image in local shell), but also remote(mount corrupted(with crafted btrfs image) USB or other storage)

Discoverer

Team bobfuzzer

Acknowledgments

This Project used ported version(to 5.0.21 and 5.3.14 linux kernel) of filesystem fuzzer 'JANUS' which developed by GeorgiaTech Systems Software & Security Lab(SSLab)

Thank you for the excellent fuzzer and paper below.