lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:   Tue, 10 Jan 2023 19:49:19 +0800
From:   Baokun Li <libaokun1@...wei.com>
To:     Jan Kara <jack@...e.cz>
CC:     <linux-ext4@...r.kernel.org>, <tytso@....edu>,
        <adilger.kernel@...ger.ca>, <ritesh.list@...il.com>,
        <linux-kernel@...r.kernel.org>, <yi.zhang@...wei.com>,
        <yukuai3@...wei.com>,
        <syzbot+77d6fcc37bbb92f26048@...kaller.appspotmail.com>
Subject: Re: [PATCH] ext4: fix task hung in ext4_xattr_delete_inode

On 2023/1/10 19:34, Jan Kara wrote:
> On Tue 10-01-23 12:27:09, Baokun Li wrote:
>> Syzbot reported a hung task problem:
>> ==================================================================
>> INFO: task syz-executor232:5073 blocked for more than 143 seconds.
>>        Not tainted 6.2.0-rc2-syzkaller-00024-g512dee0c00ad #0
>> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
>> task:syz-exec232 state:D stack:21024 pid:5073 ppid:5072 flags:0x00004004
>> Call Trace:
>>   <TASK>
>>   context_switch kernel/sched/core.c:5244 [inline]
>>   __schedule+0x995/0xe20 kernel/sched/core.c:6555
>>   schedule+0xcb/0x190 kernel/sched/core.c:6631
>>   __wait_on_freeing_inode fs/inode.c:2196 [inline]
>>   find_inode_fast+0x35a/0x4c0 fs/inode.c:950
>>   iget_locked+0xb1/0x830 fs/inode.c:1273
>>   __ext4_iget+0x22e/0x3ed0 fs/ext4/inode.c:4861
>>   ext4_xattr_inode_iget+0x68/0x4e0 fs/ext4/xattr.c:389
>>   ext4_xattr_inode_dec_ref_all+0x1a7/0xe50 fs/ext4/xattr.c:1148
>>   ext4_xattr_delete_inode+0xb04/0xcd0 fs/ext4/xattr.c:2880
>>   ext4_evict_inode+0xd7c/0x10b0 fs/ext4/inode.c:296
>>   evict+0x2a4/0x620 fs/inode.c:664
>>   ext4_orphan_cleanup+0xb60/0x1340 fs/ext4/orphan.c:474
>>   __ext4_fill_super fs/ext4/super.c:5516 [inline]
>>   ext4_fill_super+0x81cd/0x8700 fs/ext4/super.c:5644
>>   get_tree_bdev+0x400/0x620 fs/super.c:1282
>>   vfs_get_tree+0x88/0x270 fs/super.c:1489
>>   do_new_mount+0x289/0xad0 fs/namespace.c:3145
>>   do_mount fs/namespace.c:3488 [inline]
>>   __do_sys_mount fs/namespace.c:3697 [inline]
>>   __se_sys_mount+0x2d3/0x3c0 fs/namespace.c:3674
>>   do_syscall_x64 arch/x86/entry/common.c:50 [inline]
>>   do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80
>>   entry_SYSCALL_64_after_hwframe+0x63/0xcd
>> RIP: 0033:0x7fa5406fd5ea
>> RSP: 002b:00007ffc7232f968 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5
>> RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fa5406fd5ea
>> RDX: 0000000020000440 RSI: 0000000020000000 RDI: 00007ffc7232f970
>> RBP: 00007ffc7232f970 R08: 00007ffc7232f9b0 R09: 0000000000000432
>> R10: 0000000000804a03 R11: 0000000000000202 R12: 0000000000000004
>> R13: 0000555556a7a2c0 R14: 00007ffc7232f9b0 R15: 0000000000000000
>>   </TASK>
>> ==================================================================
>>
>> The problem is that the inode contains an xattr entry with ea_inum of 15
>> when cleaning up an orphan inode <15>. When evict inode <15>, the reference
>> counting of the corresponding EA inode is decreased. When EA inode <15> is
>> found by find_inode_fast() in __ext4_iget(), it is found that the EA inode
>> holds the I_FREEING flag and waits for the EA inode to complete deletion.
>> As a result, when inode <15> is being deleted, we wait for inode <15> to
>> complete the deletion, resulting in an infinite loop and triggering Hung
>> Task. To solve this problem, we only need to check whether the ino of EA
>> inode and parent is the same before getting EA inode.
>>
>> Link: https://syzkaller.appspot.com/bug?extid=77d6fcc37bbb92f26048
>> Reported-by: syzbot+77d6fcc37bbb92f26048@...kaller.appspotmail.com
>> Signed-off-by: Baokun Li <libaokun1@...wei.com>
>> ---
>>   fs/ext4/xattr.c | 7 +++++++
>>   1 file changed, 7 insertions(+)
>>
>> diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
>> index 7decaaf27e82..9ff8fcf78bb8 100644
>> --- a/fs/ext4/xattr.c
>> +++ b/fs/ext4/xattr.c
>> @@ -386,6 +386,13 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino,
>>   	struct inode *inode;
>>   	int err;
>>   
> Perhaps add a comment here like:
>
> 	/*
> 	 * We have to check for this corruption early as otherwise
> 	 * iget_locked() could wait indefinitely for the state of our
> 	 * parent inode.
> 	 */
Totally agree! Very accurate comment!
>> +	if (parent->i_ino == ea_ino) {
>> +		ext4_error(parent->i_sb,
>> +			   "Parent and EA inode have the same ino %lu", ea_ino);
>> +		err = -EUCLEAN;
> 			^^ I prefer -EFSCORRUPTED here. It is the same
> value but more descriptive name :).
OK! I will replace EUCLEAN with EFSCORRUPTED in v2.
>> +		goto error;
> 		^^ Just "return err" here. This will try to iput()
> uninitialized pointer.
>
> 								Honza
>
Indeed! I'm sorry I didn't notice this uninitialized variable.

Thank you very much for your review!
I will send a patch V2 with the changes suggested by you.
-- 
With Best Regards,
Baokun Li
.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ