Commit 82aa9b11 authored by Theodore Ts'o's avatar Theodore Ts'o Committed by Stefan Bader

ext4: add more inode number paranoia checks

BugLink: https://bugs.launchpad.net/bugs/1784409

commit c37e9e01 upstream.

If there is a directory entry pointing to a system inode (such as a
journal inode), complain and declare the file system to be corrupted.

Also, if the superblock's first inode number field is too small,
refuse to mount the file system.

This addresses CVE-2018-10882.

https://bugzilla.kernel.org/show_bug.cgi?id=200069Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
Cc: stable@kernel.org
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
parent fb2815d5
...@@ -1468,11 +1468,6 @@ static inline struct timespec ext4_current_time(struct inode *inode) ...@@ -1468,11 +1468,6 @@ static inline struct timespec ext4_current_time(struct inode *inode)
static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
{ {
return ino == EXT4_ROOT_INO || return ino == EXT4_ROOT_INO ||
ino == EXT4_USR_QUOTA_INO ||
ino == EXT4_GRP_QUOTA_INO ||
ino == EXT4_BOOT_LOADER_INO ||
ino == EXT4_JOURNAL_INO ||
ino == EXT4_RESIZE_INO ||
(ino >= EXT4_FIRST_INO(sb) && (ino >= EXT4_FIRST_INO(sb) &&
ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)); ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count));
} }
......
...@@ -3996,7 +3996,8 @@ static int __ext4_get_inode_loc(struct inode *inode, ...@@ -3996,7 +3996,8 @@ static int __ext4_get_inode_loc(struct inode *inode,
int inodes_per_block, inode_offset; int inodes_per_block, inode_offset;
iloc->bh = NULL; iloc->bh = NULL;
if (!ext4_valid_inum(sb, inode->i_ino)) if (inode->i_ino < EXT4_ROOT_INO ||
inode->i_ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))
return -EFSCORRUPTED; return -EFSCORRUPTED;
iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb); iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb);
......
...@@ -3582,6 +3582,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -3582,6 +3582,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
} else { } else {
sbi->s_inode_size = le16_to_cpu(es->s_inode_size); sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
sbi->s_first_ino = le32_to_cpu(es->s_first_ino); sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
if (sbi->s_first_ino < EXT4_GOOD_OLD_FIRST_INO) {
ext4_msg(sb, KERN_ERR, "invalid first ino: %u",
sbi->s_first_ino);
goto failed_mount;
}
if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) ||
(!is_power_of_2(sbi->s_inode_size)) || (!is_power_of_2(sbi->s_inode_size)) ||
(sbi->s_inode_size > blocksize)) { (sbi->s_inode_size > blocksize)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment