Skip to content

Commit 0a6ce20

Browse files
jankaratytso
authored andcommitted
ext4: verify orphan file size is not too big
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: 02f310f ("ext4: Speedup ext4 orphan inode handling") Cc: stable@kernel.org Signed-off-by: Jan Kara <jack@suse.cz> Message-ID: <20250909112206.10459-2-jack@suse.cz> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
1 parent 9638457 commit 0a6ce20

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

fs/ext4/orphan.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,9 +587,20 @@ int ext4_init_orphan_info(struct super_block *sb)
587587
ext4_msg(sb, KERN_ERR, "get orphan inode failed");
588588
return PTR_ERR(inode);
589589
}
590+
/*
591+
* This is just an artificial limit to prevent corrupted fs from
592+
* consuming absurd amounts of memory when pinning blocks of orphan
593+
* file in memory.
594+
*/
595+
if (inode->i_size > 8 << 20) {
596+
ext4_msg(sb, KERN_ERR, "orphan file too big: %llu",
597+
(unsigned long long)inode->i_size);
598+
ret = -EFSCORRUPTED;
599+
goto out_put;
600+
}
590601
oi->of_blocks = inode->i_size >> sb->s_blocksize_bits;
591602
oi->of_csum_seed = EXT4_I(inode)->i_csum_seed;
592-
oi->of_binfo = kmalloc_array(oi->of_blocks,
603+
oi->of_binfo = kvmalloc_array(oi->of_blocks,
593604
sizeof(struct ext4_orphan_block),
594605
GFP_KERNEL);
595606
if (!oi->of_binfo) {

0 commit comments

Comments
 (0)