Message ID | 20221201084844.2855621-1-yebin@huaweicloud.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp142149wrr; Thu, 1 Dec 2022 00:30:31 -0800 (PST) X-Google-Smtp-Source: AA0mqf60qVIeGqbaucOWuAD1jIfV4UIeJGhMRYeFWoU5FLY9c7HUrpt0vyZkp0N5lL3HN51Jd8nr X-Received: by 2002:a17:90a:6508:b0:213:3918:f2a2 with SMTP id i8-20020a17090a650800b002133918f2a2mr75455653pjj.218.1669883431110; Thu, 01 Dec 2022 00:30:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669883431; cv=none; d=google.com; s=arc-20160816; b=iw8O05UncV6m55J/AdSJYj9xKrpvpFbKfZkO8aPmqbFGnlSbHGF1xeRulgN01JRPS/ u/vjz6JL8NIlkQmKxI6654QDxw2CUG5aUyrFe+3ZxCXh3fAhOGk4pCvHvBRnh8CHe/bY r37BBZKFo+bEBu+8t4rsWwJneLjXBfB1+3JHSmhrfc4X+LJAgn2UwDGS+LaUdpdY9BI9 DZzTzSJopMHt0mgXxrJis9G2HS9dOxOU2+AQVzSEALSGAl6HsdF6jFu2aOkw10U/rf02 ohOEcv9fM6d7VQZ15GyzRDC+dua19gQ8BL+TXMzf6t+5JXxonH/tBgI59MlFmsKq+wTT mT8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=h64WIPNSl8HYj+1D540PRZFmtEvaapg77XuAqmrH9MQ=; b=qKgn1xqPBGky9DByzonDagOG04521M6VXPMBrM2nRdsh6b/V+/ao0avPeBNR/mHLzN d3v6kVhTLKFzaHpwnOkitZ+WcscskxAaGyWaCF28sr1QgYTdLYqH4H4GXZNP668SLv07 OXqKQXowzU7NznD3UxIj6d4wWB9RjXOAGt234xwqvDI73ho2s6zGrazPXa8v4eYb9rQl ZCvT9AD4O9ujihaGwm7Ga6aml6ELlueRDY0KDb5TqxJEmIDjp/2+3mqXEpLs/Z1ZI4/O euePs+GXGmxqijc2n3SkAuK32Af580lEUrsMNar6tMmcFXq6mLDrQi62fdmZjgUl9VHQ +eBQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id r24-20020a63e518000000b0045ff35cf428si3697645pgh.294.2022.12.01.00.30.17; Thu, 01 Dec 2022 00:30:31 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229668AbiLAI2U (ORCPT <rfc822;heyuhang3455@gmail.com> + 99 others); Thu, 1 Dec 2022 03:28:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57800 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229898AbiLAI14 (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 1 Dec 2022 03:27:56 -0500 Received: from dggsgout12.his.huawei.com (dggsgout12.his.huawei.com [45.249.212.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8DCDF1A20D; Thu, 1 Dec 2022 00:27:45 -0800 (PST) Received: from mail02.huawei.com (unknown [172.30.67.169]) by dggsgout12.his.huawei.com (SkyGuard) with ESMTP id 4NN8Mc2ZHDz4f3nps; Thu, 1 Dec 2022 16:27:40 +0800 (CST) Received: from huaweicloud.com (unknown [10.175.127.227]) by APP2 (Coremail) with SMTP id Syh0CgCnCrZ9ZYhjeFPFBQ--.33056S4; Thu, 01 Dec 2022 16:27:42 +0800 (CST) From: Ye Bin <yebin@huaweicloud.com> To: tytso@mit.edu, adilger.kernel@dilger.ca, linux-ext4@vger.kernel.org Cc: linux-kernel@vger.kernel.org, jack@suse.cz, Ye Bin <yebin10@huawei.com>, syzbot+4d99a966fd74bdeeec36@syzkaller.appspotmail.com Subject: [PATCH] ext4: fix WARNING in ext4_expand_extra_isize_ea Date: Thu, 1 Dec 2022 16:48:44 +0800 Message-Id: <20221201084844.2855621-1-yebin@huaweicloud.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID: Syh0CgCnCrZ9ZYhjeFPFBQ--.33056S4 X-Coremail-Antispam: 1UD129KBjvJXoWxGrW3JFy5KrWkJr4rZr4kXrb_yoWruF4Dpw 43Ary7Cr48WF9rCFs7AFy8twn8Wwn3CF4UJrWxWr1kZFy7Xw1xKFZ5Kr43XFy8trW8Jry2 qFn8tw1rKw15G3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUkYb4IE77IF4wAFF20E14v26r4j6ryUM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4 vEj48ve4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7Cj xVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x 0267AKxVW0oVCq3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG 6I80ewAv7VC0I7IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFV Cjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI 7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxV Cjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY 6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6x AIw20EY4v20xvaj40_Wr1j6rW3Jr1lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280 aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7IUbmii3UUUUU== X-CM-SenderInfo: p1hex046kxt4xhlfz01xgou0bp/ X-CFilter-Loop: Reflected X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1750999688678849807?= X-GMAIL-MSGID: =?utf-8?q?1750999688678849807?= |
Series |
ext4: fix WARNING in ext4_expand_extra_isize_ea
|
|
Commit Message
Ye Bin
Dec. 1, 2022, 8:48 a.m. UTC
From: Ye Bin <yebin10@huawei.com> Syzbot found the following issue: ------------[ cut here ]------------ WARNING: CPU: 1 PID: 3631 at mm/page_alloc.c:5534 __alloc_pages+0x30a/0x560 mm/page_alloc.c:5534 Modules linked in: CPU: 1 PID: 3631 Comm: syz-executor261 Not tainted 6.1.0-rc6-syzkaller-00308-g644e9524388a #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 RIP: 0010:__alloc_pages+0x30a/0x560 mm/page_alloc.c:5534 RSP: 0018:ffffc90003ccf080 EFLAGS: 00010246 RAX: ffffc90003ccf0e0 RBX: 000000000000000c RCX: 0000000000000000 RDX: 0000000000000028 RSI: 0000000000000000 RDI: ffffc90003ccf108 RBP: ffffc90003ccf198 R08: dffffc0000000000 R09: ffffc90003ccf0e0 R10: fffff52000799e21 R11: 1ffff92000799e1c R12: 0000000000040c40 R13: 1ffff92000799e18 R14: dffffc0000000000 R15: 1ffff92000799e14 FS: 0000555555c10300(0000) GS:ffff8880b9900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffc36f70000 CR3: 00000000744ad000 CR4: 00000000003506e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> __alloc_pages_node include/linux/gfp.h:223 [inline] alloc_pages_node include/linux/gfp.h:246 [inline] __kmalloc_large_node+0x8a/0x1a0 mm/slab_common.c:1096 __do_kmalloc_node mm/slab_common.c:943 [inline] __kmalloc+0xfe/0x1a0 mm/slab_common.c:968 kmalloc include/linux/slab.h:558 [inline] ext4_xattr_move_to_block fs/ext4/xattr.c:2558 [inline] ext4_xattr_make_inode_space fs/ext4/xattr.c:2673 [inline] ext4_expand_extra_isize_ea+0xe3f/0x1cd0 fs/ext4/xattr.c:2765 __ext4_expand_extra_isize+0x2b8/0x3f0 fs/ext4/inode.c:5857 ext4_try_to_expand_extra_isize fs/ext4/inode.c:5900 [inline] __ext4_mark_inode_dirty+0x51a/0x670 fs/ext4/inode.c:5978 ext4_inline_data_truncate+0x548/0xd00 fs/ext4/inline.c:2021 ext4_truncate+0x341/0xeb0 fs/ext4/inode.c:4221 ext4_process_orphan+0x1aa/0x2d0 fs/ext4/orphan.c:339 ext4_orphan_cleanup+0xb60/0x1340 fs/ext4/orphan.c:474 __ext4_fill_super fs/ext4/super.c:5515 [inline] ext4_fill_super+0x80ed/0x8610 fs/ext4/super.c:5643 get_tree_bdev+0x400/0x620 fs/super.c:1324 vfs_get_tree+0x88/0x270 fs/super.c:1531 do_new_mount+0x289/0xad0 fs/namespace.c:3040 do_mount fs/namespace.c:3383 [inline] __do_sys_mount fs/namespace.c:3591 [inline] __se_sys_mount+0x2d3/0x3c0 fs/namespace.c:3568 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 </TASK> Reason is allocate 16M memory by kmalloc, but MAX_ORDER is 11, kmalloc can allocate maxium size memory is 4M. XATTR_SIZE_MAX is currently 64k, but EXT4_XATTR_SIZE_MAX is '(1 << 24)', so 'ext4_xattr_check_entries()' regards this length as legal. Then trigger warning in 'ext4_xattr_move_to_block()'. To solve above issue, adjust EXT4_XATTR_SIZE_MAX to '(1 << 22)' which is kmalloc can allocate maxium size. Reported-by: syzbot+4d99a966fd74bdeeec36@syzkaller.appspotmail.com Fixes: 54dd0e0a1b25 ("ext4: add extra checks to ext4_xattr_block_get()") Signed-off-by: Ye Bin <yebin10@huawei.com> --- fs/ext4/xattr.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
Comments
Hello! On Thu 01-12-22 16:48:44, Ye Bin wrote: > From: Ye Bin <yebin10@huawei.com> > > Syzbot found the following issue: > ------------[ cut here ]------------ > WARNING: CPU: 1 PID: 3631 at mm/page_alloc.c:5534 __alloc_pages+0x30a/0x560 mm/page_alloc.c:5534 > Modules linked in: > CPU: 1 PID: 3631 Comm: syz-executor261 Not tainted 6.1.0-rc6-syzkaller-00308-g644e9524388a #0 > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 > RIP: 0010:__alloc_pages+0x30a/0x560 mm/page_alloc.c:5534 > RSP: 0018:ffffc90003ccf080 EFLAGS: 00010246 > RAX: ffffc90003ccf0e0 RBX: 000000000000000c RCX: 0000000000000000 > RDX: 0000000000000028 RSI: 0000000000000000 RDI: ffffc90003ccf108 > RBP: ffffc90003ccf198 R08: dffffc0000000000 R09: ffffc90003ccf0e0 > R10: fffff52000799e21 R11: 1ffff92000799e1c R12: 0000000000040c40 > R13: 1ffff92000799e18 R14: dffffc0000000000 R15: 1ffff92000799e14 > FS: 0000555555c10300(0000) GS:ffff8880b9900000(0000) knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 00007ffc36f70000 CR3: 00000000744ad000 CR4: 00000000003506e0 > DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 > DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 > Call Trace: > <TASK> > __alloc_pages_node include/linux/gfp.h:223 [inline] > alloc_pages_node include/linux/gfp.h:246 [inline] > __kmalloc_large_node+0x8a/0x1a0 mm/slab_common.c:1096 > __do_kmalloc_node mm/slab_common.c:943 [inline] > __kmalloc+0xfe/0x1a0 mm/slab_common.c:968 > kmalloc include/linux/slab.h:558 [inline] > ext4_xattr_move_to_block fs/ext4/xattr.c:2558 [inline] > ext4_xattr_make_inode_space fs/ext4/xattr.c:2673 [inline] > ext4_expand_extra_isize_ea+0xe3f/0x1cd0 fs/ext4/xattr.c:2765 > __ext4_expand_extra_isize+0x2b8/0x3f0 fs/ext4/inode.c:5857 > ext4_try_to_expand_extra_isize fs/ext4/inode.c:5900 [inline] > __ext4_mark_inode_dirty+0x51a/0x670 fs/ext4/inode.c:5978 > ext4_inline_data_truncate+0x548/0xd00 fs/ext4/inline.c:2021 > ext4_truncate+0x341/0xeb0 fs/ext4/inode.c:4221 > ext4_process_orphan+0x1aa/0x2d0 fs/ext4/orphan.c:339 > ext4_orphan_cleanup+0xb60/0x1340 fs/ext4/orphan.c:474 > __ext4_fill_super fs/ext4/super.c:5515 [inline] > ext4_fill_super+0x80ed/0x8610 fs/ext4/super.c:5643 > get_tree_bdev+0x400/0x620 fs/super.c:1324 > vfs_get_tree+0x88/0x270 fs/super.c:1531 > do_new_mount+0x289/0xad0 fs/namespace.c:3040 > do_mount fs/namespace.c:3383 [inline] > __do_sys_mount fs/namespace.c:3591 [inline] > __se_sys_mount+0x2d3/0x3c0 fs/namespace.c:3568 > 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 > </TASK> > > Reason is allocate 16M memory by kmalloc, but MAX_ORDER is 11, kmalloc > can allocate maxium size memory is 4M. > XATTR_SIZE_MAX is currently 64k, but EXT4_XATTR_SIZE_MAX is '(1 << 24)', > so 'ext4_xattr_check_entries()' regards this length as legal. Then trigger > warning in 'ext4_xattr_move_to_block()'. > To solve above issue, adjust EXT4_XATTR_SIZE_MAX to '(1 << 22)' which > is kmalloc can allocate maxium size. > > Reported-by: syzbot+4d99a966fd74bdeeec36@syzkaller.appspotmail.com > Fixes: 54dd0e0a1b25 ("ext4: add extra checks to ext4_xattr_block_get()") > Signed-off-by: Ye Bin <yebin10@huawei.com> Thanks for the report and the fix but I think it is actually wrong. We cannot just change EXT4_XATTR_SIZE_MAX because there may be already filesystems with this large extended attributes and we'd be suddently unable to read them. So a better fix would be to use kvmalloc() to allocate the memory which is able to accommodate arbitrary allocation size. Arguably, even better might be to make ext4_xattr_move_to_block() more clever because currently it loads attribute into memory from the inode only to store it there again. We could just create xattr entry in the block and be done with it. But it will be more complex and maybe it's not worth it... Honza > --- > fs/ext4/xattr.h | 11 ++++++----- > 1 file changed, 6 insertions(+), 5 deletions(-) > > diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h > index 824faf0b15a8..22f0c89b1184 100644 > --- a/fs/ext4/xattr.h > +++ b/fs/ext4/xattr.h > @@ -75,11 +75,12 @@ struct ext4_xattr_entry { > * for file system consistency errors, we use a somewhat bigger value. > * This allows XATTR_SIZE_MAX to grow in the future, but by using this > * instead of INT_MAX for certain consistency checks, we don't need to > - * worry about arithmetic overflows. (Actually XATTR_SIZE_MAX is > - * defined in include/uapi/linux/limits.h, so changing it is going > - * not going to be trivial....) > - */ > -#define EXT4_XATTR_SIZE_MAX (1 << 24) > + * worry about arithmetic overflows. Now, MAX_ORDER is 11 kmalloc can > + * allocate maxium size is 4M. (Actually XATTR_SIZE_MAX is defined in > + * include/uapi/linux/limits.h, so changing it is going not going to > + * be trivial....) > + */ > +#define EXT4_XATTR_SIZE_MAX (1 << 22) > > /* > * The minimum size of EA value when you start storing it in an external inode > -- > 2.31.1 >
On 2022/12/1 20:19, Jan Kara wrote: > Hello! > > On Thu 01-12-22 16:48:44, Ye Bin wrote: >> From: Ye Bin <yebin10@huawei.com> >> >> Syzbot found the following issue: >> ------------[ cut here ]------------ >> WARNING: CPU: 1 PID: 3631 at mm/page_alloc.c:5534 __alloc_pages+0x30a/0x560 mm/page_alloc.c:5534 >> Modules linked in: >> CPU: 1 PID: 3631 Comm: syz-executor261 Not tainted 6.1.0-rc6-syzkaller-00308-g644e9524388a #0 >> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 >> RIP: 0010:__alloc_pages+0x30a/0x560 mm/page_alloc.c:5534 >> RSP: 0018:ffffc90003ccf080 EFLAGS: 00010246 >> RAX: ffffc90003ccf0e0 RBX: 000000000000000c RCX: 0000000000000000 >> RDX: 0000000000000028 RSI: 0000000000000000 RDI: ffffc90003ccf108 >> RBP: ffffc90003ccf198 R08: dffffc0000000000 R09: ffffc90003ccf0e0 >> R10: fffff52000799e21 R11: 1ffff92000799e1c R12: 0000000000040c40 >> R13: 1ffff92000799e18 R14: dffffc0000000000 R15: 1ffff92000799e14 >> FS: 0000555555c10300(0000) GS:ffff8880b9900000(0000) knlGS:0000000000000000 >> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 >> CR2: 00007ffc36f70000 CR3: 00000000744ad000 CR4: 00000000003506e0 >> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 >> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 >> Call Trace: >> <TASK> >> __alloc_pages_node include/linux/gfp.h:223 [inline] >> alloc_pages_node include/linux/gfp.h:246 [inline] >> __kmalloc_large_node+0x8a/0x1a0 mm/slab_common.c:1096 >> __do_kmalloc_node mm/slab_common.c:943 [inline] >> __kmalloc+0xfe/0x1a0 mm/slab_common.c:968 >> kmalloc include/linux/slab.h:558 [inline] >> ext4_xattr_move_to_block fs/ext4/xattr.c:2558 [inline] >> ext4_xattr_make_inode_space fs/ext4/xattr.c:2673 [inline] >> ext4_expand_extra_isize_ea+0xe3f/0x1cd0 fs/ext4/xattr.c:2765 >> __ext4_expand_extra_isize+0x2b8/0x3f0 fs/ext4/inode.c:5857 >> ext4_try_to_expand_extra_isize fs/ext4/inode.c:5900 [inline] >> __ext4_mark_inode_dirty+0x51a/0x670 fs/ext4/inode.c:5978 >> ext4_inline_data_truncate+0x548/0xd00 fs/ext4/inline.c:2021 >> ext4_truncate+0x341/0xeb0 fs/ext4/inode.c:4221 >> ext4_process_orphan+0x1aa/0x2d0 fs/ext4/orphan.c:339 >> ext4_orphan_cleanup+0xb60/0x1340 fs/ext4/orphan.c:474 >> __ext4_fill_super fs/ext4/super.c:5515 [inline] >> ext4_fill_super+0x80ed/0x8610 fs/ext4/super.c:5643 >> get_tree_bdev+0x400/0x620 fs/super.c:1324 >> vfs_get_tree+0x88/0x270 fs/super.c:1531 >> do_new_mount+0x289/0xad0 fs/namespace.c:3040 >> do_mount fs/namespace.c:3383 [inline] >> __do_sys_mount fs/namespace.c:3591 [inline] >> __se_sys_mount+0x2d3/0x3c0 fs/namespace.c:3568 >> 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 >> </TASK> >> >> Reason is allocate 16M memory by kmalloc, but MAX_ORDER is 11, kmalloc >> can allocate maxium size memory is 4M. >> XATTR_SIZE_MAX is currently 64k, but EXT4_XATTR_SIZE_MAX is '(1 << 24)', >> so 'ext4_xattr_check_entries()' regards this length as legal. Then trigger >> warning in 'ext4_xattr_move_to_block()'. >> To solve above issue, adjust EXT4_XATTR_SIZE_MAX to '(1 << 22)' which >> is kmalloc can allocate maxium size. >> >> Reported-by: syzbot+4d99a966fd74bdeeec36@syzkaller.appspotmail.com >> Fixes: 54dd0e0a1b25 ("ext4: add extra checks to ext4_xattr_block_get()") >> Signed-off-by: Ye Bin <yebin10@huawei.com> > Thanks for the report and the fix but I think it is actually wrong. We > cannot just change EXT4_XATTR_SIZE_MAX because there may be already > filesystems with this large extended attributes and we'd be suddently Firstly, thanks for your advice. I have a question. Since the Linux-2.6.12-rc2 version, XATTR can only be set to 64K at most. I understand that no file's extended attribute exceeds 64K. > unable to read them. So a better fix would be to use kvmalloc() to allocate > the memory which is able to accommodate arbitrary allocation size. > > Arguably, even better might be to make ext4_xattr_move_to_block() more > clever because currently it loads attribute into memory from the inode only > to store it there again. We could just create xattr entry in the block and > be done with it. But it will be more complex and maybe it's not worth it... > > Honza > >> --- >> fs/ext4/xattr.h | 11 ++++++----- >> 1 file changed, 6 insertions(+), 5 deletions(-) >> >> diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h >> index 824faf0b15a8..22f0c89b1184 100644 >> --- a/fs/ext4/xattr.h >> +++ b/fs/ext4/xattr.h >> @@ -75,11 +75,12 @@ struct ext4_xattr_entry { >> * for file system consistency errors, we use a somewhat bigger value. >> * This allows XATTR_SIZE_MAX to grow in the future, but by using this >> * instead of INT_MAX for certain consistency checks, we don't need to >> - * worry about arithmetic overflows. (Actually XATTR_SIZE_MAX is >> - * defined in include/uapi/linux/limits.h, so changing it is going >> - * not going to be trivial....) >> - */ >> -#define EXT4_XATTR_SIZE_MAX (1 << 24) >> + * worry about arithmetic overflows. Now, MAX_ORDER is 11 kmalloc can >> + * allocate maxium size is 4M. (Actually XATTR_SIZE_MAX is defined in >> + * include/uapi/linux/limits.h, so changing it is going not going to >> + * be trivial....) >> + */ >> +#define EXT4_XATTR_SIZE_MAX (1 << 22) >> >> /* >> * The minimum size of EA value when you start storing it in an external inode >> -- >> 2.31.1 >>
On Thu 01-12-22 21:25:07, yebin (H) wrote: > > > On 2022/12/1 20:19, Jan Kara wrote: > > Hello! > > > > On Thu 01-12-22 16:48:44, Ye Bin wrote: > > > From: Ye Bin <yebin10@huawei.com> > > > > > > Syzbot found the following issue: > > > ------------[ cut here ]------------ > > > WARNING: CPU: 1 PID: 3631 at mm/page_alloc.c:5534 __alloc_pages+0x30a/0x560 mm/page_alloc.c:5534 > > > Modules linked in: > > > CPU: 1 PID: 3631 Comm: syz-executor261 Not tainted 6.1.0-rc6-syzkaller-00308-g644e9524388a #0 > > > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 > > > RIP: 0010:__alloc_pages+0x30a/0x560 mm/page_alloc.c:5534 > > > RSP: 0018:ffffc90003ccf080 EFLAGS: 00010246 > > > RAX: ffffc90003ccf0e0 RBX: 000000000000000c RCX: 0000000000000000 > > > RDX: 0000000000000028 RSI: 0000000000000000 RDI: ffffc90003ccf108 > > > RBP: ffffc90003ccf198 R08: dffffc0000000000 R09: ffffc90003ccf0e0 > > > R10: fffff52000799e21 R11: 1ffff92000799e1c R12: 0000000000040c40 > > > R13: 1ffff92000799e18 R14: dffffc0000000000 R15: 1ffff92000799e14 > > > FS: 0000555555c10300(0000) GS:ffff8880b9900000(0000) knlGS:0000000000000000 > > > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > > > CR2: 00007ffc36f70000 CR3: 00000000744ad000 CR4: 00000000003506e0 > > > DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 > > > DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 > > > Call Trace: > > > <TASK> > > > __alloc_pages_node include/linux/gfp.h:223 [inline] > > > alloc_pages_node include/linux/gfp.h:246 [inline] > > > __kmalloc_large_node+0x8a/0x1a0 mm/slab_common.c:1096 > > > __do_kmalloc_node mm/slab_common.c:943 [inline] > > > __kmalloc+0xfe/0x1a0 mm/slab_common.c:968 > > > kmalloc include/linux/slab.h:558 [inline] > > > ext4_xattr_move_to_block fs/ext4/xattr.c:2558 [inline] > > > ext4_xattr_make_inode_space fs/ext4/xattr.c:2673 [inline] > > > ext4_expand_extra_isize_ea+0xe3f/0x1cd0 fs/ext4/xattr.c:2765 > > > __ext4_expand_extra_isize+0x2b8/0x3f0 fs/ext4/inode.c:5857 > > > ext4_try_to_expand_extra_isize fs/ext4/inode.c:5900 [inline] > > > __ext4_mark_inode_dirty+0x51a/0x670 fs/ext4/inode.c:5978 > > > ext4_inline_data_truncate+0x548/0xd00 fs/ext4/inline.c:2021 > > > ext4_truncate+0x341/0xeb0 fs/ext4/inode.c:4221 > > > ext4_process_orphan+0x1aa/0x2d0 fs/ext4/orphan.c:339 > > > ext4_orphan_cleanup+0xb60/0x1340 fs/ext4/orphan.c:474 > > > __ext4_fill_super fs/ext4/super.c:5515 [inline] > > > ext4_fill_super+0x80ed/0x8610 fs/ext4/super.c:5643 > > > get_tree_bdev+0x400/0x620 fs/super.c:1324 > > > vfs_get_tree+0x88/0x270 fs/super.c:1531 > > > do_new_mount+0x289/0xad0 fs/namespace.c:3040 > > > do_mount fs/namespace.c:3383 [inline] > > > __do_sys_mount fs/namespace.c:3591 [inline] > > > __se_sys_mount+0x2d3/0x3c0 fs/namespace.c:3568 > > > 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 > > > </TASK> > > > > > > Reason is allocate 16M memory by kmalloc, but MAX_ORDER is 11, kmalloc > > > can allocate maxium size memory is 4M. > > > XATTR_SIZE_MAX is currently 64k, but EXT4_XATTR_SIZE_MAX is '(1 << 24)', > > > so 'ext4_xattr_check_entries()' regards this length as legal. Then trigger > > > warning in 'ext4_xattr_move_to_block()'. > > > To solve above issue, adjust EXT4_XATTR_SIZE_MAX to '(1 << 22)' which > > > is kmalloc can allocate maxium size. > > > > > > Reported-by: syzbot+4d99a966fd74bdeeec36@syzkaller.appspotmail.com > > > Fixes: 54dd0e0a1b25 ("ext4: add extra checks to ext4_xattr_block_get()") > > > Signed-off-by: Ye Bin <yebin10@huawei.com> > > Thanks for the report and the fix but I think it is actually wrong. We > > cannot just change EXT4_XATTR_SIZE_MAX because there may be already > > filesystems with this large extended attributes and we'd be suddently > Firstly, thanks for your advice. > I have a question. Since the Linux-2.6.12-rc2 version, XATTR can only be set > to 64K > at most. I understand that no file's extended attribute exceeds 64K. You're right that VFS actually limits xattr size to 64k. So the chances that someone actually has filesystem with larger xattrs are slim. But I know that Lustre guys run with their modified kernels and they were the ones implementing ea_inode feature so maybe they'd bumped the VFS limit as well in their kernels. Dunno. Anyway using kvmalloc() (like the xattr core does) looks like a better fix. Honza
On Thu, Dec 01, 2022 at 03:21:43PM +0100, Jan Kara wrote: > > You're right that VFS actually limits xattr size to 64k. So the chances > that someone actually has filesystem with larger xattrs are slim. But I > know that Lustre guys run with their modified kernels and they were the > ones implementing ea_inode feature so maybe they'd bumped the VFS limit as > well in their kernels. Dunno. Anyway using kvmalloc() (like the xattr core > does) looks like a better fix. I looked at this syzkaller report last night, and note that this was trying to move an extended attribute from the inode to an external inode block. Since it was in the inode, the largest the extended attribute should is going to be the inode size minus 140, plus or minus. So the real problem is that the xattr value size was completely invalid, and we weren't checking the extended attribute before trying to call ext4_xattr_move_to_block() or ext4_xattr_make_inode_space(). Cheers, - Ted
On Thu, Dec 01, 2022 at 03:21:43PM +0100, Jan Kara wrote: > You're right that VFS actually limits xattr size to 64k. So the chances > that someone actually has filesystem with larger xattrs are slim. But I > know that Lustre guys run with their modified kernels and they were the > ones implementing ea_inode feature so maybe they'd bumped the VFS limit as > well in their kernels. Upstream has 64K, so that's all that matters in the context of upstream. If someone changed it downstream, that's their problem. - Eric
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index 824faf0b15a8..22f0c89b1184 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h @@ -75,11 +75,12 @@ struct ext4_xattr_entry { * for file system consistency errors, we use a somewhat bigger value. * This allows XATTR_SIZE_MAX to grow in the future, but by using this * instead of INT_MAX for certain consistency checks, we don't need to - * worry about arithmetic overflows. (Actually XATTR_SIZE_MAX is - * defined in include/uapi/linux/limits.h, so changing it is going - * not going to be trivial....) - */ -#define EXT4_XATTR_SIZE_MAX (1 << 24) + * worry about arithmetic overflows. Now, MAX_ORDER is 11 kmalloc can + * allocate maxium size is 4M. (Actually XATTR_SIZE_MAX is defined in + * include/uapi/linux/limits.h, so changing it is going not going to + * be trivial....) + */ +#define EXT4_XATTR_SIZE_MAX (1 << 22) /* * The minimum size of EA value when you start storing it in an external inode