Skip to content
  • Chao Yu's avatar
    f2fs: fix to do sanity check with {sit,nat}_ver_bitmap_bytesize · 0983ef55
    Chao Yu authored
    [ Upstream commit c77ec61c ]
    
    This patch adds to do sanity check with {sit,nat}_ver_bitmap_bytesize
    during mount, in order to avoid accessing across cache boundary with
    this abnormal bitmap size.
    
    - Overview
    buffer overrun in build_sit_info() when mounting a crafted f2fs image
    
    - Reproduce
    
    - Kernel message
    [  548.580867] F2FS-fs (loop0): Invalid log blocks per segment (8201)
    
    [  548.580877] F2FS-fs (loop0): Can't find valid F2FS filesystem in 1th superblock
    [  548.584979] ==================================================================
    [  548.586568] BUG: KASAN: use-after-free in kmemdup+0x36/0x50
    [  548.587715] Read of size 64 at addr ffff8801e9c265ff by task mount/1295
    
    [  548.589428] CPU: 1 PID: 1295 Comm: mount Not tainted 4.18.0-rc1+ #4
    [  548.589432] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
    [  548.589438] Call Trace:
    [  548.589474]  dump_stack+0x7b/0xb5
    [  548.589487]  print_address_description+0x70/0x290
    [  548.589492]  kasan_report+0x291/0x390
    [  548.589496]  ? kmemdup+0x36/0x50
    [  548.589509]  check_memory_region+0x139/0x190
    [  548.589514]  memcpy+0x23/0x50
    [  548.589518]  kmemdup+0x36/0x50
    [  548.589545]  f2fs_build_segment_manager+0x8fa/0x3410
    [  548.589551]  ? __asan_loadN+0xf/0x20
    [  548.589560]  ? f2fs_sanity_check_ckpt+0x1be/0x240
    [  548.589566]  ? f2fs_flush_sit_entries+0x10c0/0x10c0
    [  548.589587]  ? __put_user_ns+0x40/0x40
    [  548.589604]  ? find_next_bit+0x57/0x90
    [  548.589610]  f2fs_fill_super+0x194b/0x2b40
    [  548.589617]  ? f2fs_commit_super+0x1b0/0x1b0
    [  548.589637]  ? set_blocksize+0x90/0x140
    [  548.589651]  mount_bdev+0x1c5/0x210
    [  548.589655]  ? f2fs_commit_super+0x1b0/0x1b0
    [  548.589667]  f2fs_mount+0x15/0x20
    [  548.589672]  mount_fs+0x60/0x1a0
    [  548.589683]  ? alloc_vfsmnt+0x309/0x360
    [  548.589688]  vfs_kern_mount+0x6b/0x1a0
    [  548.589699]  do_mount+0x34a/0x18c0
    [  548.589710]  ? lockref_put_or_lock+0xcf/0x160
    [  548.589716]  ? copy_mount_string+0x20/0x20
    [  548.589728]  ? memcg_kmem_put_cache+0x1b/0xa0
    [  548.589734]  ? kasan_check_write+0x14/0x20
    [  548.589740]  ? _copy_from_user+0x6a/0x90
    [  548.589744]  ? memdup_user+0x42/0x60
    [  548.589750]  ksys_mount+0x83/0xd0
    [  548.589755]  __x64_sys_mount+0x67/0x80
    [  548.589781]  do_syscall_64+0x78/0x170
    [  548.589797]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
    [  548.589820] RIP: 0033:0x7f76fc331b9a
    [  548.589821] Code: 48 8b 0d 01 c3 2b 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 ce c2 2b 00 f7 d8 64 89 01 48
    [  548.589880] RSP: 002b:00007ffd4f0a0e48 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
    [  548.589890] RAX: ffffffffffffffda RBX: 000000000146c030 RCX: 00007f76fc331b9a
    [  548.589892] RDX: 000000000146c210 RSI: 000000000146df30 RDI: 0000000001474ec0
    [  548.589895] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000013
    [  548.589897] R10: 00000000c0ed0000 R11: 0000000000000206 R12: 0000000001474ec0
    [  548.589900] R13: 000000000146c210 R14: 0000000000000000 R15: 0000000000000003
    
    [  548.590242] The buggy address belongs to the page:
    [  548.591243] page:ffffea0007a70980 count:0 mapcount:0 mapping:0000000000000000 index:0x0
    [  548.592886] flags: 0x2ffff0000000000()
    [  548.593665] raw: 02ffff0000000000 dead000000000100 dead000000000200 0000000000000000
    [  548.595258] raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
    [  548.603713] page dumped because: kasan: bad access detected
    
    [  548.605203] Memory state around the buggy address:
    [  548.606198]  ffff8801e9c26480: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    [  548.607676]  ffff8801e9c26500: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    [  548.609157] >ffff8801e9c26580: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    [  548.610629]                                                                 ^
    [  548.612088]  ffff8801e9c26600: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    [  548.613674]  ffff8801e9c26680: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    [  548.615141] ==================================================================
    [  548.616613] Disabling lock debugging due to kernel taint
    [  548.622871] WARNING: CPU: 1 PID: 1295 at mm/page_alloc.c:4065 __alloc_pages_slowpath+0xe4a/0x1420
    [  548.622878] 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
    [  548.623217] CPU: 1 PID: 1295 Comm: mount Tainted: G    B             4.18.0-rc1+ #4
    [  548.623219] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
    [  548.623226] RIP: 0010:__alloc_pages_slowpath+0xe4a/0x1420
    [  548.623227] Code: ff ff 01 89 85 c8 fe ff ff e9 91 fc ff ff 41 89 c5 e9 5c fc ff ff 0f 0b 89 f8 25 ff ff f7 ff 89 85 8c fe ff ff e9 d5 f2 ff ff <0f> 0b e9 65 f2 ff ff 65 8b 05 38 81 d2 47 f6 c4 01 74 1c 65 48 8b
    [  548.623281] RSP: 0018:ffff8801f28c7678 EFLAGS: 00010246
    [  548.623284] RAX: 0000000000000000 RBX: 00000000006040c0 RCX: ffffffffb82f73b7
    [  548.623287] RDX: 1ffff1003e518eeb RSI: 000000000000000c RDI: 0000000000000000
    [  548.623290] RBP: ffff8801f28c7880 R08: 0000000000000000 R09: ffffed0047fff2c5
    [  548.623292] R10: 0000000000000001 R11: ffffed0047fff2c4 R12: ffff8801e88de040
    [  548.623295] R13: 00000000006040c0 R14: 000000000000000c R15: ffff8801f28c7938
    [  548.623299] FS:  00007f76fca51840(0000) GS:ffff8801f6f00000(0000) knlGS:0000000000000000
    [  548.623302] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [  548.623304] CR2: 00007f19b9171760 CR3: 00000001ed952000 CR4: 00000000000006e0
    [  548.623317] Call Trace:
    [  548.623325]  ? kasan_check_read+0x11/0x20
    [  548.623330]  ? __zone_watermark_ok+0x92/0x240
    [  548.623336]  ? get_page_from_freelist+0x1c3/0x1d90
    [  548.623347]  ? _raw_spin_lock_irqsave+0x2a/0x60
    [  548.623353]  ? warn_alloc+0x250/0x250
    [  548.623358]  ? save_stack+0x46/0xd0
    [  548.623361]  ? kasan_kmalloc+0xad/0xe0
    [  548.623366]  ? __isolate_free_page+0x2a0/0x2a0
    [  548.623370]  ? mount_fs+0x60/0x1a0
    [  548.623374]  ? vfs_kern_mount+0x6b/0x1a0
    [  548.623378]  ? do_mount+0x34a/0x18c0
    [  548.623383]  ? ksys_mount+0x83/0xd0
    [  548.623387]  ? __x64_sys_mount+0x67/0x80
    [  548.623391]  ? do_syscall_64+0x78/0x170
    [  548.623396]  ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
    [  548.623401]  __alloc_pages_nodemask+0x3c5/0x400
    [  548.623407]  ? __alloc_pages_slowpath+0x1420/0x1420
    [  548.623412]  ? __mutex_lock_slowpath+0x20/0x20
    [  548.623417]  ? kvmalloc_node+0x31/0x80
    [  548.623424]  alloc_pages_current+0x75/0x110
    [  548.623436]  kmalloc_order+0x24/0x60
    [  548.623442]  kmalloc_order_trace+0x24/0xb0
    [  548.623448]  __kmalloc_track_caller+0x207/0x220
    [  548.623455]  ? f2fs_build_node_manager+0x399/0xbb0
    [  548.623460]  kmemdup+0x20/0x50
    [  548.623465]  f2fs_build_node_manager+0x399/0xbb0
    [  548.623470]  f2fs_fill_super+0x195e/0x2b40
    [  548.623477]  ? f2fs_commit_super+0x1b0/0x1b0
    [  548.623481]  ? set_blocksize+0x90/0x140
    [  548.623486]  mount_bdev+0x1c5/0x210
    [  548.623489]  ? f2fs_commit_super+0x1b0/0x1b0
    [  548.623495]  f2fs_mount+0x15/0x20
    [  548.623498]  mount_fs+0x60/0x1a0
    [  548.623503]  ? alloc_vfsmnt+0x309/0x360
    [  548.623508]  vfs_kern_mount+0x6b/0x1a0
    [  548.623513]  do_mount+0x34a/0x18c0
    [  548.623518]  ? lockref_put_or_lock+0xcf/0x160
    [  548.623523]  ? copy_mount_string+0x20/0x20
    [  548.623528]  ? memcg_kmem_put_cache+0x1b/0xa0
    [  548.623533]  ? kasan_check_write+0x14/0x20
    [  548.623537]  ? _copy_from_user+0x6a/0x90
    [  548.623542]  ? memdup_user+0x42/0x60
    [  548.623547]  ksys_mount+0x83/0xd0
    [  548.623552]  __x64_sys_mount+0x67/0x80
    [  548.623557]  do_syscall_64+0x78/0x170
    [  548.623562]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
    [  548.623566] RIP: 0033:0x7f76fc331b9a
    [  548.623567] Code: 48 8b 0d 01 c3 2b 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 ce c2 2b 00 f7 d8 64 89 01 48
    [  548.623632] RSP: 002b:00007ffd4f0a0e48 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
    [  548.623636] RAX: ffffffffffffffda RBX: 000000000146c030 RCX: 00007f76fc331b9a
    [  548.623639] RDX: 000000000146c210 RSI: 000000000146df30 RDI: 0000000001474ec0
    [  548.623641] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000013
    [  548.623643] R10: 00000000c0ed0000 R11: 0000000000000206 R12: 0000000001474ec0
    [  548.623646] R13: 000000000146c210 R14: 0000000000000000 R15: 0000000000000003
    [  548.623650] ---[ end trace 4ce02f25ff7d3df5 ]---
    [  548.623656] F2FS-fs (loop0): Failed to initialize F2FS node manager
    [  548.627936] F2FS-fs (loop0): Invalid log blocks per segment (8201)
    
    [  548.627940] F2FS-fs (loop0): Can't find valid F2FS filesystem in 1th superblock
    [  548.635835] F2FS-fs (loop0): Failed to initialize F2FS node manager
    
    - Location
    https://elixir.bootlin.com/linux/v4.18-rc1/source/fs/f2fs/segment.c#L3578
    
    
    
    	sit_i->sit_bitmap = kmemdup(src_bitmap, bitmap_size, GFP_KERNEL);
    
    Buffer overrun happens when doing memcpy. I suspect there is missing (inconsistent) checks on bitmap_size.
    
    Reported by Wen Xu (wen.xu@gatech.edu) from SSLab, Gatech.
    
    Reported-by: default avatarWen Xu <wen.xu@gatech.edu>
    Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
    Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
    Signed-off-by: default avatarSasha Levin <alexander.levin@microsoft.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    0983ef55