Skip to content

Latest commit

 

History

History

CVE-2019-19318

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

CVE-2019-19318

Target

Linux Kernel 5.3.11 btrfs FileSystem

Linux Version Availablity
5.0.21 True
5.3.11 True
5.4.0 mount fail

Bug Type

Use After Free

Abstract

mounting crafted image twice can cause use-after-free vulnerability in rwsem_can_spin_on_owner function

Reproduce

mkdir mnt
mount poc_2019_19318.img ./mnt
(1st mount crash, kernel BUG)
mount poc_2019_19318.img ./mnt
(2nd mount crash, use-after-free)

Details

Debug View

─────────────────────────────────────────────────────────── registers ────
$rax   : 0xffff88806cf51980  →  0xffff88806cf00000  →  0xffff8880655a5500 →  0xffff88806cf01100  →  0xffff88806cf02200  →  0xffff88806cf03300  →  0xffff88806cf04400  →  0xffff88806cf05500
$rbx   : 0xffff88806cf51980  →  0xffff88806cf00000  →  0xffff8880655a5500 →  0xffff88806cf01100  →  0xffff88806cf02200  →  0xffff88806cf03300  →  0xffff88806cf04400  →  0xffff88806cf05500
$rcx   : 0xffffffff8111aaef  →  0x04a8d23108458b49  →  0x04a8d23108458b49
$rdx   : 0x0000000000000001  →  0x0000000000000001
$rsp   : 0xffff888064f2f4e0  →  0x0000000000000000  →  0x0000000000000000
$rbp   : 0xffff888064f2f700  →  0x1ffff1100c9e5ee3  →  0x1ffff1100c9e5ee3
$rsi   : 0x0000000000000008  →  0x0000000000000008
$rdi   : 0xffff88806cf519b8  →  0x0000000000000000  →  0x0000000000000000
$rip   : 0xffffffff8111b0df  →  0x38438b001c95fce8  →  0x38438b001c95fce8
$r8    : 0xffffed100d44bcd0  →  0x0000000000000000  →  0x0000000000000000
$r9    : 0xffffed100d44bcd0  →  0x0000000000000000  →  0x0000000000000000
$r10   : 0x0000000000000001  →  0x0000000000000001
$r11   : 0xffffed100d44bccf  →  0x0000000000000000  →  0x0000000000000000
$r12   : 0x1ffff1100c9e5ef5  →  0x1ffff1100c9e5ef5
$r13   : 0xffff88806a25e670  →  0x0000000000000001  →  0x0000000000000001
$r14   : 0x0000000000000000  →  0x0000000000000000
$r15   : 0xffffffff833cb4e0  →  0xffff88806a25e6e0  →  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 ────
0xffff888064f2f4e0│+0x0000: 0x0000000000000000  →  0x0000000000000000	 ← $rsp
0xffff888064f2f4e8│+0x0008: 0x1ffff1100c9e5ea2  →  0x1ffff1100c9e5ea2
0xffff888064f2f4f0│+0x0010: 0xffffea00018fd2c0  →  0x0100000000022036  →0x0100000000022036
0xffff888064f2f4f8│+0x0018: 0x1ffff1100c9e5eaa  →  0x1ffff1100c9e5eaa
0xffff888064f2f500│+0x0020: 0xffff88806a25e678  →  0xffff88806cf51980  →0xffff88806cf00000  →  0xffff8880655a5500  →  0xffff88806cf01100  →  0xffff88806cf02200  →  0xffff88806cf03300
0xffff888064f2f508│+0x0028: 0x000000020000000c  →  0x000000020000000c
0xffff888064f2f510│+0x0030: 0x0000000041b58ab3  →  0x0000000041b58ab3
0xffff888064f2f518│+0x0038: 0xffffffff82f7746f  →  0x3120342032332032  →0x3120342032332032
───────────────────────────────────────────────────────── code:x86:64 ────
   0xffffffff8111b0d3 <rwsem_down_write_slowpath+1811> test   al, 0x1
   0xffffffff8111b0d5 <rwsem_down_write_slowpath+1813> jne    0xffffffff8111aafd <rwsem_down_write_slowpath+317>
   0xffffffff8111b0db <rwsem_down_write_slowpath+1819> lea    rdi, [rbx+0x38]
 → 0xffffffff8111b0df <rwsem_down_write_slowpath+1823> call   0xffffffff812e46e0 <__asan_load4>
   ↳  0xffffffff812e46e0 <__asan_load4_noabort+0> movabs rax, 0xffff7fffffffffff
      0xffffffff812e46ea <__asan_load4_noabort+10> mov    rcx, QWORD PTR [rsp]
      0xffffffff812e46ee <__asan_load4_noabort+14> cmp    rdi, rax
      0xffffffff812e46f1 <__asan_load4_noabort+17> jbe    0xffffffff812e4748 <__asan_load4+104>
      0xffffffff812e46f3 <__asan_load4_noabort+19> lea    rax, [rdi+0x3]
      0xffffffff812e46f7 <__asan_load4_noabort+23> mov    rdx, rax
─────────────────────────────────────────────────────────── arguments ────
__asan_load4 (
   long unsigned int var_0 = 0xffff88806cf519b8 → 0x0000000000000000 → 0x0000000000000000
)
───────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "", stopped, reason: BREAKPOINT
[#1] Id 2, Name: "", stopped, reason: BREAKPOINT
─────────────────────────────────────────────────────────────── trace ────
[#0] 0xffffffff8111b0df → owner_on_cpu(owner=<optimized out>)
[#1] 0xffffffff8111b0df → rwsem_can_spin_on_owner(nonspinnable=<optimizedout>, sem=<optimized out>)
[#2] 0xffffffff8111b0df → rwsem_down_write_slowpath(sem=0xffff88806a25e670, state=<optimized out>)
[#3] 0xffffffff8240a6be → __down_write(sem=<optimized out>)
[#4] 0xffffffff8240a6be → down_write(sem=0xffff88806a25e670)
[#5] 0xffffffff812f6f8a → grab_super(s=0xffff88806a25e600)
[#6] 0xffffffff812f821a → sget(type=0xffffffff833cb4a0 <btrfs_root_fs_type>, test=0xffffffff8154f8b0 <btrfs_test_super>, set=<optimized out>, flags=<optimized out>, data=0xffff88806786c400)
[#7] 0xffffffff815677a7 → btrfs_mount_root(fs_type=<optimized out>, flags=<optimized out>, device_name=<optimized out>, data=0x0 <fixed_percpu_data>)
[#8] 0xffffffff8135051b → legacy_get_tree(fc=0xffff88806ae18a00)
[#9] 0xffffffff812f76a4 → vfs_get_tree(fc=0xffff88806ae18a00)
──────────────────────────────────────────────────────────────────────────

Thread 1 hit Breakpoint 1, 0xffffffff8111b0df in owner_on_cpu (owner=<optimized out>) at kernel/locking/rwsem.c:649
649	in kernel/locking/rwsem.c
gef➤

rwsem_owner_flags(sem, &flags) returns already freed task_struct

Bug Causes

kernel/locking/rwsem.c/673 (link)

static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem,
					   unsigned long nonspinnable)
{
	struct task_struct *owner;
	unsigned long flags;
	bool ret = true;

	BUILD_BUG_ON(!(RWSEM_OWNER_UNKNOWN & RWSEM_NONSPINNABLE));

	if (need_resched()) {
		lockevent_inc(rwsem_opt_fail);
		return false;
	}

	preempt_disable();
	rcu_read_lock();
[1]	owner = rwsem_owner_flags(sem, &flags);
	/*
	 * Don't check the read-owner as the entry may be stale.
	 */
	if ((flags & nonspinnable) ||
[2]	    (owner && !(flags & RWSEM_READER_OWNED) && !owner_on_cpu(owner)))
		ret = false;
	rcu_read_unlock();
	preempt_enable();

	lockevent_cond_inc(rwsem_opt_fail, !ret);
	return ret;
}

rwsem_owner_flags returns already freed pointer[1].

it occurs use-after-free in [2]

KASAN logs

1st mount

[  117.464299] BTRFS: device fsid a62e00e8-e94e-4200-8217-12444de93c2e devid 1 transid 8 /dev/loop0
[  117.532786] BTRFS info (device loop0): disk space caching is enabled
[  117.536920] BTRFS info (device loop0): has skinny extents
[  117.888523] BTRFS info (device loop0): bdev /dev/loop0 errs: wr 0, rd 0, flush 0, corrupt 227, gen 0
[  118.434418] ------------[ cut here ]------------
[  118.437045] WARNING: CPU: 0 PID: 195 at fs/btrfs/extent-tree.c:874 btrfs_lookup_extent_info+0x5c4/0x640
[  118.437220] Modules linked in:
[  118.437220] CPU: 0 PID: 195 Comm: mount Not tainted 5.3.11 #1
[  118.437220] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
[  118.437220] RIP: 0010:btrfs_lookup_extent_info+0x5c4/0x640
[  118.437220] Code: 24 f8 0e 00 00 c7 44 24 1c 00 00 00 00 48 89 44 24 10 e9 2e fb ff ff 31 c0 e9 9c fe ff ff 48 c7 c7 c0 47 b3 82 e8 c0 dd ba ff <0f> 0b eb 87 48 8d 78 6a e8 df 2e d6 ff 41 80 4e 6a 14 e9 1e fb ff
[  118.437220] RSP: 0018:ffff888067c670a0 EFLAGS: 00000282
[  118.437220] RAX: 0000000000000024 RBX: ffff88806a825900 RCX: 0000000000000000
[  118.437220] RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffffed100cf8ce0a
[  118.437220] RBP: ffff888065af8250 R08: ffffed100da85c5b R09: ffffed100da85c5b
[  118.437220] R10: 0000000000000001 R11: ffffed100da85c5a R12: 0000000000000000
[  118.437220] R13: ffff888067cdb300 R14: ffff888065af8210 R15: ffff888067528150
[  118.437220] FS:  00007f9278dcbe40(0000) GS:ffff88806d400000(0000) knlGS:0000000000000000
[  118.437220] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  118.437220] CR2: 00007f6b2b4b4000 CR3: 0000000068ade000 CR4: 00000000000006f0
[  118.437220] Call Trace:
[  118.437220]  ? btrfs_lookup_data_extent+0x100/0x100
[  118.437220]  ? __btrfs_run_delayed_items+0x90d/0x9a0
[  118.437220]  ? kmem_cache_free+0x75/0x280
[  118.437220]  ? _raw_write_lock+0x7f/0xe0
[  118.437220]  walk_down_proc+0x280/0x440
[  118.437220]  walk_down_tree+0xe0/0x1f0
[  118.437220]  ? do_walk_down+0xba0/0xba0
[  118.437220]  btrfs_drop_snapshot+0x730/0xdc0
[  118.437220]  ? btrfs_alloc_reserved_file_extent+0x160/0x160
[  118.437220]  ? btrfs_apply_pending_changes+0x80/0x80
[  118.437220]  clean_dirty_subvols+0x17c/0x1c0
[  118.437220]  btrfs_recover_relocation+0x640/0x6d0
[  118.437220]  ? btrfs_relocate_block_group+0x400/0x400
[  118.437220]  ? try_to_wake_up+0x41e/0xaa0
[  118.437220]  ? __del_qgroup_relation+0x380/0x380
[  118.437220]  ? mutex_lock+0x93/0xf0
[  118.437220]  ? btrfs_check_rw_degradable+0x160/0x260
[  118.437220]  open_ctree+0x2f65/0x393d
[  118.437220]  ? close_ctree+0x4b0/0x4b0
[  118.437220]  ? super_setup_bdi_name+0x12e/0x1b0
[  118.437220]  ? kill_block_super+0x70/0x70
[  118.437220]  ? snprintf+0x96/0xd0
[  118.437220]  ? up_write+0x33/0x50
[  118.437220]  ? btrfs_mount_root+0x8c3/0x9e0
[  118.437220]  btrfs_mount_root+0x8c3/0x9e0
[  118.437220]  ? do_mount+0x96d/0xd10
[  118.437220]  ? ksys_mount+0x79/0xc0
[  118.437220]  ? do_syscall_64+0x5e/0x190
[  118.437220]  ? btrfs_decode_error+0x30/0x30
[  118.437220]  ? fs_parse+0x96/0x5b0
[  118.437220]  ? selinux_fs_context_parse_param+0x7c/0x100
[  118.437220]  ? show_sid+0x170/0x170
[  118.437220]  ? strcmp+0x30/0x50
[  118.437220]  ? legacy_parse_param+0x65/0x3e0
[  118.437220]  ? vfs_parse_fs_param+0x156/0x260
[  118.437220]  ? btrfs_decode_error+0x30/0x30
[  118.437220]  ? legacy_get_tree+0x6b/0xa0
[  118.437220]  ? btrfs_decode_error+0x30/0x30
[  118.437220]  legacy_get_tree+0x6b/0xa0
[  118.437220]  vfs_get_tree+0x44/0x1a0
[  118.437220]  fc_mount+0xa/0x40
[  118.437220]  vfs_kern_mount+0x77/0x80
[  118.437220]  btrfs_mount+0x204/0xb69
[  118.437220]  ? __kasan_kmalloc+0xd5/0xf0
[  118.437220]  ? legacy_init_fs_context+0x27/0x60
[  118.437220]  ? alloc_fs_context+0x1f3/0x250
[  118.437220]  ? do_mount+0x918/0xd10
[  118.437220]  ? ksys_mount+0x79/0xc0
[  118.437220]  ? __x64_sys_mount+0x5d/0x70
[  118.437220]  ? btrfs_remount+0x820/0x820
[  118.437220]  ? avc_has_extended_perms+0x770/0x770
[  118.437220]  ? fs_lookup_key.isra.1+0x27/0x40
[  118.437220]  ? fs_parse+0x96/0x5b0
[  118.437220]  ? cred_has_capability+0xfd/0x1f0
[  118.437220]  ? selinux_sb_eat_lsm_opts+0x2f0/0x2f0
[  118.437220]  ? legacy_parse_param+0x65/0x3e0
[  118.437220]  ? vfs_parse_fs_param+0x156/0x260
[  118.437220]  ? btrfs_remount+0x820/0x820
[  118.437220]  ? legacy_get_tree+0x6b/0xa0
[  118.437220]  ? btrfs_remount+0x820/0x820
[  118.437220]  legacy_get_tree+0x6b/0xa0
[  118.437220]  vfs_get_tree+0x44/0x1a0
[  118.437220]  do_mount+0x96d/0xd10
[  118.437220]  ? locks_remove_file+0x83/0x270
[  118.437220]  ? copy_mount_string+0x20/0x20
[  118.437220]  ? kasan_unpoison_shadow+0x31/0x40
[  118.437220]  ? __kasan_kmalloc+0xd5/0xf0
[  118.437220]  ? strndup_user+0x3a/0x60
[  118.437220]  ? __kmalloc_track_caller+0xd5/0x220
[  118.437220]  ? _copy_from_user+0x61/0x90
[  118.437220]  ? memdup_user+0x39/0x60
[  118.437220]  ksys_mount+0x79/0xc0
[  118.437220]  __x64_sys_mount+0x5d/0x70
[  118.437220]  do_syscall_64+0x5e/0x190
[  118.437220]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  118.437220] RIP: 0033:0x7f927848648a
[  118.437220] 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
[  118.437220] RSP: 002b:00007fffdeea9728 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
[  118.437220] RAX: ffffffffffffffda RBX: 0000558d1e091080 RCX: 00007f927848648a
[  118.437220] RDX: 0000558d1e093760 RSI: 0000558d1e092f60 RDI: 0000558d1e097600
[  118.437220] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000020
[  118.437220] R10: 00000000c0ed0000 R11: 0000000000000206 R12: 0000558d1e097600
[  118.437220] R13: 0000558d1e093760 R14: 0000000000000000 R15: 00000000ffffffff
[  118.437220] ---[ end trace 6e1e05ca401f9aba ]---
[  118.480945] ------------[ cut here ]------------
[  118.481284] kernel BUG at fs/btrfs/extent-tree.c:6521!
[  118.485682] invalid opcode: 0000 [#1] SMP KASAN NOPTI
[  118.486243] CPU: 0 PID: 195 Comm: mount Tainted: G        W         5.3.11 #1
[  118.486243] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
[  118.486243] RIP: 0010:walk_down_proc+0x416/0x440
[  118.486243] Code: 00 fe ff ff 4c 89 ef e8 98 d1 08 00 e9 e3 fd ff ff 0f 0b 0f 0b 0f 0b 0f 0b 0f 0b 4c 89 ef e8 11 cd 08 00 e9 cc fd ff ff 0f 0b <0f> 0b 4c 89 ef e8 70 d1 08 00 8b 04 24 eb b2 4c 89 ef e8 f3 cc 08
[  118.486243] RSP: 0018:ffff888067c671f0 EFLAGS: 00000246
[  118.486243] RAX: 0000000000000000 RBX: ffff888065c33c80 RCX: ffffffff81585acb
[  118.486243] RDX: dffffc0000000000 RSI: ffff88806a6a8dc0 RDI: ffff888065c33c80
[  118.486243] RBP: 0000000000000000 R08: ffffffff8132fccd R09: ffffffff81003dee
[  118.486243] R10: ffffffff81003dee R11: ffffffff8260008c R12: ffff888065af80b0
[  118.486243] R13: ffff88806a4ca8f8 R14: 0000000000000000 R15: ffff888069077700
[  118.486243] FS:  00007f9278dcbe40(0000) GS:ffff88806d400000(0000) knlGS:0000000000000000
[  118.486243] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  118.486243] CR2: 00007f6b2b4b4000 CR3: 0000000068ade000 CR4: 00000000000006f0
[  118.486243] Call Trace:
[  118.486243]  walk_down_tree+0xe0/0x1f0
[  118.486243]  ? do_walk_down+0xba0/0xba0
[  118.486243]  btrfs_drop_snapshot+0x730/0xdc0
[  118.486243]  ? btrfs_alloc_reserved_file_extent+0x160/0x160
[  118.486243]  ? btrfs_apply_pending_changes+0x80/0x80
[  118.486243]  clean_dirty_subvols+0x17c/0x1c0
[  118.486243]  btrfs_recover_relocation+0x640/0x6d0
[  118.486243]  ? btrfs_relocate_block_group+0x400/0x400
[  118.486243]  ? try_to_wake_up+0x41e/0xaa0
[  118.486243]  ? __del_qgroup_relation+0x380/0x380
[  118.486243]  ? mutex_lock+0x93/0xf0
[  118.486243]  ? btrfs_check_rw_degradable+0x160/0x260
[  118.486243]  open_ctree+0x2f65/0x393d
[  118.486243]  ? close_ctree+0x4b0/0x4b0
[  118.486243]  ? super_setup_bdi_name+0x12e/0x1b0
[  118.486243]  ? kill_block_super+0x70/0x70
[  118.486243]  ? snprintf+0x96/0xd0
[  118.486243]  ? up_write+0x33/0x50
[  118.486243]  ? btrfs_mount_root+0x8c3/0x9e0
[  118.486243]  btrfs_mount_root+0x8c3/0x9e0
[  118.486243]  ? do_mount+0x96d/0xd10
[  118.486243]  ? ksys_mount+0x79/0xc0
[  118.486243]  ? do_syscall_64+0x5e/0x190
[  118.486243]  ? btrfs_decode_error+0x30/0x30
[  118.486243]  ? fs_parse+0x96/0x5b0
[  118.486243]  ? selinux_fs_context_parse_param+0x7c/0x100
[  118.486243]  ? show_sid+0x170/0x170
[  118.486243]  ? strcmp+0x30/0x50
[  118.486243]  ? legacy_parse_param+0x65/0x3e0
[  118.486243]  ? vfs_parse_fs_param+0x156/0x260
[  118.486243]  ? btrfs_decode_error+0x30/0x30
[  118.486243]  ? legacy_get_tree+0x6b/0xa0
[  118.486243]  ? btrfs_decode_error+0x30/0x30
[  118.486243]  legacy_get_tree+0x6b/0xa0
[  118.486243]  vfs_get_tree+0x44/0x1a0
[  118.486243]  fc_mount+0xa/0x40
[  118.486243]  vfs_kern_mount+0x77/0x80
[  118.486243]  btrfs_mount+0x204/0xb69
[  118.486243]  ? __kasan_kmalloc+0xd5/0xf0
[  118.486243]  ? legacy_init_fs_context+0x27/0x60
[  118.486243]  ? alloc_fs_context+0x1f3/0x250
[  118.486243]  ? do_mount+0x918/0xd10
[  118.486243]  ? ksys_mount+0x79/0xc0
[  118.486243]  ? __x64_sys_mount+0x5d/0x70
[  118.486243]  ? btrfs_remount+0x820/0x820
[  118.486243]  ? avc_has_extended_perms+0x770/0x770
[  118.486243]  ? fs_lookup_key.isra.1+0x27/0x40
[  118.486243]  ? fs_parse+0x96/0x5b0
[  118.486243]  ? cred_has_capability+0xfd/0x1f0
[  118.486243]  ? selinux_sb_eat_lsm_opts+0x2f0/0x2f0
[  118.486243]  ? legacy_parse_param+0x65/0x3e0
[  118.486243]  ? vfs_parse_fs_param+0x156/0x260
[  118.486243]  ? btrfs_remount+0x820/0x820
[  118.486243]  ? legacy_get_tree+0x6b/0xa0
[  118.486243]  ? btrfs_remount+0x820/0x820
[  118.486243]  legacy_get_tree+0x6b/0xa0
[  118.486243]  vfs_get_tree+0x44/0x1a0
[  118.486243]  do_mount+0x96d/0xd10
[  118.486243]  ? locks_remove_file+0x83/0x270
[  118.486243]  ? copy_mount_string+0x20/0x20
[  118.486243]  ? kasan_unpoison_shadow+0x31/0x40
[  118.486243]  ? __kasan_kmalloc+0xd5/0xf0
[  118.486243]  ? strndup_user+0x3a/0x60
[  118.486243]  ? __kmalloc_track_caller+0xd5/0x220
[  118.486243]  ? _copy_from_user+0x61/0x90
[  118.486243]  ? memdup_user+0x39/0x60
[  118.486243]  ksys_mount+0x79/0xc0
[  118.486243]  __x64_sys_mount+0x5d/0x70
[  118.486243]  do_syscall_64+0x5e/0x190
[  118.486243]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  118.486243] RIP: 0033:0x7f927848648a
[  118.486243] 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
[  118.486243] RSP: 002b:00007fffdeea9728 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
[  118.486243] RAX: ffffffffffffffda RBX: 0000558d1e091080 RCX: 00007f927848648a
[  118.486243] RDX: 0000558d1e093760 RSI: 0000558d1e092f60 RDI: 0000558d1e097600
[  118.486243] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000020
[  118.486243] R10: 00000000c0ed0000 R11: 0000000000000206 R12: 0000558d1e097600
[  118.486243] R13: 0000558d1e093760 R14: 0000000000000000 R15: 00000000ffffffff
[  118.486243] Modules linked in:
[  118.522863] ---[ end trace 6e1e05ca401f9abb ]---
[  118.523662] RIP: 0010:walk_down_proc+0x416/0x440
[  118.526008] Code: 00 fe ff ff 4c 89 ef e8 98 d1 08 00 e9 e3 fd ff ff 0f 0b 0f 0b 0f 0b 0f 0b 0f 0b 4c 89 ef e8 11 cd 08 00 e9 cc fd ff ff 0f 0b <0f> 0b 4c 89 ef e8 70 d1 08 00 8b 04 24 eb b2 4c 89 ef e8 f3 cc 08
[  118.528964] RSP: 0018:ffff888067c671f0 EFLAGS: 00000246
[  118.531261] RAX: 0000000000000000 RBX: ffff888065c33c80 RCX: ffffffff81585acb
[  118.534638] RDX: dffffc0000000000 RSI: ffff88806a6a8dc0 RDI: ffff888065c33c80
[  118.535140] RBP: 0000000000000000 R08: ffffffff8132fccd R09: ffffffff81003dee
[  118.535448] R10: ffffffff81003dee R11: ffffffff8260008c R12: ffff888065af80b0
[  118.538508] R13: ffff88806a4ca8f8 R14: 0000000000000000 R15: ffff888069077700
[  118.539080] FS:  00007f9278dcbe40(0000) GS:ffff88806d400000(0000) knlGS:0000000000000000
[  118.539284] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  118.541045] CR2: 00007f6b2b4b4000 CR3: 0000000068ade000 CR4: 00000000000006f0
[  118.559157] mount (195) used greatest stack depth: 24592 bytes left
Segmentation fault

2nd mount

[  144.683854] ==================================================================
[  144.684623] BUG: KASAN: use-after-free in rwsem_down_write_slowpath+0x724/0x8d0
[  144.684623] Read of size 4 at addr ffff88806c57bff8 by task mount/227
[  144.684623]
[  144.684623] CPU: 1 PID: 227 Comm: mount Tainted: G      D W         5.3.11 #1
[  144.684623] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
[  144.684623] Call Trace:
[  144.684623]  dump_stack+0x76/0xab
[  144.684623]  print_address_description+0x70/0x3a0
[  144.684623]  ? rwsem_down_write_slowpath+0x724/0x8d0
[  144.684623]  __kasan_report+0x13a/0x19b
[  144.684623]  ? rwsem_down_write_slowpath+0x724/0x8d0
[  144.684623]  ? rwsem_down_write_slowpath+0x724/0x8d0
[  144.684623]  kasan_report+0xe/0x20
[  144.684623]  rwsem_down_write_slowpath+0x724/0x8d0
[  144.684623]  ? filemap_map_pages+0x5d0/0x5d0
[  144.684623]  ? kset_unregister+0x20/0x20
[  144.684623]  ? up_read+0x70/0x70
[  144.684623]  ? down_read+0xe8/0x1d0
[  144.684623]  ? _atomic_dec_and_lock+0xa3/0x140
[  144.684623]  ? _atomic_dec_and_lock_irqsave+0x150/0x150
[  144.684623]  ? mutex_lock+0x93/0xf0
[  144.684623]  ? __mutex_lock_slowpath+0x10/0x10
[  144.684623]  ? iput+0xb7/0x340
[  144.684623]  ? down_write+0x10e/0x120
[  144.684623]  down_write+0x10e/0x120
[  144.684623]  ? down_read+0x1d0/0x1d0
[  144.684623]  ? bd_set_size+0x60/0x60
[  144.684623]  ? _raw_write_lock+0xe0/0xe0
[  144.684623]  grab_super+0x8a/0x160
[  144.684623]  ? drop_super_exclusive+0x20/0x20
[  144.684623]  ? btrfs_test_super+0x14/0x50
[  144.684623]  ? btrfs_test_super+0x14/0x50
[  144.684623]  ? tracefs_initialized+0x10/0x10
[  144.684623]  sget+0xda/0x230
[  144.684623]  ? perf_trace_btrfs_sleep_tree_lock+0x410/0x410
[  144.684623]  btrfs_mount_root+0x557/0x9e0
[  144.684623]  ? do_mount+0x96d/0xd10
[  144.684623]  ? ksys_mount+0x79/0xc0
[  144.684623]  ? do_syscall_64+0x5e/0x190
[  144.684623]  ? btrfs_decode_error+0x30/0x30
[  144.684623]  ? fs_parse+0x96/0x5b0
[  144.684623]  ? selinux_fs_context_parse_param+0x7c/0x100
[  144.684623]  ? show_sid+0x170/0x170
[  144.684623]  ? strcmp+0x30/0x50
[  144.684623]  ? legacy_parse_param+0x65/0x3e0
[  144.684623]  ? vfs_parse_fs_param+0x156/0x260
[  144.684623]  ? btrfs_decode_error+0x30/0x30
[  144.684623]  ? legacy_get_tree+0x6b/0xa0
[  144.684623]  ? btrfs_decode_error+0x30/0x30
[  144.684623]  legacy_get_tree+0x6b/0xa0
[  144.684623]  vfs_get_tree+0x44/0x1a0
[  144.684623]  fc_mount+0xa/0x40
[  144.684623]  vfs_kern_mount+0x77/0x80
[  144.684623]  btrfs_mount+0x204/0xb69
[  144.684623]  ? __switch_to_asm+0x40/0x70
[  144.684623]  ? __switch_to_asm+0x34/0x70
[  144.684623]  ? __switch_to_asm+0x40/0x70
[  144.684623]  ? __switch_to_asm+0x34/0x70
[  144.684623]  ? __switch_to_asm+0x40/0x70
[  144.684623]  ? __switch_to_asm+0x34/0x70
[  144.684623]  ? btrfs_remount+0x820/0x820
[  144.684623]  ? avc_has_extended_perms+0x770/0x770
[  144.684623]  ? fs_lookup_key.isra.1+0x27/0x40
[  144.684623]  ? fs_parse+0x96/0x5b0
[  144.684623]  ? cred_has_capability+0xfd/0x1f0
[  144.684623]  ? selinux_sb_eat_lsm_opts+0x2f0/0x2f0
[  144.684623]  ? legacy_parse_param+0x65/0x3e0
[  144.684623]  ? vfs_parse_fs_param+0x156/0x260
[  144.684623]  ? btrfs_remount+0x820/0x820
[  144.684623]  ? legacy_get_tree+0x6b/0xa0
[  144.684623]  ? btrfs_remount+0x820/0x820
[  144.684623]  legacy_get_tree+0x6b/0xa0
[  144.684623]  vfs_get_tree+0x44/0x1a0
[  144.684623]  do_mount+0x96d/0xd10
[  144.684623]  ? locks_remove_file+0x83/0x270
[  144.684623]  ? copy_mount_string+0x20/0x20
[  144.684623]  ? kasan_unpoison_shadow+0x31/0x40
[  144.684623]  ? __kasan_kmalloc+0xd5/0xf0
[  144.684623]  ? strndup_user+0x3a/0x60
[  144.684623]  ? __kmalloc_track_caller+0xd5/0x220
[  144.684623]  ? _copy_from_user+0x61/0x90
[  144.684623]  ? memdup_user+0x39/0x60
[  144.684623]  ksys_mount+0x79/0xc0
[  144.684623]  __x64_sys_mount+0x5d/0x70
[  144.684623]  do_syscall_64+0x5e/0x190
[  144.684623]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  144.684623] RIP: 0033:0x7fd5d225648a
[  144.684623] 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
[  144.684623] RSP: 002b:00007ffc6df3b5e8 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
[  144.684623] RAX: ffffffffffffffda RBX: 000055e23d0a5080 RCX: 00007fd5d225648a
[  144.684623] RDX: 000055e23d0aaec0 RSI: 000055e23d0ab600 RDI: 000055e23d0aaea0
[  144.684623] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000020
[  144.684623] R10: 00000000c0ed0000 R11: 0000000000000206 R12: 000055e23d0aaea0
[  144.684623] R13: 000055e23d0aaec0 R14: 0000000000000000 R15: 00000000ffffffff
[  144.684623]
[  144.684623] Allocated by task 154:
[  144.684623]  save_stack+0x19/0x80
[  144.684623]  __kasan_kmalloc+0xd5/0xf0
[  144.684623]  kmem_cache_alloc_node+0xe0/0x1f0
[  144.684623]  copy_process+0xe19/0x2e00
[  144.684623]  _do_fork+0xec/0x4d0
[  144.684623]  __x64_sys_clone+0xfd/0x150
[  144.684623]  do_syscall_64+0x5e/0x190
[  144.684623]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  144.684623]
[  144.684623] Freed by task 0:
[  144.684623]  save_stack+0x19/0x80
[  144.684623]  __kasan_slab_free+0x132/0x180
[  144.684623]  kmem_cache_free+0x75/0x280
[  144.684623]  rcu_core+0x2be/0xbe0
[  144.684623]  __do_softirq+0x11b/0x3b3
[  144.684623]
[  144.684623] The buggy address belongs to the object at ffff88806c57bfc0
[  144.684623]  which belongs to the cache task_struct of size 3136
[  144.684623] The buggy address is located 56 bytes inside of
[  144.684623]  3136-byte region [ffff88806c57bfc0, ffff88806c57cc00)
[  144.684623] The buggy address belongs to the page:
[  144.684623] page:ffffea0001b15e00 refcount:1 mapcount:0 mapping:ffff88806cc99c80 index:0xffff88806c57bfc0 compound_mapcount: 0
[  144.684623] flags: 0x100000000010200(slab|head)
[  144.684623] raw: 0100000000010200 ffffea0001a84e00 0000000300000003 ffff88806cc99c80
[  144.684623] raw: ffff88806c57bfc0 00000000800a0008 00000001ffffffff 0000000000000000
[  144.684623] page dumped because: kasan: bad access detected
[  144.684623]
[  144.684623] Memory state around the buggy address:
[  144.684623]  ffff88806c57be80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  144.684623]  ffff88806c57bf00: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc
[  144.684623] >ffff88806c57bf80: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
[  144.684623]     ^
[  144.684623]  ffff88806c57c000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  144.684623]  ffff88806c57c080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  144.684623] ==================================================================

Conclusion

mounting crafted image twice can cause use-after-free vulnerability in rwsem_can_spin_on_owner function, rwsem_owner_flags returns already freed pointer, and it occurs use-after-free with task_struct in rwsem_can_spin_on_owner function.

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.