Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752188AbaGVC3d (ORCPT ); Mon, 21 Jul 2014 22:29:33 -0400 Received: from cn.fujitsu.com ([59.151.112.132]:31976 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1751139AbaGVC3c (ORCPT ); Mon, 21 Jul 2014 22:29:32 -0400 X-IronPort-AV: E=Sophos;i="5.00,931,1396972800"; d="scan'208";a="33607621" Message-ID: <53CDC9AF.2050605@cn.fujitsu.com> Date: Tue, 22 Jul 2014 10:17:19 +0800 From: Gu Zheng User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20110930 Thunderbird/7.0.1 MIME-Version: 1.0 To: Andrey Tsyvarev CC: Jaegeuk Kim , , linux-kernel , Alexey Khoroshilov Subject: Re: f2fs: Possible use-after-free when umount filesystem References: <52F320FC.50803@ispras.ru> <534BC29B.3020408@ispras.ru> <53CCF1EC.30008@ispras.ru> In-Reply-To: <53CCF1EC.30008@ispras.ru> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Originating-IP: [10.167.226.100] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Andrey, On 07/21/2014 06:56 PM, Andrey Tsyvarev wrote: > Hello, > > Using memory error detector reveals the following use-after-free error in 3.15.0: > > AddressSanitizer: heap-use-after-free in f2fs_evict_inode > Read of size 8 by thread T22279: > [] f2fs_evict_inode+0x102/0x2e0 [f2fs] /home/tester/linux-sources/linux-kasan/fs/f2fs/f2fs.h:584 > [] evict+0x15f/0x290 /home/tester/linux-sources/linux-kasan/fs/inode.c:550 > [< inlined >] iput+0x196/0x280 iput_final /home/tester/linux-sources/linux-kasan/fs/inode.c:1418 > [] iput+0x196/0x280 /home/tester/linux-sources/linux-kasan/fs/inode.c:1436 > [] f2fs_put_super+0xd6/0x170 [f2fs] /home/tester/linux-sources/linux-kasan/fs/f2fs/super.c:434 > [] generic_shutdown_super+0xc5/0x1b0 /home/tester/linux-sources/linux-kasan/fs/super.c:406 > [] kill_block_super+0x4d/0xb0 /home/tester/linux-sources/linux-kasan/fs/super.c:1019 > [] deactivate_locked_super+0x66/0x80 /home/tester/linux-sources/linux-kasan/fs/super.c:284 > [] deactivate_super+0x68/0x80 /home/tester/linux-sources/linux-kasan/fs/super.c:307 > [] mntput_no_expire+0x198/0x250 /home/tester/linux-sources/linux-kasan/fs/namespace.c:986 (discriminator 3) > [< inlined >] SyS_umount+0xe9/0x1a0 SYSC_umount /home/tester/linux-sources/linux-kasan/fs/namespace.c:1424 > [] SyS_umount+0xe9/0x1a0 /home/tester/linux-sources/linux-kasan/fs/namespace.c:1392 > [] system_call_fastpath+0x16/0x1b /home/tester/linux-sources/linux-kasan/arch/x86/kernel/entry_64.S:426 > > Freed by thread T3: > [] f2fs_i_callback+0x27/0x30 [f2fs] /home/tester/linux-sources/linux-kasan/fs/f2fs/super.c:408 > [< inlined >] rcu_process_callbacks+0x2d6/0x930 __rcu_reclaim /home/tester/linux-sources/linux-kasan/kernel/rcu/rcu.h:114 > [< inlined >] rcu_process_callbacks+0x2d6/0x930 rcu_do_batch /home/tester/linux-sources/linux-kasan/kernel/rcu/tree.c:2242 > [< inlined >] rcu_process_callbacks+0x2d6/0x930 invoke_rcu_callbacks /home/tester/linux-sources/linux-kasan/kernel/rcu/tree.c:2499 > [< inlined >] rcu_process_callbacks+0x2d6/0x930 __rcu_process_callbacks /home/tester/linux-sources/linux-kasan/kernel/rcu/tree.c:2466 > [] rcu_process_callbacks+0x2d6/0x930 /home/tester/linux-sources/linux-kasan/kernel/rcu/tree.c:2483 > [] __do_softirq+0x142/0x380 /home/tester/linux-sources/linux-kasan/kernel/softirq.c:269 > [] run_ksoftirqd+0x30/0x50 /home/tester/linux-sources/linux-kasan/kernel/softirq.c:658 > [] smpboot_thread_fn+0x197/0x280 /home/tester/linux-sources/linux-kasan/kernel/smpboot.c:160 > [] kthread+0x148/0x160 /home/tester/linux-sources/linux-kasan/kernel/kthread.c:207 > [] ret_from_fork+0x7c/0xb0 /home/tester/linux-sources/linux-kasan/arch/x86/kernel/entry_64.S:351 > > Allocated by thread T22276: > [] f2fs_alloc_inode+0x2d/0x170 [f2fs] /home/tester/linux-sources/linux-kasan/fs/f2fs/super.c:356 > [] alloc_inode+0x2d/0xe0 /home/tester/linux-sources/linux-kasan/fs/inode.c:208 > [] iget_locked+0x10a/0x230 /home/tester/linux-sources/linux-kasan/fs/inode.c:1085 > [] f2fs_iget+0x35/0xa80 [f2fs] /home/tester/linux-sources/linux-kasan/fs/f2fs/inode.c:129 > [] f2fs_fill_super+0xb53/0xff0 [f2fs] /home/tester/linux-sources/linux-kasan/fs/f2fs/super.c:1021 > [] mount_bdev+0x1de/0x240 /home/tester/linux-sources/linux-kasan/fs/super.c:992 > [] f2fs_mount+0x10/0x20 [f2fs] /home/tester/linux-sources/linux-kasan/fs/f2fs/super.c:1127 > [] mount_fs+0x55/0x220 /home/tester/linux-sources/linux-kasan/fs/super.c:1095 > [] vfs_kern_mount+0x66/0x200 /home/tester/linux-sources/linux-kasan/fs/namespace.c:851 > [< inlined >] do_mount+0x2b4/0x1120 do_new_mount /home/tester/linux-sources/linux-kasan/fs/namespace.c:2129 > [] do_mount+0x2b4/0x1120 /home/tester/linux-sources/linux-kasan/fs/namespace.c:2453 > [< inlined >] SyS_mount+0xb2/0x110 SYSC_mount /home/tester/linux-sources/linux-kasan/fs/namespace.c:2647 > [] SyS_mount+0xb2/0x110 /home/tester/linux-sources/linux-kasan/fs/namespace.c:2620 > [] system_call_fastpath+0x16/0x1b /home/tester/linux-sources/linux-kasan/arch/x86/kernel/entry_64.S:426 > > The buggy address ffff8800587866c8 is located 48 bytes inside > of 680-byte region [ffff880058786698, ffff880058786940) > > Memory state around the buggy address: > ffff880058786100: ffffffff ffffffff ffffffff ffffffff > ffff880058786200: ffffffff ffffffff ffffffrr rrrrrrrr > ffff880058786300: rrrrrrrr rrffffff ffffffff ffffffff > ffff880058786400: ffffffff ffffffff ffffffff ffffffff > ffff880058786500: ffffffff ffffffff ffffffff fffffffr >>ffff880058786600: rrrrrrrr rrrrrrrr rrrfffff ffffffff > ^ > ffff880058786700: ffffffff ffffffff ffffffff ffffffff > ffff880058786800: ffffffff ffffffff ffffffff ffffffff > ffff880058786900: ffffffff rrrrrrrr rrrrrrrr rrrr.... > ffff880058786a00: ........ ........ ........ ........ > ffff880058786b00: ........ ........ ........ ........ > Legend: > f - 8 freed bytes > r - 8 redzone bytes > . - 8 allocated bytes > x=1..7 - x allocated bytes + (8-x) redzone bytes > > > Investigation shows, that f2fs_evict_inode, when called for 'meta_inode', uses invalidate_mapping_pages() for 'node_inode'. > But 'node_inode' is deleted before 'meta_inode' in f2fs_put_super via iput(). > > It seems that in common usage scenario this use-after-free is benign, because 'node_inode' remains partially valid data even after kmem_cache_free(). > But things may change if, while 'meta_inode' is evicted in one f2fs filesystem, another (mounted) f2fs filesystem requests inode from cache, and formely > 'node_inode' of the first filesystem is returned. The analysis seems reasonable. Have you tried to swap the reclaim order of node_inde and meta_inode? diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 870fe19..e114418 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -430,8 +430,8 @@ static void f2fs_put_super(struct super_block *sb) if (sbi->s_dirty && get_pages(sbi, F2FS_DIRTY_NODES)) write_checkpoint(sbi, true); - iput(sbi->node_inode); iput(sbi->meta_inode); + iput(sbi->node_inode); /* destroy f2fs internal modules */ destroy_node_manager(sbi); Thanks, Gu > > > Found by Linux File System Verification project (linuxtesting.org). > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/