Bug 199835 - out-of-bound access in finish_rmw() that leads to invalid memory read when mounting and operating a crafted btrfs image
Summary: out-of-bound access in finish_rmw() that leads to invalid memory read when mo...
Status: RESOLVED UNREPRODUCIBLE
Alias: None
Product: File System
Classification: Unclassified
Component: btrfs (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: BTRFS virtual assignee
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-05-26 02:49 UTC by Wen Xu
Modified: 2018-07-04 14:53 UTC (History)
1 user (show)

See Also:
Kernel Version: 4.17
Subsystem:
Regression: No
Bisected commit-id:


Attachments
The (compressed) crafted image which causes crash (135.59 KB, application/zip)
2018-05-26 02:49 UTC, Wen Xu
Details
poc.c (3.18 KB, text/plain)
2018-05-26 02:49 UTC, Wen Xu
Details

Description Wen Xu 2018-05-26 02:49:07 UTC
Created attachment 276189 [details]
The (compressed) crafted image which causes crash

- Overview
Invalid memory read when mounting and operating a crafted btrfs image potentially caused by use-after-free

- Reproduce
# mkdir mnt
# mount -t btrfs 284.img mnt
# gcc -o poc poc.c
# ./poc ./mnt

- Kernel Message
[  246.544703] BTRFS: device fsid 12b338de-a2e9-40fa-a4b0-90e53b7c5773 devid 1 transid 8 /dev/loop0
[  246.546957] BTRFS info (device loop0): disk space caching is enabled
[  246.546960] BTRFS info (device loop0): has skinny extents
[  246.549934] BTRFS info (device loop0): creating UUID tree
[  255.395240] general protection fault: 0000 [#1] SMP PTI
[  255.397268] Modules linked in: snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd i2c_piix4 soundcore mac_hid ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi autofs4 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx raid1 raid0 multipath linear qxl drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm 8139too drm crct10dif_pclmul crc32_pclmul aesni_intel aes_x86_64 crypto_simd cryptd glue_helper 8139cp floppy mii pata_acpi
[  255.408217] CPU: 1 PID: 1323 Comm: poc Not tainted 4.17.0-rc5+ #5
[  255.409404] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[  255.411232] RIP: 0010:finish_rmw+0x2fa/0x550
[  255.412065] RSP: 0018:ffffb22dc12bb810 EFLAGS: 00010246
[  255.413102] RAX: 0000000000000001 RBX: ffff979a74367c00 RCX: 0000000000000002
[  255.414489] RDX: ffff979a74367d08 RSI: 0009f97840000000 RDI: ffff979a74367c98
[  255.415875] RBP: ffffb22dc12bb898 R08: 0000000000000001 R09: ffff979a7014e000
[  255.417270] R10: 0000000000000001 R11: 000000000000000f R12: 0000000000000000
[  255.418653] R13: ffffb22dc12bb810 R14: ffffd67888cb4200 R15: 0000000000000001
[  255.420039] FS:  00007f7762a67700(0000) GS:ffff979a7fd00000(0000) knlGS:0000000000000000
[  255.421623] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  255.422748] CR2: 00000000022d4158 CR3: 000000023370c000 CR4: 00000000000006e0
[  255.424143] Call Trace:
[  255.424641]  full_stripe_write+0xa2/0xb0
[  255.425441]  raid56_parity_write+0xf6/0x170
[  255.426270]  btrfs_map_bio+0x321/0x350
[  255.427014]  btrfs_submit_bio_hook+0xd7/0x180
[  255.427871]  ? btrfs_map_block+0x10/0x20
[  255.428644]  submit_one_bio+0x5d/0x80
[  255.429379]  submit_extent_page+0xe0/0x1d0
[  255.430189]  __extent_writepage_io+0x259/0x400
[  255.431061]  ? end_extent_writepage+0xa0/0xa0
[  255.431918]  __extent_writepage+0x21b/0x310
[  255.432741]  extent_write_cache_pages+0x2af/0x3c0
[  255.433678]  ? btrfs_inode_rsv_release+0xbf/0x120
[  255.434601]  extent_writepages+0x50/0x80
[  255.435374]  ? __btrfs_btree_balance_dirty+0x36/0x60
[  255.436350]  btrfs_writepages+0x21/0x30
[  255.438039]  do_writepages+0x1f/0x70
[  255.438756]  __filemap_fdatawrite_range+0xc6/0x100
[  255.439703]  filemap_fdatawrite_range+0x13/0x20
[  255.440599]  btrfs_fdatawrite_range+0x20/0x50
[  255.441476]  start_ordered_ops+0x57/0xa0
[  255.442255]  btrfs_sync_file+0xa4/0x410
[  255.443016]  ? btrfs_sync_file+0xa4/0x410
[  255.443812]  vfs_fsync_range+0x48/0x80
[  255.444556]  do_fsync+0x3d/0x70
[  255.445194]  __x64_sys_fdatasync+0x17/0x20
[  255.446008]  do_syscall_64+0x5a/0x110
[  255.446738]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  255.447730] RIP: 0033:0x7f776257f800
[  255.448439] RSP: 002b:00007ffefd313a48 EFLAGS: 00000246 ORIG_RAX: 000000000000004b
[  255.449945] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f776257f800
[  255.451342] RDX: 0000000000008000 RSI: 0000000000602140 RDI: 0000000000000003
[  255.452737] RBP: 00007ffefd313bb0 R08: 0000000000000003 R09: 0000000000000000
[  255.454139] R10: 00000000000002e8 R11: 0000000000000246 R12: 0000000000400c20
[  255.455533] R13: 00007ffefd313cb0 R14: 0000000000000000 R15: 0000000000000000
[  255.456937] Code: 01 00 00 00 44 89 ee 48 89 df e8 b2 f4 ff ff 48 85 c0 48 89 c2 75 ac eb cb 45 31 ff 31 c0 e9 e7 fe ff ff 49 8b 75 00 48 8b 45 a0 <48> 8b 16 49 8b 44 c5 00 48 89 10 48 8d 78 08 48 8b 96 f8 0f 00
[  255.460616] RIP: finish_rmw+0x2fa/0x550 RSP: ffffb22dc12bb810
[  255.461810] ---[ end trace 9a398ac42c98af79 ]---

- Reason
https://elixir.bootlin.com/linux/v4.17-rc5/source/fs/btrfs/raid56.c#L1260

} else {
/* raid5 */
memcpy(pointers[nr_data], pointers[0], PAGE_SIZE);
run_xor(pointers + 1, nr_data - 1, PAGE_SIZE);
}

Here pointers[nr_data] is not a valid value, namely 0009f97840000000 (RSI). I re-run on KASAN build, and get the following message:

[  264.776904] ==================================================================
[  264.803281] BUG: KASAN: slab-out-of-bounds in index_rbio_pages+0x1bb/0x2f0
[  264.804680] Write of size 8 at addr ffff8801e5769090 by task poc/1363

[  264.806296] CPU: 0 PID: 1363 Comm: poc Not tainted 4.17.0-rc5+ #6
[  264.806299] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[  264.806306] Call Trace:
[  264.806324]  dump_stack+0x7b/0xb5
[  264.806341]  print_address_description+0x70/0x290
[  264.806346]  kasan_report+0x291/0x390
[  264.806351]  ? index_rbio_pages+0x1bb/0x2f0
[  264.806356]  __asan_store8+0x57/0x90
[  264.806361]  index_rbio_pages+0x1bb/0x2f0
[  264.806367]  finish_rmw+0x17f/0x970
[  264.806377]  ? __alloc_pages_nodemask+0x1d6/0x3c0
[  264.806382]  ? finish_rmw+0xb7/0x970
[  264.806388]  ? index_rbio_pages+0x2f0/0x2f0
[  264.806394]  full_stripe_write+0x103/0x110
[  264.806399]  raid56_parity_write+0x19d/0x230
[  264.806409]  btrfs_map_bio+0x6b0/0x6e0
[  264.806418]  ? btrfs_csum_one_bio+0x6f6/0x720
[  264.806422]  ? btrfs_rmap_block+0x420/0x420
[  264.806430]  btrfs_submit_bio_hook+0x185/0x290
[  264.806434]  ? btrfs_merge_bio_hook+0x16b/0x190
[  264.806439]  ? __endio_write_update_ordered+0x300/0x300
[  264.806445]  submit_one_bio+0xd5/0x100
[  264.806449]  submit_extent_page+0x113/0x270
[  264.806455]  __extent_writepage_io+0x356/0x5b0
[  264.806459]  ? end_extent_writepage+0x100/0x100
[  264.806466]  __extent_writepage+0x3a8/0x4a0
[  264.806472]  ? __extent_writepage_io+0x5b0/0x5b0
[  264.806485]  ? percpu_counter_add_batch+0x22/0xa0
[  264.806492]  ? clear_page_dirty_for_io+0x334/0x450
[  264.806498]  extent_write_cache_pages+0x461/0x5b0
[  264.806504]  ? __extent_writepage+0x4a0/0x4a0
[  264.806510]  ? __btrfs_buffered_write+0xab1/0xb10
[  264.806521]  ? btrfs_dirty_pages+0x380/0x380
[  264.806529]  ? __vfs_getxattr+0x67/0x90
[  264.806534]  extent_writepages+0xa6/0xf0
[  264.806540]  ? extent_write_locked_range+0x2a0/0x2a0
[  264.806545]  ? file_remove_privs+0xb4/0x1f0
[  264.806550]  ? generic_update_time+0x170/0x170
[  264.806554]  btrfs_writepages+0x2c/0x40
[  264.806559]  do_writepages+0x37/0xb0
[  264.806567]  __filemap_fdatawrite_range+0x19a/0x1f0
[  264.806571]  ? delete_from_page_cache_batch+0x4e0/0x4e0
[  264.806576]  ? btrfs_file_write_iter+0x537/0xa16
[  264.806582]  ? btrfs_sync_file+0x700/0x700
[  264.806587]  filemap_fdatawrite_range+0x13/0x20
[  264.806592]  btrfs_fdatawrite_range+0x38/0x90
[  264.806597]  start_ordered_ops+0xc2/0x130
[  264.806601]  ? btrfs_fdatawrite_range+0x90/0x90
[  264.806607]  ? may_open_dev+0x50/0x50
[  264.806614]  ? apparmor_task_setrlimit+0x270/0x270
[  264.806619]  btrfs_sync_file+0x186/0x700
[  264.806624]  ? btrfs_sync_file+0x186/0x700
[  264.806633]  ? __fsnotify_update_child_dentry_flags.part.1+0x160/0x160
[  264.806638]  ? __fsnotify_inode_delete+0x20/0x20
[  264.806643]  ? start_ordered_ops+0x130/0x130
[  264.806649]  ? __sb_end_write+0x30/0x50
[  264.806655]  ? start_ordered_ops+0x130/0x130
[  264.806662]  vfs_fsync_range+0x68/0x100
[  264.806667]  ? __fget_light+0xc9/0xe0
[  264.806672]  do_fsync+0x3d/0x70
[  264.806677]  __x64_sys_fdatasync+0x24/0x30
[  264.806684]  do_syscall_64+0x78/0x170
[  264.806693]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  264.806710] RIP: 0033:0x7fcfa89a2800
[  264.806713] RSP: 002b:00007ffdaccb9018 EFLAGS: 00000246 ORIG_RAX: 000000000000004b
[  264.806723] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fcfa89a2800
[  264.806726] RDX: 0000000000008000 RSI: 0000000000602140 RDI: 0000000000000003
[  264.806728] RBP: 00007ffdaccb9180 R08: 0000000000000003 R09: 0000000000000000
[  264.806731] R10: 00000000000002e8 R11: 0000000000000246 R12: 0000000000400c20
[  264.806733] R13: 00007ffdaccb9280 R14: 0000000000000000 R15: 0000000000000000

[  264.807073] Allocated by task 1363:
[  264.807782]  save_stack+0x46/0xd0
[  264.807787]  kasan_kmalloc+0xad/0xe0
[  264.807791]  __kmalloc+0x11f/0x240
[  264.807795]  alloc_rbio+0x85/0x300
[  264.807799]  raid56_parity_write+0x2a/0x230
[  264.807802]  btrfs_map_bio+0x6b0/0x6e0
[  264.807806]  btrfs_submit_bio_hook+0x185/0x290
[  264.807809]  submit_one_bio+0xd5/0x100
[  264.807813]  submit_extent_page+0x113/0x270
[  264.807817]  __extent_writepage_io+0x356/0x5b0
[  264.807820]  __extent_writepage+0x3a8/0x4a0
[  264.807824]  extent_write_cache_pages+0x461/0x5b0
[  264.807828]  extent_writepages+0xa6/0xf0
[  264.807831]  btrfs_writepages+0x2c/0x40
[  264.807835]  do_writepages+0x37/0xb0
[  264.807839]  __filemap_fdatawrite_range+0x19a/0x1f0
[  264.807843]  filemap_fdatawrite_range+0x13/0x20
[  264.807847]  btrfs_fdatawrite_range+0x38/0x90
[  264.807851]  start_ordered_ops+0xc2/0x130
[  264.807855]  btrfs_sync_file+0x186/0x700
[  264.807859]  vfs_fsync_range+0x68/0x100
[  264.807862]  do_fsync+0x3d/0x70
[  264.807866]  __x64_sys_fdatasync+0x24/0x30
[  264.807870]  do_syscall_64+0x78/0x170
[  264.807873]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

[  264.808201] Freed by task 877:
[  264.808841]  save_stack+0x46/0xd0
[  264.808846]  __kasan_slab_free+0x13c/0x1a0
[  264.808849]  kasan_slab_free+0xe/0x10
[  264.808852]  kfree+0x8c/0x1c0
[  264.808860]  load_elf_binary+0x137f/0x28bc
[  264.808864]  search_binary_handler+0x110/0x2c0
[  264.808868]  do_execveat_common.isra.33+0xac2/0xda0
[  264.808871]  __x64_sys_execve+0x57/0x70
[  264.808875]  do_syscall_64+0x78/0x170
[  264.808878]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

[  264.809201] The buggy address belongs to the object at ffff8801e5768f00
                which belongs to the cache kmalloc-512 of size 512
[  264.811644] The buggy address is located 400 bytes inside of
                512-byte region [ffff8801e5768f00, ffff8801e5769100)
[  264.813966] The buggy address belongs to the page:
[  264.814931] page:ffffea000795da00 count:1 mapcount:0 mapping:0000000000000000 index:0x0 compound_mapcount: 0
[  264.816870] flags: 0x2ffff0000008100(slab|head)
[  264.817772] raw: 02ffff0000008100 0000000000000000 0000000000000000 00000001800c000c
[  264.819286] raw: ffffea000796d480 0000000c0000000c ffff8801f6c02e00 0000000000000000
[  264.820813] page dumped because: kasan: bad access detected

[  264.822223] Memory state around the buggy address:
[  264.823172]  ffff8801e5768f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  264.824601]  ffff8801e5769000: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc
[  264.826020] >ffff8801e5769080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  264.827430]                          ^
[  264.828177]  ffff8801e5769100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  264.829599]  ffff8801e5769180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  264.831007] ==================================================================

Reported by Wen Xu and Po-Ning Tseng from SSLab, Gatech
Comment 1 Wen Xu 2018-05-26 02:49:38 UTC
Created attachment 276191 [details]
poc.c
Comment 2 Wen Xu 2018-05-26 02:50:57 UTC
btrfs config:
CONFIG_BTRFS_FS=y
CONFIG_BTRFS_FS_POSIX_ACL=y
# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
# CONFIG_BTRFS_DEBUG is not set
# CONFIG_BTRFS_ASSERT is not set
# CONFIG_BTRFS_FS_REF_VERIFY is not set

Note You need to log in before you can comment on or make changes to this bug.