Skip to content

bobfuzzer/CVE-2019-18885

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 

CVE-2019-18885


bobfuzzer

project team in BoB(a.k.a Best of the Best), Republic of Korea. (bobfuzzer@gmail.com)

finding bugs in linux kernel filesystem modules

Team Members

Project Member: 김동희(Kieast), 조형진(zkaryaJo), 홍승표(Ph4nt0m), 남지효(NJhyo), 정원영(nonetype)

Project Leader: 조성준(DelspoN)

Project Mentor: 이상섭(k1rh4), 박천성(Ashine)


Infomations

null dereference in btrfs_verify_dev_extents(loop list entry)

Overview

on mounting crafted btrfs image, got Null-Ptr-Deref.

Target

Tested on Linux Kernel 5.0.21 BTRFS filesystem(source here)

(It can be need CONFIG_BTRFS_FS=m option.)

Reproduce

attached crafted image on here

mkdir ./mnt
mount -t btrfs ./poc_2019_18885.img ./mnt

Bug Causes

fs/btrfs/volumes.c:430

static struct btrfs_device *find_device(struct btrfs_fs_devices *fs_devices,
		u64 devid, const u8 *uuid)
{
	struct btrfs_device *dev;

[1]	list_for_each_entry(dev, &fs_devices->devices, dev_list) {
		if (dev->devid == devid &&
		    (!uuid || !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE))) {
			return dev;
		}
	}
	return NULL;
}

in list_for_each_entry loop([1]), &fs_devices->devices list entry can be NULL

Debugger View

[ Legend: Modified register | Code | Heap | Stack | String ]
─────────────────────────────────────────────────────────── registers ────
$rax   : 0x0000000000000000  →  0x0000000000000000
$rbx   : 0xdffffc0000000000  →  0xdffffc0000000000
$rcx   : 0x0000000000000098  →  0x0000000000000098
$rdx   : 0x0000000000000013  →  0x0000000000000013
$rsp   : 0xffff888063d4e620  →  0xffff888067d9a200  →  0x1e44a09cf7d0cbce →  0x1e44a09cf7d0cbce
$rbp   : 0x0000000000c00000  →  0x0000000000c00000
$rsi   : 0x0000000000000001  →  0x0000000000000001
$rdi   : 0xffff88806a4eb248  →  0x0000000000000000  →  0x0000000000000000
$rip   : 0xffffffff81def0e8  →  0x0890850f001a3c80  →  0x0890850f001a3c80
$r8    : 0x1ffff1100d49d781  →  0x1ffff1100d49d781
$r9    : 0x0000000000000000  →  0x0000000000000000
$r10   : 0x0000000000000001  →  0x0000000000000001
$r11   : 0xffffed100cfb3463  →  0x0000000000000000  →  0x0000000000000000
$r12   : 0x0000000000000000  →  0x0000000000000000
$r13   : 0xffff888069f3b4d0  →  0xffff888069d0a560  →  0x0000000001c09000 →  0x0000000001c09000
$r14   : 0x0000000000000001  →  0x0000000000000001
$r15   : 0xffff8880696ee1a0  →  0xffff8880696ee000  →  0x0000000000000001 →  0x0000000000000001
$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 ────
0xffff888063d4e620│+0x0000: 0xffff888067d9a200  →  0x1e44a09cf7d0cbce  →0x1e44a09cf7d0cbce	 ← $rsp
0xffff888063d4e628│+0x0008: 0xffff888063d4e6b8  →  0x0000000000000001  →0x0000000000000001
0xffff888063d4e630│+0x0010: 0xffffed100c7a9cdf  →  0x00000000f2f8f8f8  →0x00000000f2f8f8f8
0xffff888063d4e638│+0x0018: 0x0000000000800000  →  0x0000000000800000
0xffff888063d4e640│+0x0020: 0xffff888063d4e6c0  →  0x00000000c00000cc  →0x00000000c00000cc
0xffff888063d4e648│+0x0028: 0xffff888063d4e6f8  →  0x0000000000000001  →0x0000000000000001
0xffff888063d4e650│+0x0030: 0xffff888067d9a318  →  0x0000000000000000  →0x0000000000000000
0xffff888063d4e658│+0x0038: 0x0000000000800000  →  0x0000000000800000
───────────────────────────────────────────────────────── code:x86:64 ────
   0xffffffff81def0da <btrfs_verify_dev_extents+1898> lea    rcx, [rax+0x98]
   0xffffffff81def0e1 <btrfs_verify_dev_extents+1905> mov    rdx, rcx
   0xffffffff81def0e4 <btrfs_verify_dev_extents+1908> shr    rdx, 0x3
 → 0xffffffff81def0e8 <btrfs_verify_dev_extents+1912> cmp    BYTE PTR [rdx+rbx*1], 0x0
   0xffffffff81def0ec <btrfs_verify_dev_extents+1916> jne    0xffffffff81def982 <btrfs_verify_dev_extents+4114>
   0xffffffff81def0f2 <btrfs_verify_dev_extents+1922> mov    rax, QWORD PTR [rax+0x98]
   0xffffffff81def0f9 <btrfs_verify_dev_extents+1929> cmp    rax, rcx
   0xffffffff81def0fc <btrfs_verify_dev_extents+1932> je     0xffffffff81def95c <btrfs_verify_dev_extents+4076>
   0xffffffff81def102 <btrfs_verify_dev_extents+1938> lea    rdi, [rax+0x88]
─────────────────────────────────────── source:fs/btrfs/volumes.c+430 ────
    425	 static struct btrfs_device *find_device(struct btrfs_fs_devices *fs_devices,
    426	 		u64 devid, const u8 *uuid)
    427	 {
    428	 	struct btrfs_device *dev;
    429
 →  430	 	list_for_each_entry(dev, &fs_devices->devices, dev_list) {
    431	 		if (dev->devid == devid &&
    432	 		    (!uuid || !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE))) {
    433	 			return dev;
    434	 		}
    435	 	}
───────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "", stopped, reason: BREAKPOINT
[#1] Id 2, Name: "", stopped, reason: BREAKPOINT
─────────────────────────────────────────────────────────────── trace ────
[#0] 0xffffffff81def0e8 → find_device(uuid=<optimized out>, devid=<optimized out>, fs_devices=<optimized out>)
[#1] 0xffffffff81def0e8 → verify_one_dev_extent(physical_len=<optimized out>, physical_offset=<optimized out>, devid=<optimized out>, chunk_offset=<optimized out>, fs_info=<optimized out>)
[#2] 0xffffffff81def0e8 → btrfs_verify_dev_extents(fs_info=<optimized out>)
[#3] 0xffffffff81d243f0 → open_ctree(sb=0xffff888069cf3b80, fs_devices=<optimized out>, options=<optimized out>)
[#4] 0xffffffff81c7c5d4 → btrfs_fill_super(data=<optimized out>, fs_devices=<optimized out>, sb=<optimized out>)
[#5] 0xffffffff81c7c5d4 → btrfs_mount_root(fs_type=<optimized out>, flags=<optimized out>, device_name=<optimized out>, data=0x0 <irq_stack_union>)
[#6] 0xffffffff816979d9 → mount_fs(type=0xffff88806a4eb248, flags=0x0, name=<optimized out>, data=<optimized out>)
[#7] 0xffffffff8170e8d9 → vfs_kern_mount(type=<optimized out>, flags=<optimized out>, name=0xffff88806c594160 "/dev/loop0", data=0x0 <irq_stack_union>)
[#8] 0xffffffff8170ec2a → vfs_kern_mount(type=<optimized out>, flags=<optimized out>, name=<optimized out>, data=<optimized out>)
[#9] 0xffffffff81c810d5 → btrfs_mount(fs_type=<optimized out>, flags=0x0,device_name=<optimized out>, data=0x0 <irq_stack_union>)
──────────────────────────────────────────────────────────────────────────

Thread 2 hit Breakpoint 1, 0xffffffff81def0e8 in find_device (uuid=<optimized out>, devid=<optimized out>, fs_devices=<optimized out>) at fs/btrfs/volumes.c:430
430		list_for_each_entry(dev, &fs_devices->devices, dev_list) {

instruction cmp BYTE PTR [rdx+rbx*1], 0x0 trying to read 0xdffffc0000000000 + 0x13 address value

KASAN Logs

[  196.251167] BTRFS: device fsid a62e00e8-e94e-4200-8217-12444de93c2e devid 1 transid 8 /dev/loop0
[  196.392627] BTRFS info (device loop0): disk space caching is enabled
[  196.395228] BTRFS info (device loop0): has skinny extents
[  196.770076] BTRFS critical (device loop0): corrupt leaf: root=1 block=29417472 slot=6 ino=6, name hash mismatch with key, have 0x00000000be52bff8 e
xpect 0x000000008dbfc2d2
[  196.794355] BTRFS info (device loop0): read error corrected: ino 0 off 29417472 (dev /dev/loop0 sector 73840)
[  196.879172] kasan: CONFIG_KASAN_INLINE enabled
[  196.881094] kasan: GPF could be caused by NULL-ptr deref or user memory access
[  196.883004] general protection fault: 0000 [#1] SMP KASAN NOPTI
[  196.883474] CPU: 0 PID: 1989 Comm: mount Not tainted 5.0.21 #1
[  196.883474] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
[  196.883474] RIP: 0010:btrfs_verify_dev_extents+0x778/0x1140
[  196.883474] Code: c8 00 00 00 48 89 fa 48 c1 ea 03 80 3c 1a 00 0f 85 31 06 00 00 48 8b 80 c8 00 00 00 48 8d 88 98 00 00 00 48 89 ca 48 c1 ea 03 <8$
> 3c 1a 00 0f 85 90 08 00 00 48 8b 80 98 00 00 00 48 39 c8 0f 84

[  196.883474] RSP: 0018:ffff888067eee620 EFLAGS: 00000202
[  196.883474] RAX: 0000000000000000 RBX: dffffc0000000000 RCX: 0000000000000098
[  196.883474] RDX: 0000000000000013 RSI: 0000000000000001 RDI: ffff888069afa348
[  196.883474] RBP: 0000000000c00000 R08: 1ffff1100d8c3f81 R09: 0000000000000000
[  196.883474] R10: 0000000000000001 R11: ffffed100c82f023 R12: 0000000000000000
[  196.883474] R13: ffff888069e5f210 R14: 0000000000000001 R15: ffff888069f061a0
[  196.883474] FS:  00007f581c668e40(0000) GS:ffff88806d000000(0000) knlGS:0000000000000000
[  196.883474] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  196.883474] CR2: 0000564ef42ea000 CR3: 0000000069f98000 CR4: 00000000000006f0[  196.883474] Call Trace:
[  196.883474]  ? run_one_async_done+0x250/0x250
[  196.883474]  ? btrfs_bg_type_to_factor+0x10/0x10
[  196.883474]  ? __kasan_slab_free+0x143/0x180
[  196.883474]  ? btrfs_read_tree_root+0x166/0x330
[  196.883474]  ? btrfs_read_tree_root+0x166/0x330
[  196.883474]  open_ctree+0x4cd0/0x7ada
[  196.883474]  ? close_ctree+0xa10/0xa10
[  196.883474]  ? __lock_text_start+0x8/0x8
[  196.883474]  ? __save_stack_trace+0x8d/0xf0
[  196.883474]  ? depot_save_stack+0x2d9/0x470
[  196.883474]  ? lockref_put_or_lock+0x1c0/0x360
[  196.883474]  ? lockref_put_return+0x280/0x280
[  196.883474]  ? __debugfs_create_file+0x69/0x380
[  196.883474]  ? super_setup_bdi_name+0x135/0x260
[  196.883474]  ? mount_fs+0xb9/0x370
[  196.883474]  ? vfs_kern_mount.part.28+0xb9/0x400
[  196.883474]  ? mount_fs+0xb9/0x370
[  196.883474]  ? vfs_kern_mount.part.28+0xb9/0x400
[  196.883474]  ? do_mount+0xef4/0x2d40
[  196.883474]  ? ksys_mount+0x7b/0xd0
[  196.883474]  ? do_syscall_64+0x12b/0x440
[  196.883474]  ? __dentry_path+0x31e/0x6e0
[  196.883474]  ? rcu_qs+0x2f0/0x2f0
[  196.883474]  ? __alloc_pages_nodemask+0x467/0xa00
[  196.883474]  ? dput+0x33b/0x540
[  196.883474]  ? rcu_qs+0x2f0/0x2f0
[  196.883474]  ? page_alloc_cpu_dead+0x30/0x30
[  196.883474]  ? free_pcp_prepare+0xb8/0x220
[  196.883474]  ? _raw_spin_lock+0x99/0x130
[  196.883474]  ? _raw_read_lock_irq+0x30/0x30
[  196.883474]  ? __fsnotify_inode_delete+0x10/0x10
[  196.883474]  ? get_nr_inodes+0xf0/0xf0
[  196.883474]  ? __d_instantiate+0x366/0x6e0
[  196.883474]  ? __lookup_slow+0x1f7/0x450
[  196.883474]  ? rcu_qs+0x2f0/0x2f0
[  196.883474]  ? _raw_spin_lock+0x30/0x130
[  196.883474]  ? _raw_read_lock_irq+0x30/0x30
[  196.883474]  ? _raw_read_lock_irq+0x30/0x30
[  196.883474]  ? _raw_spin_lock+0x99/0x130
[  196.883474]  ? _raw_read_lock_irq+0x30/0x30
[  196.883474]  ? _raw_spin_lock_bh+0xa4/0x130
[  196.883474]  ? _raw_write_trylock+0x1f0/0x1f0
[  196.883474]  ? __debugfs_create_file+0x277/0x380
[  196.883474]  ? debugfs_create_dir+0x286/0x360
[  196.883474]  ? address_val+0x90/0x90
[  196.883474]  ? set_wb_congested+0x30/0x30
[  196.883474]  ? rcu_qs+0x2f0/0x2f0
[  196.883474]  ? __kasan_kmalloc.constprop.4+0xa0/0xd0
[  196.883474]  ? super_setup_bdi_name+0x135/0x260
[  196.883474]  ? kill_block_super+0xd0/0xd0
[  196.883474]  ? snprintf+0x8f/0xc0
[  196.883474]  ? btrfs_mount_root+0xe24/0x14c0
[  196.883474]  btrfs_mount_root+0xe24/0x14c0
[  196.883474]  ? btrfs_decode_error+0x50/0x50
[  196.883474]  ? module_enable_ro.part.69+0x160/0x160
[  196.883474]  ? deref_stack_reg+0xab/0x110
[  196.883474]  ? __read_once_size_nocheck.constprop.8+0x10/0x10
[  196.883474]  ? deref_stack_reg+0xab/0x110
[  196.883474]  ? __free_insn_slot+0x450/0x450
[  196.883474]  ? rcu_is_watching+0x7d/0x130
[  196.883474]  ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  196.883474]  ? rcu_barrier_trace+0x260/0x260
[  196.883474]  ? mount_fs+0xb9/0x370
[  196.883474]  ? btrfs_decode_error+0x50/0x50
[  196.883474]  mount_fs+0xb9/0x370
[  196.883474]  ? pcpu_next_unpop+0xe0/0xe0
[  196.883474]  ? __kernel_text_address+0x9/0x30
[  196.883474]  ? emergency_thaw_all+0x230/0x230
[  196.883474]  ? apic_timer_interrupt+0xa/0x20
[  196.883474]  vfs_kern_mount.part.28+0xb9/0x400
[  196.883474]  ? __cleanup_mnt+0x10/0x10
[  196.883474]  ? __lock_text_start+0x8/0x8
[  196.883474]  ? pcpu_alloc_area+0x170/0x3c0
[  196.883474]  btrfs_mount+0x3c5/0x1fd9
[  196.883474]  ? btrfs_remount+0x1190/0x1190
[  196.883474]  ? ida_free+0x3b0/0x3b0
[  196.883474]  ? kasan_unpoison_shadow+0x30/0x40
[  196.883474]  ? __kasan_kmalloc.constprop.4+0xa0/0xd0
[  196.883474]  ? dl_cpu_busy+0x1f0/0x1f0
[  196.883474]  ? alloc_vfsmnt+0x146/0x950
[  196.883474]  ? memcpy+0x34/0x50
[  196.883474]  ? alloc_vfsmnt+0x617/0x950
[  196.883474]  ? m_stop+0x10/0x10
[  196.883474]  ? memcpy+0x34/0x50
[  196.883474]  ? avc_has_perm_noaudit+0x22a/0x4c0
[  196.883474]  ? avc_has_perm+0x24f/0x620
[  196.883474]  ? avc_has_extended_perms+0x1320/0x1320
[  196.883474]  ? __read_once_size_nocheck.constprop.8+0x10/0x10
[  196.883474]  ? mount_fs+0xb9/0x370
[  196.883474]  mount_fs+0xb9/0x370
[  196.883474]  ? emergency_thaw_all+0x230/0x230
[  196.883474]  ? __module_get+0x1a0/0x1a0
[  196.883474]  ? selinux_sb_eat_lsm_opts+0x520/0x520
[  196.883474]  vfs_kern_mount.part.28+0xb9/0x400
[  196.883474]  ? __cleanup_mnt+0x10/0x10
[  196.883474]  ? getname_flags+0xb5/0x500
[  196.883474]  ? __get_fs_type+0x79/0xb0
[  196.883474]  do_mount+0xef4/0x2d40
[  196.883474]  ? copy_mount_string+0x20/0x20
[  196.883474]  ? save_stack+0x89/0xb0
[  196.883474]  ? __kasan_kmalloc.constprop.4+0xa0/0xd0
[  196.883474]  ? __kmalloc_track_caller+0xc7/0x1d0
[  196.883474]  ? memdup_user+0x23/0x60
[  196.883474]  ? __x64_sys_mount+0xb5/0x150
[  196.883474]  ? do_syscall_64+0x12b/0x440
[  196.883474]  ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  196.883474]  ? security_file_free+0x3a/0x70
[  196.883474]  ? kmem_cache_free+0x70/0x1a0
[  196.883474]  ? __fput+0x3f1/0x840
[  196.883474]  ? _copy_to_user+0x68/0x90
[  196.883474]  ? _raw_spin_lock_irq+0x9a/0x130
[  196.883474]  ? _raw_write_unlock_irqrestore+0x110/0x110
[  196.883474]  ? __close_fd+0x32a/0x540
[  196.883474]  ? task_work_run+0xd0/0x290
[  196.883474]  ? rcu_qs+0x2f0/0x2f0
[  196.883474]  ? kasan_unpoison_shadow+0x30/0x40
[  196.883474]  ? __kasan_kmalloc.constprop.4+0xa0/0xd0
[  196.883474]  ? strndup_user+0x42/0x90
[  196.883474]  ? __kmalloc_track_caller+0xc7/0x1d0
[  196.883474]  ? _copy_from_user+0x70/0xa0
[  196.883474]  ? memdup_user+0x39/0x60
[  196.883474]  ksys_mount+0x7b/0xd0
[  196.883474]  __x64_sys_mount+0xb5/0x150
[  196.883474]  do_syscall_64+0x12b/0x440
[  196.883474]  ? syscall_return_slowpath+0x2e0/0x2e0
[  196.883474]  ? prepare_exit_to_usermode+0x1be/0x210
[  196.883474]  ? perf_trace_sys_enter+0x1050/0x1050
[  196.883474]  ? __x64_sys_sigaltstack+0x270/0x270
[  196.883474]  ? __put_user_4+0x1c/0x30
[  196.883474]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  196.883474] RIP: 0033:0x7f581bd2348a
[  196.883474] Code: 48 8b 0d 11 fa 2a 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 00 0f 05 <48
> 3d 01 f0 ff ff 73 01 c3 48 8b 0d de f9 2a 00 f7 d8 64 89 01 48

[  196.883474] RSP: 002b:00007fffbf988ac8 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5
[  196.883474] RAX: ffffffffffffffda RBX: 000055718faa2080 RCX: 00007f581bd2348a
[  196.883474] RDX: 000055718faa2260 RSI: 000055718faa7ec0 RDI: 000055718faa8db0
[  196.883474] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000020
[  196.883474] R10: 00000000c0ed0000 R11: 0000000000000202 R12: 000055718faa8db0
[  196.883474] R13: 000055718faa2260 R14: 0000000000000000 R15: 00000000ffffffff
[  196.883474] Modules linked in:
[  196.934565] ---[ end trace b2518a0a4d2b3ae0 ]---
[  196.935064] RIP: 0010:btrfs_verify_dev_extents+0x778/0x1140
[  196.935271] Code: c8 00 00 00 48 89 fa 48 c1 ea 03 80 3c 1a 00 0f 85 31 06 00 00 48 8b 80 c8 00 00 00 48 8d 88 98 00 00 00 48 89 ca 48 c1 ea 03 <80
> 3c 1a 00 0f 85 90 08 00 00 48 8b 80 98 00 00 00 48 39 c8 0f 84

[  196.939094] RSP: 0018:ffff888067eee620 EFLAGS: 00000202
[  196.942503] RAX: 0000000000000000 RBX: dffffc0000000000 RCX: 0000000000000098
[  196.942811] RDX: 0000000000000013 RSI: 0000000000000001 RDI: ffff888069afa348
[  196.943370] RBP: 0000000000c00000 R08: 1ffff1100d8c3f81 R09: 0000000000000000
[  196.946786] R10: 0000000000000001 R11: ffffed100c82f023 R12: 0000000000000000
[  196.947634] R13: ffff888069e5f210 R14: 0000000000000001 R15: ffff888069f061a0
[  196.950778] FS:  00007f581c668e40(0000) GS:ffff88806d000000(0000) knlGS:0000000000000000
[  196.952541] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  196.952704] CR2: 0000564ef42ea000 CR3: 0000000069f98000 CR4: 00000000000006f0

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.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published