Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c37e9e01 authored by Theodore Ts'o's avatar Theodore Ts'o
Browse files

ext4: add more inode number paranoia checks

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=200069



Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
Cc: stable@kernel.org
parent 8bc1379b
Loading
Loading
Loading
Loading
+0 −5
Original line number Original line Diff line number Diff line
@@ -1502,11 +1502,6 @@ static inline struct ext4_inode_info *EXT4_I(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));
}
}
+2 −1
Original line number Original line Diff line number Diff line
@@ -4506,7 +4506,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);
+5 −0
Original line number Original line Diff line number Diff line
@@ -3858,6 +3858,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)) {