Skip to content

Commit 2b9da79

Browse files
jankaragregkh
authored andcommitted
ext4: verify orphan file size is not too big
commit 0a6ce20c156442a4ce2a404747bb0fb05d54eeb3 upstream. 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: [email protected] Fixes: 02f310f ("ext4: Speedup ext4 orphan inode handling") Cc: [email protected] Signed-off-by: Jan Kara <[email protected]> Message-ID: <[email protected]> Signed-off-by: Theodore Ts'o <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e966366 commit 2b9da79

1 file changed

Lines changed: 12 additions & 1 deletion

File tree

fs/ext4/orphan.c

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

0 commit comments

Comments
 (0)