• Chao Yu's avatar
    f2fs: fix to do sanity check with block address in main area · bdffda8d
    Chao Yu authored
    commit c9b60788 upstream.
    
    This patch add to do sanity check with below field:
    - cp_pack_total_block_count
    - blkaddr of data/node
    - extent info
    
    - Overview
    BUG() in verify_block_addr() when writing to a corrupted f2fs image
    
    - Reproduce (4.18 upstream kernel)
    
    - POC (poc.c)
    
    static void activity(char *mpoint) {
    
      char *foo_bar_baz;
      int err;
    
      static int buf[8192];
      memset(buf, 0, sizeof(buf));
    
      err = asprintf(&foo_bar_baz, "%s/foo/bar/baz", mpoint);
    
      int fd = open(foo_bar_baz, O_RDWR | O_TRUNC, 0777);
      if (fd >= 0) {
        write(fd, (char *)buf, sizeof(buf));
        fdatasync(fd);
        close(fd);
      }
    }
    
    int main(int argc, char *argv[]) {
      activity(argv[1]);
      return 0;
    }
    
    - Kernel message
    [  689.349473] F2FS-fs (loop0): Mounted with checkpoint version = 3
    [  699.728662] WARNING: CPU: 0 PID: 1309 at fs/f2fs/segment.c:2860 f2fs_inplace_write_data+0x232/0x240
    [  699.728670] Modules linked in: snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd mac_hid i2c_piix4 soundcore ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx raid1 raid0 multipath linear 8139too crct10dif_pclmul crc32_pclmul qxl drm_kms_helper syscopyarea aesni_intel sysfillrect sysimgblt fb_sys_fops ttm drm aes_x86_64 crypto_simd cryptd 8139cp glue_helper mii pata_acpi floppy
    [  699.729056] CPU: 0 PID: 1309 Comm: a.out Not tainted 4.18.0-rc1+ #4
    [  699.729064] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
    [  699.729074] RIP: 0010:f2fs_inplace_write_data+0x232/0x240
    [  699.729076] Code: ff e9 cf fe ff ff 49 8d 7d 10 e8 39 45 ad ff 4d 8b 7d 10 be 04 00 00 00 49 8d 7f 48 e8 07 49 ad ff 45 8b 7f 48 e9 fb fe ff ff <0f> 0b f0 41 80 4d 48 04 e9 65 fe ff ff 90 66 66 66 66 90 55 48 8d
    [  699.729130] RSP: 0018:ffff8801f43af568 EFLAGS: 00010202
    [  699.729139] RAX: 000000000000003f RBX: ffff8801f43af7b8 RCX: ffffffffb88c9113
    [  699.729142] RDX: 0000000000000003 RSI: dffffc0000000000 RDI: ffff8802024e5540
    [  699.729144] RBP: ffff8801f43af590 R08: 0000000000000009 R09: ffffffffffffffe8
    [  699.729147] R10: 0000000000000001 R11: ffffed0039b0596a R12: ffff8802024e5540
    [  699.729149] R13: ffff8801f0335500 R14: ffff8801e3e7a700 R15: ffff8801e1ee4450
    [  699.729154] FS:  00007f9bf97f5700(0000) GS:ffff8801f6e00000(0000) knlGS:0000000000000000
    [  699.729156] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [  699.729159] CR2: 00007f9bf925d170 CR3: 00000001f0c34000 CR4: 00000000000006f0
    [  699.729171] Call Trace:
    [  699.729192]  f2fs_do_write_data_page+0x2e2/0xe00
    [  699.729203]  ? f2fs_should_update_outplace+0xd0/0xd0
    [  699.729238]  ? memcg_drain_all_list_lrus+0x280/0x280
    [  699.729269]  ? __radix_tree_replace+0xa3/0x120
    [  699.729276]  __write_data_page+0x5c7/0xe30
    [  699.729291]  ? kasan_check_read+0x11/0x20
    [  699.729310]  ? page_mapped+0x8a/0x110
    [  699.729321]  ? page_mkclean+0xe9/0x160
    [  699.729327]  ? f2fs_do_write_data_page+0xe00/0xe00
    [  699.729331]  ? invalid_page_referenced_vma+0x130/0x130
    [  699.729345]  ? clear_page_dirty_for_io+0x332/0x450
    [  699.729351]  f2fs_write_cache_pages+0x4ca/0x860
    [  699.729358]  ? __write_data_page+0xe30/0xe30
    [  699.729374]  ? percpu_counter_add_batch+0x22/0xa0
    [  699.729380]  ? kasan_check_write+0x14/0x20
    [  699.729391]  ? _raw_spin_lock+0x17/0x40
    [  699.729403]  ? f2fs_mark_inode_dirty_sync.part.18+0x16/0x30
    [  699.729413]  ? iov_iter_advance+0x113/0x640
    [  699.729418]  ? f2fs_write_end+0x133/0x2e0
    [  699.729423]  ? balance_dirty_pages_ratelimited+0x239/0x640
    [  699.729428]  f2fs_write_data_pages+0x329/0x520
    [  699.729433]  ? generic_perform_write+0x250/0x320
    [  699.729438]  ? f2fs_write_cache_pages+0x860/0x860
    [  699.729454]  ? current_time+0x110/0x110
    [  699.729459]  ? f2fs_preallocate_blocks+0x1ef/0x370
    [  699.729464]  do_writepages+0x37/0xb0
    [  699.729468]  ? f2fs_write_cache_pages+0x860/0x860
    [  699.729472]  ? do_writepages+0x37/0xb0
    [  699.729478]  __filemap_fdatawrite_range+0x19a/0x1f0
    [  699.729483]  ? delete_from_page_cache_batch+0x4e0/0x4e0
    [  699.729496]  ? __vfs_write+0x2b2/0x410
    [  699.729501]  file_write_and_wait_range+0x66/0xb0
    [  699.729506]  f2fs_do_sync_file+0x1f9/0xd90
    [  699.729511]  ? truncate_partial_data_page+0x290/0x290
    [  699.729521]  ? __sb_end_write+0x30/0x50
    [  699.729526]  ? vfs_write+0x20f/0x260
    [  699.729530]  f2fs_sync_file+0x9a/0xb0
    [  699.729534]  ? f2fs_do_sync_file+0xd90/0xd90
    [  699.729548]  vfs_fsync_range+0x68/0x100
    [  699.729554]  ? __fget_light+0xc9/0xe0
    [  699.729558]  do_fsync+0x3d/0x70
    [  699.729562]  __x64_sys_fdatasync+0x24/0x30
    [  699.729585]  do_syscall_64+0x78/0x170
    [  699.729595]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
    [  699.729613] RIP: 0033:0x7f9bf930d800
    [  699.729615] Code: 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 83 3d 49 bf 2c 00 00 75 10 b8 4b 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 be 78 01 00 48 89 04 24
    [  699.729668] RSP: 002b:00007ffee3606c68 EFLAGS: 00000246 ORIG_RAX: 000000000000004b
    [  699.729673] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f9bf930d800
    [  699.729675] RDX: 0000000000008000 RSI: 00000000006010a0 RDI: 0000000000000003
    [  699.729678] RBP: 00007ffee3606ca0 R08: 0000000001503010 R09: 0000000000000000
    [  699.729680] R10: 00000000000002e8 R11: 0000000000000246 R12: 0000000000400610
    [  699.729683] R13: 00007ffee3606da0 R14: 0000000000000000 R15: 0000000000000000
    [  699.729687] ---[ end trace 4ce02f25ff7d3df5 ]---
    [  699.729782] ------------[ cut here ]------------
    [  699.729785] kernel BUG at fs/f2fs/segment.h:654!
    [  699.731055] invalid opcode: 0000 [#1] SMP KASAN PTI
    [  699.732104] CPU: 0 PID: 1309 Comm: a.out Tainted: G        W         4.18.0-rc1+ #4
    [  699.733684] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
    [  699.735611] RIP: 0010:f2fs_submit_page_bio+0x29b/0x730
    [  699.736649] Code: 54 49 8d bd 18 04 00 00 e8 b2 59 af ff 41 8b 8d 18 04 00 00 8b 45 b8 41 d3 e6 44 01 f0 4c 8d 73 14 41 39 c7 0f 82 37 fe ff ff <0f> 0b 65 8b 05 2c 04 77 47 89 c0 48 0f a3 05 52 c1 d5 01 0f 92 c0
    [  699.740524] RSP: 0018:ffff8801f43af508 EFLAGS: 00010283
    [  699.741573] RAX: 0000000000000000 RBX: ffff8801f43af7b8 RCX: ffffffffb88a7cef
    [  699.743006] RDX: 0000000000000007 RSI: dffffc0000000000 RDI: ffff8801e3e7a64c
    [  699.744426] RBP: ffff8801f43af558 R08: ffffed003e066b55 R09: ffffed003e066b55
    [  699.745833] R10: 0000000000000001 R11: ffffed003e066b54 R12: ffffea0007876940
    [  699.747256] R13: ffff8801f0335500 R14: ffff8801e3e7a600 R15: 0000000000000001
    [  699.748683] FS:  00007f9bf97f5700(0000) GS:ffff8801f6e00000(0000) knlGS:0000000000000000
    [  699.750293] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [  699.751462] CR2: 00007f9bf925d170 CR3: 00000001f0c34000 CR4: 00000000000006f0
    [  699.752874] Call Trace:
    [  699.753386]  ? f2fs_inplace_write_data+0x93/0x240
    [  699.754341]  f2fs_inplace_write_data+0xd2/0x240
    [  699.755271]  f2fs_do_write_data_page+0x2e2/0xe00
    [  699.756214]  ? f2fs_should_update_outplace+0xd0/0xd0
    [  699.757215]  ? memcg_drain_all_list_lrus+0x280/0x280
    [  699.758209]  ? __radix_tree_replace+0xa3/0x120
    [  699.759164]  __write_data_page+0x5c7/0xe30
    [  699.760002]  ? kasan_check_read+0x11/0x20
    [  699.760823]  ? page_mapped+0x8a/0x110
    [  699.761573]  ? page_mkclean+0xe9/0x160
    [  699.762345]  ? f2fs_do_write_data_page+0xe00/0xe00
    [  699.763332]  ? invalid_page_referenced_vma+0x130/0x130
    [  699.764374]  ? clear_page_dirty_for_io+0x332/0x450
    [  699.765347]  f2fs_write_cache_pages+0x4ca/0x860
    [  699.766276]  ? __write_data_page+0xe30/0xe30
    [  699.767161]  ? percpu_counter_add_batch+0x22/0xa0
    [  699.768112]  ? kasan_check_write+0x14/0x20
    [  699.768951]  ? _raw_spin_lock+0x17/0x40
    [  699.769739]  ? f2fs_mark_inode_dirty_sync.part.18+0x16/0x30
    [  699.770885]  ? iov_iter_advance+0x113/0x640
    [  699.771743]  ? f2fs_write_end+0x133/0x2e0
    [  699.772569]  ? balance_dirty_pages_ratelimited+0x239/0x640
    [  699.773680]  f2fs_write_data_pages+0x329/0x520
    [  699.774603]  ? generic_perform_write+0x250/0x320
    [  699.775544]  ? f2fs_write_cache_pages+0x860/0x860
    [  699.776510]  ? current_time+0x110/0x110
    [  699.777299]  ? f2fs_preallocate_blocks+0x1ef/0x370
    [  699.778279]  do_writepages+0x37/0xb0
    [  699.779026]  ? f2fs_write_cache_pages+0x860/0x860
    [  699.779978]  ? do_writepages+0x37/0xb0
    [  699.780755]  __filemap_fdatawrite_range+0x19a/0x1f0
    [  699.781746]  ? delete_from_page_cache_batch+0x4e0/0x4e0
    [  699.782820]  ? __vfs_write+0x2b2/0x410
    [  699.783597]  file_write_and_wait_range+0x66/0xb0
    [  699.784540]  f2fs_do_sync_file+0x1f9/0xd90
    [  699.785381]  ? truncate_partial_data_page+0x290/0x290
    [  699.786415]  ? __sb_end_write+0x30/0x50
    [  699.787204]  ? vfs_write+0x20f/0x260
    [  699.787941]  f2fs_sync_file+0x9a/0xb0
    [  699.788694]  ? f2fs_do_sync_file+0xd90/0xd90
    [  699.789572]  vfs_fsync_range+0x68/0x100
    [  699.790360]  ? __fget_light+0xc9/0xe0
    [  699.791128]  do_fsync+0x3d/0x70
    [  699.791779]  __x64_sys_fdatasync+0x24/0x30
    [  699.792614]  do_syscall_64+0x78/0x170
    [  699.793371]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
    [  699.794406] RIP: 0033:0x7f9bf930d800
    [  699.795134] Code: 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 83 3d 49 bf 2c 00 00 75 10 b8 4b 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 be 78 01 00 48 89 04 24
    [  699.798960] RSP: 002b:00007ffee3606c68 EFLAGS: 00000246 ORIG_RAX: 000000000000004b
    [  699.800483] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f9bf930d800
    [  699.801923] RDX: 0000000000008000 RSI: 00000000006010a0 RDI: 0000000000000003
    [  699.803373] RBP: 00007ffee3606ca0 R08: 0000000001503010 R09: 0000000000000000
    [  699.804798] R10: 00000000000002e8 R11: 0000000000000246 R12: 0000000000400610
    [  699.806233] R13: 00007ffee3606da0 R14: 0000000000000000 R15: 0000000000000000
    [  699.807667] Modules linked in: snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd mac_hid i2c_piix4 soundcore ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx raid1 raid0 multipath linear 8139too crct10dif_pclmul crc32_pclmul qxl drm_kms_helper syscopyarea aesni_intel sysfillrect sysimgblt fb_sys_fops ttm drm aes_x86_64 crypto_simd cryptd 8139cp glue_helper mii pata_acpi floppy
    [  699.817079] ---[ end trace 4ce02f25ff7d3df6 ]---
    [  699.818068] RIP: 0010:f2fs_submit_page_bio+0x29b/0x730
    [  699.819114] Code: 54 49 8d bd 18 04 00 00 e8 b2 59 af ff 41 8b 8d 18 04 00 00 8b 45 b8 41 d3 e6 44 01 f0 4c 8d 73 14 41 39 c7 0f 82 37 fe ff ff <0f> 0b 65 8b 05 2c 04 77 47 89 c0 48 0f a3 05 52 c1 d5 01 0f 92 c0
    [  699.822919] RSP: 0018:ffff8801f43af508 EFLAGS: 00010283
    [  699.823977] RAX: 0000000000000000 RBX: ffff8801f43af7b8 RCX: ffffffffb88a7cef
    [  699.825436] RDX: 0000000000000007 RSI: dffffc0000000000 RDI: ffff8801e3e7a64c
    [  699.826881] RBP: ffff8801f43af558 R08: ffffed003e066b55 R09: ffffed003e066b55
    [  699.828292] R10: 0000000000000001 R11: ffffed003e066b54 R12: ffffea0007876940
    [  699.829750] R13: ffff8801f0335500 R14: ffff8801e3e7a600 R15: 0000000000000001
    [  699.831192] FS:  00007f9bf97f5700(0000) GS:ffff8801f6e00000(0000) knlGS:0000000000000000
    [  699.832793] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [  699.833981] CR2: 00007f9bf925d170 CR3: 00000001f0c34000 CR4: 00000000000006f0
    [  699.835556] ==================================================================
    [  699.837029] BUG: KASAN: stack-out-of-bounds in update_stack_state+0x38c/0x3e0
    [  699.838462] Read of size 8 at addr ffff8801f43af970 by task a.out/1309
    
    [  699.840086] CPU: 0 PID: 1309 Comm: a.out Tainted: G      D W         4.18.0-rc1+ #4
    [  699.841603] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
    [  699.843475] Call Trace:
    [  699.843982]  dump_stack+0x7b/0xb5
    [  699.844661]  print_address_description+0x70/0x290
    [  699.845607]  kasan_report+0x291/0x390
    [  699.846351]  ? update_stack_state+0x38c/0x3e0
    [  699.853831]  __asan_load8+0x54/0x90
    [  699.854569]  update_stack_state+0x38c/0x3e0
    [  699.855428]  ? __read_once_size_nocheck.constprop.7+0x20/0x20
    [  699.856601]  ? __save_stack_trace+0x5e/0x100
    [  699.857476]  unwind_next_frame.part.5+0x18e/0x490
    [  699.858448]  ? unwind_dump+0x290/0x290
    [  699.859217]  ? clear_page_dirty_for_io+0x332/0x450
    [  699.860185]  __unwind_start+0x106/0x190
    [  699.860974]  __save_stack_trace+0x5e/0x100
    [  699.861808]  ? __save_stack_trace+0x5e/0x100
    [  699.862691]  ? unlink_anon_vmas+0xba/0x2c0
    [  699.863525]  save_stack_trace+0x1f/0x30
    [  699.864312]  save_stack+0x46/0xd0
    [  699.864993]  ? __alloc_pages_slowpath+0x1420/0x1420
    [  699.865990]  ? flush_tlb_mm_range+0x15e/0x220
    [  699.866889]  ? kasan_check_write+0x14/0x20
    [  699.867724]  ? __dec_node_state+0x92/0xb0
    [  699.868543]  ? lock_page_memcg+0x85/0xf0
    [  699.869350]  ? unlock_page_memcg+0x16/0x80
    [  699.870185]  ? page_remove_rmap+0x198/0x520
    [  699.871048]  ? mark_page_accessed+0x133/0x200
    [  699.871930]  ? _cond_resched+0x1a/0x50
    [  699.872700]  ? unmap_page_range+0xcd4/0xe50
    [  699.873551]  ? rb_next+0x58/0x80
    [  699.874217]  ? rb_next+0x58/0x80
    [  699.874895]  __kasan_slab_free+0x13c/0x1a0
    [  699.875734]  ? unlink_anon_vmas+0xba/0x2c0
    [  699.876563]  kasan_slab_free+0xe/0x10
    [  699.877315]  kmem_cache_free+0x89/0x1e0
    [  699.878095]  unlink_anon_vmas+0xba/0x2c0
    [  699.878913]  free_pgtables+0x101/0x1b0
    [  699.879677]  exit_mmap+0x146/0x2a0
    [  699.880378]  ? __ia32_sys_munmap+0x50/0x50
    [  699.881214]  ? kasan_check_read+0x11/0x20
    [  699.882052]  ? mm_update_next_owner+0x322/0x380
    [  699.882985]  mmput+0x8b/0x1d0
    [  699.883602]  do_exit+0x43a/0x1390
    [  699.884288]  ? mm_update_next_owner+0x380/0x380
    [  699.885212]  ? f2fs_sync_file+0x9a/0xb0
    [  699.885995]  ? f2fs_do_sync_file+0xd90/0xd90
    [  699.886877]  ? vfs_fsync_range+0x68/0x100
    [  699.887694]  ? __fget_light+0xc9/0xe0
    [  699.888442]  ? do_fsync+0x3d/0x70
    [  699.889118]  ? __x64_sys_fdatasync+0x24/0x30
    [  699.889996]  rewind_stack_do_exit+0x17/0x20
    [  699.890860] RIP: 0033:0x7f9bf930d800
    [  699.891585] Code: Bad RIP value.
    [  699.892268] RSP: 002b:00007ffee3606c68 EFLAGS: 00000246 ORIG_RAX: 000000000000004b
    [  699.893781] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f9bf930d800
    [  699.895220] RDX: 0000000000008000 RSI: 00000000006010a0 RDI: 0000000000000003
    [  699.896643] RBP: 00007ffee3606ca0 R08: 0000000001503010 R09: 0000000000000000
    [  699.898069] R10: 00000000000002e8 R11: 0000000000000246 R12: 0000000000400610
    [  699.899505] R13: 00007ffee3606da0 R14: 0000000000000000 R15: 0000000000000000
    
    [  699.901241] The buggy address belongs to the page:
    [  699.902215] page:ffffea0007d0ebc0 count:0 mapcount:0 mapping:0000000000000000 index:0x0
    [  699.903811] flags: 0x2ffff0000000000()
    [  699.904585] raw: 02ffff0000000000 0000000000000000 ffffffff07d00101 0000000000000000
    [  699.906125] raw: 0000000000000000 0000000000240000 00000000ffffffff 0000000000000000
    [  699.907673] page dumped because: kasan: bad access detected
    
    [  699.909108] Memory state around the buggy address:
    [  699.910077]  ffff8801f43af800: 00 f1 f1 f1 f1 00 f4 f4 f4 f3 f3 f3 f3 00 00 00
    [  699.911528]  ffff8801f43af880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    [  699.912953] >ffff8801f43af900: 00 00 00 00 00 00 00 00 f1 01 f4 f4 f4 f2 f2 f2
    [  699.914392]                                                              ^
    [  699.915758]  ffff8801f43af980: f2 00 f4 f4 00 00 00 00 f2 00 00 00 00 00 00 00
    [  699.917193]  ffff8801f43afa00: 00 00 00 00 00 00 00 00 00 f3 f3 f3 00 00 00 00
    [  699.918634] ==================================================================
    
    - Location
    https://elixir.bootlin.com/linux/v4.18-rc1/source/fs/f2fs/segment.h#L644
    
    Reported-by Wen Xu <wen.xu@gatech.edu>
    Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
    Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
    [bwh: Backported to 4.4:
     - CoW is not implemented so check f2fs_io_info::blk_addr instead of
       f2fs_io_info::{old,new}_blkaddr
     - Operation code is f2fs_io_info::rw instead of f2fs_io_info::op
     - f2fs_stop_checkpoint() only takes one argument
     - In f2fs_map_blocks(), validate dn.data_blkaddr instead of blkaddr
     - Adjust context]
    Signed-off-by: default avatarBen Hutchings <ben.hutchings@codethink.co.uk>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    bdffda8d
inode.c 12.9 KB