Created attachment 275407 [details] The crafted image which causes kernel panic - Overview out-of-bound access in ext4_ext_drop_refs() when operating on a crafted ext4 image - Reproduce # mkdir mnt # mount -t ext4 91.img mnt # gcc -o poc poc.c # ./poc ./mnt I reproduced it on both ext4 dev branch (4.16) and upstream kernel (4.17). - Reason https://elixir.bootlin.com/linux/latest/source/fs/ext4/extents.c#L711 void ext4_ext_drop_refs(struct ext4_ext_path *path) { int depth, i; if (!path) return; depth = path->p_depth; for (i = 0; i <= depth; i++, path++) if (path->p_bh) { brelse(path->p_bh); path->p_bh = NULL; } } Here it seems kernel lacks sanitary checks on depth, which makes the pointer path move out of its boundary. - Kernel Message [ 237.005192] EXT4-fs (loop0): warning: checktime reached, running e2fsck is recommended [ 237.048673] EXT4-fs (loop0): mounted filesystem with ordered data mode. Opts: (null) [ 240.488058] EXT4-fs error (device loop0): ext4_find_extent:903: inode #5: comm poc: pblk 0 bad header/extent: invalid magic - magic 0, entries 0, max 0(0), depth 0(4294967294) [ 240.525640] Aborting journal on device loop0-8. [ 240.547657] EXT4-fs (loop0): Remounting filesystem read-only [ 240.548579] ================================================================== [ 240.549942] BUG: KASAN: slab-out-of-bounds in ext4_ext_drop_refs+0x33/0x70 [ 240.551051] Read of size 8 at addr ffff880115ec94d8 by task poc/1350 [ 240.552272] CPU: 0 PID: 1350 Comm: poc Not tainted 4.16.0-rc1+ #3 [ 240.552276] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 [ 240.552279] Call Trace: [ 240.552302] dump_stack+0x63/0x8d [ 240.552317] print_address_description+0x70/0x290 [ 240.552323] kasan_report+0x290/0x390 [ 240.552329] ? ext4_ext_drop_refs+0x33/0x70 [ 240.552338] __asan_load8+0x54/0x90 [ 240.552344] ext4_ext_drop_refs+0x33/0x70 [ 240.552350] ext4_find_extent+0x259/0x450 [ 240.552357] ext4_ext_map_blocks+0x144/0x1f60 [ 240.552363] ? save_stack+0x46/0xd0 [ 240.552370] ? kasan_kmalloc+0xad/0xe0 [ 240.552377] ? ext4_iget+0xf8/0x16e0 [ 240.552383] ? ext4_find_delalloc_cluster+0x60/0x60 [ 240.552397] ? generic_permission+0x192/0x1e0 [ 240.552402] ? may_open+0xd9/0x150 [ 240.552409] ? path_openat+0x47f/0x1e30 [ 240.552415] ? do_filp_open+0x12b/0x1d0 [ 240.552421] ? do_sys_open+0x17c/0x2c0 [ 240.552426] ? SyS_open+0x1e/0x20 [ 240.552438] ? do_syscall_64+0xf2/0x1f0 [ 240.552450] ? entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 240.552463] ? update_stack_state+0x27c/0x3e0 [ 240.552470] ? __read_once_size_nocheck.constprop.7+0x20/0x20 [ 240.552478] ? __save_stack_trace+0x5e/0x100 [ 240.552488] ? mark_page_accessed+0x133/0x200 [ 240.552496] ? __find_get_block+0xf8/0x3c0 [ 240.552506] ? map_id_range_down+0x195/0x1c0 [ 240.552513] ? ext4_es_lookup_extent+0xfc/0x2f0 [ 240.552518] ext4_map_blocks+0x683/0xa50 [ 240.552525] ? kasan_kmalloc+0xad/0xe0 [ 240.552531] ? ext4_issue_zeroout+0xa0/0xa0 [ 240.552540] ? wake_atomic_t_function+0xa0/0xa0 [ 240.552547] ? inode_sb_list_add+0x93/0xc0 [ 240.552554] ? inode_set_flags+0x2b/0x50 [ 240.552559] ext4_getblk+0xa6/0x2a0 [ 240.552564] ? ext4_iget+0x135e/0x16e0 [ 240.552569] ? ext4_iomap_begin+0x7a0/0x7a0 [ 240.552576] ext4_bread_batch+0x5c/0x1c0 [ 240.552588] ext4_xattr_inode_read+0x1d1/0x2f0 [ 240.552596] ? ext4_xattr_inode_free_quota.part.28+0x90/0x90 [ 240.552602] ? kasan_kmalloc+0xad/0xe0 [ 240.552607] ? __kmalloc+0x109/0x230 [ 240.552613] ? ext4_get_acl+0x63/0x2d0 [ 240.552620] ? get_acl+0xa3/0x140 [ 240.552626] ? generic_permission+0x192/0x1e0 [ 240.552631] ? inode_permission+0x46/0x1f0 [ 240.552636] ? may_open+0xd9/0x150 [ 240.552642] ? path_openat+0x47f/0x1e30 [ 240.552649] ? _cond_resched+0x1a/0x50 [ 240.552656] ? up_write+0x16/0x40 [ 240.552661] ? ext4_xattr_inode_iget+0xd2/0x200 [ 240.552668] ext4_xattr_inode_get+0x13a/0x430 [ 240.552674] ? ext4_xattr_release_block+0x3d0/0x3d0 [ 240.552680] ? mb_cache_entry_create+0x180/0x2c0 [ 240.552684] ? kasan_slab_free+0xe/0x10 [ 240.552690] ? kmem_cache_free+0x7c/0x1f0 [ 240.552697] ? strlen+0xf/0x40 [ 240.552702] ? xattr_find_entry+0xb0/0x140 [ 240.552708] ext4_xattr_get+0x4b6/0x4d0 [ 240.552715] ? ext4_xattr_ibody_get+0x320/0x320 [ 240.552721] ? __kmalloc+0x109/0x230 [ 240.552726] ext4_get_acl+0x8e/0x2d0 [ 240.552732] ? __d_rehash+0x89/0xb0 [ 240.552737] get_acl+0xa3/0x140 [ 240.552744] generic_permission+0x192/0x1e0 [ 240.552750] inode_permission+0x46/0x1f0 [ 240.552756] may_open+0xd9/0x150 [ 240.552762] path_openat+0x47f/0x1e30 [ 240.552767] ? __save_stack_trace+0x92/0x100 [ 240.552775] ? vfs_link+0x4e0/0x4e0 [ 240.552781] ? kasan_kmalloc+0xad/0xe0 [ 240.552787] ? kmem_cache_alloc+0xbb/0x1d0 [ 240.552792] ? getname_flags+0x76/0x2c0 [ 240.552798] ? getname+0x12/0x20 [ 240.552802] ? do_sys_open+0x14b/0x2c0 [ 240.552807] ? SyS_open+0x1e/0x20 [ 240.552812] ? do_syscall_64+0xf2/0x1f0 [ 240.552818] ? entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 240.552823] ? exit_to_usermode_loop+0xf2/0x100 [ 240.552828] ? do_syscall_64+0x1c0/0x1f0 [ 240.552834] ? entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 240.552842] ? __ext4_journal_stop+0xa0/0x100 [ 240.552849] do_filp_open+0x12b/0x1d0 [ 240.552855] ? may_open_dev+0x50/0x50 [ 240.552862] ? kasan_kmalloc+0xad/0xe0 [ 240.552869] do_sys_open+0x17c/0x2c0 [ 240.552874] ? do_sys_open+0x17c/0x2c0 [ 240.552879] ? filp_open+0x60/0x60 [ 240.552885] ? mem_cgroup_handle_over_high+0x21/0xd0 [ 240.552890] ? do_sys_open+0x2c0/0x2c0 [ 240.552895] SyS_open+0x1e/0x20 [ 240.552900] do_syscall_64+0xf2/0x1f0 [ 240.552907] entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 240.552912] RIP: 0033:0x7f979d764040 [ 240.552914] RSP: 002b:00007ffc945a5f88 EFLAGS: 00000246 ORIG_RAX: 0000000000000002 [ 240.552925] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f979d764040 [ 240.552928] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000002143080 [ 240.552931] RBP: 00007ffc945a60f0 R08: 00007f979da31bd8 R09: 0000000000000001 [ 240.552934] R10: 000000000000069d R11: 0000000000000246 R12: 0000000000400c20 [ 240.552937] R13: 00007ffc945a61f0 R14: 0000000000000000 R15: 0000000000000000 [ 240.553197] Allocated by task 1350: [ 240.553749] save_stack+0x46/0xd0 [ 240.553754] kasan_kmalloc+0xad/0xe0 [ 240.553759] __kmalloc+0x109/0x230 [ 240.553764] ext4_find_extent+0x3cf/0x450 [ 240.553770] ext4_ext_map_blocks+0x144/0x1f60 [ 240.553774] ext4_map_blocks+0x683/0xa50 [ 240.553778] ext4_getblk+0xa6/0x2a0 [ 240.553782] ext4_bread_batch+0x5c/0x1c0 [ 240.553787] ext4_xattr_inode_read+0x1d1/0x2f0 [ 240.553792] ext4_xattr_inode_get+0x13a/0x430 [ 240.553797] ext4_xattr_get+0x4b6/0x4d0 [ 240.553802] ext4_get_acl+0x8e/0x2d0 [ 240.553806] get_acl+0xa3/0x140 [ 240.553812] generic_permission+0x192/0x1e0 [ 240.553817] inode_permission+0x46/0x1f0 [ 240.553822] may_open+0xd9/0x150 [ 240.553827] path_openat+0x47f/0x1e30 [ 240.553832] do_filp_open+0x12b/0x1d0 [ 240.553836] do_sys_open+0x17c/0x2c0 [ 240.553840] SyS_open+0x1e/0x20 [ 240.553845] do_syscall_64+0xf2/0x1f0 [ 240.553851] entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 240.554099] Freed by task 1157: [ 240.554611] save_stack+0x46/0xd0 [ 240.554618] __kasan_slab_free+0x13e/0x1a0 [ 240.554621] kasan_slab_free+0xe/0x10 [ 240.554626] kfree+0x90/0x1b0 [ 240.554635] kernfs_put_open_node.isra.10+0xc2/0xf0 [ 240.554641] kernfs_fop_release+0x6c/0x120 [ 240.554646] __fput+0x17a/0x350 [ 240.554651] ____fput+0xe/0x10 [ 240.554658] task_work_run+0xba/0xe0 [ 240.554663] exit_to_usermode_loop+0xf2/0x100 [ 240.554668] do_syscall_64+0x1c0/0x1f0 [ 240.554673] entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 240.554924] The buggy address belongs to the object at ffff880115ec9480 which belongs to the cache kmalloc-64 of size 64 [ 240.556787] The buggy address is located 24 bytes to the right of 64-byte region [ffff880115ec9480, ffff880115ec94c0) [ 240.558619] The buggy address belongs to the page: [ 240.559366] page:ffffea000457b240 count:1 mapcount:0 mapping: (null) index:0x0 [ 240.560591] flags: 0x2ffff0000000100(slab) [ 240.561235] raw: 02ffff0000000100 0000000000000000 0000000000000000 00000001802a002a [ 240.562432] raw: ffffea0004548d00 0000000d0000000d ffff88011ac01700 0000000000000000 [ 240.563599] page dumped because: kasan: bad access detected [ 240.564693] Memory state around the buggy address: [ 240.565428] ffff880115ec9380: 00 00 07 fc fc fc fc fc fb fb fb fb fb fb fb fb [ 240.566531] ffff880115ec9400: fc fc fc fc fb fb fb fb fb fb fb fb fc fc fc fc [ 240.567628] >ffff880115ec9480: 00 00 00 00 00 00 fc fc fc fc fc fc fb fb fb fb [ 240.568729] ^ [ 240.569661] ffff880115ec9500: fb fb fb fb fc fc fc fc fb fb fb fb fb fb fb fb [ 240.570764] ffff880115ec9580: fc fc fc fc fb fb fb fb fb fb fb fb fc fc fc fc [ 240.571868] ================================================================== [ 240.572970] Disabling lock debugging due to kernel taint [ 240.573040] general protection fault: 0000 [#1] SMP KASAN PTI [ 240.573934] 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 btrfs zstd_decompress zstd_compress xxhash raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq raid1 raid0 multipath linear 8139too qxl drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm crct10dif_pclmul crc32_pclmul aesni_intel aes_x86_64 crypto_simd cryptd 8139cp glue_helper floppy mii pata_acpi [ 240.582372] CPU: 0 PID: 1350 Comm: poc Tainted: G B 4.16.0-rc1+ #3 [ 240.583499] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 [ 240.584940] RIP: 0010:__brelse+0x16/0x40 [ 240.585552] RSP: 0018:ffff88011392f190 EFLAGS: 00010296 [ 240.586367] RAX: 0000000000000000 RBX: 6f6602030000000c RCX: ffffffff934081b6 [ 240.587448] RDX: 0000000000000000 RSI: 0000000000000004 RDI: 6f6602030000006c [ 240.588533] RBP: ffff88011392f198 R08: fffffbfff2a80459 R09: ffffffff954022fc [ 240.589617] R10: 000000000000000b R11: fffffbfff2a80458 R12: 0000000000000002 [ 240.590717] R13: 000000000000ffff R14: 000000000000ffff R15: ffffffffffffff8b [ 240.591812] FS: 00007f979dc52700(0000) GS:ffff88011b000000(0000) knlGS:0000000000000000 [ 240.593044] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 240.593924] CR2: 000000000214b158 CR3: 00000001132fa000 CR4: 00000000000006f0 [ 240.595030] Call Trace: [ 240.595424] ext4_ext_drop_refs+0x40/0x70 [ 240.596054] ext4_find_extent+0x259/0x450 [ 240.596682] ext4_ext_map_blocks+0x144/0x1f60 [ 240.597369] ? save_stack+0x46/0xd0 [ 240.597919] ? kasan_kmalloc+0xad/0xe0 [ 240.598517] ? ext4_iget+0xf8/0x16e0 [ 240.599083] ? ext4_find_delalloc_cluster+0x60/0x60 [ 240.599845] ? generic_permission+0x192/0x1e0 [ 240.600526] ? may_open+0xd9/0x150 [ 240.601065] ? path_openat+0x47f/0x1e30 [ 240.601664] ? do_filp_open+0x12b/0x1d0 [ 240.602274] ? do_sys_open+0x17c/0x2c0 [ 240.602858] ? SyS_open+0x1e/0x20 [ 240.603378] ? do_syscall_64+0xf2/0x1f0 [ 240.603973] ? entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 240.604781] ? update_stack_state+0x27c/0x3e0 [ 240.605459] ? __read_once_size_nocheck.constprop.7+0x20/0x20 [ 240.606351] ? __save_stack_trace+0x5e/0x100 [ 240.607011] ? mark_page_accessed+0x133/0x200 [ 240.607685] ? __find_get_block+0xf8/0x3c0 [ 240.608318] ? map_id_range_down+0x195/0x1c0 [ 240.608977] ? ext4_es_lookup_extent+0xfc/0x2f0 [ 240.609672] ext4_map_blocks+0x683/0xa50 [ 240.610313] ? kasan_kmalloc+0xad/0xe0 [ 240.610899] ? ext4_issue_zeroout+0xa0/0xa0 [ 240.611548] ? wake_atomic_t_function+0xa0/0xa0 [ 240.612250] ? inode_sb_list_add+0x93/0xc0 [ 240.612888] ? inode_set_flags+0x2b/0x50 [ 240.613499] ext4_getblk+0xa6/0x2a0 [ 240.614045] ? ext4_iget+0x135e/0x16e0 [ 240.614642] ? ext4_iomap_begin+0x7a0/0x7a0 [ 240.615291] ext4_bread_batch+0x5c/0x1c0 [ 240.615904] ext4_xattr_inode_read+0x1d1/0x2f0 [ 240.616593] ? ext4_xattr_inode_free_quota.part.28+0x90/0x90 [ 240.617465] ? kasan_kmalloc+0xad/0xe0 [ 240.618050] ? __kmalloc+0x109/0x230 [ 240.618619] ? ext4_get_acl+0x63/0x2d0 [ 240.619204] ? get_acl+0xa3/0x140 [ 240.619727] ? generic_permission+0x192/0x1e0 [ 240.620403] ? inode_permission+0x46/0x1f0 [ 240.621040] ? may_open+0xd9/0x150 [ 240.621575] ? path_openat+0x47f/0x1e30 [ 240.622177] ? _cond_resched+0x1a/0x50 [ 240.622775] ? up_write+0x16/0x40 [ 240.623301] ? ext4_xattr_inode_iget+0xd2/0x200 [ 240.624008] ext4_xattr_inode_get+0x13a/0x430 [ 240.624684] ? ext4_xattr_release_block+0x3d0/0x3d0 [ 240.625442] ? mb_cache_entry_create+0x180/0x2c0 [ 240.626158] ? kasan_slab_free+0xe/0x10 [ 240.626770] ? kmem_cache_free+0x7c/0x1f0 [ 240.627400] ? strlen+0xf/0x40 [ 240.627886] ? xattr_find_entry+0xb0/0x140 [ 240.628531] ext4_xattr_get+0x4b6/0x4d0 [ 240.629136] ? ext4_xattr_ibody_get+0x320/0x320 [ 240.629844] ? __kmalloc+0x109/0x230 [ 240.630421] ext4_get_acl+0x8e/0x2d0 [ 240.630985] ? __d_rehash+0x89/0xb0 [ 240.631538] get_acl+0xa3/0x140 [ 240.632037] generic_permission+0x192/0x1e0 [ 240.632697] inode_permission+0x46/0x1f0 [ 240.633315] may_open+0xd9/0x150 [ 240.633828] path_openat+0x47f/0x1e30 [ 240.634416] ? __save_stack_trace+0x92/0x100 [ 240.635082] ? vfs_link+0x4e0/0x4e0 [ 240.635632] ? kasan_kmalloc+0xad/0xe0 [ 240.636219] ? kmem_cache_alloc+0xbb/0x1d0 [ 240.636859] ? getname_flags+0x76/0x2c0 [ 240.637458] ? getname+0x12/0x20 [ 240.637993] ? do_sys_open+0x14b/0x2c0 [ 240.638592] ? SyS_open+0x1e/0x20 [ 240.639116] ? do_syscall_64+0xf2/0x1f0 [ 240.639721] ? entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 240.640533] ? exit_to_usermode_loop+0xf2/0x100 [ 240.641238] ? do_syscall_64+0x1c0/0x1f0 [ 240.641854] ? entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 240.642676] ? __ext4_journal_stop+0xa0/0x100 [ 240.643357] do_filp_open+0x12b/0x1d0 [ 240.643933] ? may_open_dev+0x50/0x50 [ 240.644511] ? kasan_kmalloc+0xad/0xe0 [ 240.645101] do_sys_open+0x17c/0x2c0 [ 240.645664] ? do_sys_open+0x17c/0x2c0 [ 240.646263] ? filp_open+0x60/0x60 [ 240.646801] ? mem_cgroup_handle_over_high+0x21/0xd0 [ 240.647572] ? do_sys_open+0x2c0/0x2c0 [ 240.648175] SyS_open+0x1e/0x20 [ 240.648695] do_syscall_64+0xf2/0x1f0 [ 240.649287] entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 240.650066] RIP: 0033:0x7f979d764040 [ 240.650636] RSP: 002b:00007ffc945a5f88 EFLAGS: 00000246 ORIG_RAX: 0000000000000002 [ 240.651791] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f979d764040 [ 240.652878] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000002143080 [ 240.653960] RBP: 00007ffc945a60f0 R08: 00007f979da31bd8 R09: 0000000000000001 [ 240.655053] R10: 000000000000069d R11: 0000000000000246 R12: 0000000000400c20 [ 240.656136] R13: 00007ffc945a61f0 R14: 0000000000000000 R15: 0000000000000000 [ 240.657220] Code: ff ff ff 31 c0 5d c3 0f 1f 40 00 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 89 e5 53 48 89 fb 48 83 c7 60 e8 5a 63 f6 ff <8b> 43 60 85 c0 74 07 3e ff 4b 60 5b 5d c3 48 c7 c7 a0 21 51 94 [ 240.660183] RIP: __brelse+0x16/0x40 RSP: ffff88011392f190 [ 240.661063] ---[ end trace b32f37694f699b71 ]--- Reported by Wen Xu at SSlab, Gatech
Created attachment 275409 [details] poc.c
*** Bug 199989 has been marked as a duplicate of this bug. ***
(In reply to Theodore Tso from comment #2) > *** Bug 199989 has been marked as a duplicate of this bug. *** Hi Ted, Could you CC the patch of "ext4: verify the depth of extent tree in ext4_find_extent()" to me? I could not find this as you mentioned under bug 199989. Thanks, Wen
Yeah, sorry, I hadn't sent it out yet. I've been trying to send out fixes in batches, but then I made the mistake of trying to tackle #200015, which has been a real mess to analyze.
Fix is here: http://patchwork.ozlabs.org/patch/929744/
This issue has been assigned CVE-2018-10877 Red Hat Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1596795