From 653baf1a1fae420004d1013e011892edf8c99044 Mon Sep 17 00:00:00 2001 From: Liao Yuanhong Date: Mon, 24 Nov 2025 16:08:39 +0800 Subject: [PATCH 1/4] ext4: use kmalloc_array() for array space allocation stable inclusion from stable-v6.6.103 commit e0bb195aea7ab037fe9c82ed9ce99e225e8094f6 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICXO12 CVE: CVE-2025-38220 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=e0bb195aea7ab037fe9c82ed9ce99e225e8094f6 -------------------------------- commit 76dba1fe277f6befd6ef650e1946f626c547387a upstream. Replace kmalloc(size * sizeof) with kmalloc_array() for safer memory allocation and overflow prevention. Cc: stable@kernel.org Signed-off-by: Liao Yuanhong Link: https://patch.msgid.link/20250811125816.570142-1-liaoyuanhong@vivo.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman Signed-off-by: Yongjian Sun --- fs/ext4/orphan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c index e5b47dda3317..a23b0c01f809 100644 --- a/fs/ext4/orphan.c +++ b/fs/ext4/orphan.c @@ -590,8 +590,9 @@ int ext4_init_orphan_info(struct super_block *sb) } oi->of_blocks = inode->i_size >> sb->s_blocksize_bits; oi->of_csum_seed = EXT4_I(inode)->i_csum_seed; - oi->of_binfo = kmalloc(oi->of_blocks*sizeof(struct ext4_orphan_block), - GFP_KERNEL); + oi->of_binfo = kmalloc_array(oi->of_blocks, + sizeof(struct ext4_orphan_block), + GFP_KERNEL); if (!oi->of_binfo) { ret = -ENOMEM; goto out_put; -- Gitee From d56c8f74f27cd00fb1ea50b151b02fa054628cbd Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 24 Nov 2025 16:08:40 +0800 Subject: [PATCH 2/4] ext4: verify orphan file size is not too big mainline inclusion from mainline-v6.18-rc1 commit 0a6ce20c156442a4ce2a404747bb0fb05d54eeb3 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID6BVL CVE: CVE-2025-38220 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=0a6ce20c156442a4ce2a404747bb0fb05d54eeb3 -------------------------------- In principle orphan file can be arbitrarily large. However orphan replay needs to traverse it all and we also pin all its buffers in memory. Thus filesystems with absurdly large orphan files can lead to big amounts of memory consumed. Limit orphan file size to a sane value and also use kvmalloc() for allocating array of block descriptor structures to avoid large order allocations for sane but large orphan files. Reported-by: syzbot+0b92850d68d9b12934f5@syzkaller.appspotmail.com Fixes: 02f310fcf47f ("ext4: Speedup ext4 orphan inode handling") Cc: stable@kernel.org Signed-off-by: Jan Kara Message-ID: <20250909112206.10459-2-jack@suse.cz> Signed-off-by: Theodore Ts'o Signed-off-by: Yongjian Sun --- fs/ext4/orphan.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c index a23b0c01f809..4ea88ff7a689 100644 --- a/fs/ext4/orphan.c +++ b/fs/ext4/orphan.c @@ -588,9 +588,20 @@ int ext4_init_orphan_info(struct super_block *sb) ext4_msg(sb, KERN_ERR, "get orphan inode failed"); return PTR_ERR(inode); } + /* + * This is just an artificial limit to prevent corrupted fs from + * consuming absurd amounts of memory when pinning blocks of orphan + * file in memory. + */ + if (inode->i_size > 8 << 20) { + ext4_msg(sb, KERN_ERR, "orphan file too big: %llu", + (unsigned long long)inode->i_size); + ret = -EFSCORRUPTED; + goto out_put; + } oi->of_blocks = inode->i_size >> sb->s_blocksize_bits; oi->of_csum_seed = EXT4_I(inode)->i_csum_seed; - oi->of_binfo = kmalloc_array(oi->of_blocks, + oi->of_binfo = kvmalloc_array(oi->of_blocks, sizeof(struct ext4_orphan_block), GFP_KERNEL); if (!oi->of_binfo) { -- Gitee From 7598a0af5e2c346e0a3f936552dad965b45f12a8 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 24 Nov 2025 16:08:41 +0800 Subject: [PATCH 3/4] ext4: free orphan info with kvfree mainline inclusion from mainline-v6.18-rc2 commit 971843c511c3c2f6eda96c6b03442913bfee6148 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID6BVL CVE: CVE-2025-38220 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=971843c511c3c2f6eda96c6b03442913bfee6148 -------------------------------- Orphan info is now getting allocated with kvmalloc_array(). Free it with kvfree() instead of kfree() to avoid complaints from mm. Reported-by: Chris Mason Fixes: 0a6ce20c1564 ("ext4: verify orphan file size is not too big") Cc: stable@vger.kernel.org Signed-off-by: Jan Kara Message-ID: <20251007134936.7291-2-jack@suse.cz> Signed-off-by: Theodore Ts'o Signed-off-by: Yongjian Sun --- fs/ext4/orphan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c index 4ea88ff7a689..d4e79eb6aa21 100644 --- a/fs/ext4/orphan.c +++ b/fs/ext4/orphan.c @@ -517,7 +517,7 @@ void ext4_release_orphan_info(struct super_block *sb) return; for (i = 0; i < oi->of_blocks; i++) brelse(oi->of_binfo[i].ob_bh); - kfree(oi->of_binfo); + kvfree(oi->of_binfo); } static struct ext4_orphan_block_tail *ext4_orphan_block_tail( @@ -642,7 +642,7 @@ int ext4_init_orphan_info(struct super_block *sb) out_free: for (i--; i >= 0; i--) brelse(oi->of_binfo[i].ob_bh); - kfree(oi->of_binfo); + kvfree(oi->of_binfo); out_put: iput(inode); return ret; -- Gitee From a8c5c5d6f05e70205e78173e1dc53fee3610e4b8 Mon Sep 17 00:00:00 2001 From: Baokun Li Date: Mon, 24 Nov 2025 16:08:42 +0800 Subject: [PATCH 4/4] ext4: align max orphan file size with e2fsprogs limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit maillist inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID6BVL CVE: CVE-2025-40179 Reference: https://lore.kernel.org/all/20251120134233.2994147-1-libaokun@huaweicloud.com/ -------------------------------- Kernel commit 0a6ce20c1564 ("ext4: verify orphan file size is not too big") limits the maximum supported orphan file size to 8 << 20. However, in e2fsprogs, the orphan file size is set to 32–512 filesystem blocks when creating a filesystem. With 64k block size, formatting an ext4 fs >32G gives an orphan file bigger than the kernel allows, so mount prints an error and fails: EXT4-fs (vdb): orphan file too big: 8650752 EXT4-fs (vdb): mount failed To prevent this issue and allow previously created 64KB filesystems to mount, we updates the maximum allowed orphan file size in the kernel to 512 filesystem blocks. Fixes: 0a6ce20c1564 ("ext4: verify orphan file size is not too big") Signed-off-by: Baokun Li Signed-off-by: Yongjian Sun --- fs/ext4/orphan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c index d4e79eb6aa21..bb0aebb9c699 100644 --- a/fs/ext4/orphan.c +++ b/fs/ext4/orphan.c @@ -8,6 +8,8 @@ #include "ext4.h" #include "ext4_jbd2.h" +#define EXT4_MAX_ORPHAN_FILE_BLOCKS 512 + static int ext4_orphan_file_add(handle_t *handle, struct inode *inode) { int i, j, start; @@ -593,7 +595,7 @@ int ext4_init_orphan_info(struct super_block *sb) * consuming absurd amounts of memory when pinning blocks of orphan * file in memory. */ - if (inode->i_size > 8 << 20) { + if (inode->i_size > (EXT4_MAX_ORPHAN_FILE_BLOCKS << inode->i_blkbits)) { ext4_msg(sb, KERN_ERR, "orphan file too big: %llu", (unsigned long long)inode->i_size); ret = -EFSCORRUPTED; -- Gitee