Bug 199403

Summary: KASAN: use-after-free in jbd2_journal_commit_transaction()
Product: File System Reporter: Wen Xu (wen.xu)
Component: ext4Assignee: fs_ext4 (fs_ext4)
Status: RESOLVED CODE_FIX    
Severity: normal CC: tytso, wen.xu
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 4.16 Subsystem:
Regression: No Bisected commit-id:
Attachments: The crafted image which causes kernel panic
poc.c
Another possible uaf location detected with latest linux kernel master branch

Description Wen Xu 2018-04-16 01:42:05 UTC
Created attachment 275387 [details]
The crafted image which causes kernel panic

- Overview
use-after-free in ext4_ext_remove_space() when mounting and operating a crafted ext4 image

- Reproduce 
I feel it has higher probability to trigger the bug using VM with 1 or 2 cores.
# mkdir mnt
# mount -t ext4 65.img mnt
# gcc -o poc poc.c
# ./poc ./mnt

I reproduce it on both ext4 dev branch and latest linux kernel branch. With latest linux kernel branch, use-after-free is detected in jbd2_journal_commit_transaction. 

- Kernel Dump (ext4 dev branch, 4.16.0-rc1)
[  262.536008] ==================================================================
[  262.537223] BUG: KASAN: use-after-free in ext4_ext_remove_space+0x563/0x1d40
[  262.538275] Read of size 4 at addr ffff8800691c72ac by task poc/1791

[  262.539507] CPU: 1 PID: 1791 Comm: poc Not tainted 4.16.0-rc1+ #3
[  262.539511] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[  262.539514] Call Trace:
[  262.539536]  dump_stack+0x63/0x8d
[  262.539546]  print_address_description+0x70/0x290
[  262.539869]  kasan_report+0x290/0x390
[  262.539887]  ? ext4_ext_remove_space+0x563/0x1d40
[  262.539900]  __asan_load4+0x78/0x80
[  262.539906]  ext4_ext_remove_space+0x563/0x1d40
[  262.539913]  ? ext4_es_free_extent+0x109/0x210
[  262.539919]  ? __kasan_slab_free+0x153/0x1a0
[  262.539926]  ? kmem_cache_free+0x7c/0x1f0
[  262.539933]  ? ext4_es_free_extent+0x109/0x210
[  262.539939]  ? ext4_ext_index_trans_blocks+0x70/0x70
[  262.539946]  ? ext4_es_scan+0x1c0/0x1c0
[  262.539954]  ext4_ext_truncate+0xd2/0xe0
[  262.539962]  ext4_truncate+0x5e7/0x760
[  262.539968]  ? ext4_punch_hole+0x680/0x680
[  262.539975]  ? ext4_empty_dir+0x420/0x420
[  262.539981]  ext4_setattr+0x869/0xe00
[  262.539991]  notify_change+0x4d8/0x670
[  262.539998]  do_truncate+0xe8/0x160
[  262.540002]  ? do_truncate+0xe8/0x160
[  262.540007]  ? file_open_root+0x1c0/0x1c0
[  262.540016]  ? common_perm+0x1c0/0x1c0
[  262.540026]  path_openat+0x5fb/0x1e30
[  262.540034]  ? __save_stack_trace+0x92/0x100
[  262.540042]  ? vfs_link+0x4e0/0x4e0
[  262.540048]  ? kasan_kmalloc+0xad/0xe0
[  262.540053]  ? kmem_cache_alloc+0xbb/0x1d0
[  262.540059]  ? getname_flags+0x76/0x2c0
[  262.540064]  ? getname+0x12/0x20
[  262.540069]  ? do_sys_open+0x14b/0x2c0
[  262.540073]  ? SyS_open+0x1e/0x20
[  262.540082]  ? do_syscall_64+0xf2/0x1f0
[  262.540091]  ? entry_SYSCALL_64_after_hwframe+0x21/0x86
[  262.540097]  ? mb_free_blocks+0xa40/0xa40
[  262.540104]  ? rcu_segcblist_enqueue+0x79/0x90
[  262.540111]  ? call_rcu_sched+0x17/0x20
[  262.540118]  do_filp_open+0x12b/0x1d0
[  262.540124]  ? may_open_dev+0x50/0x50
[  262.540131]  ? kasan_kmalloc+0xad/0xe0
[  262.540138]  do_sys_open+0x17c/0x2c0
[  262.540143]  ? do_sys_open+0x17c/0x2c0
[  262.540148]  ? filp_open+0x60/0x60
[  262.540155]  ? mem_cgroup_handle_over_high+0x21/0xd0
[  262.540160]  ? do_sys_open+0x2c0/0x2c0
[  262.540165]  SyS_open+0x1e/0x20
[  262.540170]  do_syscall_64+0xf2/0x1f0
[  262.540177]  entry_SYSCALL_64_after_hwframe+0x21/0x86
[  262.540182] RIP: 0033:0x7f1c856dc040
[  262.540185] RSP: 002b:00007ffe6287d778 EFLAGS: 00000246 ORIG_RAX: 0000000000000002
[  262.540191] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f1c856dc040
[  262.540194] RDX: 00000000000001ff RSI: 0000000000000202 RDI: 0000000001d6e080
[  262.540197] RBP: 00007ffe6287d8e0 R08: 0000000000000003 R09: 0000000000000000
[  262.540200] R10: 0000000000000463 R11: 0000000000000246 R12: 0000000000400c20
[  262.540203] R13: 00007ffe6287d9e0 R14: 0000000000000000 R15: 0000000000000000

[  262.540517] Allocated by task 1:
[  262.541033]  save_stack+0x46/0xd0
[  262.541039]  kasan_kmalloc+0xad/0xe0
[  262.541044]  kasan_slab_alloc+0x12/0x20
[  262.541049]  kmem_cache_alloc+0xbb/0x1d0
[  262.541054]  getname_flags+0x76/0x2c0
[  262.541060]  user_path_at_empty+0x23/0x40
[  262.541064]  vfs_statx+0xce/0x160
[  262.541068]  SYSC_newstat+0x8c/0xe0
[  262.541072]  SyS_newstat+0xe/0x10
[  262.541077]  do_syscall_64+0xf2/0x1f0
[  262.541082]  entry_SYSCALL_64_after_hwframe+0x21/0x86

[  262.541332] Freed by task 1:
[  262.541793]  save_stack+0x46/0xd0
[  262.541799]  __kasan_slab_free+0x13e/0x1a0
[  262.541803]  kasan_slab_free+0xe/0x10
[  262.541808]  kmem_cache_free+0x7c/0x1f0
[  262.541813]  putname+0x80/0x90
[  262.541818]  filename_lookup+0x191/0x280
[  262.541824]  user_path_at_empty+0x36/0x40
[  262.541827]  vfs_statx+0xce/0x160
[  262.541831]  SYSC_newstat+0x8c/0xe0
[  262.541835]  SyS_newstat+0xe/0x10
[  262.541840]  do_syscall_64+0xf2/0x1f0
[  262.541845]  entry_SYSCALL_64_after_hwframe+0x21/0x86

[  262.542098] The buggy address belongs to the object at ffff8800691c6600
                which belongs to the cache names_cache of size 4096
[  262.544011] The buggy address is located 3244 bytes inside of
                4096-byte region [ffff8800691c6600, ffff8800691c7600)
[  262.545840] The buggy address belongs to the page:
[  262.546585] page:ffffea0001a47000 count:1 mapcount:0 mapping:          (null) index:0x0 compound_mapcount: 0
[  262.548082] flags: 0x1ffff0000008100(slab|head)
[  262.548808] raw: 01ffff0000008100 0000000000000000 0000000000000000 0000000100070007
[  262.550017] raw: dead000000000100 dead000000000200 ffff88006ce261c0 0000000000000000
[  262.551212] page dumped because: kasan: bad access detected

[  262.552329] Memory state around the buggy address:
[  262.553098]  ffff8800691c7180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  262.554213]  ffff8800691c7200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  262.555328] >ffff8800691c7280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  262.556450]                                   ^
[  262.557161]  ffff8800691c7300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  262.558283]  ffff8800691c7380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  262.559402] ==================================================================
[  262.560528] Disabling lock debugging due to kernel taint
[  262.562799] EXT4-fs error (device loop0): ext4_free_blocks:4750: comm poc: Freeing blocks not in datazone - block = 281473316796022, count = 2048
[  262.599249] EXT4-fs error (device loop0): ext4_free_blocks:4750: comm poc: Freeing blocks not in datazone - block = 172790829285375, count = 19214
[  262.627928] EXT4-fs error (device loop0): ext4_free_blocks:4750: comm poc: Freeing blocks not in datazone - block = 281472445215392, count = 2048
[  262.660030] EXT4-fs error (device loop0): ext4_free_blocks:4750: comm poc: Freeing blocks not in datazone - block = 109684874774528, count = 14080
[  262.688922] ------------[ cut here ]------------
[  262.688932] kernel BUG at fs/buffer.c:3058!
[  262.689627] invalid opcode: 0000 [#1] SMP KASAN PTI
[  262.690387] Modules linked in: snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore mac_hid i2c_piix4 ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi autofs4 btrfs zstd_decompress zstd_compress xxhash raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq raid1 raid0 multipath linear 8139too crct10dif_pclmul crc32_pclmul qxl drm_kms_helper syscopyarea sysfillrect aesni_intel sysimgblt fb_sys_fops ttm drm aes_x86_64 crypto_simd 8139cp cryptd glue_helper mii floppy pata_acpi
[  262.698496] CPU: 0 PID: 1791 Comm: poc Tainted: G    B            4.16.0-rc1+ #3
[  262.699642] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[  262.701111] RIP: 0010:submit_bh_wbc+0x2c2/0x2f0
[  262.701818] RSP: 0018:ffff88006969f6a8 EFLAGS: 00010246
[  262.702632] RAX: 0000000000000004 RBX: ffff8800649e1e70 RCX: ffffffff9d40aa2d
[  262.703728] RDX: dffffc0000000000 RSI: 0000000000000000 RDI: ffff8800649e1e70
[  262.704837] RBP: ffff88006969f6f0 R08: 0000000000000000 R09: ffff88006477baa8
[  262.705940] R10: 00000000eaef9492 R11: ffffed000d2d3e0b R12: ffff88006969f7f8
[  262.707043] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[  262.708144] FS:  00007f1c85bca700(0000) GS:ffff88006d000000(0000) knlGS:0000000000000000
[  262.709398] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  262.710290] CR2: 00007ff5c401d0d8 CR3: 000000006a948000 CR4: 00000000000006f0
[  262.711395] Call Trace:
[  262.711792]  ll_rw_block+0x9b/0xe0
[  262.712338]  __block_write_begin_int+0x7f8/0x940
[  262.713075]  ? _ext4_get_block+0x290/0x290
[  262.713726]  ? __breadahead+0xd0/0xd0
[  262.714318]  ? jbd2__journal_start+0x19d/0x300
[  262.715028]  __block_write_begin+0x11/0x20
[  262.715677]  ext4_write_begin+0x334/0x780
[  262.716313]  ? ext4_truncate+0x760/0x760
[  262.716945]  ? update_stack_state+0x27c/0x3e0
[  262.717637]  generic_perform_write+0x192/0x310
[  262.718339]  ? generic_write_checks+0x1f0/0x1f0
[  262.719053]  ? file_update_time+0x1e9/0x240
[  262.719715]  ? current_time+0x80/0x80
[  262.720300]  ? is_bpf_text_address+0xe/0x20
[  262.720974]  __generic_file_write_iter+0x261/0x2e0
[  262.721735]  ext4_file_write_iter+0x1dd/0x7e0
[  262.722426]  ? ext4_file_mmap+0x150/0x150
[  262.723067]  ? save_stack+0x46/0xd0
[  262.723628]  ? __kasan_slab_free+0x13e/0x1a0
[  262.724303]  ? kasan_slab_free+0xe/0x10
[  262.724927]  ? kmem_cache_free+0x7c/0x1f0
[  262.725571]  ? aa_file_perm+0xdb/0x570
[  262.726172]  ? SyS_open+0x1e/0x20
[  262.726710]  ? do_syscall_64+0xf2/0x1f0
[  262.727323]  ? entry_SYSCALL_64_after_hwframe+0x21/0x86
[  262.728152]  ? aa_path_link+0x210/0x210
[  262.728775]  ? iov_iter_init+0x82/0xc0
[  262.729376]  __vfs_write+0x294/0x3f0
[  262.729950]  ? kernel_read+0xa0/0xa0
[  262.730523]  ? may_open_dev+0x50/0x50
[  262.731109]  ? common_file_perm+0xca/0x220
[  262.731763]  ? rw_verify_area+0x78/0x140
[  262.732401]  vfs_write+0xf9/0x260
[  262.732939]  SyS_write+0xb4/0x140
[  262.733474]  ? SyS_read+0x140/0x140
[  262.734035]  ? SyS_read+0x140/0x140
[  262.734596]  do_syscall_64+0xf2/0x1f0
[  262.735189]  entry_SYSCALL_64_after_hwframe+0x21/0x86
[  262.735987] RIP: 0033:0x7f1c856dc2c0
[  262.736562] RSP: 002b:00007ffe6287d778 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[  262.737740] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f1c856dc2c0
[  262.738849] RDX: 0000000000008000 RSI: 0000000000602140 RDI: 0000000000000003
[  262.739962] RBP: 00007ffe6287d8e0 R08: 0000000000000003 R09: 0000000000000000
[  262.741078] R10: 0000000000000463 R11: 0000000000000246 R12: 0000000000400c20
[  262.742176] R13: 00007ffe6287d9e0 R14: 0000000000000000 R15: 0000000000000000
[  262.743284] Code: 0f 45 e8 45 09 f5 e8 ee 38 f6 ff 45 89 6c 24 10 4c 89 e7 e8 b1 cd 3a 00 48 83 c4 20 31 c0 5b 41 5c 41 5d 41 5e 41 5f 5d c3 0f 0b <0f> 0b 48 8d 43 20 48 89 45 d0 48 8d 43 10 48 89 45 b8 e9 44 fe
[  262.746250] RIP: submit_bh_wbc+0x2c2/0x2f0 RSP: ffff88006969f6a8
[  262.747236] ---[ end trace c4bccbf286b60fa8 ]---

Reported by Wen Xu at SSLab, Gatech
Comment 1 Wen Xu 2018-04-16 01:42:21 UTC
Created attachment 275389 [details]
poc.c
Comment 2 Wen Xu 2018-04-16 01:43:42 UTC
Created attachment 275391 [details]
Another possible uaf location detected with latest linux kernel master branch
Comment 3 Theodore Tso 2018-06-14 05:15:35 UTC
There is a completely issue with the latest Linux tree.  (I suspect the earlier UAF was fixed recent fix.)

As far as the latest UAF is concerned, this is triggered by the fact that allocation bitmaps are marked as uninitialized for block group #0.  Ext4 shouldn't have paid attention to these flags, since the prerequisite file system feature (uninit_bg or metadata_csum) was not set.  In addition, even if one of those two feature flags were set, ext4 should report an file system corruption if bitmaps for bg 0 are marked as uninitialized and refuse to try to clear those bitmaps, since nothing good can happen.

This will be fixed by the patch:

    ext4: only look at the bg_flags field if it is valid
    
    The bg_flags field in the block group descripts is only valid if the
    uninit_bg or metadata_csum feature is enabled.  We were not
    consistently looking at this field; fix this.
    
    Also block group #0 must never have uninitialized allocation bitmaps,
    or need to be zeroed, since that's where the root inode, and other
    special inodes are set up.  Check for these conditions and mark the
    file system as corrupted if they are detected.
Comment 4 Theodore Tso 2018-06-17 17:49:00 UTC
Patchwork link: http://patchwork.ozlabs.org/patch/929239/
Comment 6 Theodore Tso 2018-07-02 15:57:24 UTC
This issue has been assigned CVE-2018-10876.

Red Hat bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1596773