mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-21 01:51:18 +00:00
ext4: check for invalid block size early when mounting a file system
commit c9200760da
upstream.
Check for valid block size directly by validating s_log_block_size; we
were doing this in two places. First, by calculating blocksize via
BLOCK_SIZE << s_log_block_size, and then checking that the blocksize
was valid. And then secondly, by checking s_log_block_size directly.
The first check is not reliable, and can trigger an UBSAN warning if
s_log_block_size on a maliciously corrupted superblock is greater than
22. This is harmless, since the second test will correctly reject the
maliciously fuzzed file system, but to make syzbot shut up, and
because the two checks are duplicative in any case, delete the
blocksize check, and move the s_log_block_size earlier in
ext4_fill_super().
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reported-by: syzbot+345b75652b1d24227443@syzkaller.appspotmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8ed894f111
commit
721972b866
1 changed files with 16 additions and 24 deletions
|
@ -4186,19 +4186,26 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
|||
*/
|
||||
sbi->s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT;
|
||||
|
||||
blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
|
||||
if (le32_to_cpu(es->s_log_block_size) >
|
||||
(EXT4_MAX_BLOCK_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Invalid log block size: %u",
|
||||
le32_to_cpu(es->s_log_block_size));
|
||||
goto failed_mount;
|
||||
}
|
||||
if (le32_to_cpu(es->s_log_cluster_size) >
|
||||
(EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Invalid log cluster size: %u",
|
||||
le32_to_cpu(es->s_log_cluster_size));
|
||||
goto failed_mount;
|
||||
}
|
||||
|
||||
blocksize = EXT4_MIN_BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
|
||||
|
||||
if (blocksize == PAGE_SIZE)
|
||||
set_opt(sb, DIOREAD_NOLOCK);
|
||||
|
||||
if (blocksize < EXT4_MIN_BLOCK_SIZE ||
|
||||
blocksize > EXT4_MAX_BLOCK_SIZE) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Unsupported filesystem blocksize %d (%d log_block_size)",
|
||||
blocksize, le32_to_cpu(es->s_log_block_size));
|
||||
goto failed_mount;
|
||||
}
|
||||
|
||||
if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) {
|
||||
sbi->s_inode_size = EXT4_GOOD_OLD_INODE_SIZE;
|
||||
sbi->s_first_ino = EXT4_GOOD_OLD_FIRST_INO;
|
||||
|
@ -4416,21 +4423,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
|||
if (!ext4_feature_set_ok(sb, (sb_rdonly(sb))))
|
||||
goto failed_mount;
|
||||
|
||||
if (le32_to_cpu(es->s_log_block_size) >
|
||||
(EXT4_MAX_BLOCK_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Invalid log block size: %u",
|
||||
le32_to_cpu(es->s_log_block_size));
|
||||
goto failed_mount;
|
||||
}
|
||||
if (le32_to_cpu(es->s_log_cluster_size) >
|
||||
(EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Invalid log cluster size: %u",
|
||||
le32_to_cpu(es->s_log_cluster_size));
|
||||
goto failed_mount;
|
||||
}
|
||||
|
||||
if (le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) > (blocksize / 4)) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Number of reserved GDT blocks insanely large: %d",
|
||||
|
|
Loading…
Reference in a new issue